#line 57 "/home/ubuntu/felix/src/packages/web.fdoc" include "web/__init__"; publish """ Implements Basic HTTP Authentication """ class HTTPBasicAuth { open HTTPConnection; open HTTPRequest; open Assoc_list; open HTTPResponse; open Base64; open ServerConfig; open HTTPHandler; publish """ A default app_handler for implementing Basic Auth. You must supply a function that takes a user name and password and returns fru or fals if authenticated. You must also supply a realm string which appears in the Authentication Prompt of the browser. This app_handler uses a route that applies to all pages """ fun app_handlers(auth_source:(string*string->bool),realm:string) => (Cons (http_handler(http_basic_auth_route,(http_basic_auth(auth_source,realm))), Empty[http_handler])); publish """ A default route for http auth applies to all pages """ fun http_basic_auth_route(config:server_config,request:http_request) => true; private fun basic(s:string) =>ltrim s "Basic "; publish """ Handler for http_basic_auth if Authorization header supplied by browser attemps to authenticate against auth source. If Authorization header not supplied send WWW-Authenticate header """ gen http_basic_auth (auth_source:(string*string->bool),realm:string) (conn:http_connection, request:http_request) = { http_basic_auth (auth_source,realm,"Unauthorized") (conn, request); } gen http_basic_auth (auth_source:(string*string->bool),realm:string,unauth_content:string) (conn:http_connection, request:http_request) = { if match (find (fun(x:string)=>x=="Authorization") request.headers) with |Some a => match split(decode(basic(a)),":") with |Cons(n,Cons(p,Empty)) => auth_source(n,p) |_ => false endmatch |_ => false endmatch do set_dirty(conn,false); return ; else val hdrs:assoc_list[string,string] = Cons (("WWW-Authenticate","Basic realm=\""+realm+"\""), Empty[string*string]); var us = make_unauthorized(hdrs,unauth_content); write(conn,us); done set_dirty(conn,true); return ; } publish """Authentication wrapper for a http_handler function, prcesses HTTP Authentication and passes control to handler if Authentication succedes otherwise returns Unauthorized response to the browser""" proc requires_auth (auth_source:(string*string->bool),realm:string, handler_fn:(http_connection*http_request) -> void) (conn:http_connection, request:http_request ) = { http_basic_auth (auth_source,realm) (conn, request); if not *conn.dirty do handler_fn(conn,request); done } proc requires_auth (auth_source:(string*string->bool),realm:string, handler_fn:(http_connection*http_request) -> void, unauthorized_content:string) (conn:http_connection, request:http_request ) = { http_basic_auth (auth_source,realm,unauthorized_content) (conn, request); if not *conn.dirty do handler_fn(conn,request); done } gen authorized_user (conn:http_connection, request:http_request) => match (find (fun(x:string)=>x=="Authorization") request.headers) with |Some a => match split(decode(basic(a)),":") with |Cons(n,Cons(p,Empty)) => Some n |_ => None[string] endmatch |_ => None[string] endmatch ; }