Commit | Line | Data |
---|---|---|
24cfa984 AA |
1 | <?php |
2 | /*************************************************************************** | |
9f5bd98e | 3 | * Copyright (C) 2003-2010 Polytechnique.org * |
24cfa984 AA |
4 | * http://opensource.polytechnique.org/ * |
5 | * * | |
6 | * This program is free software; you can redistribute it and/or modify * | |
7 | * it under the terms of the GNU General Public License as published by * | |
8 | * the Free Software Foundation; either version 2 of the License, or * | |
9 | * (at your option) any later version. * | |
10 | * * | |
11 | * This program is distributed in the hope that it will be useful, * | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
14 | * GNU General Public License for more details. * | |
15 | * * | |
16 | * You should have received a copy of the GNU General Public License * | |
17 | * along with this program; if not, write to the Free Software * | |
18 | * Foundation, Inc., * | |
19 | * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * | |
20 | ***************************************************************************/ | |
21 | ||
a1af4a99 AA |
22 | |
23 | /* Definitions for the OpenId Specification | |
24 | * http://openid.net/specs/openid-authentication-2_0.html | |
7eaf07e9 | 25 | * |
a1af4a99 AA |
26 | * OP Endpoint URL: https://www.polytechnique.org/openid |
27 | * OP Identifier: https://www.polytechnique.org/openid | |
b21f0bb5 AA |
28 | * User Identifier: https://www.polytechnique.org/openid/{hruid} |
29 | * OP-Local Identifier: {hruid} | |
30 | */ | |
31 | ||
32 | /* This implementation supports two modes: | |
33 | * - entering the OP Identifier, which can simply be 'polytechnique.org' | |
34 | * - entering the User Identifier, or some URL that resolves there | |
35 | * In both cases, Yadis discovery is made possible through the X-XRDS-Location | |
36 | * header. | |
7eaf07e9 | 37 | * |
b21f0bb5 AA |
38 | * In the former case, Yadis discovery is performed on /, or where it redirects; |
39 | * see platal.php. It resolves to the XRDS for this OP, and User Identifier | |
40 | * selection is performed after forcing the user to log in. This only works for | |
41 | * version 2.0 of the OpenId protocol. | |
42 | * | |
43 | * In the latter cas, Yadis discovery is performed on /openid/{hruid}. It | |
44 | * resolves ta a user-specific XRDS. This page also features HTML-based | |
45 | * discovery. This works with any version of the protocol. | |
a1af4a99 AA |
46 | */ |
47 | ||
33536353 AA |
48 | /* Testing suite is here: |
49 | * http://openidenabled.com/resources/openid-test/ | |
b21f0bb5 AA |
50 | * It only supports User Indentifiers. |
51 | * | |
52 | * To test OP Identifiers, download the JanRain PHP library and use the | |
53 | * consumer provided as an example (although it appears that a failure is | |
54 | * mistakenly reported: 'Server denied check_authentication'). | |
55 | * Reading the source of the server can also help understanding the code below. | |
33536353 AA |
56 | */ |
57 | ||
33536353 | 58 | |
24cfa984 AA |
59 | class OpenidModule extends PLModule |
60 | { | |
61 | function handlers() | |
62 | { | |
63 | return array( | |
34d91db6 VZ |
64 | 'openid' => $this->make_hook('openid', AUTH_PUBLIC), |
65 | 'openid/melix' => $this->make_hook('melix', AUTH_PUBLIC), | |
66 | 'openid/xrds' => $this->make_hook('xrds', AUTH_PUBLIC), | |
67 | 'openid/trust' => $this->make_hook('trust', AUTH_MDP), | |
68 | 'openid/trusted' => $this->make_hook('trusted', AUTH_MDP), | |
69 | 'admin/openid/trusted' => $this->make_hook('admin_trusted', AUTH_MDP, 'admin'), | |
24cfa984 AA |
70 | ); |
71 | } | |
72 | ||
34d91db6 | 73 | function handler_openid(&$page, $login = null) |
24cfa984 | 74 | { |
a1af4a99 | 75 | $this->load('openid.inc.php'); |
34d91db6 VZ |
76 | $requested_user = User::getSilent($login); |
77 | $server = new OpenId(); | |
b69727b4 | 78 | |
a8e858d3 | 79 | // Spec §4.1.2: if "openid.mode" is absent, we SHOULD assume that |
34d91db6 VZ |
80 | // the request is not an OpenId message. |
81 | if (!$server->IsOpenIdRequest()) { | |
82 | if ($requested_user) { | |
83 | $server->RenderDiscoveryPage($page, $requested_user); | |
84 | return; | |
85 | } else { | |
86 | pl_redirect('Xorg/OpenId'); | |
87 | } | |
88 | exit; | |
24cfa984 AA |
89 | } |
90 | ||
34d91db6 VZ |
91 | // Initializes the OpenId environment from the request. |
92 | $server->Initialize(); | |
93 | ||
94 | // In modes 'checkid_immediate' and 'checkid_setup', we need to check | |
95 | // by ourselves that we want to allow the user to be authenticated. | |
96 | // Otherwise it can simply be forwarded to the Server object. | |
97 | if ($server->IsAuthorizationRequest()) { | |
98 | $authorized = S::logged() && | |
99 | $server->IsUserAuthorized(S::user()) && | |
100 | $server->IsEndpointTrusted(S::user()); | |
101 | ||
102 | if ($authorized) { | |
103 | // TODO(vzanotti): SReg requests are currently not honored if | |
104 | // the website is already trusted. We may want to redirect SReg | |
105 | // requests to /openid/trust, to allow the user to choose. | |
106 | $server->AnswerRequest(true); | |
107 | } else if ($server->IsImmediateRequest()) { | |
108 | $server->AnswerRequest(false); | |
109 | } else { | |
110 | // The user is currently not authorized to get her authorization | |
111 | // request approved. Two possibilities: | |
112 | // * the endpoint is not yet trusted => redirect to openid/trust | |
113 | // * the user is not logged in => log in the user. | |
114 | // | |
115 | // The second case requires a special handling when the request | |
116 | // was POSTed, as our current log in mechanism does not preserve | |
117 | // POST arguments. | |
118 | $openid_args = $server->GetQueryStringForRequest(); | |
119 | if (S::logged()) { | |
120 | pl_redirect('openid/trust', $openid_args); | |
c1390811 | 121 | } else if (Post::has('openid_mode')) { |
34d91db6 VZ |
122 | pl_redirect('openid', $openid_args); |
123 | } else { | |
124 | return PL_DO_AUTH; | |
125 | } | |
126 | } | |
127 | } else { | |
128 | $server->HandleRequest(); | |
129 | } | |
1bda7469 | 130 | |
34d91db6 VZ |
131 | // All requests should have been answered at this point. The best here |
132 | // is to get the user back to a safe page. | |
133 | pl_redirect(''); | |
134 | } | |
1bda7469 | 135 | |
34d91db6 VZ |
136 | function handler_melix(&$page, $login = null) |
137 | { | |
138 | $this->load('openid.inc.php'); | |
1bda7469 | 139 | |
34d91db6 VZ |
140 | global $globals; |
141 | $melix = ($login ? $login . '@' . $globals->mail->alias_dom : null); | |
a1af4a99 | 142 | |
34d91db6 VZ |
143 | if ($melix && ($requested_user = User::getSilent($melix))) { |
144 | $server = new OpenId(); | |
145 | $server->RenderDiscoveryPage($page, $requested_user); | |
33536353 | 146 | } else { |
34d91db6 | 147 | pl_redirect('Xorg/OpenId'); |
24cfa984 | 148 | } |
a1af4a99 | 149 | } |
b69727b4 | 150 | |
34d91db6 | 151 | function handler_xrds(&$page, $login = null) |
a1af4a99 AA |
152 | { |
153 | $this->load('openid.inc.php'); | |
34d91db6 VZ |
154 | $requested_user = User::getSilent($login); |
155 | $server = new OpenId(); | |
24cfa984 | 156 | |
34d91db6 VZ |
157 | if (!$login) { |
158 | $server->RenderMainXrdsPage($page); | |
159 | } else if ($requested_user) { | |
160 | $server->RenderUserXrdsPage($page, $requested_user); | |
161 | } else { | |
162 | return PL_NOT_FOUND; | |
a1af4a99 | 163 | } |
34d91db6 | 164 | } |
24cfa984 | 165 | |
34d91db6 VZ |
166 | function handler_trust(&$page) |
167 | { | |
168 | $this->load('openid.inc.php'); | |
169 | $server = new OpenId(); | |
a1af4a99 | 170 | $user = S::user(); |
b21f0bb5 | 171 | |
34d91db6 VZ |
172 | // Initializes the OpenId environment from the request. |
173 | if (!$server->Initialize() || !$server->IsAuthorizationRequest()) { | |
174 | $page->kill("Ta requête OpenID a échoué, merci de réessayer."); | |
a1af4a99 AA |
175 | } |
176 | ||
34d91db6 VZ |
177 | // Prepares the SREG data, if any is required. |
178 | $sreg_response = $server->GetSRegDataForRequest($user); | |
12d4424c | 179 | |
34d91db6 VZ |
180 | // Asks the user about her trust level of the current request, if not |
181 | // done yet. | |
182 | if (!Post::has('trust_accept') && !Post::has('trust_cancel')) { | |
a1af4a99 | 183 | $page->changeTpl('openid/trust.tpl'); |
34d91db6 VZ |
184 | $page->assign('openid_query', $server->GetQueryStringForRequest()); |
185 | $page->assign('relying_party', $server->GetEndpoint()); | |
186 | $page->assign('sreg_data', $sreg_response->contents()); | |
2e5fbf5e | 187 | |
34d91db6 | 188 | return; |
2e5fbf5e AA |
189 | } |
190 | ||
34d91db6 VZ |
191 | // Interprets the form results, and updates the user whitelist. |
192 | S::assert_xsrf_token(); | |
193 | $trusted = $server->UpdateEndpointTrust( | |
194 | $user, | |
195 | Post::b('trust_accept') && !Post::b('trust_cancel'), | |
196 | Post::b('trust_always')); | |
197 | ||
198 | // Finally answers the request. | |
199 | if ($server->IsUserAuthorized($user) && $trusted) { | |
80c1ab91 | 200 | $server->AnswerRequest(true, Post::b('trust_sreg') ? $sreg_response : null); |
34d91db6 VZ |
201 | } else { |
202 | $server->AnswerRequest(false); | |
a1af4a99 | 203 | } |
b69727b4 AA |
204 | } |
205 | ||
b8f1396f AA |
206 | function handler_trusted(&$page, $action = 'list', $id = null) |
207 | { | |
b8f1396f AA |
208 | $page->setTitle('Sites tiers de confiance'); |
209 | $page->assign('title', 'Mes sites tiers de confiance pour OpenId'); | |
864957c1 FB |
210 | $table_editor = new PLTableEditor('openid/trusted', 'account_auth_openid', 'id'); |
211 | $table_editor->set_where_clause(XDB::format('uid = {?}', S::user()->id())); | |
212 | $table_editor->vars['uid']['display'] = false; | |
b8f1396f AA |
213 | $table_editor->describe('url', 'site tiers', true); |
214 | $page->assign('deleteonly', true); | |
51e5bc7d AA |
215 | $table_editor->apply($page, $action, $id); |
216 | } | |
217 | ||
218 | function handler_admin_trusted(&$page, $action = 'list', $id = null) | |
219 | { | |
220 | $page->setTitle('Sites tiers de confiance'); | |
221 | $page->assign('title', 'Sites tiers de confiance globaux pour OpenId'); | |
864957c1 FB |
222 | $table_editor = new PLTableEditor('admin/openid/trusted', 'account_auth_openid', 'id'); |
223 | $table_editor->set_where_clause('uid IS NULL'); | |
224 | $table_editor->vars['uid']['display'] = false; | |
51e5bc7d AA |
225 | $table_editor->describe('url', 'site tiers', true); |
226 | $page->assign('readonly', true); | |
b8f1396f AA |
227 | $table_editor->apply($page, $action, $id); |
228 | } | |
24cfa984 AA |
229 | } |
230 | ||
231 | // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: | |
eb5a266d | 232 | ?> |