FastCGI implementation in OCaml
1(** Authorizer role implementation for FastCGI.
2
3 The Authorizer role performs access control decisions for web requests.
4 An Authorizer FastCGI application receives all the information associated
5 with an HTTP request and generates an authorized/unauthorized decision.
6
7 In case of an authorized decision, the Authorizer can associate name-value
8 pairs with the HTTP request for use by subsequent processing stages. When
9 giving an unauthorized decision, the Authorizer sends a complete response
10 to the HTTP client with appropriate error information.
11
12 This role is commonly used for:
13 - Authentication and authorization checks
14 - Access control based on IP addresses, user roles, or request attributes
15 - Rate limiting and quota enforcement
16 - Custom security policies
17
18 The web server may proceed with additional access checks after a successful
19 authorization, including requests to other Authorizers, depending on its
20 configuration. *)
21
22(** {1 Authorization Types} *)
23
24(** Authorization result.
25
26 Represents the outcome of an authorization decision. The Authorizer can
27 either grant access (possibly with additional variables) or deny access
28 with a complete error response. *)
29type auth_result =
30 | Authorized of (string * string) list (** Request is authorized. The list contains
31 variable bindings that will be added to
32 the request environment for subsequent
33 processing stages. *)
34 | Unauthorized of {
35 status : int; (** HTTP status code for the error response
36 (typically 401, 403, or 429). *)
37 headers : (string * string) list; (** HTTP headers for the error response.
38 May include WWW-Authenticate, etc. *)
39 body : string; (** Error response body content sent to the client. *)
40 } (** Request is denied. The web server will send this error
41 response directly to the client without further processing. *)
42
43(** Authorization request information.
44
45 Contains the relevant information from an HTTP request needed to make
46 authorization decisions. This is extracted from the CGI environment
47 variables provided by the web server. *)
48type auth_request = {
49 method_ : string; (** HTTP method (GET, POST, etc.). *)
50 uri : string; (** Request URI being accessed. *)
51 remote_addr : string option; (** Client IP address, if available.
52 Useful for IP-based access control. *)
53 remote_user : string option; (** Authenticated username, if any.
54 Set by prior authentication stages. *)
55 auth_type : string option; (** Authentication method used (Basic, Bearer, etc.).
56 Indicates how the user was authenticated. *)
57 headers : (string * string) list; (** HTTP headers from the request.
58 May contain authorization headers, user agents, etc. *)
59}
60
61(** {1 Conversion Functions} *)
62
63(** Convert FastCGI request to authorization request.
64
65 Extracts authorization-relevant information from FastCGI
66 parameters and creates an auth request object.
67
68 @param request FastCGI request
69 @return Authorization request *)
70val request_of_fastcgi : 'a Fastcgi_types.request -> auth_request
71
72(** Convert authorization result to FastCGI response.
73
74 Writes the authorization decision to the FastCGI response
75 streams in the correct format.
76
77 @param result Authorization decision
78 @param response FastCGI response
79 @return Response result *)
80val response_of_result : auth_result -> 'a Fastcgi_types.response -> Fastcgi_types.response_result
81
82(** {1 Handler Utilities} *)
83
84(** Authorizer handler type. *)
85type 'a authorizer_handler = 'a Fastcgi_types.request -> 'a Fastcgi_types.response -> Fastcgi_types.response_result
86
87(** Convenience handler wrapper for authorization handlers.
88
89 Converts an authorization handler function into a FastCGI handler.
90 This allows writing handlers that work with auth request/result
91 types instead of raw FastCGI types.
92
93 @param handler Authorization handler function
94 @return FastCGI authorizer handler *)
95val auth_handler :
96 (auth_request -> auth_result) ->
97 'a authorizer_handler
98
99(** {1 Common Authorization Patterns} *)
100
101(** Create a simple allow/deny authorizer.
102
103 @param predicate Function that returns true for authorized requests
104 @return Authorization result *)
105val simple_authorizer : (auth_request -> bool) -> (auth_request -> auth_result)
106
107(** IP-based authorization.
108
109 @param allowed_ips List of allowed IP addresses/ranges
110 @param request Authorization request
111 @return Authorization result *)
112val ip_authorizer : string list -> auth_request -> auth_result
113
114(** User-based authorization.
115
116 @param allowed_users List of allowed usernames
117 @param request Authorization request
118 @return Authorization result *)
119val user_authorizer : string list -> auth_request -> auth_result
120
121(** Role-based authorization.
122
123 @param get_user_roles Function to get roles for a user
124 @param required_roles Roles required for access
125 @param request Authorization request
126 @return Authorization result *)
127val role_authorizer :
128 get_user_roles:(string -> string list) ->
129 required_roles:string list ->
130 auth_request ->
131 auth_result
132
133(** Time-based authorization.
134
135 @param allowed_hours List of allowed hours (0-23)
136 @param request Authorization request
137 @return Authorization result *)
138val time_authorizer : int list -> auth_request -> auth_result
139
140(** {1 Authentication Integration} *)
141
142(** Basic authentication handler.
143
144 @param realm Authentication realm
145 @param verify_credentials Function to verify username/password
146 @param request Authorization request
147 @return Authorization result *)
148val basic_auth :
149 realm:string ->
150 verify_credentials:(string -> string -> bool) ->
151 auth_request ->
152 auth_result
153
154(** Bearer token authentication.
155
156 @param verify_token Function to verify and decode token
157 @param request Authorization request
158 @return Authorization result *)
159val bearer_auth :
160 verify_token:(string -> (string * (string * string) list) option) ->
161 auth_request ->
162 auth_result
163
164(** API key authentication.
165
166 @param header_name Header containing API key
167 @param verify_key Function to verify API key
168 @param request Authorization request
169 @return Authorization result *)
170val api_key_auth :
171 header_name:string ->
172 verify_key:(string -> (string * (string * string) list) option) ->
173 auth_request ->
174 auth_result
175
176(** {1 Response Helpers} *)
177
178(** Create a standard 401 Unauthorized response.
179
180 @param realm Authentication realm
181 @param message Error message
182 @return Unauthorized result *)
183val unauthorized_response :
184 realm:string ->
185 message:string ->
186 auth_result
187
188(** Create a standard 403 Forbidden response.
189
190 @param message Error message
191 @return Unauthorized result *)
192val forbidden_response :
193 message:string ->
194 auth_result
195
196(** Create a custom error response.
197
198 @param status HTTP status code
199 @param headers Additional headers
200 @param body Response body
201 @return Unauthorized result *)
202val error_response :
203 status:int ->
204 headers:(string * string) list ->
205 body:string ->
206 auth_result
207
208(** {1 Variable Binding} *)
209
210(** Create authorized response with variables.
211
212 Variables are passed to subsequent FastCGI applications
213 as environment variables with "Variable-" prefix.
214
215 @param variables Name-value pairs to bind
216 @return Authorized result *)
217val authorized_with_variables : (string * string) list -> auth_result
218
219(** Add authentication information as variables.
220
221 @param user Authenticated username
222 @param auth_type Authentication method
223 @param additional Additional variables
224 @return Variable bindings *)
225val auth_variables :
226 user:string ->
227 auth_type:string ->
228 additional:(string * string) list ->
229 (string * string) list