| 
									
										
										
										
											2010-10-24 18:54:19 -04:00
										 |  |  | ! Copyright (c) 2008, 2010 Slava Pestov | 
					
						
							| 
									
										
										
										
											2008-03-11 04:39:09 -04:00
										 |  |  | ! See http://factorcode.org/license.txt for BSD license. | 
					
						
							| 
									
										
										
										
											2008-05-26 01:47:27 -04:00
										 |  |  | USING: accessors assocs namespaces kernel sequences sets | 
					
						
							| 
									
										
										
										
											2010-10-24 18:54:19 -04:00
										 |  |  | destructors combinators fry logging io.encodings.utf8 | 
					
						
							|  |  |  | io.encodings.string io.binary io.sockets.secure random checksums | 
					
						
							|  |  |  | checksums.sha urls | 
					
						
							| 
									
										
										
										
											2008-06-16 04:34:17 -04:00
										 |  |  | html.forms | 
					
						
							| 
									
										
										
										
											2008-04-26 19:56:51 -04:00
										 |  |  | http.server | 
					
						
							| 
									
										
										
										
											2008-06-02 16:00:03 -04:00
										 |  |  | http.server.filters | 
					
						
							|  |  |  | http.server.dispatchers | 
					
						
							| 
									
										
										
										
											2008-06-16 04:34:17 -04:00
										 |  |  | furnace.actions | 
					
						
							| 
									
										
										
										
											2008-11-24 21:26:11 -05:00
										 |  |  | furnace.utilities | 
					
						
							| 
									
										
										
										
											2008-06-18 01:37:04 -04:00
										 |  |  | furnace.redirection | 
					
						
							| 
									
										
										
										
											2008-06-16 04:34:17 -04:00
										 |  |  | furnace.boilerplate | 
					
						
							|  |  |  | furnace.auth.providers | 
					
						
							|  |  |  | furnace.auth.providers.db ;
 | 
					
						
							| 
									
										
										
										
											2010-03-09 03:56:07 -05:00
										 |  |  | FROM: assocs => change-at ;
 | 
					
						
							| 
									
										
										
										
											2010-02-26 17:17:40 -05:00
										 |  |  | FROM: namespaces => set ;
 | 
					
						
							| 
									
										
										
										
											2008-06-01 18:22:39 -04:00
										 |  |  | IN: furnace.auth | 
					
						
							| 
									
										
										
										
											2008-03-11 04:39:09 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | SYMBOL: logged-in-user | 
					
						
							| 
									
										
										
										
											2008-03-17 05:31:13 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-09 18:04:20 -04:00
										 |  |  | : logged-in? ( -- ? )
 | 
					
						
							|  |  |  |     logged-in-user get >boolean ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : username ( -- string/f )
 | 
					
						
							|  |  |  |     logged-in-user get dup [ username>> ] when ;
 | 
					
						
							| 
									
										
										
										
											2008-06-16 04:46:54 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-03-17 05:31:13 -04:00
										 |  |  | GENERIC: init-user-profile ( responder -- )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: object init-user-profile drop ;
 | 
					
						
							| 
									
										
										
										
											2008-03-11 04:39:09 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-26 19:56:51 -04:00
										 |  |  | M: dispatcher init-user-profile | 
					
						
							|  |  |  |     default>> init-user-profile ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: filter-responder init-user-profile | 
					
						
							|  |  |  |     responder>> init-user-profile ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-30 05:53:01 -04:00
										 |  |  | : profile ( -- assoc ) logged-in-user get profile>> ;
 | 
					
						
							| 
									
										
										
										
											2008-03-17 05:31:13 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-04-30 05:53:01 -04:00
										 |  |  | : user-changed ( -- )
 | 
					
						
							|  |  |  |     logged-in-user get t >>changed? drop ;
 | 
					
						
							| 
									
										
										
										
											2008-03-17 05:31:13 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : uget ( key -- value )
 | 
					
						
							|  |  |  |     profile at ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : uset ( value key -- )
 | 
					
						
							| 
									
										
										
										
											2008-04-30 05:53:01 -04:00
										 |  |  |     profile set-at
 | 
					
						
							|  |  |  |     user-changed ;
 | 
					
						
							| 
									
										
										
										
											2008-03-17 05:31:13 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : uchange ( quot key -- )
 | 
					
						
							|  |  |  |     profile swap change-at
 | 
					
						
							| 
									
										
										
										
											2008-04-30 05:53:01 -04:00
										 |  |  |     user-changed ; inline
 | 
					
						
							| 
									
										
										
										
											2008-05-01 17:24:50 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | SYMBOL: capabilities | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | V{ } clone capabilities set-global
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-05-26 01:47:27 -04:00
										 |  |  | : define-capability ( word -- ) capabilities get adjoin ;
 | 
					
						
							| 
									
										
										
										
											2008-06-16 04:34:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-18 01:37:04 -04:00
										 |  |  | TUPLE: realm < dispatcher name users checksum secure ;
 | 
					
						
							| 
									
										
										
										
											2008-06-16 04:34:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-10 00:41:45 -04:00
										 |  |  | GENERIC: login-required* ( description capabilities realm -- response )
 | 
					
						
							| 
									
										
										
										
											2008-06-16 04:34:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-09-22 17:09:20 -04:00
										 |  |  | GENERIC: user-registered ( user realm -- response )
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: object user-registered 2drop URL" $realm" <redirect> ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-09 18:04:20 -04:00
										 |  |  | GENERIC: init-realm ( realm -- )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-16 04:34:17 -04:00
										 |  |  | GENERIC: logged-in-username ( realm -- username )
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-10 00:41:45 -04:00
										 |  |  | : login-required ( description capabilities -- * )
 | 
					
						
							|  |  |  |     realm get login-required* exit-with ;
 | 
					
						
							| 
									
										
										
										
											2008-06-16 04:34:17 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : new-realm ( responder name class -- realm )
 | 
					
						
							|  |  |  |     new-dispatcher | 
					
						
							|  |  |  |         swap >>name | 
					
						
							|  |  |  |         swap >>default | 
					
						
							|  |  |  |         users-in-db >>users | 
					
						
							| 
									
										
										
										
											2008-06-18 01:37:04 -04:00
										 |  |  |         sha-256 >>checksum | 
					
						
							| 
									
										
										
										
											2010-10-24 18:54:19 -04:00
										 |  |  |         ssl-supported? >>secure ; inline
 | 
					
						
							| 
									
										
										
										
											2008-06-16 04:34:17 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : users ( -- provider )
 | 
					
						
							|  |  |  |     realm get users>> ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: user-saver user ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | C: <user-saver> user-saver | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: user-saver dispose | 
					
						
							|  |  |  |     user>> dup changed?>> [ users update-user ] [ drop ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : save-user-after ( user -- )
 | 
					
						
							|  |  |  |     <user-saver> &dispose drop ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-16 06:16:51 -04:00
										 |  |  | : init-user ( user -- )
 | 
					
						
							|  |  |  |     [ [ logged-in-user set ] [ save-user-after ] bi ] when* ;
 | 
					
						
							| 
									
										
										
										
											2008-06-16 04:34:17 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-09 18:04:20 -04:00
										 |  |  | \ init-user DEBUG add-input-logging | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-16 04:34:17 -04:00
										 |  |  | M: realm call-responder* ( path responder -- response )
 | 
					
						
							|  |  |  |     dup realm set
 | 
					
						
							| 
									
										
										
										
											2008-07-09 18:04:20 -04:00
										 |  |  |     logged-in? [ | 
					
						
							|  |  |  |         dup init-realm | 
					
						
							|  |  |  |         dup logged-in-username | 
					
						
							|  |  |  |         dup [ users get-user ] when
 | 
					
						
							|  |  |  |         init-user | 
					
						
							|  |  |  |     ] unless
 | 
					
						
							| 
									
										
										
										
											2008-06-16 04:34:17 -04:00
										 |  |  |     call-next-method ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : encode-password ( string salt -- bytes )
 | 
					
						
							|  |  |  |     [ utf8 encode ] [ 4 >be ] bi* append
 | 
					
						
							|  |  |  |     realm get checksum>> checksum-bytes ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : >>encoded-password ( user string -- user )
 | 
					
						
							|  |  |  |     32 random-bits [ encode-password ] keep
 | 
					
						
							|  |  |  |     [ >>password ] [ >>salt ] bi* ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : valid-login? ( password user -- ? )
 | 
					
						
							|  |  |  |     [ salt>> encode-password ] [ password>> ] bi = ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : check-login ( password username -- user/f )
 | 
					
						
							|  |  |  |     users get-user dup [ [ valid-login? ] keep and ] [ 2drop f ] if ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-18 01:37:04 -04:00
										 |  |  | : if-secure-realm ( quot -- )
 | 
					
						
							|  |  |  |     realm get secure>> [ if-secure ] [ call ] if ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | TUPLE: secure-realm-only < filter-responder ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | C: <secure-realm-only> secure-realm-only | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | M: secure-realm-only call-responder* | 
					
						
							| 
									
										
										
										
											2008-09-10 23:11:40 -04:00
										 |  |  |     '[ _ _ call-next-method ] if-secure-realm ;
 | 
					
						
							| 
									
										
										
										
											2008-06-18 01:37:04 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-06-16 04:34:17 -04:00
										 |  |  | TUPLE: protected < filter-responder description capabilities ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : <protected> ( responder -- protected )
 | 
					
						
							|  |  |  |     protected new
 | 
					
						
							|  |  |  |         swap >>responder ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2008-07-09 18:04:20 -04:00
										 |  |  | : have-capabilities? ( capabilities -- ? )
 | 
					
						
							| 
									
										
										
										
											2008-09-08 02:11:09 -04:00
										 |  |  |     realm get secure>> secure-connection? not and [ drop f ] [ | 
					
						
							|  |  |  |         logged-in-user get { | 
					
						
							|  |  |  |             { [ dup not ] [ 2drop f ] } | 
					
						
							|  |  |  |             { [ dup deleted>> 1 = ] [ 2drop f ] } | 
					
						
							|  |  |  |             [ capabilities>> subset? ] | 
					
						
							|  |  |  |         } cond
 | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-06-16 04:34:17 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | M: protected call-responder* ( path responder -- response )
 | 
					
						
							| 
									
										
										
										
											2008-09-08 02:11:09 -04:00
										 |  |  |     dup protected set
 | 
					
						
							|  |  |  |     dup capabilities>> have-capabilities? | 
					
						
							|  |  |  |     [ call-next-method ] [ | 
					
						
							|  |  |  |         [ drop ] [ [ description>> ] [ capabilities>> ] bi ] bi*
 | 
					
						
							|  |  |  |         realm get login-required* | 
					
						
							|  |  |  |     ] if ;
 | 
					
						
							| 
									
										
										
										
											2008-06-16 04:34:17 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : <auth-boilerplate> ( responder -- responder' )
 | 
					
						
							|  |  |  |     <boilerplate> { realm "boilerplate" } >>template ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : password-mismatch ( -- * )
 | 
					
						
							|  |  |  |     "passwords do not match" validation-error | 
					
						
							| 
									
										
										
										
											2008-07-10 00:41:45 -04:00
										 |  |  |     validation-failed ;
 | 
					
						
							| 
									
										
										
										
											2008-06-16 04:34:17 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : same-password-twice ( -- )
 | 
					
						
							|  |  |  |     "new-password" value "verify-password" value =
 | 
					
						
							|  |  |  |     [ password-mismatch ] unless ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : user-exists ( -- * )
 | 
					
						
							|  |  |  |     "username taken" validation-error | 
					
						
							| 
									
										
										
										
											2008-07-10 00:41:45 -04:00
										 |  |  |     validation-failed ;
 |