protected function body()
 {
     if (!$this->isInputValid(['resetLink' => 'isNotEmpty', 'pass' => 'isNotEmpty'])) {
         return false;
     }
     $resetLink = $this->getParams('resetLink');
     if (strlen($resetLink) < 1) {
         // We double-check here. This should not be necessary because the isInputValid function takes care of this.
         // However, if there is a bug in isInputValid that causes the check to be skipped,
         // this will allow the user to change the password of the first user with no resetLink active.
         // This could plausibly be the administrator.
         return $this->death(StringID::HackerError);
     }
     $encryptionType = Security::HASHTYPE_PHPASS;
     $newPassword = $this->getParams('pass');
     $newPasswordHash = Security::hash($newPassword, $encryptionType);
     $usersWithThisResetLink = Repositories::getRepository(Repositories::User)->findBy(['resetLink' => $resetLink]);
     if (count($usersWithThisResetLink) !== 1) {
         return $this->death(StringID::ResetLinkDoesNotExist);
     }
     /**
      * @var $user \User
      */
     $user = $usersWithThisResetLink[0];
     if ($user->getResetLinkExpiry() < new \DateTime()) {
         return $this->death(StringID::ResetLinkExpired);
     }
     $user->setResetLink('');
     $user->setPass($newPasswordHash);
     Repositories::persistAndFlush($user);
     return true;
 }
 public function testCheck()
 {
     $this->assertTrue(Security::check("hello", "5d41402abc4b2a76b9719d911017c592", Security::HASHTYPE_MD5));
     $this->assertTrue(Security::check("hi", "49f68a5c8493ec2c0bf489821c21fc3b", Security::HASHTYPE_MD5));
     $this->assertTrue(Security::check("hello", '$2a$08$uHDGnFAtkAbBdH/iRt.jQOViR6bd2g3wwn6IS7MyvlMHoMvvBXDyi', Security::HASHTYPE_PHPASS));
     $this->assertFalse(Security::check("hello2", "5d41402abc4b2a76b9719d911017c592", Security::HASHTYPE_MD5));
     $this->assertFalse(Security::check("hello2", "hello2", Security::HASHTYPE_MD5));
     $this->assertFalse(Security::check("hello2", "5d41402abc4b2a76b9719d911017c592", Security::HASHTYPE_PHPASS));
 }
示例#3
0
 /**
  * Runs this script.
  * @return bool Is it successful?
  * @throws \Exception Should never occur.
  */
 protected function body()
 {
     $inputs = array('name' => array('isAlphaNumeric', 'hasLength' => array('min_length' => Constants::UsernameMinLength, 'max_length' => Constants::UsernameMaxLength)), 'realname' => array('isNotEmpty', 'isName'), 'email' => 'isEmail', 'pass' => array(), 'repass' => array());
     if (!$this->isInputValid($inputs)) {
         return false;
     }
     // Extract input data
     $username = strtolower($this->getParams('name'));
     $realname = $this->getParams('realname');
     $email = $this->getParams('email');
     $pass = $this->getParams('pass');
     $repass = $this->getParams('repass');
     $id = $this->getParams('id');
     $type = $this->getParams('type');
     $user = null;
     $isIdSet = $id !== null && $id !== '';
     $isTypeSet = $type !== null && $type !== '';
     // Extract database data
     if ($id) {
         $user = Repositories::findEntity(Repositories::User, $id);
     }
     $userExists = $user != null;
     $sameNameUserExists = count(Repositories::getRepository(Repositories::User)->findBy(['name' => $username])) > 0;
     // Custom verification of input data
     if ($pass !== $repass) {
         return $this->death(StringID::InvalidInput);
     }
     if ($userExists) {
         if ((strlen($pass) < Constants::PasswordMinLength || strlen($pass) > Constants::PasswordMaxLength) && $pass !== "") {
             return $this->death(StringID::InvalidInput);
         }
     } else {
         // A new user must have full password
         if (strlen($pass) < Constants::PasswordMinLength || strlen($pass) > Constants::PasswordMaxLength) {
             return $this->death(StringID::InvalidInput);
         }
     }
     $code = '';
     $unhashedPass = $pass;
     $pass = Security::hash($pass, Security::HASHTYPE_PHPASS);
     $canAddUsers = User::instance()->hasPrivileges(User::usersAdd);
     $canEditUsers = User::instance()->hasPrivileges(User::usersManage);
     $isEditingSelf = $id == User::instance()->getId();
     // This must not be a strict comparison.
     /**
      * @var $user \User
      */
     if (!$userExists && !$sameNameUserExists) {
         if ($this->getParams('fromRegistrationForm')) {
             if ($type != Repositories::StudentUserType) {
                 return $this->death(StringID::InsufficientPrivileges);
             }
             $code = md5(uniqid(mt_rand(), true));
             $emailText = file_get_contents(Config::get("paths", "registrationEmail"));
             $emailText = str_replace("%{Username}", $username, $emailText);
             $emailText = str_replace("%{ActivationCode}", $code, $emailText);
             $emailText = str_replace("%{Link}", Config::getHttpRoot() . "#activate", $emailText);
             $lines = explode("\n", $emailText);
             $subject = $lines[0];
             // The first line is subject.
             $text = preg_replace('/^.*\\n/', '', $emailText);
             // Everything except the first line.
             $returnCode = Core::sendEmail($email, $subject, $text);
             if (!$returnCode) {
                 return $this->stop(ErrorCode::mail, 'user registration failed', 'email could not be sent');
             }
         } else {
             if (!$canAddUsers) {
                 return $this->death(StringID::InsufficientPrivileges);
             }
         }
         $user = new \User();
         /** @var \UserType $typeEntity */
         $typeEntity = Repositories::findEntity(Repositories::UserType, $type);
         $user->setType($typeEntity);
         $user->setPass($pass);
         $user->setName($username);
         $user->setEmail($email);
         $user->setActivationCode($code);
         $user->setEncryptionType(Security::HASHTYPE_PHPASS);
         $user->setRealName($realname);
         Repositories::persistAndFlush($user);
     } elseif ($isIdSet) {
         if (!$canEditUsers && ($isTypeSet || !$isEditingSelf)) {
             return $this->stop(ErrorCode::lowPrivileges, 'cannot edit data of users other than yourself');
         }
         $type = $isTypeSet ? $type : $user->getType()->getId();
         /** @var \UserType $typeEntity */
         $typeEntity = Repositories::findEntity(Repositories::UserType, $type);
         if ($unhashedPass) {
             $user->setPass($pass);
             $user->setEncryptionType(Security::HASHTYPE_PHPASS);
         }
         $user->setType($typeEntity);
         $user->setEmail($email);
         $user->setActivationCode('');
         $user->setRealName($realname);
         Repositories::persistAndFlush($user);
     } else {
         return $this->death(StringID::UserNameExists);
     }
     return true;
 }
示例#4
0
 /**
  * Tries to log user in with supplied credentials.
  * @param string $name username
  * @param string $pass password
  * @return bool true if login was successful
  */
 public function login($name, $pass)
 {
     if ($this->data != null) {
         $this->logout();
     }
     /// Username is case-insensitive.
     $name = strtolower($name);
     $users = Repositories::getRepository(Repositories::User)->findBy(['name' => $name]);
     if (!empty($users)) {
         /**
          * @var $user \User
          */
         $user = $users[0];
         if ($user->getActivationCode() !== '') {
             // Non-empty activation code means the account is not yet activated.
             return false;
         }
         $authenticationSuccess = Security::check($pass, $user->getPass(), $user->getEncryptionType());
         if ($authenticationSuccess) {
             $this->data = array('id' => $user->getId(), 'name' => $user->getName(), 'privileges' => $user->getType()->getPrivileges(), 'realName' => $user->getRealName(), 'email' => $user->getEmail(), 'lastAccess' => $user->getLastAccess()->format("Y-m-d H:i:s"), 'applicationVersion' => implode('.', Config::get('version')), User::sendEmailOnAssignmentAvailableStudent => $user->getSendEmailOnNewAssignment() ? 1 : 0, User::sendEmailOnSubmissionConfirmedTutor => $user->getSendEmailOnNewSubmission() ? 1 : 0, User::sendEmailOnSubmissionRatedStudent => $user->getSendEmailOnSubmissionRated() ? 1 : 0);
             $this->refresh();
             $user->setLastAccess(new \DateTime());
             Repositories::persistAndFlush($user);
             $this->entity = $user;
             return true;
         } else {
             return false;
         }
     }
     return false;
 }