]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/WikiUser.php
Jeff's hacks II.
[SourceForge/phpwiki.git] / lib / WikiUser.php
1 <?php rcs_id('$Id: WikiUser.php,v 1.1 2001-09-18 19:16:23 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 class WikiUser 
12 {
13     // Arg $login_mode:
14     //   default:  Anonymous users okay.
15     //   'ANON_OK': Anonymous access is fine.
16     //   'REQUIRE_AUTH': User must be authenticated.
17     //   'LOGOUT':  Force logout.
18     //   'LOGIN':   Force authenticated login.
19     function WikiUser (&$request, $auth_mode = '') {
20         $this->_request = &$request;
21         // Restore from cookie.
22         $this->_restore();
23         
24         if ($this->state == 'authorized' && $auth_mode == 'LOGIN') {
25             // ...logout
26             $this->realm++;
27             $this->state = 'loggedout';
28         }
29       
30         if ($auth_mode != 'LOGOUT') {
31             $user = $this->_get_authenticated_userid();
32
33             if (!$user && $auth_mode != 'ANON_OK')
34                 $warning = $this->_demand_http_authentication(); //NORETURN
35         }
36         
37         if (empty($user)) {
38             // Authentication failed
39             if ($this->state == 'authorized')
40                 $this->realm++;
41             $this->state = 'loggedout';
42             $this->userid = $request->get('REMOTE_HOST');
43         }
44         else {
45             // Successful authentication
46             $this->state = 'authorized';
47             $this->userid = $user;
48         }
49
50         // Save state to cookie and/or session registry.
51         $this->_save($request);
52
53         if (isset($warning))
54             echo $warning;
55     }
56
57     function id () {
58         return $this->userid;
59     }
60
61     function authenticated_id() {
62         if ($this->is_authenticated())
63             return $this->id();
64         else
65             return $this->_request->get('REMOTE_ADDR');
66     }
67
68     function is_authenticated () {
69         return $this->state == 'authorized';
70     }
71          
72     function is_admin () {
73         return $this->is_authenticated() && $this->userid == ADMIN_USER;
74     }
75
76     function must_be_admin ($action = "") {
77         if (! $this->is_admin()) 
78             {
79                 if ($action)
80                     $to_what = sprintf(gettext("to perform action '%s'"), $action);
81                 else
82                     $to_what = gettext("to do that");
83                 ExitWiki(gettext("You must be logged in as an administrator")
84                          . " $to_what");
85             }
86     }
87
88     // This is a bit of a hack:
89     function setPreferences ($prefs) {
90         $req = &$this->_request;
91         $req->setCookieVar('WIKI_PREFS', $prefs, 365); // expire in a year.
92     }
93
94     function getPreferences () {
95         $req = &$this->_request;
96
97         $prefs = array('edit_area.width' => 80,
98                        'edit_area.height' => 22);
99
100         $saved = $req->getCookieVar('WIKI_PREFS');
101         
102         if (is_array($saved)) {
103             foreach ($saved as $key => $vval) {
104                 if (isset($pref[$key]) && !empty($val))
105                     $prefs[$key] = $val;
106             }
107         }
108
109         // Some sanity checks. (FIXME: should move somewhere else)
110         if (!($prefs['edit_area.width'] >= 30 && $prefs['edit_area.width'] <= 150))
111             $prefs['edit_area.width'] = 80;
112         if (!($prefs['edit_area.height'] >= 5 && $prefs['edit_area.height'] <= 80))
113             $prefs['edit_area.height'] = 22;
114         return $prefs;
115     }
116    
117     function _get_authenticated_userid () {
118         if ( ! ($user = $this->_get_http_authenticated_userid()) )
119             return false;
120        
121         switch ($this->state) {
122         case 'login':
123             // Either we just asked for a password, or cookies are not enabled.
124             // In either case, proceed with successful login.
125             return $user;
126         case 'loggedout':
127             // We're logged out.  Ignore http authed user.
128             return false;
129         default:
130             // FIXME: Can't reset auth cache on Mozilla (and probably others),
131             // so for now, just trust the saved state
132             return $this->userid;
133           
134             // Else, as long as the user hasn't changed, fine.
135             if ($user && $user != $this->userid)
136                 return false;
137             return $user;
138         }
139     }
140
141     function _get_http_authenticated_userid () {
142         global $WikiNameRegexp;
143
144         $userid = $this->_request->get('PHP_AUTH_USER');
145         $passwd = $this->_request->get('PHP_AUTH_PW');
146
147         if (!empty($userid) && $userid == ADMIN_USER) {
148             if (!empty($passwd) && $passwd == ADMIN_PASSWD)
149                 return $userid;
150         }
151         elseif (ALLOW_BOGO_LOGIN
152                 && preg_match('/\A' . $WikiNameRegexp . '\z/', $userid)) {
153             // FIXME: this shouldn't count as authenticated.
154             return $userid;
155         }
156         return false;
157     }
158    
159     function _demand_http_authentication () {
160         if (!defined('ADMIN_USER') || !defined('ADMIN_PASSWD')
161             || ADMIN_USER == '' || ADMIN_PASSWD =='') {
162             return
163                 "<p><b>"
164                 . gettext("You must set the administrator account and password before you can log in.")
165                 . "</b></p>\n";
166         }
167
168         // Request password
169         $this->userid = '';
170         $this->state = 'login';
171       
172         $this->_save();
173         header('WWW-Authenticate: Basic realm="' . $this->realm . '"');
174         header("HTTP/1.0 401 Unauthorized");
175         if (ACCESS_LOG)
176             $LogEntry->status = 401;
177         echo "<p>" . gettext ("You entered an invalid login or password.") . "\n";
178         if (ALLOW_BOGO_LOGIN) {
179             echo "<p>";
180             echo gettext ("You can log in using any valid WikiWord as a user ID.") . "\n";
181             echo gettext ("(Any password will work, except, of course for the admin user.)") . "\n";
182         }
183       
184         ExitWiki();
185     }
186
187     function _copy($object) {
188         if (!is_object($object))
189             return false;
190         if (strtolower(get_class($object)) != 'wikiuser')
191             return false;
192
193         $this->userid = $object->userid;
194         $this->state = $object->state;
195         $this->realm = $object->realm;
196         return true;
197     }
198        
199     function _restore() {
200         $req = &$this->_request;
201         
202         if ( $this->_copy($req->getSessionVar('auth_state')) )
203             return;
204         elseif ( $this->_copy($req->getCookieVar('WIKI_AUTH')) )
205             return;
206         else {
207             // Default state.
208             $this->userid = '';
209             $this->state = 'login';
210             $this->realm = 'PhpWiki0000';
211         }
212     }
213
214     function _save() {
215         $req = &$this->_request;
216
217         $req->setSessionVar('auth_state', $this);
218         $req->setCookieVar('WIKI_AUTH', $this);
219     }
220 }
221
222 // Local Variables:
223 // mode: php
224 // tab-width: 8
225 // c-basic-offset: 4
226 // c-hanging-comment-ender-p: nil
227 // indent-tabs-mode: nil
228 // End:   
229 ?>