35
36:- module(user_db,
37 [ set_user_database/1, 38
39 user_add/2, 40 user_del/1, 41 set_user_property/2, 42
43 openid_add_server/2, 44 openid_del_server/1, 45 openid_set_property/2, 46 openid_current_server/1, 47 openid_server_property/2, 48 openid_server_properties/2, 49
50 user_property/2, 51 check_permission/2, 52 validate_password/2, 53 password_hash/2, 54
55 login/1, 56 login/2, 57 logout/1, 58 current_user/1, 59 logged_on/1, 60 logged_on/2, 61 ensure_logged_on/1, 62 authorized/1, 63
64 deny_all_users/1 65 ]). 66:- use_module(library(http/http_session)). 67:- use_module(library(http/http_wrapper)). 68:- use_module(library(http/http_openid)). 69:- use_module(library(http/http_authenticate)). 70:- use_module(library(lists)). 71:- use_module(library(broadcast)). 72:- use_module(library(error)). 73:- use_module(library(uri)). 74:- use_module(library(debug)). 75:- use_module(library(persistency)). 76:- use_module(openid).
91:- dynamic
92 logged_in/4, 93 user/2, 94 denied/1. 95
96
97 100
101:- persistent
102 user(_Name, _UserOptions),
103 grant_openid_server(_Server, _ServerOptions).
109set_user_database(File) :-
110 db_attach(File, [sync(close)]).
116user_add(Name, Options) :-
117 must_be(atom, Name),
118 assert_user(Name, Options).
124user_del(Name) :-
125 must_be(atom, Name),
126 ( user(Name, _)
127 -> retractall_user(Name, _)
128 ; existence_error(user, Name)
129 ).
135set_user_property(Name, Prop) :-
136 must_be(atom, Name),
137 ( user(Name, OldProps)
138 -> ( memberchk(Prop, OldProps)
139 -> true
140 ; functor(Prop, PropName, Arity),
141 functor(Unbound, PropName, Arity),
142 delete(OldProps, Unbound, NewProps),
143 retractall_user(Name, _),
144 assert_user(Name, [Prop|NewProps])
145 )
146 ; existence_error(user, Name)
147 ).
154openid_add_server(Server, _Options) :-
155 openid_current_server(Server),
156 !,
157 throw(error(permission_error(create, openid_server, Server),
158 context(_, 'Already present'))).
159openid_add_server(Server, Options) :-
160 assert_grant_openid_server(Server, Options).
167openid_del_server(Server) :-
168 retractall_grant_openid_server(Server, _).
175openid_set_property(Server, Prop) :-
176 must_be(atom, Server),
177 ( grant_openid_server(Server, OldProps)
178 -> ( memberchk(Prop, OldProps)
179 -> true
180 ; functor(Prop, PropName, Arity),
181 functor(Unbound, PropName, Arity),
182 delete(OldProps, Unbound, NewProps),
183 retractall_grant_openid_server(Server, _),
184 assert_grant_openid_server(Server, [Prop|NewProps])
185 )
186 ; existence_error(openid_server, Server)
187 ).
193openid_current_server(Server) :-
194 grant_openid_server(Server, _).
202:- dynamic
203 registered_server/2. 204
205openid_server_properties(Server, Properties) :-
206 ( registered_server(Server, Registered)
207 -> grant_openid_server(Registered, Properties)
208 ; grant_openid_server(Server, Properties)
209 -> true
210 ; grant_openid_server(Registered, Properties),
211 match_server(Server, Registered)
212 -> assert(registered_server(Server, Registered))
213 ; grant_openid_server(*, Properties)
214 ).
220match_server(Server, Registered) :-
221 uri_host(Server, SHost),
222 uri_host(Registered, RHost),
223 atomic_list_concat(SL, '.', SHost),
224 atomic_list_concat(RL, '.', RHost),
225 append(_, RL, SL),
226 !.
227
228uri_host(URI, Host) :-
229 uri_components(URI, CL),
230 uri_data(authority, CL, Authority),
231 uri_authority_components(Authority, AC),
232 uri_authority_data(host, AC, Host).
241openid_server_property(Server, Property) :-
242 openid_server_properties(Server, Properties),
243 ( var(Property)
244 -> member(Property, Properties)
245 ; memberchk(Property, Properties)
246 ).
247
248
249
257current_user(User) :-
258 user(User, _).
276user_property(User, Property) :-
277 nonvar(User), nonvar(Property),
278 !,
279 uprop(Property, User),
280 !.
281user_property(User, Property) :-
282 uprop(Property, User).
283
284uprop(session(SessionID), User) :-
285 ( nonvar(SessionID) 286 -> !
287 ; true
288 ),
289 logged_in(SessionID, User, _, _).
290uprop(connection(LoginTime, Idle), User) :-
291 logged_in(SessionID, User, LoginTime, _),
292 http_current_session(SessionID, idle(Idle)).
293uprop(url(URL), User) :-
294 ( http_in_session(SessionID),
295 logged_in(SessionID, User, _LoginTime, Options)
296 -> true
297 ; Options = []
298 ),
299 user_url(User, URL, Options).
300uprop(Prop, User) :-
301 nonvar(User),
302 !,
303 ( user(User, Properties)
304 -> true
305 ; openid_server(User, OpenID, Server),
306 openid_server_properties(Server, ServerProperties)
307 -> Properties = [ type(openid),
308 openid(OpenID),
309 openid_server(Server)
310 | ServerProperties
311 ]
312 ),
313 ( nonvar(Prop)
314 -> memberchk(Prop, Properties)
315 ; member(Prop, Properties)
316 ).
317uprop(Prop, User) :-
318 user(User, Properties),
319 member(Prop, Properties).
320
321
322user_url(User, URL, _) :-
323 uri_is_global(User),
324 !,
325 URL = User.
326user_url(User, URL, Options) :-
327 openid_for_local_user(User, URL, Options).
328
329
330
338validate_password(User, Password) :-
339 user(User, Options),
340 memberchk(password(Hash), Options),
341 password_hash(Password, Hash).
349password_hash(Password, Hash) :-
350 var(Hash),
351 !,
352 phrase("$1$", HashString, _),
353 crypt(Password, HashString),
354 atom_codes(Hash, HashString).
355password_hash(Password, Hash) :-
356 crypt(Password, Hash).
357
358
359
367logged_on(User) :-
368 http_in_session(SessionID),
369 user_property(User, session(SessionID)),
370 !.
371logged_on(User) :-
372 http_current_request(Request),
373 memberchk(authorization(Text), Request),
374 http_authorization_data(Text, basic(User, Password)),
375 validate_password(User, Password),
376 !.
384logged_on(User, Default) :-
385 ( logged_on(User0)
386 -> User = User0
387 ; User = Default
388 ).
396ensure_logged_on(User) :-
397 http_current_request(Request),
398 openid_user(Request, User, []).
408authorized(Action) :-
409 catch(check_permission(anonymous, Action), _, fail),
410 !.
411authorized(Action) :-
412 ensure_logged_on(User),
413 check_permission(User, Action).
422check_permission(User, Operation) :-
423 \+ denied(User, Operation),
424 user_property(User, allow(Operations)),
425 memberchk(Operation, Operations),
426 !.
427check_permission(_, _) :-
428 http_current_request(Request),
429 memberchk(path(Path), Request),
430 permission_error(http_location, access, Path).
438denied(admin, _) :- !, fail.
439denied(_, Operation) :-
440 denied(Operation).
447deny_all_users(Term) :-
448 ( denied(X),
449 X =@= Term
450 -> true
451 ; assert(denied(Term))
452 ).
460login(User) :-
461 login(User, []).
462login(User, Options) :-
463 must_be(atom, User),
464 get_time(Time),
465 open_session(Session),
466 retractall(logged_in(Session, _, _, _)),
467 asserta(logged_in(Session, User, Time, Options)),
468 broadcast(cliopatria(login(User, Session))),
469 debug(login, 'Login user ~w on session ~w', [User, Session]).
476logout(User) :-
477 must_be(atom, User),
478 broadcast(cliopatria(logout(User))),
479 retractall(logged_in(_Session, User, _Time, _Options)),
480 debug(login, 'Logout user ~w', [User]).
481
483
484:- listen(http_session(end(Session, _Peer)),
485 ( atom(Session),
486 retractall(logged_in(Session, _User, _Time, _Options))
487 )). 488
490
491:- http_set_session_options([ create(noauto)
492 ]). 493open_session(Session) :-
494 http_open_session(Session, [])
User administration
Core user administration. The user administration is based on the following:
preferences.pl
implements user preferencesopenid.pl
implements OpenID server and client */