/** * Validate a username * * @param $username * * @return bool|string */ public static function ValidateUsername($username) { // Usernames need to be unique across the system, since they will be used as URL identifiers. // However, blank usernames are acceptable. if ($username == '') { return true; } // Usernames should start with a number at least. if (!preg_match('/^[a-zA-Z].*/', $username)) { return 'Please start nicknames with a letter.'; } // and should not contain spaces if (strpos($username, ' ') !== false) { return 'Please do not include spaces in your nickname.'; } // Usernames should be only a-z, 0-9, and a few standard characters. if (!preg_match('/^[a-zA-Z0-9\\-\\.@_+]*$/', $username)) { return 'Please ensure that your nickname only contains letters, numbers, and dashes.'; } // Search the database for the same username. Remember, THERE CAN ONLY BE ONE! $match = UserUserConfigModel::Find(array('key' => 'username', 'value' => $username), 1); //if($match && $match->get('user_id') != $userconfig->get('user_id')){ if ($match) { return 'Requested username is already taken!'; } // yay! return true; }
public function testLinkedRecord1(){ // Just get one UserUserConfigModel $model = UserUserConfigModel::Find([], 1); if(!$model){ $this->markTestSkipped('No users found on the system, is Core installed?'); return; } // Get the user by the linked key $user = $model->getLink('user_id'); $this->assertInstanceOf('UserModel', $user); }
/** * View a user's public profile */ public function view() { $view = $this->getView(); $request = $this->getPageRequest(); $manager = \Core\user()->checkAccess('p:/user/users/manage'); // Current user an admin? // First argument here will either be the username or user id. $arg1 = $request->getParameter(0); $user = UserModel::Construct($arg1); if (!($user && $user->exists())) { // Try by username instead. $match = UserUserConfigModel::Find(array('key' => 'username', 'value' => $arg1), 1); if (!$match) { return View::ERROR_NOTFOUND; } $user = UserModel::Construct($match->get('user_id')); } if (!$user) { return View::ERROR_NOTFOUND; } // If the UA requested the user by ID but the user has a username set, return a 404 as well. // This should help cut down on scanning attempts for userdata. if (is_numeric($arg1) && $user->get('username')) { return View::ERROR_NOTFOUND; } // Now see why username needs to not begin with a number? :p /** @var $user UserModel */ // Only allow this if the user is either the same user or has the user manage permission. if ($user->get('id') == \Core\user()->get('id') || $manager) { $editor = true; } else { $editor = false; } $view->controls = ViewControls::DispatchModel($user); $view->title = $user->getDisplayName(); $view->assign('user', $user); $view->assign('profiles', $user->get('external_profiles')); }
/** * This set explicitly handles the value, and has the extended logic required * for error checking and validation. * * @param string $value The value to set * @return boolean */ public function setValue($value) { $valid = $this->validate($value); if($valid !== true){ $this->_error = $valid; return false; } if(!$value){ // If it doesn't have a value, then GREAT! // The above validation handles if a value is required. $this->_attributes['value'] = ''; return true; } // This determines what data will be passed in. // If the current user can lookup, then it'll be the ID of the user. // If the current user can't, then it'll be the full user name of of the user. $canlookup = \Core\user()->checkAccess('p:/user/search/autocomplete'); if(!$canlookup){ // I need to lookup the username here. $uuc = UserUserConfigModel::Find(['key = username', 'value = ' . $value], 1); if(!$uuc){ $this->_error = 'Invalid user specified!'; return false; } $value = $uuc->get('user_id'); } $this->_attributes['value'] = $value; return true; }
/** * Import the given data into the destination Model. * * @param array $data Indexed array of records to import/merge from the external source. * @param array $options Any options required for the import, such as merge, key, etc. * @param boolean $output_realtime Set to true to output the log in real time as the import happens. * * @throws Exception * * @return \Core\ModelImportLogger */ public static function Import($data, $options, $output_realtime = false) { $log = new \Core\ModelImportLogger('User Importer', $output_realtime); $merge = isset($options['merge']) ? $options['merge'] : true; $pk = isset($options['key']) ? $options['key'] : null; if(!$pk) { throw new Exception( 'Import requires a "key" field on options containing the primary key to compare against locally.' ); } // Load in members from the group // Set the default group on new accounts, if a default is set. $defaultgroups = \UserGroupModel::Find(["default = 1"]); $groups = []; $gnames = []; foreach($defaultgroups as $g) { /** @var \UserGroupModel $g */ $groups[] = $g->get('id'); $gnames[] = $g->get('name'); } if(sizeof($groups)) { $log->log('Found ' . sizeof($groups) . ' default groups for new users: ' . implode(', ', $gnames)); } else { $log->log('No groups set as default, new users will not belong to any groups.'); } $log->log('Starting ' . ($merge ? '*MERGE*' : '*skipping*' ) . ' import of ' . sizeof($data) . ' users'); foreach($data as $dat) { if(isset($dat[$pk])){ // Only check the information if the primary key is set on this record. if($pk == 'email' || $pk == 'id') { // These are the only two fields on the User object itself. $user = UserModel::Find([$pk . ' = ' . $dat[ $pk ]], 1); } else { $uucm = UserUserConfigModel::Find(['key = ' . $pk, 'value = ' . $dat[ $pk ]], 1); if($uucm) { $user = $uucm->getLink('UserModel'); } else { // Try the lookup from the email address instead. // This will force accounts that exist to be synced up correctly. // The only caveat to this is that users will not be updated with the foreign key if merge is disabled. $user = UserModel::Find(['email = ' . $dat['email']], 1); } } } else{ $user = null; } $status_type = $user ? 'Updated' : 'Created'; if($user && !$merge) { $log->duplicate('Skipped user ' . $user->getLabel() . ', already exists and merge not requested'); // Skip to the next record. continue; } if(!$user) { // All incoming users must have an email address! if(!isset($dat['email'])) { $log->error('Unable to import user without an email address!'); // Skip to the next record. continue; } // Meta fields that may or may not be present, but should be for reporting purposes. if(!isset($dat['registration_ip'])) { $dat['registration_ip'] = REMOTE_IP; } if(!isset($dat['registration_source'])) { $dat['registration_source'] = \Core\user()->exists() ? 'admin' : 'self'; } if(!isset($dat['registration_invitee'])) { $dat['registration_invitee'] = \Core\user()->get('id'); } // New user! $user = new UserModel(); } // No else needed, else is there IS a valid $user object and it's setup ready to go. // Handle all the properties for this user! foreach($dat as $key => $val){ if($key == 'avatar' && strpos($val, '://') !== false){ // Sync the user avatar. $log->actionStart('Downloading ' . $dat['avatar']); $f = new \Core\Filestore\Backends\FileRemote($dat['avatar']); $dest = \Core\Filestore\Factory::File('public/user/avatar/' . $f->getBaseFilename()); if($dest->identicalTo($f)) { $log->actionSkipped(); } else { $f->copyTo($dest); $user->set('avatar', 'public/user/avatar/' . $dest->getBaseFilename()); $log->actionSuccess(); } } elseif($key == 'profiles' && is_array($val)) { $new_profiles = $val; // Pull the current profiles from the account $profiles = $user->get('external_profiles'); if($profiles && is_array($profiles)) { $current_flat = []; foreach($profiles as $current_profile) { $current_flat[] = $current_profile['url']; } // Merge in any *actual* new profile foreach($new_profiles as $new_profile) { if(!in_array($new_profile['url'], $current_flat)) { $profiles[] = $new_profile; } } unset($new_profile, $new_profiles, $current_flat, $current_profile); } else { $profiles = $new_profiles; unset($new_profiles); } $user->set('external_profiles', $profiles); } elseif($key == 'backend'){ // Was a backend requested? // This gets merged instead of replaced entirely. $user->enableAuthDriver($val); } elseif($key == 'groups'){ $user->setGroups($val); } else{ // Default Behaviour, // save the key into whatever field it was set to go to. $user->set($key, $val); } } try { // Set the default groups loaded from the system. if(!$user->exists()){ $user->setGroups($groups); } $status = $user->save(); } catch(Exception $e) { $log->error($e->getMessage()); // Skip to the next. continue; } if($status) { $log->success($status_type . ' user ' . $user->getLabel() . ' successfully!'); } else { $log->skip('Skipped user ' . $user->getLabel() . ', no changes detected.'); } } $log->finalize(); return $log; }