]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/WikiUser.php
Big refactor of lib/WikiUser.php. The login mechanism no longer uses
[SourceForge/phpwiki.git] / lib / WikiUser.php
1 <?php rcs_id('$Id: WikiUser.php,v 1.10 2002-01-19 07:21:58 dairiki Exp $');
2
3 // It is anticipated that when userid support is added to phpwiki,
4 // this object will hold much more information (e-mail, home(wiki)page,
5 // etc.) about the user.
6    
7 // There seems to be no clean way to "log out" a user when using
8 // HTTP authentication.
9 // So we'll hack around this by storing the currently logged
10 // in username and other state information in a cookie.
11
12 define('WIKIAUTH_ANON', 0);
13 define('WIKIAUTH_BOGO', 1);
14 define('WIKIAUTH_USER', 2);     // currently unused.
15 define('WIKIAUTH_ADMIN', 10);
16
17 class WikiUser 
18 {
19     var $_userid = false;
20     var $_level  = false;
21
22     /**
23      * Constructor.
24      */
25     function WikiUser (&$request) {
26         $this->_request = &$request;
27
28         // Restore from session state.
29         $this->_restore();
30
31         $login_args = $request->getArg('login');
32         if ($login_args) {
33             $request->setArg('login', false);
34             if ($request->get('REQUEST_METHOD') == 'POST')
35                 $this->_handleLoginPost($login_args);
36         }
37     }
38
39     function _handleLoginPost ($postargs) {
40         if (!is_array($postargs))
41             return;
42
43         $keys = array('userid', 'password', 'require_level', 'login', 'logout', 'cancel');
44         foreach ($keys as $key) 
45             $args[$key] = isset($postargs[$key]) ? $postargs[$key] : false;
46         extract($args);
47         $require_level = max(0, min(WIKIAUTH_ADMIN, (int) $require_level));
48
49         if ($logout) {
50             // logout button
51             $this->logout();
52             return;
53         }
54         if ($cancel)
55             return;             // user hit cancel button.
56         if (!$login && !$userid)
57             return;
58         
59         if ($this->attemptLogin($userid, $password, $require_level))
60             return;             // login succeeded
61
62         if ($this->_pwcheck($userid, $password))
63             $failmsg = _("Insufficient permissions.");
64         elseif ($password !== false)
65             $failmsg = _("Invalid password or userid.");
66         else
67             $failmsg = '';
68
69         $this->showLoginForm($require_level, $userid, $failmsg);
70     }
71         
72     /**
73      */
74     function requireAuth ($require_level) {
75         if ($require_level > $this->_level)
76             $this->showLoginForm($require_level);
77     }
78     
79     function showLoginForm ($require_level = 0, $default_user = false, $fail_message = '') {
80
81         include_once('lib/Template.php');
82         
83         $login = new WikiTemplate('login');
84
85         $login->qreplace('REQUIRE', $require_level);
86         
87         if (!empty($default_user))
88             $login->qreplace('DEFAULT_USERID', $default_user);
89         elseif (!empty($this->_failed_userid))
90             $login->qreplace('DEFAULT_USERID', $this->_failed_userid);
91
92         if ($fail_message)
93             $login->qreplace('FAILURE_MESSAGE', $fail_message);
94
95         // FIXME: Need message: You must sign/log in before you can '%s' '%s'.
96         $top = new WikiTemplate('top');
97         $top->replace('TITLE', _("Sign In"));
98         $top->replace('HEADER', _("Please Sign In"));
99
100         $top->printExpansion($login);
101         ExitWiki();
102     }
103       
104     /**
105      * Logout the current user (if any).
106      */
107     function logout () {
108         $this->_level = false;
109         $this->_userid = false;
110         $this->_save();
111     }
112
113     /**
114      * Attempt to log in.
115      *
116      * @param $userid string Username.
117      * @param $password string Password.
118      * @return bool True iff log in was successful.
119      */
120     function attemptLogin ($userid, $password = false, $require_level = 0) {
121         $level = $this->_pwcheck ($userid, $password);
122         if ($level === false) {
123             // bad password
124             return false;
125         }
126         if ($level < $require_level) {
127             // insufficient access
128             return false;
129         }
130         
131         // Success!
132         $this->_login($userid, $level);
133         return $this->isSignedIn();
134     }
135
136         
137             
138     function getId () {
139         return ( $this->isSignedIn()
140                  ? $this->_userid
141                  : $this->_request->get('REMOTE_ADDR') ); 
142     }
143
144     function getAuthenticatedId() {
145         return ( $this->isAuthenticated()
146                  ? $this->_userid
147                  : $this->_request->get('REMOTE_ADDR') ); 
148     }
149
150     function isSignedIn () {
151         return $this->_level >= WIKIAUTH_BOGO;
152     }
153         
154     function isAuthenticated () {
155         return $this->_level >= WIKIAUTH_USER;
156     }
157          
158     function isAdmin () {
159         return $this->_level == WIKIAUTH_ADMIN;
160     }
161
162     /**
163      * Login with given access level
164      *
165      * No check for correct password is done.
166      */
167     function _login ($userid, $level = WIKIAUTH_BOGO) {
168         $this->_userid = $userid;
169         $this->_level = $level;
170         $this->_save();
171     }
172
173     /**
174      * Check password.
175      */
176     function _pwcheck ($userid, $passwd) {
177         global $WikiNameRegexp;
178         
179         if (!empty($userid) && $userid == ADMIN_USER) {
180             if (!empty($passwd) && $passwd == ADMIN_PASSWD)
181                 return WIKIAUTH_ADMIN;
182             return false;
183         }
184         elseif (ALLOW_BOGO_LOGIN
185                 && preg_match('/\A' . $WikiNameRegexp . '\z/', $userid)) {
186             return WIKIAUTH_BOGO;
187         }
188         return false;
189     }
190     
191
192
193     // This is a bit of a hack:
194     function setPreferences ($prefs) {
195         $req = &$this->_request;
196         $req->setCookieVar('WIKI_PREFS', $prefs, 365); // expire in a year.
197     }
198
199     function getPreferences () {
200         $req = &$this->_request;
201
202         $prefs = array('edit_area.width' => 80,
203                        'edit_area.height' => 22);
204
205         $saved = $req->getCookieVar('WIKI_PREFS');
206         
207         if (is_array($saved)) {
208             foreach ($saved as $key => $val) {
209                 if (isset($prefs[$key]) && !empty($val))
210                     $prefs[$key] = $val;
211             }
212         }
213
214         // Some sanity checks. (FIXME: should move somewhere else)
215         if (!($prefs['edit_area.width'] >= 30 && $prefs['edit_area.width'] <= 150))
216             $prefs['edit_area.width'] = 80;
217         if (!($prefs['edit_area.height'] >= 5 && $prefs['edit_area.height'] <= 80))
218             $prefs['edit_area.height'] = 22;
219         return $prefs;
220     }
221    
222
223
224     function _copy($saved) {
225         if (!is_array($saved) || !isset($saved['userid']) || !isset($saved['level']))
226             return false;
227
228         $this->_userid = $saved['userid'];
229         $this->_level = $saved['level'];
230         return true;
231     }
232        
233     function _restore () {
234         $req = &$this->_request;
235         
236         if ( $this->_copy($req->getSessionVar('auth_state')) )
237             return;
238         if ( $this->_ok() )
239             return;
240         
241         // Default state: logged out.
242         $this->_userid = false;
243         $this->_level = false;
244     }
245
246     function _save () {
247         $req = &$this->_request;
248
249         
250         $saved = array('userid' => $this->_userid,
251                        'level' => $this->_level);
252         
253         $req->setSessionVar('auth_state', $saved);
254     }
255
256     /** Invariant
257      */
258     function _ok () {
259         if (empty($this->_userid) || empty($this->_level)) {
260             // This is okay if truly logged out.
261             return $this->_userid === false && $this->_level === false;
262         }
263         // User is logged in...
264         
265         // Check for valid authlevel.
266         if (!in_array($this->_level, array(WIKIAUTH_BOGO, WIKIAUTH_USER, WIKIAUTH_ADMIN)))
267             return false;
268
269         // Check for valid userid.
270         if (!is_string($this->_userid))
271             return false;
272         return true;
273     }
274 }
275
276 // Local Variables:
277 // mode: php
278 // tab-width: 8
279 // c-basic-offset: 4
280 // c-hanging-comment-ender-p: nil
281 // indent-tabs-mode: nil
282 // End:   
283 ?>