Subversion Repositories php_users

Rev

Rev 10 | Rev 17 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 10 Rev 16
Line 55... Line 55...
55
 */
55
 */
56
 
56
 
57
 class Users {
57
 class Users {
58
   
58
   
59
   /**
59
   /**
60
    * @var string[] $dbDefinition Contains the configuration for the class
60
    * @var string[] $configuration Contains the configuration for the class
61
    * 
61
    * 
62
    * May be modified by the calling program. Must be replicated in userDataSource class
62
    * May be modified by the calling program. Must be replicated in userDataSource class
63
    */
63
    */
64
   private $dbDefinition = array(
64
   protected $configuration = array(
65
      /*
65
      /*
66
       * what to use for html input fields
66
       * what to use for html input fields
67
       * These are passed to sprintf, with label, fieldname, title, placeholder and current value, in that order
67
       * These are passed to sprintf, with label, fieldname, title, placeholder and current value, in that order
68
       */
68
       */
69
      'screens'         => array (
69
      'screens'         => array (
Line 118... Line 118...
118
            ) // table users
118
            ) // table users
119
         ) // tables
119
         ) // tables
120
      );
120
      );
121
 
121
 
122
   /** @var string[] $data Contains the information for the current logged in user */
122
   /** @var string[] $data Contains the information for the current logged in user */
123
   private $data = array();
123
   protected $data = array();
124
   /** @var string[] $errors Contains errors that can occur */
124
   /** @var string[] $errors Contains errors that can occur */
125
   private $errors = array();
125
   protected $errors = array();
126
   /** @var string[] $workingOn During administration, contains the record being modified */
126
   /** @var string[] $workingOn During administration, contains the record being modified */
127
   private $workingOn = array();
127
   protected $workingOn = array();
128
 
128
 
129
   /**
129
   /**
130
    * constructor for an instance of the class
130
    * constructor for an instance of the class
131
    * 
131
    * 
132
    * Anything in $customFields will be recursively merged with $dbDefinition, overwriting
132
    * Anything in $customFields will be recursively merged with $configuration, overwriting
133
    * as necessary.
133
    * as necessary.
134
    * 
134
    * 
135
    * @param string[] $customFields array to merge into $dbDefinition
135
    * @param string[] $customFields array to merge into $configuration
136
    */
136
    */
137
   public function __construct( $customFields = array() ) {
137
   public function __construct( $customFields = array() ) {
138
      if ( $customFields ) {
138
      if ( $customFields ) {
139
         $this->dbDefinition = array_merge_recursive( $this->dbDefinition, $customFields );
139
         $this->configuration = array_merge_recursive( $this->configuration, $customFields );
140
      }
140
      }
141
   } // constructor
141
   } // constructor
142
   
142
   
143
   /**
143
   /**
144
    * getter for $this->errors
144
    * getter for $this->errors
Line 202... Line 202...
202
   /**
202
   /**
203
    * Validates a connection and, on success, populates $data
203
    * Validates a connection and, on success, populates $data
204
    * 
204
    * 
205
    * Function will validate the username and password passed in, using
205
    * Function will validate the username and password passed in, using
206
    * data connection $connection. On success, populates class member $data
206
    * data connection $connection. On success, populates class member $data
207
    * with the values from the database (only those listed in $dbDefinition)
207
    * with the values from the database (only those listed in $configuration)
208
    * 
208
    * 
209
    * On Failure, appends $error with a failure string
209
    * On Failure, appends $error with a failure string
210
    * 
210
    * 
211
    * @param string $username The username to be matched in database
211
    * @param string $username The username to be matched in database
212
    * @param string $password The password (unencrypted) the user entered
212
    * @param string $password The password (unencrypted) the user entered
213
    * @param usersDataSource $connection A connection to the data source
213
    * @param usersDataSource $connection A connection to the data source
214
    * 
214
    * 
215
    */
215
    */
216
   private function validate( $username, $password, $connection ) {
216
   protected function validate( $username, $password, $connection ) {
217
      $result = $connection->getPassword( $username );
217
      $result = $connection->getPassword( $username );
218
      if ( password_verify( $password, $result['pass'] ) ) {
218
      if ( password_verify( $password, $result['pass'] ) ) {
219
         $result = $connection->getRecord( $username );
219
         $result = $connection->getRecord( $username );
220
         $this->data['id'] = $result['id'];
220
         $this->data['id'] = $result['id'];
221
         foreach ( $this->dbDefinition['tables']['users']['fields'] as $key => $record ) {
221
         foreach ( $this->configuration['tables']['users']['fields'] as $key => $record ) {
222
            if ( $key != 'pass' )
222
            if ( $key != 'pass' )
223
               $this->data[$key] = $result[$key];
223
               $this->data[$key] = $result[$key];
224
         }
224
         }
225
      } else {
225
      } else {
226
         $this->errors[] = 'Login Failed: Unknown username or password';
226
         $this->errors[] = 'Login Failed: Unknown username or password';
227
         foreach ( $this->dbDefinition['tables']['users']['fields'] as $key => $record ) {
227
         foreach ( $this->configuration['tables']['users']['fields'] as $key => $record ) {
228
            $this->data[$key] = null;
228
            $this->data[$key] = null;
229
         }
229
         }
230
      }
230
      }
231
   } // validate
231
   } // validate
232
               
232
               
Line 275... Line 275...
275
   /**
275
   /**
276
    * Simple helper script to calculate next script to call
276
    * Simple helper script to calculate next script to call
277
    * 
277
    * 
278
    * Returns one of three URL strings, in order of precedence
278
    * Returns one of three URL strings, in order of precedence
279
    * $nextScript
279
    * $nextScript
280
    * $dbDefinition['screens']['validateScript']
280
    * $configuration['screens']['validateScript']
281
    * PHP_SELF
281
    * PHP_SELF
282
    * 
282
    * 
283
    * @param string $nextScript URL to call
283
    * @param string $nextScript URL to call
284
    * @return string URL
284
    * @return string URL
285
    */
285
    */
286
   private function getNextScript( $nextScript = null ) {
286
   protected function getNextScript( $nextScript = null ) {
287
      if ( ! isset( $nextScript ) ) {
287
      if ( ! isset( $nextScript ) ) {
288
         $nextScript = $this->dbDefinition['screens']['validateScript'] ?:
288
         $nextScript = $this->configuration['screens']['validateScript'] ?:
289
                           htmlentities($_SERVER["PHP_SELF"]);
289
                           htmlentities($_SERVER["PHP_SELF"]);
290
      }
290
      }
291
      return $nextScript;
291
      return $nextScript;
292
   }
292
   }
293
   
293
   
Line 299... Line 299...
299
    * 
299
    * 
300
    * @param string $nextScript URL to call form
300
    * @param string $nextScript URL to call form
301
    * 
301
    * 
302
    * @return string HTML code for display
302
    * @return string HTML code for display
303
    */
303
    */
304
   private function logInScreen( $nextScript = null ) {
304
   protected function logInScreen( $nextScript = null ) {
305
      $return =  sprintf( 
305
      $return =  sprintf( 
306
         $this->dbDefinition['screens']['login form'],
306
         $this->configuration['screens']['login form'],
307
         $this->getNextScript( $nextScript ),
307
         $this->getNextScript( $nextScript ),
308
         $this->dbDefinition['screens']['loginScreen']
308
         $this->configuration['screens']['loginScreen']
309
      );
309
      );
310
      $return .= $this->errors();
310
      $return .= $this->errors();
311
      $this->clearErrors();
311
      $this->clearErrors();
312
      return $return;
312
      return $return;
313
   }
313
   }
Line 326... Line 326...
326
    * 
326
    * 
327
    * Knows how to handle INPUT types TEXT, TEXTAREA, PASSWORD and 
327
    * Knows how to handle INPUT types TEXT, TEXTAREA, PASSWORD and 
328
    * special html type boolean, which is checkboxes.
328
    * special html type boolean, which is checkboxes.
329
    * 
329
    * 
330
    * @param string $field name of the field to populate
330
    * @param string $field name of the field to populate
331
    * @param string[] $record Record from $dbDefinition[...][fields]
331
    * @param string[] $record Record from $configuration[...][fields]
332
    * @param string $value the current value to put in INPUT
332
    * @param string $value the current value to put in INPUT
333
    * 
333
    * 
334
    * @return string An HTML INPUT entity
334
    * @return string An HTML INPUT entity
335
    */
335
    */
336
   private function makeHTMLField ( $field, $record, $value ) {
336
   protected function makeHTMLField ( $field, $record, $value ) {
337
      $return = array();
337
      $return = array();
338
      $temp = sprintf( $this->dbDefinition['html input fields'][$record['html type']], 
338
      $temp = sprintf( $this->configuration['html input fields'][$record['html type']], 
339
                        $record['label'] ?: $field,
339
                        $record['label'] ?: $field,
340
                        $this->dbDefinition['input prefix'] . $field, 
340
                        $this->configuration['input prefix'] . $field, 
341
                        !empty($record['instructions']) ? $record['instructions'] : '',
341
                        !empty($record['instructions']) ? $record['instructions'] : '',
342
                        !empty($record['hint']) ? $record['hint'] : '',
342
                        !empty($record['hint']) ? $record['hint'] : '',
343
                        $field
343
                        $field
344
                     );
344
                     );
345
 
345
 
Line 373... Line 373...
373
    * 
373
    * 
374
    * @return string HTML containing all of the INPUT records a user can edit
374
    * @return string HTML containing all of the INPUT records a user can edit
375
    */
375
    */
376
   public function editScreen() {
376
   public function editScreen() {
377
      $return = array();
377
      $return = array();
378
      $return[] = $this->dbDefinition['screens']['adminScreen'];
378
      $return[] = $this->configuration['screens']['adminScreen'];
379
      $return[] = "<input type='hidden' name='id' value=" . $this->workingOn['id'] . "'>\n";
379
      $return[] = "<input type='hidden' name='id' value=" . $this->workingOn['id'] . "'>\n";
380
      foreach ( $this->dbDefinition['tables']['users']['fields'] as $field => $record ) {
380
      foreach ( $this->configuration['tables']['users']['fields'] as $field => $record ) {
381
         // if this field is restricted and we are not admin, just skip it
381
         // if this field is restricted and we are not admin, just skip it
382
         // also skip if it is our record
382
         // also skip if it is our record
383
         if ( isset( $record['restrict'] ) && ( $this->data['id'] == $this->workingOn['id'] ) )
383
         if ( isset( $record['restrict'] ) && ( $this->data['id'] == $this->workingOn['id'] ) )
384
            continue;
384
            continue;
385
         // now process the field
385
         // now process the field
Line 393... Line 393...
393
    * 
393
    * 
394
    * Initializes all fields to something non-null and sets id to -1
394
    * Initializes all fields to something non-null and sets id to -1
395
    * 
395
    * 
396
    * @return string[] An array initialized with all records needed
396
    * @return string[] An array initialized with all records needed
397
    */
397
    */
398
   private function emptyWorkingOn() {
398
   protected function emptyWorkingOn() {
399
      $new = array();
399
      $new = array();
400
      $new['id'] = -1;
400
      $new['id'] = -1;
401
      foreach ( $this->dbDefinition['tables']['users']['fields'] as $field => $record ) {
401
      foreach ( $this->configuration['tables']['users']['fields'] as $field => $record ) {
402
         if ( isset( $record['default'] ) ) {
402
         if ( isset( $record['default'] ) ) {
403
            $new[$field] = $record['default'];
403
            $new[$field] = $record['default'];
404
         } else {
404
         } else {
405
            switch ($record['html type']) {
405
            switch ($record['html type']) {
406
               case 'text'    :
406
               case 'text'    :
Line 455... Line 455...
455
      // default to working on ourself
455
      // default to working on ourself
456
      if ( ! ( isset( $this->workingOn ) && count( $this->workingOn ) ) ) {
456
      if ( ! ( isset( $this->workingOn ) && count( $this->workingOn ) ) ) {
457
         $this->workingOn = $this->data;
457
         $this->workingOn = $this->data;
458
      }
458
      }
459
      // we have no data, so we should create a form for them to enter something
459
      // we have no data, so we should create a form for them to enter something
460
      if ( ! isset( $_REQUEST[$this->dbDefinition['input prefix'] . $this->dbDefinition['tables']['users']['form test']] ) ) {
460
      if ( ! isset( $_REQUEST[$this->configuration['input prefix'] . $this->configuration['tables']['users']['form test']] ) ) {
461
         // create the screen
461
         // create the screen
462
         $return = $this->editScreen();
462
         $return = $this->editScreen();
463
         if ( $this->data['admin'] ) {
463
         if ( $this->data['admin'] ) {
464
            $return .= $this->allUsersHTML( $connection );
464
            $return .= $this->allUsersHTML( $connection );
465
         }
465
         }
466
         return sprintf( $this->dbDefinition['screens']['edit form'],
466
         return sprintf( $this->configuration['screens']['edit form'],
467
            $nextScript,
467
            $nextScript,
468
            $return
468
            $return
469
            );
469
            );
470
      } else { // we are processing
470
      } else { // we are processing
471
         $data = array();
471
         $data = array();
472
         foreach ( $this->dbDefinition['tables']['users']['fields'] as $field => $record ) {
472
         foreach ( $this->configuration['tables']['users']['fields'] as $field => $record ) {
473
            // if this field is restricted it is our record, skip it
473
            // if this field is restricted it is our record, skip it
474
            if ( isset( $record['restrict'] ) && ( $this->data['id'] == $this->workingOn['id'] ) )
474
            if ( isset( $record['restrict'] ) && ( $this->data['id'] == $this->workingOn['id'] ) )
475
               continue;
475
               continue;
476
            $htmlFieldName = $this->dbDefinition['input prefix'] . $field;
476
            $htmlFieldName = $this->configuration['input prefix'] . $field;
477
            $temp = '';
477
            $temp = '';
478
            switch ( $record['html type'] ) {
478
            switch ( $record['html type'] ) {
479
               case 'password':
479
               case 'password':
480
                  if ( ! empty( $_REQUEST[$htmlFieldName] ) ) {
480
                  if ( ! empty( $_REQUEST[$htmlFieldName] ) ) {
481
                     $data[$field] = password_hash( $_REQUEST[$htmlFieldName], PASSWORD_DEFAULT );
481
                     $data[$field] = password_hash( $_REQUEST[$htmlFieldName], PASSWORD_DEFAULT );
482
                     if ( isset( $this->dbDefinition['tables']['users']['fields']['last password change'] ) ) {
482
                     if ( isset( $this->configuration['tables']['users']['fields']['last password change'] ) ) {
483
                        $data['last password change'] = date("YmdHis");
483
                        $data['last password change'] = date("YmdHis");
484
                     }
484
                     }
485
                  }
485
                  }
486
                  break;
486
                  break;
487
               case 'boolean' :
487
               case 'boolean' :