annotate jamendo/sparql-archived/SeRQL/http_admin.pl @ 27:d95e683fbd35 tip

Enable CORS on urispace redirects as well
author Chris Cannam
date Tue, 20 Feb 2018 14:52:02 +0000
parents df9685986338
children
rev   line source
Chris@0 1 /* $Id$
Chris@0 2
Chris@0 3 Part of SWI-Prolog
Chris@0 4
Chris@0 5 Author: Jan Wielemaker
Chris@0 6 E-mail: wielemak@science.uva.nl
Chris@0 7 WWW: http://www.swi-prolog.org
Chris@0 8 Copyright (C): 1985-2007, University of Amsterdam
Chris@0 9
Chris@0 10 This program is free software; you can redistribute it and/or
Chris@0 11 modify it under the terms of the GNU General Public License
Chris@0 12 as published by the Free Software Foundation; either version 2
Chris@0 13 of the License, or (at your option) any later version.
Chris@0 14
Chris@0 15 This program is distributed in the hope that it will be useful,
Chris@0 16 but WITHOUT ANY WARRANTY; without even the implied warranty of
Chris@0 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Chris@0 18 GNU General Public License for more details.
Chris@0 19
Chris@0 20 You should have received a copy of the GNU Lesser General Public
Chris@0 21 License along with this library; if not, write to the Free Software
Chris@0 22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Chris@0 23
Chris@0 24 As a special exception, if you link this library with other files,
Chris@0 25 compiled with a Free Software compiler, to produce an executable, this
Chris@0 26 library does not by itself cause the resulting executable to be covered
Chris@0 27 by the GNU General Public License. This exception does not however
Chris@0 28 invalidate any other reasons why the executable file might be covered by
Chris@0 29 the GNU General Public License.
Chris@0 30 */
Chris@0 31
Chris@0 32 :- module(http_admin,
Chris@0 33 [ reload_attr/2 % +Window, -Attribute
Chris@0 34 ]).
Chris@0 35 :- use_module(user_db).
Chris@0 36 :- use_module(library('http/http_parameters')).
Chris@0 37 :- use_module(library('http/http_session')).
Chris@0 38 :- use_module(library('http/html_write')).
Chris@0 39 :- use_module(library('http/mimetype')).
Chris@0 40 :- use_module(library('http/http_dispatch')).
Chris@0 41 :- use_module(library(url)).
Chris@0 42 :- use_module(library(debug)).
Chris@0 43 :- use_module(library(lists)).
Chris@0 44 :- use_module(library(option)).
Chris@0 45 :- use_module(library(http_settings)).
Chris@0 46
Chris@0 47
Chris@0 48 :- http_handler('/admin/tasks', tasks, []).
Chris@0 49 :- http_handler('/admin/listUsers', list_users, []).
Chris@0 50 :- http_handler('/admin/form/createAdmin', create_admin, []).
Chris@0 51 :- http_handler('/admin/form/addUser', add_user_form, []).
Chris@0 52 :- http_handler('/admin/form/addOpenIDServer', add_openid_server_form, []).
Chris@0 53 :- http_handler('/admin/addUser', add_user, []).
Chris@0 54 :- http_handler('/admin/addOpenIDServer', add_openid_server, []).
Chris@0 55 :- http_handler('/admin/form/editUser', edit_user_form, []).
Chris@0 56 :- http_handler('/admin/editUser', edit_user, []).
Chris@0 57 :- http_handler('/admin/delUser', del_user, []).
Chris@0 58 :- http_handler('/admin/form/editOpenIDServer', edit_openid_server_form, []).
Chris@0 59 :- http_handler('/admin/editOpenIDServer', edit_openid_server, []).
Chris@0 60 :- http_handler('/admin/delOpenIDServer', del_openid_server, []).
Chris@0 61 :- http_handler('/admin/form/changePassword', change_password_form, []).
Chris@0 62 :- http_handler('/admin/changePassword', change_password, []).
Chris@0 63 :- http_handler('/user/form/login', login_form, []).
Chris@0 64 :- http_handler('/user/login', user_login, []).
Chris@0 65 :- http_handler('/user/logout', user_logout, []).
Chris@0 66 :- http_handler('/admin/settings', settings, []).
Chris@0 67 :- http_handler('/admin/save_settings', save_settings, []).
Chris@0 68 :- http_handler('/css/settings.css', http_reply_file(library('settings.css'), []), []).
Chris@0 69
Chris@0 70 %% tasks(+Request)
Chris@0 71 %
Chris@0 72 % Present menu with administrative tasks.
Chris@0 73
Chris@0 74 tasks(_Request) :-
Chris@0 75 reply_page('Administrative tasks',
Chris@0 76 [ \action('listUsers', 'List users')
Chris@0 77 ]).
Chris@0 78
Chris@0 79
Chris@0 80 action(URL, Label) -->
Chris@0 81 html([a([target=main, href=URL], Label), br([])]).
Chris@0 82
Chris@0 83 %% list_users(+Request)
Chris@0 84 %
Chris@0 85 % HTTP Handler listing registered users.
Chris@0 86
Chris@0 87 list_users(_Request) :-
Chris@0 88 authorized(admin(list_users)),
Chris@0 89 reply_page('Users',
Chris@0 90 [ h1('Users'),
Chris@0 91 \user_table,
Chris@0 92 p([ \action('form/addUser', 'Add user')
Chris@0 93 ]),
Chris@0 94 h1('OpenID servers'),
Chris@0 95 \openid_server_table,
Chris@0 96 p([ \action('form/addOpenIDServer', 'Add OpenID server')
Chris@0 97 ])
Chris@0 98 ]).
Chris@0 99
Chris@0 100 %% user_table//
Chris@0 101 %
Chris@0 102 % HTML DCG generating a table of registered users.
Chris@0 103
Chris@0 104 user_table -->
Chris@0 105 { setof(U, current_user(U), Users)
Chris@0 106 },
Chris@0 107 html([ table([ border(1)
Chris@0 108 ],
Chris@0 109 [ tr([ th('UserID'),
Chris@0 110 th('RealName'),
Chris@0 111 th('On since'),
Chris@0 112 th('Idle')
Chris@0 113 ])
Chris@0 114 | \list_users(Users)
Chris@0 115 ])
Chris@0 116 ]).
Chris@0 117
Chris@0 118 list_users([]) -->
Chris@0 119 [].
Chris@0 120 list_users([User|T]) -->
Chris@0 121 { user_property(User, realname(Name)),
Chris@0 122 www_form_encode(User, Encoded),
Chris@0 123 format(string(Edit), 'form/editUser?user=~w', [Encoded]),
Chris@0 124 findall(Idle-Login,
Chris@0 125 user_property(User, connection(Login, Idle)),
Chris@0 126 Pairs0),
Chris@0 127 keysort(Pairs0, Pairs),
Chris@0 128 ( Pairs == []
Chris@0 129 -> OnLine = (-)
Chris@0 130 ; length(Pairs, N),
Chris@0 131 Pairs = [Idle-Login|_],
Chris@0 132 OnLine = online(Login, Idle, N)
Chris@0 133 )
Chris@0 134 },
Chris@0 135 html(tr([ td(User),
Chris@0 136 td(Name),
Chris@0 137 td(\on_since(OnLine)),
Chris@0 138 td(\idle(OnLine)),
Chris@0 139 td(a(href(Edit), 'Edit'))
Chris@0 140 ])),
Chris@0 141 list_users(T).
Chris@0 142
Chris@0 143 on_since(online(Login, _Idle, _Connections)) --> !,
Chris@0 144 { format_time(string(Date), '%+', Login)
Chris@0 145 },
Chris@0 146 html(Date).
Chris@0 147 on_since(_) -->
Chris@0 148 html(-).
Chris@0 149
Chris@0 150 idle(online(_Login, Idle, _Connections)) -->
Chris@0 151 { mmss_duration(Idle, String)
Chris@0 152 },
Chris@0 153 html(String).
Chris@0 154 idle(_) -->
Chris@0 155 html(-).
Chris@0 156
Chris@0 157
Chris@0 158 mmss_duration(Time, String) :- % Time in seconds
Chris@0 159 Secs is round(Time),
Chris@0 160 Hour is Secs // 3600,
Chris@0 161 Min is (Secs // 60) mod 60,
Chris@0 162 Sec is Secs mod 60,
Chris@0 163 format(string(String), '~`0t~d~2|:~`0t~d~5|:~`0t~d~8|', [Hour, Min, Sec]).
Chris@0 164
Chris@0 165
Chris@0 166
Chris@0 167 /*******************************
Chris@0 168 * ADD USERS *
Chris@0 169 *******************************/
Chris@0 170
Chris@0 171 %% create_admin(+Request)
Chris@0 172 %
Chris@0 173 % Create the administrator login.
Chris@0 174
Chris@0 175 create_admin(_Request) :-
Chris@0 176 ( current_user(_)
Chris@0 177 -> throw(error(permission_error(create, user, admin),
Chris@0 178 context(_, 'Already initialized')))
Chris@0 179 ; true
Chris@0 180 ),
Chris@0 181 reply_page('Create administrator',
Chris@0 182 [ h1(align(center), 'Create administrator'),
Chris@0 183
Chris@0 184 p('No accounts are available on this server. \
Chris@0 185 This form allows for creation of an administrative \
Chris@0 186 account that can subsequently be used to create \
Chris@0 187 new users.'),
Chris@0 188
Chris@0 189 form([ action('../addUser'),
Chris@0 190 method('GET')
Chris@0 191 ],
Chris@0 192 [ \hidden(read, on),
Chris@0 193 \hidden(write, on),
Chris@0 194 \hidden(admin, on),
Chris@0 195
Chris@0 196 table([ border(1),
Chris@0 197 align(center)
Chris@0 198 ],
Chris@0 199 [ \input(user, 'Name',
Chris@0 200 [value('admin')]),
Chris@0 201 \input(realname, 'Realname',
Chris@0 202 [value('Administrator')]),
Chris@0 203 \input(pwd1, 'Password',
Chris@0 204 [type(password)]),
Chris@0 205 \input(pwd2, 'Retype',
Chris@0 206 [type(password)]),
Chris@0 207 tr(td([ colspan(2),
Chris@0 208 align(right)
Chris@0 209 ],
Chris@0 210 input([ type(submit),
Chris@0 211 value('Create')
Chris@0 212 ])))
Chris@0 213 ])
Chris@0 214 ])
Chris@0 215 ]).
Chris@0 216
Chris@0 217
Chris@0 218 %% add_user_form(+Request)
Chris@0 219 %
Chris@0 220 % Form to register a user.
Chris@0 221
Chris@0 222 add_user_form(_Request) :-
Chris@0 223 authorized(admin(add_user)),
Chris@0 224 reply_page('Add new user',
Chris@0 225 [ \new_user_form
Chris@0 226 ]).
Chris@0 227
Chris@0 228 new_user_form -->
Chris@0 229 html([ h1('Add new user'),
Chris@0 230 form([ action('../addUser'),
Chris@0 231 method('GET')
Chris@0 232 ],
Chris@0 233 table([ border(1)
Chris@0 234 ],
Chris@0 235 [ \input(user, 'Name',
Chris@0 236 []),
Chris@0 237 \input(realname, 'Realname',
Chris@0 238 []),
Chris@0 239 \input(pwd1, 'Password',
Chris@0 240 [type(password)]),
Chris@0 241 \input(pwd2, 'Retype',
Chris@0 242 [type(password)]),
Chris@0 243 \permissions(-),
Chris@0 244 tr(td([ colspan(2),
Chris@0 245 align(right)
Chris@0 246 ],
Chris@0 247 input([ type(submit),
Chris@0 248 value('Create')
Chris@0 249 ])))
Chris@0 250 ]))
Chris@0 251 ]).
Chris@0 252
Chris@0 253
Chris@0 254 input(Name, Label, Options) -->
Chris@0 255 html(tr([ td(align(right), Label),
Chris@0 256 td(input([name(Name),size(40)|Options]))
Chris@0 257 ])).
Chris@0 258
Chris@0 259 %% add_user(+Request)
Chris@0 260 %
Chris@0 261 % Register a new user.
Chris@0 262
Chris@0 263 add_user(Request) :-
Chris@0 264 ( \+ current_user(_)
Chris@0 265 -> true
Chris@0 266 ; authorized(admin(add_user))
Chris@0 267 ),
Chris@0 268 http_parameters(Request,
Chris@0 269 [ user(User, [ length > 2 ]),
Chris@0 270 realname(RealName, [ length > 2 ]),
Chris@0 271 pwd1(Password, [ length > 5 ]),
Chris@0 272 pwd2(Retype, [ length > 5 ]),
Chris@0 273 read(Read),
Chris@0 274 write(Write),
Chris@0 275 admin(Admin)
Chris@0 276 ],
Chris@0 277 [ attribute_declarations(attribute_decl)
Chris@0 278 ]),
Chris@0 279 ( current_user(User)
Chris@0 280 -> throw(error(permission_error(create, user, User),
Chris@0 281 context(_, 'Already present')))
Chris@0 282 ; true
Chris@0 283 ),
Chris@0 284 ( Password == Retype
Chris@0 285 -> true
Chris@0 286 ; throw(password_mismatch)
Chris@0 287 ),
Chris@0 288 password_hash(Password, Hash),
Chris@0 289 phrase(allow(Read, Write, Admin), Allow),
Chris@0 290 user_add(User,
Chris@0 291 [ realname(RealName),
Chris@0 292 password(Hash),
Chris@0 293 allow(Allow)
Chris@0 294 ]),
Chris@0 295 ( User == admin
Chris@0 296 -> user_add(anonymous,
Chris@0 297 [ realname('Define rights for not-logged in users'),
Chris@0 298 allow([read(_,_)])
Chris@0 299 ]),
Chris@0 300 reply_login([user(User), password(Password)])
Chris@0 301 ; list_users(Request)
Chris@0 302 ).
Chris@0 303
Chris@0 304 %% edit_user_form(+Request)
Chris@0 305 %
Chris@0 306 % Form to edit user properties
Chris@0 307
Chris@0 308 edit_user_form(Request) :-
Chris@0 309 authorized(admin(user(edit))),
Chris@0 310 http_parameters(Request,
Chris@0 311 [ user(User, [])
Chris@0 312 ]),
Chris@0 313
Chris@0 314 www_form_encode(User, Encoded),
Chris@0 315 format(string(Delete), '../delUser?user=~w', [Encoded]),
Chris@0 316
Chris@0 317 user_property(User, realname(RealName)),
Chris@0 318
Chris@0 319 reply_page('Edit user',
Chris@0 320 [ h4(['Edit user ', User, ' (', RealName, ')']),
Chris@0 321
Chris@0 322 form([ action('../editUser'),
Chris@0 323 method('GET')
Chris@0 324 ],
Chris@0 325 [ \hidden(user, User),
Chris@0 326 table([ border(1),
Chris@0 327 align(center)
Chris@0 328 ],
Chris@0 329 [ \user_property(User,
Chris@0 330 realname,
Chris@0 331 'Realname',
Chris@0 332 []),
Chris@0 333 \permissions(User),
Chris@0 334 tr(td([ colspan(2),
Chris@0 335 align(right)
Chris@0 336 ],
Chris@0 337 input([ type(submit),
Chris@0 338 value('Modify')
Chris@0 339 ])))
Chris@0 340 ])
Chris@0 341 ]),
Chris@0 342
Chris@0 343 p([ \action(Delete, [ 'Delete ',
Chris@0 344 b(User),
Chris@0 345 ' (', b(RealName), ')'
Chris@0 346 ])
Chris@0 347 ])
Chris@0 348 ]).
Chris@0 349
Chris@0 350 user_property(User, Name, Label, Options) -->
Chris@0 351 { Term =.. [Name, Value],
Chris@0 352 user_property(User, Term)
Chris@0 353 -> O2 = [value(Value)|Options]
Chris@0 354 ; O2 = Options
Chris@0 355 },
Chris@0 356 html(tr([ td(align(right), Label),
Chris@0 357 td(input([name(Name),size(40)|O2]))
Chris@0 358 ])).
Chris@0 359
Chris@0 360 permissions(User) -->
Chris@0 361 html(tr([ td(align(right), 'Permissions'),
Chris@0 362 td([ \permission_checkbox(User, read, 'Read'),
Chris@0 363 \permission_checkbox(User, write, 'Write'),
Chris@0 364 \permission_checkbox(User, admin, 'Admin')
Chris@0 365 ])
Chris@0 366 ])).
Chris@0 367
Chris@0 368 permission_checkbox(User, Name, Label) -->
Chris@0 369 { ( User \== (-),
Chris@0 370 ( user_property(User, allow(Actions))
Chris@0 371 -> true
Chris@0 372 ; openid_server_property(User, allow(Actions))
Chris@0 373 ),
Chris@0 374 pterm(Name, Action),
Chris@0 375 memberchk(Action, Actions)
Chris@0 376 -> Opts = [checked]
Chris@0 377 ; Opts = []
Chris@0 378 )
Chris@0 379 },
Chris@0 380 html([ input([ type(checkbox),
Chris@0 381 name(Name)
Chris@0 382 | Opts
Chris@0 383 ]),
Chris@0 384 Label
Chris@0 385 ]).
Chris@0 386
Chris@0 387 %% edit_user(Request)
Chris@0 388 %
Chris@0 389 % Handle reply from edit user form.
Chris@0 390
Chris@0 391 edit_user(Request) :-
Chris@0 392 authorized(admin(user(edit))),
Chris@0 393 http_parameters(Request,
Chris@0 394 [ user(User, []),
Chris@0 395 realname(RealName,
Chris@0 396 [ optional(true),
Chris@0 397 length > 2
Chris@0 398 ]),
Chris@0 399 read(Read),
Chris@0 400 write(Write),
Chris@0 401 admin(Admin)
Chris@0 402 ],
Chris@0 403 [ attribute_declarations(attribute_decl)
Chris@0 404 ]),
Chris@0 405 modify_user(User, realname(RealName)),
Chris@0 406 modify_permissions(User, Read, Write, Admin),
Chris@0 407 list_users(Request).
Chris@0 408
Chris@0 409
Chris@0 410 modify_user(User, Property) :-
Chris@0 411 Property =.. [_Name|Value],
Chris@0 412 ( ( var(Value)
Chris@0 413 ; Value == ''
Chris@0 414 )
Chris@0 415 -> true
Chris@0 416 ; set_user_property(User, Property)
Chris@0 417 ).
Chris@0 418
Chris@0 419 modify_permissions(User, Read, Write, Admin) :-
Chris@0 420 phrase(allow(Read, Write, Admin), Allow),
Chris@0 421 set_user_property(User, allow(Allow)).
Chris@0 422
Chris@0 423 allow(Read, Write, Admin) -->
Chris@0 424 allow(read, Read),
Chris@0 425 allow(write, Write),
Chris@0 426 allow(admin, Admin).
Chris@0 427
Chris@0 428 allow(Access, on) -->
Chris@0 429 { pterm(Access, Allow)
Chris@0 430 }, !,
Chris@0 431 [ Allow
Chris@0 432 ].
Chris@0 433 allow(_Access, off) --> !,
Chris@0 434 [].
Chris@0 435
Chris@0 436 pterm(read, read(_Repositiory, _Action)).
Chris@0 437 pterm(write, write(_Repositiory, _Action)).
Chris@0 438 pterm(admin, admin(_Action)).
Chris@0 439
Chris@0 440
Chris@0 441 %% del_user(+Request)
Chris@0 442 %
Chris@0 443 % Delete a user
Chris@0 444
Chris@0 445 del_user(Request) :- !,
Chris@0 446 authorized(admin(del_user)),
Chris@0 447 http_parameters(Request,
Chris@0 448 [ user(User, [])
Chris@0 449 ]),
Chris@0 450 ( User == admin
Chris@0 451 -> throw(error(permission_error(delete, user, User), _))
Chris@0 452 ; true
Chris@0 453 ),
Chris@0 454 user_del(User),
Chris@0 455 list_users(Request).
Chris@0 456
Chris@0 457
Chris@0 458 %% change_password_form(+Request)
Chris@0 459 %
Chris@0 460 % Allow user to change the password
Chris@0 461
Chris@0 462 change_password_form(_Request) :-
Chris@0 463 logged_on(User),
Chris@0 464 user_property(User, realname(RealName)),
Chris@0 465 reply_page('Change password',
Chris@0 466 [ h4(['Change password for ', User, ' (', RealName, ')']),
Chris@0 467
Chris@0 468 form([ action('../changePassword'),
Chris@0 469 method('GET')
Chris@0 470 ],
Chris@0 471 [ table([ border(1),
Chris@0 472 align(center)
Chris@0 473 ],
Chris@0 474 [ \user_or_old(User),
Chris@0 475 \input(pwd1, 'New Password',
Chris@0 476 [type(password)]),
Chris@0 477 \input(pwd2, 'Retype',
Chris@0 478 [type(password)]),
Chris@0 479 tr(td([ align(right),
Chris@0 480 colspan(2)
Chris@0 481 ],
Chris@0 482 input([ type(submit),
Chris@0 483 value('Change password')
Chris@0 484 ])))
Chris@0 485 ])
Chris@0 486 ])
Chris@0 487 ]).
Chris@0 488
Chris@0 489 user_or_old(admin) --> !,
Chris@0 490 input(user, 'User', []).
Chris@0 491 user_or_old(_) -->
Chris@0 492 input(pwd0, 'Old password', [type(password)]).
Chris@0 493
Chris@0 494
Chris@0 495 %% change_password(+Request)
Chris@0 496 %
Chris@0 497 % Actually change the password. The user must be logged on.
Chris@0 498
Chris@0 499 change_password(Request) :-
Chris@0 500 logged_on(Login),
Chris@0 501 http_parameters(Request,
Chris@0 502 [ user(User, [ optional(true) ]),
Chris@0 503 pwd0(Password, [ optional(true) ]),
Chris@0 504 pwd1(New, [ length > 5 ]),
Chris@0 505 pwd2(Retype, [ length > 5 ])
Chris@0 506 ]),
Chris@0 507 ( Login == admin
Chris@0 508 -> ( current_user(User)
Chris@0 509 -> true
Chris@0 510 ; throw(error(existence_error(user, User), _))
Chris@0 511 )
Chris@0 512 ; Login = User,
Chris@0 513 validate_password(User, Password)
Chris@0 514 ),
Chris@0 515 ( New == Retype
Chris@0 516 -> true
Chris@0 517 ; throw(password_mismatch)
Chris@0 518 ),
Chris@0 519 password_hash(New, Hash),
Chris@0 520 set_user_property(User, password(Hash)),
Chris@0 521 reply_page('Password changed',
Chris@0 522 [ h1(align(center), 'Password changed'),
Chris@0 523 p([ 'Your password has been changed successfully' ])
Chris@0 524 ]).
Chris@0 525
Chris@0 526
Chris@0 527 /*******************************
Chris@0 528 * LOGIN *
Chris@0 529 *******************************/
Chris@0 530
Chris@0 531 %% login_form(+Request)
Chris@0 532 %
Chris@0 533 % HTTP handler that presents a form to login.
Chris@0 534
Chris@0 535 login_form(_Request) :-
Chris@0 536 reply_page('Login',
Chris@0 537 [ h1(align(center), 'Login'),
Chris@0 538 form([ action('../login'),
Chris@0 539 method('GET')
Chris@0 540 ],
Chris@0 541 table([ tr([ th(align(right), 'User:'),
Chris@0 542 td(input([ name(user),
Chris@0 543 size(40)
Chris@0 544 ]))
Chris@0 545 ]),
Chris@0 546 tr([ th(align(right), 'Password:'),
Chris@0 547 td(input([ type(password),
Chris@0 548 name(password),
Chris@0 549 size(40)
Chris@0 550 ]))
Chris@0 551 ]),
Chris@0 552 tr([ td([ align(right), colspan(2) ],
Chris@0 553 input([ type(submit),
Chris@0 554 value('Login')
Chris@0 555 ]))
Chris@0 556 ])
Chris@0 557 ])
Chris@0 558 )
Chris@0 559 ]).
Chris@0 560
Chris@0 561 %% user_login(+Request)
Chris@0 562 %
Chris@0 563 % Handle =user= and =password=. If there is a parameter
Chris@0 564 % =return_to= or =|openid.return_to|=, reply using a redirect to
Chris@0 565 % the given URL. Otherwise display a welcome page.
Chris@0 566
Chris@0 567 user_login(Request) :- !,
Chris@0 568 http_parameters(Request,
Chris@0 569 [ user(User, []),
Chris@0 570 password(Password, []),
Chris@0 571 'openid.return_to'(ReturnTo, [optional(true)]),
Chris@0 572 'return_to'(ReturnTo, [optional(true)])
Chris@0 573 ]),
Chris@0 574 ( var(ReturnTo)
Chris@0 575 -> Extra = []
Chris@0 576 ; Extra = [ return_to(ReturnTo) ]
Chris@0 577 ),
Chris@0 578 reply_login([ user(User),
Chris@0 579 password(Password)
Chris@0 580 | Extra
Chris@0 581 ]).
Chris@0 582
Chris@0 583
Chris@0 584 reply_login(Options) :-
Chris@0 585 option(user(User), Options),
Chris@0 586 option(password(Password), Options),
Chris@0 587 validate_password(User, Password), !,
Chris@0 588 login(User),
Chris@0 589 ( option(return_to(ReturnTo), Options)
Chris@0 590 -> throw(http_reply(moved_temporary(ReturnTo)))
Chris@0 591 ; reload_attr(sidebar, OnLoad),
Chris@0 592 reply_page('Login ok',
Chris@0 593 body([ OnLoad
Chris@0 594 ],
Chris@0 595 [ h1(align(center), ['Welcome ', User])
Chris@0 596 ]))
Chris@0 597 ).
Chris@0 598 reply_login(_) :-
Chris@0 599 reply_page('Login failed',
Chris@0 600 [ h1(align(center), 'Login failed'),
Chris@0 601 p(['Password incorrect'])
Chris@0 602 ]).
Chris@0 603
Chris@0 604 %% user_logout(+Request)
Chris@0 605 %
Chris@0 606 % Logout the current user
Chris@0 607
Chris@0 608 user_logout(_Request) :-
Chris@0 609 logged_on(User),
Chris@0 610 logout(User),
Chris@0 611 reload_attr(sidebar, OnLoad),
Chris@0 612 reply_page('Logout',
Chris@0 613 body([ OnLoad
Chris@0 614 ],
Chris@0 615 [ h1(align(center), ['Logged out ', User])
Chris@0 616 ])).
Chris@0 617
Chris@0 618 reload_attr(Frame, onLoad(Script)) :-
Chris@0 619 concat_atom([ 'top.frames[\'', Frame, '\'].location=top.frames[\'',
Chris@0 620 Frame, '\'].location.href'
Chris@0 621 ], Script).
Chris@0 622
Chris@0 623
Chris@0 624 attribute_decl(read, Options) :- bool(off, Options).
Chris@0 625 attribute_decl(write, Options) :- bool(off, Options).
Chris@0 626 attribute_decl(admin, Options) :- bool(off, Options).
Chris@0 627
Chris@0 628 bool(Def,
Chris@0 629 [ default(Def),
Chris@0 630 type(oneof([on, off]))
Chris@0 631 ]).
Chris@0 632
Chris@0 633
Chris@0 634 /*******************************
Chris@0 635 * OPENID ADMIN *
Chris@0 636 *******************************/
Chris@0 637
Chris@0 638 %% add_openid_server_form(+Request)
Chris@0 639 %
Chris@0 640 % Register an OpenID server
Chris@0 641
Chris@0 642 add_openid_server_form(_Request) :-
Chris@0 643 authorized(admin(add_openid_server)),
Chris@0 644 reply_page('Add OpenID server',
Chris@0 645 [ \new_openid_form
Chris@0 646 ]).
Chris@0 647
Chris@0 648
Chris@0 649 %% new_openid_form// is det.
Chris@0 650 %
Chris@0 651 % Present form to add a new OpenID provider.
Chris@0 652
Chris@0 653 new_openid_form -->
Chris@0 654 html([ h1('Add new OpenID server'),
Chris@0 655 form([ action('../addOpenIDServer'),
Chris@0 656 method('GET')
Chris@0 657 ],
Chris@0 658 table([ border(1)
Chris@0 659 ],
Chris@0 660 [ \input(openid_server, 'Server homepage', []),
Chris@0 661 \input(openid_description, 'Server description',
Chris@0 662 []),
Chris@0 663 \permissions(-),
Chris@0 664 tr(td([ colspan(2),
Chris@0 665 align(right)
Chris@0 666 ],
Chris@0 667 input([ type(submit),
Chris@0 668 value('Create')
Chris@0 669 ])))
Chris@0 670 ])),
Chris@0 671 p([ 'Use this form to define access rights for users of an ',
Chris@0 672 a(href('http://www.openid.net'), 'OpenID'), ' server.',
Chris@0 673 'The special server', code(*), ' specifies access for all OpenID servers.',
Chris@0 674 'Here are some examples of servers:'
Chris@0 675 ]),
Chris@0 676 ul([ li(code('http://myopenid.com')),
Chris@0 677 li(code('http://videntity.org'))
Chris@0 678 ])
Chris@0 679 ]).
Chris@0 680
Chris@0 681
Chris@0 682 %% add_openid_server(+Request)
Chris@0 683 %
Chris@0 684 % Allow access from an OpenID server
Chris@0 685
Chris@0 686 add_openid_server(Request) :-
Chris@0 687 authorized(admin(add_openid_server)),
Chris@0 688 http_parameters(Request,
Chris@0 689 [ openid_server(Server0, []),
Chris@0 690 openid_description(Description, [ optional(true) ]),
Chris@0 691 read(Read),
Chris@0 692 write(Write)
Chris@0 693 ],
Chris@0 694 [ attribute_declarations(attribute_decl)
Chris@0 695 ]),
Chris@0 696 phrase(allow(Read, Write, off), Allow),
Chris@0 697 canonical_url(Server0, Server),
Chris@0 698 Options = [ description(Description),
Chris@0 699 allow(Allow)
Chris@0 700 ],
Chris@0 701 remove_optional(Options, Properties),
Chris@0 702 openid_add_server(Server, Properties),
Chris@0 703 list_users(Request).
Chris@0 704
Chris@0 705 remove_optional([], []).
Chris@0 706 remove_optional([H|T0], [H|T]) :-
Chris@0 707 arg(1, H, A),
Chris@0 708 nonvar(A), !,
Chris@0 709 remove_optional(T0, T).
Chris@0 710 remove_optional([_|T0], T) :-
Chris@0 711 remove_optional(T0, T).
Chris@0 712
Chris@0 713
Chris@0 714 canonical_url(Var, Var) :-
Chris@0 715 var(Var), !.
Chris@0 716 canonical_url(*, *) :- !.
Chris@0 717 canonical_url(URL0, URL) :-
Chris@0 718 parse_url(URL0, Parts),
Chris@0 719 parse_url(URL, Parts).
Chris@0 720
Chris@0 721
Chris@0 722 %% edit_openid_server_form(+Request)
Chris@0 723 %
Chris@0 724 % Form to edit user properties
Chris@0 725
Chris@0 726 edit_openid_server_form(Request) :-
Chris@0 727 authorized(admin(openid(edit))),
Chris@0 728 http_parameters(Request,
Chris@0 729 [ openid_server(Server, [])
Chris@0 730 ]),
Chris@0 731
Chris@0 732 www_form_encode(Server, Encoded),
Chris@0 733 format(string(Delete),
Chris@0 734 '../delOpenIDServer?openid_server=~w', [Encoded]),
Chris@0 735
Chris@0 736 reply_page('Edit OpenID server',
Chris@0 737 [ h4(['Edit OpenID server ', Server]),
Chris@0 738
Chris@0 739 form([ action('../editOpenIDServer'),
Chris@0 740 method('GET')
Chris@0 741 ],
Chris@0 742 [ \hidden(openid_server, Server),
Chris@0 743 table([ border(1)
Chris@0 744 ],
Chris@0 745 [ \openid_property(Server, description, 'Description', []),
Chris@0 746 \permissions(Server),
Chris@0 747 tr(td([ colspan(2),
Chris@0 748 align(right)
Chris@0 749 ],
Chris@0 750 input([ type(submit),
Chris@0 751 value('Modify')
Chris@0 752 ])))
Chris@0 753 ])
Chris@0 754 ]),
Chris@0 755
Chris@0 756 p([ \action(Delete, [ 'Delete ', b(Server) ]) ])
Chris@0 757 ]).
Chris@0 758
Chris@0 759
Chris@0 760 openid_property(Server, Name, Label, Options) -->
Chris@0 761 { Term =.. [Name, Value],
Chris@0 762 openid_server_property(Server, Term)
Chris@0 763 -> O2 = [value(Value)|Options]
Chris@0 764 ; O2 = Options
Chris@0 765 },
Chris@0 766 html(tr([ td(align(right), Label),
Chris@0 767 td(input([name(Name),size(40)|O2]))
Chris@0 768 ])).
Chris@0 769
Chris@0 770
Chris@0 771 %% openid_server_table//
Chris@0 772 %
Chris@0 773 % List registered openid servers
Chris@0 774
Chris@0 775 openid_server_table -->
Chris@0 776 { setof(S, openid_current_server(S), Servers), !
Chris@0 777 },
Chris@0 778 html([ table([ border(1)
Chris@0 779 ],
Chris@0 780 [ tr([ th('Server'),
Chris@0 781 th('Description')
Chris@0 782 ])
Chris@0 783 | \openid_list_servers(Servers)
Chris@0 784 ])
Chris@0 785 ]).
Chris@0 786 openid_server_table -->
Chris@0 787 [].
Chris@0 788
Chris@0 789 openid_list_servers([]) -->
Chris@0 790 [].
Chris@0 791 openid_list_servers([H|T]) -->
Chris@0 792 openid_list_server(H),
Chris@0 793 openid_list_servers(T).
Chris@0 794
Chris@0 795 openid_list_server(Server) -->
Chris@0 796 { www_form_encode(Server, Encoded),
Chris@0 797 format(string(Edit), 'form/editOpenIDServer?openid_server=~w', [Encoded])
Chris@0 798 },
Chris@0 799 html(tr([td(\openid_server(Server)),
Chris@0 800 td(\openid_field(Server, description)),
Chris@0 801 td(a(href(Edit), 'Edit'))
Chris@0 802 ])).
Chris@0 803
Chris@0 804 openid_server(*) --> !,
Chris@0 805 html(*).
Chris@0 806 openid_server(Server) -->
Chris@0 807 html(a(href(Server), Server)).
Chris@0 808
Chris@0 809 openid_field(Server, Field) -->
Chris@0 810 { Term =.. [Field, Value],
Chris@0 811 openid_server_property(Server, Term)
Chris@0 812 }, !,
Chris@0 813 html(Value).
Chris@0 814 openid_field(_, _) -->
Chris@0 815 [].
Chris@0 816
Chris@0 817
Chris@0 818 %% edit_openid_server(Request)
Chris@0 819 %
Chris@0 820 % Handle reply from OpenID server form.
Chris@0 821
Chris@0 822 edit_openid_server(Request) :-
Chris@0 823 authorized(admin(openid(edit))),
Chris@0 824 http_parameters(Request,
Chris@0 825 [ openid_server(Server, []),
Chris@0 826 description(Description,
Chris@0 827 [ optional(true),
Chris@0 828 length > 2
Chris@0 829 ]),
Chris@0 830 read(Read),
Chris@0 831 write(Write),
Chris@0 832 admin(Admin)
Chris@0 833 ],
Chris@0 834 [ attribute_declarations(attribute_decl)
Chris@0 835 ]),
Chris@0 836 modify_openid(Server, description(Description)),
Chris@0 837 openid_modify_permissions(Server, Read, Write, Admin),
Chris@0 838 list_users(Request).
Chris@0 839
Chris@0 840
Chris@0 841 modify_openid(User, Property) :-
Chris@0 842 Property =.. [_Name|Value],
Chris@0 843 ( ( var(Value)
Chris@0 844 ; Value == ''
Chris@0 845 )
Chris@0 846 -> true
Chris@0 847 ; openid_set_property(User, Property)
Chris@0 848 ).
Chris@0 849
Chris@0 850
Chris@0 851 openid_modify_permissions(Server, Read, Write, Admin) :-
Chris@0 852 phrase(allow(Read, Write, Admin), Allow),
Chris@0 853 openid_set_property(Server, allow(Allow)).
Chris@0 854
Chris@0 855
Chris@0 856 %% del_openid_server(+Request)
Chris@0 857 %
Chris@0 858 % Delete an OpenID Server
Chris@0 859
Chris@0 860 del_openid_server(Request) :- !,
Chris@0 861 authorized(admin(openid(delete))),
Chris@0 862 http_parameters(Request,
Chris@0 863 [ openid_server(Server, [])
Chris@0 864 ]),
Chris@0 865 openid_del_server(Server),
Chris@0 866 list_users(Request).
Chris@0 867
Chris@0 868
Chris@0 869 /*******************************
Chris@0 870 * SETTINGS *
Chris@0 871 *******************************/
Chris@0 872
Chris@0 873 %% settings(+Request)
Chris@0 874 %
Chris@0 875 % Show current settings. Is user is =admin=, allow editing the
Chris@0 876 % settings.
Chris@0 877
Chris@0 878 settings(_Request) :-
Chris@0 879 ( catch(authorized(admin(edit_settings)), _, fail)
Chris@0 880 -> Edit = true
Chris@0 881 ; authorized(read(admin, settings)),
Chris@0 882 Edit = false
Chris@0 883 ),
Chris@0 884 phrase(page([ title('Settings'),
Chris@0 885 link([ rel(stylesheet),
Chris@0 886 type('text/css'),
Chris@0 887 href('../css/settings.css')
Chris@0 888 ])
Chris@0 889 ],
Chris@0 890 [ \http_show_settings([ edit(Edit),
Chris@0 891 hide_module(false),
Chris@0 892 action('save_settings')
Chris@0 893 ])
Chris@0 894 ]), HTML),
Chris@0 895 format('Content-type: text/html~n~n'),
Chris@0 896 print_html(HTML).
Chris@0 897
Chris@0 898 %% save_settings(+Request)
Chris@0 899 %
Chris@0 900 % Save modified settings.
Chris@0 901
Chris@0 902 save_settings(Request) :-
Chris@0 903 authorized(admin(edit_settings)),
Chris@0 904 phrase(page([ title('Save settings'),
Chris@0 905 link([ rel(stylesheet),
Chris@0 906 type('text/css'),
Chris@0 907 href('../css/settings.css')
Chris@0 908 ])
Chris@0 909 ],
Chris@0 910 [ \http_apply_settings(Request, [save(true)])
Chris@0 911 ]), HTML),
Chris@0 912 format('Content-type: text/html~n~n'),
Chris@0 913 print_html(HTML).
Chris@0 914
Chris@0 915
Chris@0 916 /*******************************
Chris@0 917 * EMIT *
Chris@0 918 *******************************/
Chris@0 919
Chris@0 920 %% hidden(+Name, +Value)
Chris@0 921 %
Chris@0 922 % Create a hidden input field with given name and value
Chris@0 923
Chris@0 924 hidden(Name, Value) -->
Chris@0 925 html(input([ type(hidden),
Chris@0 926 name(Name),
Chris@0 927 value(Value)
Chris@0 928 ])).
Chris@0 929
Chris@0 930
Chris@0 931 reply_page(Title, Content) :-
Chris@0 932 phrase(page(title(Title), Content), HTML),
Chris@0 933 format('Content-type: text/html~n~n'),
Chris@0 934 print_html(HTML).
Chris@0 935
Chris@0 936 % Support Cross-Referencer and PceEmacs.
Chris@0 937
Chris@0 938 :- multifile
Chris@0 939 emacs_prolog_colours:goal_colours/2,
Chris@0 940 prolog:called_by/2.
Chris@0 941
Chris@0 942
Chris@0 943 emacs_prolog_colours:goal_colours(reply_page(_, HTML),
Chris@0 944 built_in-[classify, Colours]) :-
Chris@0 945 catch(html_write:html_colours(HTML, Colours), _, fail).
Chris@0 946 prolog:called_by(reply_page(_, HTML), Called) :-
Chris@0 947 catch(phrase(html_write:called_by(HTML), Called), _, fail).