Commit | Line | Data |
---|---|---|
88a4c51b FB |
1 | <?php |
2 | /*************************************************************************** | |
3 | * Copyright (C) 2003-2008 Polytechnique.org * | |
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 | ||
22 | ||
23 | /** The PlSession is a wrapper around the user session management. | |
24 | */ | |
25 | abstract class PlSession | |
26 | { | |
27 | /** Build a new session object. | |
28 | * If a session is already started, this just wraps the session... if no | |
29 | * session is currently started, this set the base session variables. | |
30 | * * auth contains the current authentication level. The level is | |
31 | * an integer that grows with the security of the authentication | |
32 | * method. | |
33 | * * perms contains the current permission flags of the user. This flags | |
34 | * depends on the category of the user. | |
35 | * * challenge contains a random uniq id for authentication. | |
36 | * * xsrf_token contains a random uniq id for xsrf prevention. | |
37 | * * user contains a reference to the current user. | |
38 | */ | |
39 | public function __construct() | |
40 | { | |
c0799142 | 41 | $this->create(); |
88a4c51b FB |
42 | } |
43 | ||
44 | /** Build the session structure with system fields. | |
45 | */ | |
46 | private function fillSession() | |
47 | { | |
48 | S::bootstrap('user', null); | |
49 | S::bootstrap('auth', AUTH_PUBLIC); | |
50 | S::bootstrap('challenge', sha1(uniqid(rand(), true))); | |
51 | S::bootstrap('xsrf_token', rand_url_id()); | |
52 | S::bootstrap('perms', new PlFlagSet()); | |
53 | } | |
54 | ||
55 | /** Write current session and close it. | |
56 | */ | |
57 | public function close() | |
58 | { | |
59 | session_write_close(); | |
60 | } | |
61 | ||
c0799142 FB |
62 | /** Create a new session |
63 | */ | |
64 | private function create() | |
65 | { | |
66 | session_start(); | |
67 | $this->fillSession(); | |
68 | } | |
69 | ||
88a4c51b FB |
70 | /** Kill the current session. |
71 | */ | |
72 | public function destroy() | |
73 | { | |
74 | session_destroy(); | |
75 | unset($_SESSION); | |
c0799142 | 76 | $this->create(); |
88a4c51b FB |
77 | } |
78 | ||
79 | /** Check if the user has at least the given authentication level. | |
80 | */ | |
81 | public function checkAuth($level) | |
82 | { | |
83 | return S::i('auth') >= $level; | |
84 | } | |
85 | ||
86 | /** Check if the user has the given permissions. | |
87 | */ | |
88 | public function checkPerms($perms) | |
89 | { | |
90 | return S::v('perms')->hasFlagCombination($perms); | |
91 | } | |
92 | ||
93 | /** Run authentication procedure to reach at least the given level. | |
94 | */ | |
95 | public function start($level) | |
96 | { | |
c0799142 | 97 | $backup = S::i($level); |
88a4c51b FB |
98 | if ($this->checkAuth($level)) { |
99 | return true; | |
100 | } | |
101 | $user = $this->doAuth($level); | |
c0799142 FB |
102 | if (is_null($user)) { |
103 | return false; | |
104 | } | |
105 | if (!$this->checkAuth($level)) { | |
106 | $this->destroy(); | |
88a4c51b FB |
107 | return false; |
108 | } | |
109 | if ($this->startSessionAs($user, $level)) { | |
110 | if (is_null(S::v('user'))) { | |
111 | S::set('user', $user); | |
112 | } | |
113 | return true; | |
114 | } else { | |
115 | $this->destroy(); | |
116 | } | |
117 | return false; | |
118 | } | |
119 | ||
120 | ||
121 | /*** Abstract methods ***/ | |
122 | ||
c0799142 FB |
123 | /** Function that check authentication at build time of the session object. |
124 | * This is useful to perform authentication from a cookie or when coming | |
125 | * back from a authentication service. | |
126 | * | |
127 | * This function must NOT try to launch a new authenticatioin procedure. It | |
128 | * just tests if the environment contains sufficient information to start | |
129 | * a user session. | |
130 | * | |
131 | * This function return false if informations are available but lead to an | |
132 | * authentication failure (invalid cookie, invalid service return data...) | |
133 | */ | |
134 | abstract public function startAvailableAuth(); | |
135 | ||
88a4c51b FB |
136 | /** Run the effectively authentication procedure to reach the given user. |
137 | * This method must return a user object (that will be used to fill the | |
138 | * $_SESSION['user'] field). | |
139 | * | |
140 | * If auth failed, the function MUST return null. If auth succeed, the | |
141 | * field $_SESSION['auth'] MUST be filled to the current effective level. | |
142 | */ | |
143 | abstract protected function doAuth($level); | |
144 | ||
145 | /** Set the session environment to the given user and authentication level. | |
146 | * This function MUST return false if a session is already started and the | |
147 | * user mismatch. | |
148 | * | |
149 | * On succes, this function MUST return true. | |
150 | * If $level is set to -1, this means you are building a new SUID session. | |
151 | */ | |
152 | abstract protected function startSessionAs($user, $level); | |
153 | ||
154 | ||
155 | /*** SUID management ***/ | |
156 | ||
157 | /** Start a new SUID session. | |
158 | */ | |
159 | public function startSUID($user) | |
160 | { | |
161 | if (isset($_SESSION['suid'])) { | |
162 | return false; | |
163 | } | |
164 | $newsession = array(); | |
165 | $backup =& $_SESSION; | |
166 | $_SESSION =& $newsession; | |
167 | $this->fillSession(); | |
168 | S::set('suid', $backup); | |
169 | if (!$this->startSessionAs($user, -1)) { | |
170 | $this->stopSUID(); | |
171 | return false; | |
172 | } | |
173 | return true; | |
174 | } | |
175 | ||
176 | /** Stop a SUID session | |
177 | */ | |
178 | public function stopSUID() | |
179 | { | |
180 | if (!isset($_SESSION['suid'])) { | |
181 | return false; | |
182 | } | |
183 | $_SESSION =& $_SESSION['suid']; | |
184 | return true; | |
185 | } | |
186 | ||
187 | ||
188 | /*** Thresholds ***/ | |
189 | ||
190 | /** Minimum level of authentication that is considered as sure. | |
191 | */ | |
192 | abstract public function sureLevel(); | |
193 | } | |
194 | ||
195 | // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: | |
196 | ?> |