1 <?php rcs_id('$Id: WikiUser.php,v 1.5 2001-12-06 20:44:13 dairiki Exp $');
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.
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.
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.
24 // don't check for HTTP auth if there's nothing to worry about
26 // FIXME: the addition of this short-cut introduced a security hole.
27 // Since $this->_restore can potentially restore $this from a
28 // user provided cookie, a carefully constructed cookie can
29 // be used to effectively log in (even as admin) without
32 // For now, I'm disabling the code which saves/restores $this
33 // in a cookie. (Login state is still preserved in session vars.)
34 // I'll work on a longer term solution.
36 if ( $this->state == 'authorized'
37 && $auth_mode != 'LOGIN'
38 && $auth_mode != 'LOGOUT' )
41 if ($this->state == 'authorized' && $auth_mode == 'LOGIN') {
44 $this->state = 'loggedout';
47 if ($auth_mode != 'LOGOUT') {
48 $user = $this->_get_authenticated_userid();
50 if (!$user && $auth_mode != 'ANON_OK')
51 $warning = $this->_demand_http_authentication(); //NORETURN
55 // Authentication failed
56 if ($this->state == 'authorized')
58 $this->state = 'loggedout';
59 $this->userid = $request->get('REMOTE_HOST');
62 // Successful authentication
63 $this->state = 'authorized';
64 $this->userid = $user;
67 // Save state to cookie and/or session registry.
68 $this->_save($request);
78 function authenticated_id() {
79 if ($this->is_authenticated())
82 return $this->_request->get('REMOTE_ADDR');
85 function is_authenticated () {
86 return $this->state == 'authorized';
89 function is_admin () {
90 return $this->is_authenticated() && $this->userid == ADMIN_USER;
93 function must_be_admin ($action = "") {
94 if (! $this->is_admin())
97 $to_what = sprintf(gettext("to perform action '%s'"), $action);
99 $to_what = gettext("to do that");
100 ExitWiki(gettext("You must be logged in as an administrator")
105 // This is a bit of a hack:
106 function setPreferences ($prefs) {
107 $req = &$this->_request;
108 $req->setCookieVar('WIKI_PREFS', $prefs, 365); // expire in a year.
111 function getPreferences () {
112 $req = &$this->_request;
114 $prefs = array('edit_area.width' => 80,
115 'edit_area.height' => 22);
117 $saved = $req->getCookieVar('WIKI_PREFS');
119 if (is_array($saved)) {
120 foreach ($saved as $key => $val) {
121 if (isset($prefs[$key]) && !empty($val))
126 // Some sanity checks. (FIXME: should move somewhere else)
127 if (!($prefs['edit_area.width'] >= 30 && $prefs['edit_area.width'] <= 150))
128 $prefs['edit_area.width'] = 80;
129 if (!($prefs['edit_area.height'] >= 5 && $prefs['edit_area.height'] <= 80))
130 $prefs['edit_area.height'] = 22;
134 function _get_authenticated_userid () {
135 if ( ! ($user = $this->_get_http_authenticated_userid()) )
138 switch ($this->state) {
140 // Either we just asked for a password, or cookies are not enabled.
141 // In either case, proceed with successful login.
144 // We're logged out. Ignore http authed user.
147 // FIXME: Can't reset auth cache on Mozilla (and probably others),
148 // so for now, just trust the saved state
149 return $this->userid;
151 // Else, as long as the user hasn't changed, fine.
152 if ($user && $user != $this->userid)
158 function _get_http_authenticated_userid () {
159 global $WikiNameRegexp;
161 $userid = $this->_request->get('PHP_AUTH_USER');
162 $passwd = $this->_request->get('PHP_AUTH_PW');
164 if (!empty($userid) && $userid == ADMIN_USER) {
165 if (!empty($passwd) && $passwd == ADMIN_PASSWD)
168 elseif (ALLOW_BOGO_LOGIN
169 && preg_match('/\A' . $WikiNameRegexp . '\z/', $userid)) {
170 // FIXME: this shouldn't count as authenticated.
176 function _demand_http_authentication () {
177 if (!defined('ADMIN_USER') || !defined('ADMIN_PASSWD')
178 || ADMIN_USER == '' || ADMIN_PASSWD =='') {
181 . gettext("You must set the administrator account and password before you can log in.")
187 $this->state = 'login';
190 $request = &$this->_request;
191 header('WWW-Authenticate: Basic realm="' . $this->realm . '"');
192 $request->setStatus("HTTP/1.0 401 Unauthorized");
193 echo "<p>" . gettext ("You entered an invalid login or password.") . "\n";
194 if (ALLOW_BOGO_LOGIN) {
196 echo gettext ("You can log in using any valid WikiWord as a user ID.") . "\n";
197 echo gettext ("(Any password will work, except, of course for the admin user.)") . "\n";
203 function _copy($object) {
204 if (!is_object($object))
206 if (strtolower(get_class($object)) != 'wikiuser')
209 $this->userid = $object->userid;
210 $this->state = $object->state;
211 $this->realm = $object->realm;
215 function _restore() {
216 $req = &$this->_request;
218 if ( $this->_copy($req->getSessionVar('auth_state')) )
220 // FIXME: Disable restore from cookie (see note in WikiUser().)
221 //elseif ( $this->_copy($req->getCookieVar('WIKI_AUTH')) )
226 $this->state = 'login';
227 $this->realm = 'PhpWiki0000';
232 $req = &$this->_request;
234 $req->setSessionVar('auth_state', $this);
235 // FIXME: Disable restore from cookie (see note in WikiUser().)
236 //$req->setCookieVar('WIKI_AUTH', $this);
244 // c-hanging-comment-ender-p: nil
245 // indent-tabs-mode: nil