annotate jamendo/sparql-archived/SeRQL/openid.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): 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(rdfql_openid,
Chris@0 33 [ openid_for_local_user/2
Chris@0 34 ]).
Chris@0 35 :- use_module(library('http/http_dispatch')).
Chris@0 36 :- use_module(library('http/http_wrapper')).
Chris@0 37 :- use_module(library('http/http_openid')).
Chris@0 38 :- use_module(library('http/http_parameters')).
Chris@0 39 :- use_module(library('http/http_session')).
Chris@0 40 :- use_module(library('http/html_write')).
Chris@0 41 :- use_module(library(lists)).
Chris@0 42 :- use_module(library(error)).
Chris@0 43 :- use_module(library(option)).
Chris@0 44 :- use_module(library(url)).
Chris@0 45 :- use_module(library(socket)).
Chris@0 46 :- use_module(library(debug)).
Chris@0 47 :- use_module(library(settings)).
Chris@0 48 :- use_module(http_admin).
Chris@0 49 :- use_module(user_db).
Chris@0 50
Chris@0 51
Chris@0 52 /** <module> OpenID server and client access
Chris@0 53
Chris@0 54 @author Jan Wielemaker
Chris@0 55 */
Chris@0 56
Chris@0 57 /*******************************
Chris@0 58 * CUSTOMISE OPENID *
Chris@0 59 *******************************/
Chris@0 60
Chris@0 61 :- http_handler(prefix('/openid/grant'), openid_grant, []).
Chris@0 62 :- http_handler(prefix('/openid/file'), openid_file, []).
Chris@0 63
Chris@0 64 :- multifile
Chris@0 65 http_openid:openid_hook/2.
Chris@0 66
Chris@0 67 http_openid:openid_hook(login(OpenID)) :-
Chris@0 68 login(OpenID).
Chris@0 69 http_openid:openid_hook(logout(OpenID)) :-
Chris@0 70 logout(OpenID).
Chris@0 71 http_openid:openid_hook(logged_in(OpenID)) :-
Chris@0 72 http_session_id(Session),
Chris@0 73 user_property(OpenID, session(Session)).
Chris@0 74 http_openid:openid_hook(trusted(OpenID, Server)) :-
Chris@0 75 ( openid_server_properties(Server, _)
Chris@0 76 -> true
Chris@0 77 ; format(string(Msg), 'OpenID server ~w is not trusted', [Server]),
Chris@0 78 throw(error(permission_error(login, openid, OpenID),
Chris@0 79 context(_, Msg)))
Chris@0 80 ).
Chris@0 81
Chris@0 82
Chris@0 83 :- http_handler('/openid/login', login_page, [priority(10)]).
Chris@0 84
Chris@0 85 login_page(Request) :-
Chris@0 86 http_parameters(Request,
Chris@0 87 [ 'openid.return_to'(ReturnTo, [])
Chris@0 88 ]),
Chris@0 89 reply_html_page([ title('Login'),
Chris@0 90 \openid_css,
Chris@0 91 link([ rel(stylesheet),
Chris@0 92 type('text/css'),
Chris@0 93 href('../rdfql.css')
Chris@0 94 ])
Chris@0 95 ],
Chris@0 96 [ \explain_login(ReturnTo),
Chris@0 97 \openid_login_form(ReturnTo, []),
Chris@0 98 \local_login(ReturnTo)
Chris@0 99 ]).
Chris@0 100
Chris@0 101 explain_login(ReturnTo) -->
Chris@0 102 { parse_url(ReturnTo, Parts),
Chris@0 103 memberchk(path(Path), Parts)
Chris@0 104 },
Chris@0 105 html(div(class('rdfql-login'),
Chris@0 106 [ p([ 'You are trying to access a page (~w) that requires authorization.'-[Path],
Chris@0 107 'You can either login using an ', a(href('http://www.openid.net'), 'OpenID'),
Chris@0 108 \explain_trusted_openid
Chris@0 109 ])
Chris@0 110 ])).
Chris@0 111
Chris@0 112 explain_trusted_openid -->
Chris@0 113 { openid_current_server(*) }, !,
Chris@0 114 html(' or a local login.').
Chris@0 115 explain_trusted_openid -->
Chris@0 116 html([' from one of our ', a(href(list_trusted_servers), 'trusted providers'), ' or a local login']).
Chris@0 117
Chris@0 118 local_login(ReturnTo) -->
Chris@0 119 html(div(class('local-login'),
Chris@0 120 [ div(class('local-message'),
Chris@0 121 'Login with your local username and password'),
Chris@0 122 form([ action('../user/login'),
Chris@0 123 method('GET')
Chris@0 124 ],
Chris@0 125 [ \hidden('openid.return_to', ReturnTo),
Chris@0 126 div(input([name(user), size(20)])),
Chris@0 127 div([ input([name(password), size(20), type(password)]),
Chris@0 128 input([type(submit), value('login')])
Chris@0 129 ])
Chris@0 130 ])
Chris@0 131 ])).
Chris@0 132
Chris@0 133 hidden(Name, Value) -->
Chris@0 134 html(input([type(hidden), name(Name), value(Value)])).
Chris@0 135
Chris@0 136
Chris@0 137 :- http_handler('/openid/list_trusted_servers', trusted_openid_servers, []).
Chris@0 138
Chris@0 139 %% trusted_openid_servers(+Request)
Chris@0 140 %
Chris@0 141 % HTTP handler to emit a list of OpenID servers we trust.
Chris@0 142
Chris@0 143 trusted_openid_servers(_Request) :-
Chris@0 144 findall(S, openid_current_server(S), Servers),
Chris@0 145 reply_html_page(title('Trusted OpenID servers'),
Chris@0 146 [ h4('Trusted OpenID servers'),
Chris@0 147 p([ 'We accept OpenID logins from the following OpenID providers. ',
Chris@0 148 'Please register with one of them.'
Chris@0 149 ]),
Chris@0 150 ul(\trusted_openid_servers(Servers))
Chris@0 151 ]).
Chris@0 152
Chris@0 153 trusted_openid_servers([]) -->
Chris@0 154 [].
Chris@0 155 trusted_openid_servers([H|T]) -->
Chris@0 156 trusted_openid_server(H),
Chris@0 157 trusted_openid_servers(T).
Chris@0 158
Chris@0 159 trusted_openid_server(*) --> !.
Chris@0 160 trusted_openid_server(URL) -->
Chris@0 161 html(li(a(href(URL), URL))).
Chris@0 162
Chris@0 163
Chris@0 164 /*******************************
Chris@0 165 * OPENID SERVER *
Chris@0 166 *******************************/
Chris@0 167
Chris@0 168 :- http_handler(prefix('/user/'), openid_userpage, []).
Chris@0 169 :- http_handler(prefix('/openid/server'), openid_server([]), []).
Chris@0 170
Chris@0 171 http_openid:openid_hook(grant(Request, Options)) :-
Chris@0 172 ( option(identity(Identity), Options),
Chris@0 173 option(password(Password), Options),
Chris@0 174 file_base_name(Identity, User),
Chris@0 175 validate_password(User, Password)
Chris@0 176 -> option(trustroot(TrustRoot), Options),
Chris@0 177 debug(openid, 'Granted access for ~w to ~w', [Identity, TrustRoot])
Chris@0 178 ; memberchk(path(Path), Request),
Chris@0 179 throw(error(permission_error(http_location, access, Path),
Chris@0 180 context(_, 'Wrong password')))
Chris@0 181 ).
Chris@0 182
Chris@0 183
Chris@0 184 %% openid_userpage(+Request)
Chris@0 185 %
Chris@0 186 % Server user page for a registered user
Chris@0 187
Chris@0 188 openid_userpage(Request) :-
Chris@0 189 memberchk(path(Path), Request),
Chris@0 190 concat_atom(Parts, /, Path),
Chris@0 191 append(_, [user, User], Parts), !,
Chris@0 192 file_base_name(Path, User),
Chris@0 193 ( current_user(User)
Chris@0 194 -> http_global_url('../openid/server', Me),
Chris@0 195 findall(P, user_property(User, P), Props),
Chris@0 196 reply_html_page([ link([ rel('openid.server'),
Chris@0 197 href(Me)
Chris@0 198 ]),
Chris@0 199 title('OpenID page for user ~w'-[User])
Chris@0 200 ],
Chris@0 201 [ h1('OpenID page for user ~w'-[User]),
Chris@0 202 \user_properties(Props)
Chris@0 203 ])
Chris@0 204 ; existence_error(http_location, Path)
Chris@0 205 ).
Chris@0 206
Chris@0 207
Chris@0 208 user_properties([]) -->
Chris@0 209 [].
Chris@0 210 user_properties([H|T]) -->
Chris@0 211 user_property(H),
Chris@0 212 user_properties(T).
Chris@0 213
Chris@0 214 user_property(realname(Name)) --> !,
Chris@0 215 html(div(['Real name: ', Name])).
Chris@0 216 user_property(connection(Login, IdleF)) --> !,
Chris@0 217 { format_time(string(S), '%+', Login),
Chris@0 218 Idle is round(IdleF),
Chris@0 219 Hours is Idle // 3600,
Chris@0 220 Min is Idle mod 3600 // 60,
Chris@0 221 Sec is Idle mod 60
Chris@0 222 },
Chris@0 223 html(div(['Logged in since ~s, idle for ~d:~d:~d'-
Chris@0 224 [S, Hours,Min,Sec]])).
Chris@0 225 user_property(_) -->
Chris@0 226 [].
Chris@0 227
Chris@0 228
Chris@0 229 %% openid_for_local_user(+User, -URL) is semidet.
Chris@0 230 %
Chris@0 231 % URL is the OpenID for the local user User.
Chris@0 232
Chris@0 233 openid_for_local_user(User, URL) :-
Chris@0 234 http_current_request(Request),
Chris@0 235 openid_current_host(Request, Host, Port),
Chris@0 236 ( catch(setting(http:prefix, Prefix), _, fail)
Chris@0 237 -> true
Chris@0 238 ; Prefix = '/'
Chris@0 239 ),
Chris@0 240 ( Port == 80
Chris@0 241 -> format(atom(URL), 'http://~w~w/user/~w',
Chris@0 242 [ Host, Prefix, User ])
Chris@0 243 ; format(atom(URL), 'http://~w:~w/~w/user/~w',
Chris@0 244 [ Host, Port, Prefix, User ])
Chris@0 245 ).
Chris@0 246
Chris@0 247
Chris@0 248
Chris@0 249 /*******************************
Chris@0 250 * UTIL *
Chris@0 251 *******************************/
Chris@0 252
Chris@0 253 %% http_global_url(+Relative, -URL) is det.
Chris@0 254 %
Chris@0 255 % URL is a fully qualified URL relative to the current request.
Chris@0 256
Chris@0 257 http_global_url(Local, URL) :-
Chris@0 258 http_current_request(Request),
Chris@0 259 openid_current_host(Request, Host, Port),
Chris@0 260 option(path(Path), Request, '/'),
Chris@0 261 option(protocol(Protocol), Request, http),
Chris@0 262 Base = [ protocol(Protocol),
Chris@0 263 host(Host),
Chris@0 264 port(Port),
Chris@0 265 path(Path)
Chris@0 266 ],
Chris@0 267 global_url(Local, Base, URL).
Chris@0 268
Chris@0 269
Chris@0 270 /*******************************
Chris@0 271 * TEST *
Chris@0 272 *******************************/
Chris@0 273
Chris@0 274 :- http_handler('/user/form/login', login_handler, [priority(10)]).
Chris@0 275
Chris@0 276 login_handler(_Request) :-
Chris@0 277 ensure_logged_on(User),
Chris@0 278 user_property(User, url(URL)),
Chris@0 279 reload_attr(sidebar, OnLoad),
Chris@0 280 reply_html_page(title('Login ok'),
Chris@0 281 body(OnLoad,
Chris@0 282 [ h1('Login ok'),
Chris@0 283 p(['You''re logged on with OpenID ',
Chris@0 284 a(href(URL), URL)])
Chris@0 285 ])).