]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/WikiUser/PearDb.php
add DBAUTH_PREF_INSERT: self-creating users. by John Stevens
[SourceForge/phpwiki.git] / lib / WikiUser / PearDb.php
1 <?php //-*-php-*-
2 rcs_id('$Id: PearDb.php,v 1.9 2005-10-10 19:43:49 rurban Exp $');
3 /* Copyright (C) 2004 ReiniUrban
4  * This file is part of PhpWiki. Terms and Conditions see LICENSE. (GPL2)
5  */
6
7 class _PearDbPassUser
8 extends _DbPassUser
9 /**
10  * Pear DB methods
11  * Now optimized not to use prepare, ...query(sprintf($sql,quote())) instead.
12  * We use FETCH_MODE_ROW, so we don't need aliases in the auth_* SQL statements.
13  *
14  * @tables: user
15  * @tables: pref
16  */
17 {
18     var $_authmethod = 'PearDb';
19     function _PearDbPassUser($UserName='',$prefs=false) {
20         //global $DBAuthParams;
21         if (!$this->_prefs and isa($this,"_PearDbPassUser")) {
22             if ($prefs) $this->_prefs = $prefs;
23         }
24         if (!isset($this->_prefs->_method))
25             _PassUser::_PassUser($UserName);
26         elseif (!$this->isValidName($UserName)) {
27             trigger_error(_("Invalid username."), E_USER_WARNING);
28             return false;
29         }
30         $this->_userid = $UserName;
31         // make use of session data. generally we only initialize this every time, 
32         // but do auth checks only once
33         $this->_auth_crypt_method = $GLOBALS['request']->_dbi->getAuthParam('auth_crypt_method');
34         return $this;
35     }
36
37     function getPreferences() {
38         // override the generic slow method here for efficiency and not to 
39         // clutter the homepage metadata with prefs.
40         _AnonUser::getPreferences();
41         $this->getAuthDbh();
42         if (isset($this->_prefs->_select)) {
43             $dbh = &$this->_auth_dbi;
44             $db_result = $dbh->query(sprintf($this->_prefs->_select, $dbh->quote($this->_userid)));
45             // patched by frederik@pandora.be
46             $prefs = $db_result->fetchRow();
47             $prefs_blob = @$prefs["prefs"]; 
48             if ($restored_from_db = $this->_prefs->retrieve($prefs_blob)) {
49                 $updated = $this->_prefs->updatePrefs($restored_from_db);
50                 //$this->_prefs = new UserPreferences($restored_from_db);
51                 return $this->_prefs;
52             }
53         }
54         if ($this->_HomePagehandle) {
55             if ($restored_from_page = $this->_prefs->retrieve
56                 ($this->_HomePagehandle->get('pref'))) {
57                 $updated = $this->_prefs->updatePrefs($restored_from_page);
58                 //$this->_prefs = new UserPreferences($restored_from_page);
59                 return $this->_prefs;
60             }
61         }
62         return $this->_prefs;
63     }
64
65     function setPreferences($prefs, $id_only=false) {
66         // if the prefs are changed
67         if ($count = _AnonUser::setPreferences($prefs, 1)) {
68             //global $request;
69             //$user = $request->_user;
70             //unset($user->_auth_dbi);
71             // this must be done in $request->_setUser, not here!
72             //$request->setSessionVar('wiki_user', $user);
73             $this->getAuthDbh();
74             $packed = $this->_prefs->store();
75             if (!$id_only and isset($this->_prefs->_update)) {
76                 $dbh = &$this->_auth_dbi;
77                 // check if the user already exists (not needed with mysql REPLACE)
78                 $db_result = $dbh->query(sprintf($this->_prefs->_select, 
79                                                  $dbh->quote($this->_userid)));
80                 $prefs = $db_result->fetchRow();
81                 $prefs_blob = @$prefs["prefs"]; 
82                 // If there are prefs for the user, update them.
83                 if($prefs_blob != "" ){
84                     $dbh->simpleQuery(sprintf($this->_prefs->_update,
85                                               $dbh->quote($packed),
86                                               $dbh->quote($this->_userid)));
87                 } else {
88                     // Otherwise, insert a record for them and set it to the defaults.
89                     // johst@deakin.edu.au
90                     $dbi = $GLOBALS['request']->getDbh();
91                     $this->_prefs->_insert = $this->prepare($dbi->getAuthParam('pref_insert'),
92                                                             array("pref_blob", "userid"));
93                     $dbh->query(sprintf($this->_prefs->_insert,
94                                         $dbh->quote($packed),
95                                         $dbh->quote($this->_userid)));
96                 }
97                 //delete pageprefs:
98                 if ($this->_HomePagehandle and $this->_HomePagehandle->get('pref'))
99                     $this->_HomePagehandle->set('pref', '');
100             } else {
101                 //store prefs in homepage, not in cookie
102                 if ($this->_HomePagehandle and !$id_only)
103                     $this->_HomePagehandle->set('pref', $packed);
104             }
105             return $count; //count($this->_prefs->unpack($packed));
106         }
107         return 0;
108     }
109
110     function userExists() {
111         //global $DBAuthParams;
112         $this->getAuthDbh();
113         $dbh = &$this->_auth_dbi;
114         if (!$dbh) { // needed?
115             return $this->_tryNextUser();
116         }
117         if (!$this->isValidName()) {
118             trigger_error(_("Invalid username."),E_USER_WARNING);
119             return $this->_tryNextUser();
120         }
121         $dbi =& $GLOBALS['request']->_dbi;
122         // Prepare the configured auth statements
123         if ($dbi->getAuthParam('auth_check') and empty($this->_authselect)) {
124             $this->_authselect = $this->prepare($dbi->getAuthParam('auth_check'), 
125                                                 array("userid", "password"));
126         }
127         //NOTE: for auth_crypt_method='crypt' no special auth_user_exists is needed
128         if (!$dbi->getAuthParam('auth_user_exists') 
129             and $this->_auth_crypt_method == 'crypt' 
130             and $this->_authselect) 
131         {
132             $rs = $dbh->query(sprintf($this->_authselect, $dbh->quote($this->_userid)));
133             if ($rs->numRows())
134                 return true;
135         }
136         else {
137             if (! $dbi->getAuthParam('auth_user_exists'))
138                 trigger_error(fmt("%s is missing", 'DBAUTH_AUTH_USER_EXISTS'),
139                               E_USER_WARNING);
140             $this->_authcheck = $this->prepare($dbi->getAuthParam('auth_user_exists'), "userid");
141             $rs = $dbh->query(sprintf($this->_authcheck, $dbh->quote($this->_userid)));
142             if ($rs->numRows())
143                 return true;
144         }
145         // User does not exist yet.
146         // Maybe the user is allowed to create himself. Generally not wanted in 
147         // external databases, but maybe wanted for the wiki database, for performance 
148         // reasons
149         if (empty($this->_authcreate) and $dbi->getAuthParam('auth_create')) {
150             $this->_authcreate = $this->prepare($dbi->getAuthParam('auth_create'),
151                                                 array("userid", "password"));
152         }
153         if (!empty($this->_authcreate) and 
154             isset($GLOBALS['HTTP_POST_VARS']['auth']) and
155             isset($GLOBALS['HTTP_POST_VARS']['auth']['passwd'])) 
156         {
157             $passwd = $GLOBALS['HTTP_POST_VARS']['auth']['passwd'];
158             $dbh->simpleQuery(sprintf($this->_authcreate,
159                                       $dbh->quote($passwd),
160                                       $dbh->quote($this->_userid)));
161             return true;
162         }
163         return $this->_tryNextUser();
164     }
165  
166     function checkPass($submitted_password) {
167         //global $DBAuthParams;
168         $this->getAuthDbh();
169         if (!$this->_auth_dbi) {  // needed?
170             return $this->_tryNextPass($submitted_password);
171         }
172         if (!$this->isValidName()) {
173             return $this->_tryNextPass($submitted_password);
174         }
175         if (!$this->_checkPassLength($submitted_password)) {
176             return WIKIAUTH_FORBIDDEN;
177         }
178         if (!isset($this->_authselect))
179             $this->userExists();
180         if (!isset($this->_authselect))
181             trigger_error(fmt("Either %s is missing or DATABASE_TYPE != '%s'",
182                               'DBAUTH_AUTH_CHECK', 'SQL'),
183                           E_USER_WARNING);
184
185         //NOTE: for auth_crypt_method='crypt'  defined('ENCRYPTED_PASSWD',true) must be set
186         $dbh = &$this->_auth_dbi;
187         if ($this->_auth_crypt_method == 'crypt') {
188             $stored_password = $dbh->getOne(sprintf($this->_authselect, 
189                                                     $dbh->quote($this->_userid)));
190             $result = $this->_checkPass($submitted_password, $stored_password);
191         } else {
192             $okay = $dbh->getOne(sprintf($this->_authselect,
193                                          $dbh->quote($submitted_password),
194                                          $dbh->quote($this->_userid)));
195             $result = !empty($okay);
196         }
197
198         if ($result) {
199             $this->_level = WIKIAUTH_USER;
200             return $this->_level;
201         } elseif (USER_AUTH_POLICY === 'strict') {
202             $this->_level = WIKIAUTH_FORBIDDEN;
203             return $this->_level;
204         } else {
205             return $this->_tryNextPass($submitted_password);
206         }
207     }
208
209     function mayChangePass() {
210         return $GLOBALS['request']->_dbi->getAuthParam('auth_update');
211     }
212
213     function storePass($submitted_password) {
214         if (!$this->isValidName()) {
215             return false;
216         }
217         $this->getAuthDbh();
218         $dbh = &$this->_auth_dbi;
219         $dbi =& $GLOBALS['request']->_dbi;
220         if ($dbi->getAuthParam('auth_update') and empty($this->_authupdate)) {
221             $this->_authupdate = $this->prepare($dbi->getAuthParam('auth_update'),
222                                                 array("userid", "password"));
223         }
224         if (empty($this->_authupdate)) {
225             trigger_error(fmt("Either %s is missing or DATABASE_TYPE != '%s'",
226                               'DBAUTH_AUTH_UPDATE','SQL'),
227                           E_USER_WARNING);
228             return false;
229         }
230
231         if ($this->_auth_crypt_method == 'crypt') {
232             if (function_exists('crypt'))
233                 $submitted_password = crypt($submitted_password);
234         }
235         $dbh->simpleQuery(sprintf($this->_authupdate,
236                                   $dbh->quote($submitted_password),
237                                   $dbh->quote($this->_userid)
238                                   ));
239         return true;
240     }
241 }
242
243 // $Log: not supported by cvs2svn $
244 // Revision 1.8  2005/08/06 13:21:09  rurban
245 // switch to natural order password, userid
246 //
247 // Revision 1.7  2005/02/14 12:28:27  rurban
248 // fix policy strict. Thanks to Mikhail Vladimirov
249 //
250 // Revision 1.6  2005/01/06 15:44:22  rurban
251 // move password length checker to correct method. thanks to Charles Corrigan
252 //
253 // Revision 1.5  2004/12/26 17:11:17  rurban
254 // just copyright
255 //
256 // Revision 1.4  2004/12/20 16:05:01  rurban
257 // gettext msg unification
258 //
259 // Revision 1.3  2004/12/19 00:58:02  rurban
260 // Enforce PASSWORD_LENGTH_MINIMUM in almost all PassUser checks,
261 // Provide an errormessage if so. Just PersonalPage and BogoLogin not.
262 // Simplify httpauth logout handling and set sessions for all methods.
263 // fix main.php unknown index "x" getLevelDescription() warning.
264 //
265 // Revision 1.2  2004/11/10 15:29:21  rurban
266 // * requires newer Pear_DB (as the internal one): quote() uses now escapeSimple for strings
267 // * ACCESS_LOG_SQL: fix cause request not yet initialized
268 // * WikiDB: moved SQL specific methods upwards
269 // * new Pear_DB quoting: same as ADODB and as newer Pear_DB.
270 //   fixes all around: WikiGroup, WikiUserNew SQL methods, SQL logging
271 //
272 // Revision 1.1  2004/11/01 10:43:58  rurban
273 // seperate PassUser methods into seperate dir (memory usage)
274 // fix WikiUser (old) overlarge data session
275 // remove wikidb arg from various page class methods, use global ->_dbi instead
276 // ...
277 //
278
279 // Local Variables:
280 // mode: php
281 // tab-width: 8
282 // c-basic-offset: 4
283 // c-hanging-comment-ender-p: nil
284 // indent-tabs-mode: nil
285 // End:
286 ?>