HTTP authorization framework, first cut
parent
b3fcd179a0
commit
955387f5b7
|
@ -0,0 +1,25 @@
|
|||
! Copyright (C) 2008 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
IN: http.server.auth
|
||||
USING: new-slots accessors http.server.auth.providers.null
|
||||
http.server.auth.strategies.null ;
|
||||
|
||||
TUPLE: authentication responder provider strategy ;
|
||||
|
||||
: <authentication> ( responder -- authentication )
|
||||
null-auth-provider null-auth-strategy
|
||||
authentication construct-boa ;
|
||||
|
||||
SYMBOL: current-user-id
|
||||
SYMBOL: auth-provider
|
||||
SYMBOL: auth-strategy
|
||||
|
||||
M: authentication call-responder ( request path responder -- response )
|
||||
dup provider>> auth-provider set
|
||||
dup strategy>> auth-strategy set
|
||||
pick auth-provider get logged-in? dup current-user-id set
|
||||
[
|
||||
responder>> call-responder
|
||||
] [
|
||||
2drop auth-provider get require-login
|
||||
] if* ;
|
|
@ -0,0 +1,41 @@
|
|||
! Copyright (c) 2007 Chris Double.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: accessors new-slots quotations assocs kernel splitting
|
||||
base64 html.elements io combinators http.server
|
||||
http.server.auth.providers http.server.auth.providers.null
|
||||
http sequences ;
|
||||
IN: http.server.auth.basic
|
||||
|
||||
TUPLE: basic-auth responder realm provider ;
|
||||
|
||||
C: <basic-auth> basic-auth
|
||||
|
||||
: authorization-ok? ( provider header -- ? )
|
||||
#! Given the realm and the 'Authorization' header,
|
||||
#! authenticate the user.
|
||||
dup [
|
||||
" " split1 swap "Basic" = [
|
||||
base64> ":" split1 spin check-login
|
||||
] [
|
||||
2drop f
|
||||
] if
|
||||
] [
|
||||
2drop f
|
||||
] if ;
|
||||
|
||||
: <401> ( realm -- response )
|
||||
401 "Unauthorized" <trivial-response>
|
||||
"Basic realm=\"" rot "\"" 3append
|
||||
"WWW-Authenticate" set-header
|
||||
[
|
||||
<html> <body>
|
||||
"Username or Password is invalid" write
|
||||
</body> </html>
|
||||
] >>body ;
|
||||
|
||||
: logged-in? ( request responder -- ? )
|
||||
provider>> swap "authorization" header authorization-ok? ;
|
||||
|
||||
M: basic-auth call-responder ( request path responder -- response )
|
||||
pick over logged-in?
|
||||
[ responder>> call-responder ] [ 2nip realm>> <401> ] if ;
|
|
@ -0,0 +1,69 @@
|
|||
! Copyright (c) 2008 Slava Pestov
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: accessors new-slots quotations assocs kernel splitting
|
||||
base64 html.elements io combinators http.server
|
||||
http.server.auth.providers http.server.actions
|
||||
http.server.sessions http.server.templating.fhtml http sequences
|
||||
io.files namespaces ;
|
||||
IN: http.server.auth.login
|
||||
|
||||
TUPLE: login-auth responder provider ;
|
||||
|
||||
C: (login-auth) login-auth
|
||||
|
||||
SYMBOL: logged-in?
|
||||
SYMBOL: provider
|
||||
SYMBOL: post-login-url
|
||||
|
||||
: login-page ( -- response )
|
||||
"text/html" <content> [
|
||||
"extra/http/server/auth/login/login.fhtml"
|
||||
resource-path run-template-file
|
||||
] >>body ;
|
||||
|
||||
: <login-action>
|
||||
<action>
|
||||
[ login-page ] >>get
|
||||
|
||||
{
|
||||
{ "name" [ ] }
|
||||
{ "password" [ ] }
|
||||
} >>post-params
|
||||
[
|
||||
"password" get
|
||||
"name" get
|
||||
provider sget check-login [
|
||||
t logged-in? sset
|
||||
post-login-url sget <permanent-redirect>
|
||||
] [
|
||||
login-page
|
||||
] if
|
||||
] >>post ;
|
||||
|
||||
: <logout-action>
|
||||
<action>
|
||||
[
|
||||
f logged-in? sset
|
||||
request get "login" <permanent-redirect>
|
||||
] >>post ;
|
||||
|
||||
M: login-auth call-responder ( request path responder -- response )
|
||||
logged-in? sget
|
||||
[ responder>> call-responder ] [
|
||||
pick method>> "GET" = [
|
||||
nip
|
||||
provider>> provider sset
|
||||
dup request-url post-login-url sset
|
||||
"login" f session-link <permanent-redirect>
|
||||
] [
|
||||
3drop <400>
|
||||
] if
|
||||
] if ;
|
||||
|
||||
: <login-auth> ( responder provider -- auth )
|
||||
(login-auth)
|
||||
<dispatcher>
|
||||
swap >>default
|
||||
<login-action> "login" add-responder
|
||||
<logout-action> "logout" add-responder
|
||||
<cookie-sessions> ;
|
|
@ -0,0 +1,25 @@
|
|||
<html>
|
||||
<body>
|
||||
<h1>Login required</h1>
|
||||
|
||||
<form method="POST" action="login">
|
||||
<table>
|
||||
|
||||
<tr>
|
||||
<td>User name:</td>
|
||||
<td><input name="name" /></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>Password:</td>
|
||||
<td><input type="password" name="password" /></td>
|
||||
</tr>
|
||||
|
||||
</table>
|
||||
|
||||
<input type="submit" value="Log in" />
|
||||
|
||||
</form>
|
||||
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,18 @@
|
|||
IN: http.server.auth.providers.assoc.tests
|
||||
USING: http.server.auth.providers
|
||||
http.server.auth.providers.assoc tools.test
|
||||
namespaces ;
|
||||
|
||||
<assoc-auth-provider> "provider" set
|
||||
|
||||
"slava" "provider" get new-user
|
||||
|
||||
[ "slava" "provider" get new-user ] [ user-exists? ] must-fail-with
|
||||
|
||||
[ f ] [ "fdasf" "slava" "provider" get check-login ] unit-test
|
||||
|
||||
[ "xx" "blah" "provider" get set-password ] [ no-such-user? ] must-fail-with
|
||||
|
||||
"fdasf" "slava" "provider" get set-password
|
||||
|
||||
[ t ] [ "fdasf" "slava" "provider" get check-login ] unit-test
|
|
@ -0,0 +1,23 @@
|
|||
! Copyright (C) 2008 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
IN: http.server.auth.providers.assoc
|
||||
USING: new-slots accessors assocs kernel
|
||||
http.server.auth.providers ;
|
||||
|
||||
TUPLE: assoc-auth-provider assoc ;
|
||||
|
||||
: <assoc-auth-provider> ( -- provider )
|
||||
H{ } clone assoc-auth-provider construct-boa ;
|
||||
|
||||
M: assoc-auth-provider check-login
|
||||
assoc>> at = ;
|
||||
|
||||
M: assoc-auth-provider new-user
|
||||
assoc>>
|
||||
2dup key? [ drop user-exists ] when
|
||||
t -rot set-at ;
|
||||
|
||||
M: assoc-auth-provider set-password
|
||||
assoc>>
|
||||
2dup key? [ drop no-such-user ] unless
|
||||
set-at ;
|
|
@ -0,0 +1,24 @@
|
|||
IN: http.server.auth.providers.db.tests
|
||||
USING: http.server.auth.providers
|
||||
http.server.auth.providers.db tools.test
|
||||
namespaces db db.sqlite db.tuples continuations ;
|
||||
|
||||
db-auth-provider "provider" set
|
||||
|
||||
"auth-test.db" sqlite-db [
|
||||
|
||||
[ user drop-table ] ignore-errors
|
||||
[ user create-table ] ignore-errors
|
||||
|
||||
"slava" "provider" get new-user
|
||||
|
||||
[ "slava" "provider" get new-user ] [ user-exists? ] must-fail-with
|
||||
|
||||
[ f ] [ "fdasf" "slava" "provider" get check-login ] unit-test
|
||||
|
||||
[ "xx" "blah" "provider" get set-password ] [ no-such-user? ] must-fail-with
|
||||
|
||||
"fdasf" "slava" "provider" get set-password
|
||||
|
||||
[ t ] [ "fdasf" "slava" "provider" get check-login ] unit-test
|
||||
] with-db
|
|
@ -0,0 +1,53 @@
|
|||
! Copyright (C) 2008 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: db db.tuples db.types new-slots accessors
|
||||
http.server.auth.providers kernel ;
|
||||
IN: http.server.auth.providers.db
|
||||
|
||||
TUPLE: user name password ;
|
||||
|
||||
: <user> user construct-empty ;
|
||||
|
||||
user "USERS"
|
||||
{
|
||||
{ "name" "NAME" { VARCHAR 256 } +assigned-id+ }
|
||||
{ "password" "PASSWORD" { VARCHAR 256 } +not-null+ }
|
||||
} define-persistent
|
||||
|
||||
: init-users-table ( -- )
|
||||
user create-table ;
|
||||
|
||||
TUPLE: db-auth-provider ;
|
||||
|
||||
: db-auth-provider T{ db-auth-provider } ;
|
||||
|
||||
M: db-auth-provider check-login
|
||||
drop
|
||||
<user>
|
||||
swap >>name
|
||||
swap >>password
|
||||
select-tuple >boolean ;
|
||||
|
||||
M: db-auth-provider new-user
|
||||
drop
|
||||
[
|
||||
<user>
|
||||
swap >>name
|
||||
|
||||
dup select-tuple [ name>> user-exists ] when
|
||||
|
||||
"unassigned" >>password
|
||||
|
||||
insert-tuple
|
||||
] with-transaction ;
|
||||
|
||||
M: db-auth-provider set-password
|
||||
drop
|
||||
[
|
||||
<user>
|
||||
swap >>name
|
||||
|
||||
dup select-tuple [ ] [ no-such-user ] ?if
|
||||
|
||||
swap >>password update-tuple
|
||||
] with-transaction ;
|
|
@ -0,0 +1,14 @@
|
|||
! Copyright (C) 2008 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: http.server.auth.providers kernel ;
|
||||
IN: http.server.auth.providers.null
|
||||
|
||||
TUPLE: null-auth-provider ;
|
||||
|
||||
: null-auth-provider T{ null-auth-provider } ;
|
||||
|
||||
M: null-auth-provider check-login 3drop f ;
|
||||
|
||||
M: null-auth-provider new-user 3drop f ;
|
||||
|
||||
M: null-auth-provider set-password 3drop f ;
|
|
@ -0,0 +1,18 @@
|
|||
! Copyright (C) 2008 Slava Pestov.
|
||||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: kernel ;
|
||||
IN: http.server.auth.providers
|
||||
|
||||
GENERIC: check-login ( password user provider -- ? )
|
||||
|
||||
GENERIC: new-user ( user provider -- )
|
||||
|
||||
GENERIC: set-password ( password user provider -- )
|
||||
|
||||
TUPLE: user-exists name ;
|
||||
|
||||
: user-exists ( name -- * ) \ user-exists construct-boa throw ;
|
||||
|
||||
TUPLE: no-such-user name ;
|
||||
|
||||
: no-such-user ( name -- * ) \ no-such-user construct-boa throw ;
|
|
@ -4,6 +4,12 @@ kernel accessors ;
|
|||
|
||||
: with-session \ session swap with-variable ; inline
|
||||
|
||||
TUPLE: foo ;
|
||||
|
||||
C: <foo> foo
|
||||
|
||||
M: foo init-session drop 0 "x" sset ;
|
||||
|
||||
"1234" f <session> [
|
||||
[ ] [ 3 "x" sset ] unit-test
|
||||
|
||||
|
@ -18,8 +24,7 @@ kernel accessors ;
|
|||
[ t ] [ f <cookie-sessions> cookie-sessions? ] unit-test
|
||||
|
||||
[ ] [
|
||||
f <url-sessions>
|
||||
[ 0 "x" sset ] >>init
|
||||
<foo> <url-sessions>
|
||||
"manager" set
|
||||
] unit-test
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@ IN: http.server.sessions
|
|||
|
||||
GENERIC: init-session ( responder -- )
|
||||
|
||||
M: dispatcher init-session drop ;
|
||||
|
||||
TUPLE: session-manager responder sessions ;
|
||||
|
||||
: <session-manager> ( responder class -- responder' )
|
||||
|
|
|
@ -9,7 +9,7 @@ assocs ;
|
|||
|
||||
IN: http.server.templating.fhtml
|
||||
|
||||
: templating-vocab ( -- vocab-name ) "http.server.templating" ;
|
||||
: templating-vocab ( -- vocab-name ) "http.server.templating.fhtml" ;
|
||||
|
||||
! See apps/http-server/test/ or libs/furnace/ for template usage
|
||||
! examples
|
||||
|
|
Loading…
Reference in New Issue