/**
  * {@inheritdoc}
  */
 protected function isValid($value)
 {
     if (!$value instanceof UserDto) {
         $this->addError('Value must be of type UserDto', 1436254418);
     }
     if ($value->getPassword() !== $value->getPasswordConfirmation()) {
         $this->result->forProperty('passwordConfirmation')->addError(new Error('Password does not match confirmation', 1436254655));
     }
     if ($this->crowdClient->getUser($value->getUsername()) !== NULL) {
         $this->result->forProperty('username')->addError(new Error('The chosen username is not available', 1436267801));
     }
 }
 /**
  * Authenticates against a crowd instance.
  *
  * @param \TYPO3\Flow\Security\Authentication\TokenInterface $authenticationToken The token to be authenticated
  * @return void
  * @throws \TYPO3\Flow\Security\Exception\UnsupportedAuthenticationTokenException
  */
 public function authenticate(TokenInterface $authenticationToken)
 {
     if (!$authenticationToken instanceof UsernamePassword) {
         throw new UnsupportedAuthenticationTokenException('This provider cannot authenticate the given token.', 1217339845);
     }
     $credentials = $authenticationToken->getCredentials();
     if (is_array($credentials) && isset($credentials['username']) && isset($credentials['password'])) {
         $crowdAuthenticationResponse = $this->crowdClient->authenticate($credentials['username'], $credentials['password']);
         if ($crowdAuthenticationResponse !== NULL) {
             /** @var $account \TYPO3\Flow\Security\Account */
             $account = NULL;
             $providerName = $this->name;
             $accountRepository = $this->accountRepository;
             $this->securityContext->withoutAuthorizationChecks(function () use($credentials, $providerName, $accountRepository, &$account) {
                 $account = $accountRepository->findActiveByAccountIdentifierAndAuthenticationProviderName($credentials['username'], $providerName);
             });
             if ($account === NULL) {
                 $account = new Account();
                 $account->setAuthenticationProviderName($providerName);
                 $account->setAccountIdentifier($credentials['username']);
                 $this->accountRepository->add($account);
             }
             $authenticateRole = $this->policyService->getRole($this->options['authenticateRole']);
             if ($account->hasRole($authenticateRole) === FALSE) {
                 $account->addRole($authenticateRole);
             }
             $crowdUser = $this->partyService->getAssignedPartyOfAccount($account);
             if ($crowdUser instanceof Person) {
                 if ($crowdUser->getName()->getFirstName() !== $crowdAuthenticationResponse['first-name']) {
                     $crowdUser->getName()->setFirstName($crowdAuthenticationResponse['first-name']);
                     $this->partyRepository->update($crowdUser);
                 }
                 if ($crowdUser->getName()->getLastName() !== $crowdAuthenticationResponse['last-name']) {
                     $crowdUser->getName()->setLastName($crowdAuthenticationResponse['last-name']);
                     $this->partyRepository->update($crowdUser);
                 }
                 if ($crowdUser->getPrimaryElectronicAddress()->getIdentifier() !== $crowdAuthenticationResponse['email']) {
                     $crowdUser->getPrimaryElectronicAddress()->setIdentifier($crowdAuthenticationResponse['email']);
                     $this->partyRepository->update($crowdUser);
                 }
             } else {
                 $crowdUser = new Person();
                 $crowdUser->setName(new PersonName('', $crowdAuthenticationResponse['first-name'], '', $crowdAuthenticationResponse['last-name']));
                 $email = new ElectronicAddress();
                 $email->setIdentifier($crowdAuthenticationResponse['email']);
                 $email->setType(ElectronicAddress::TYPE_EMAIL);
                 $crowdUser->setPrimaryElectronicAddress($email);
                 $this->partyRepository->add($crowdUser);
                 $this->partyService->assignAccountToParty($account, $crowdUser);
             }
             $authenticationToken->setAuthenticationStatus(TokenInterface::AUTHENTICATION_SUCCESSFUL);
             $authenticationToken->setAccount($account);
         } else {
             $authenticationToken->setAuthenticationStatus(TokenInterface::WRONG_CREDENTIALS);
         }
     } elseif ($authenticationToken->getAuthenticationStatus() !== TokenInterface::AUTHENTICATION_SUCCESSFUL) {
         $authenticationToken->setAuthenticationStatus(TokenInterface::NO_CREDENTIALS_GIVEN);
     }
 }
 /**
  * @param string $password
  * @param string $passwordConfirmation
  * @return void
  */
 public function resetAction($password, $passwordConfirmation)
 {
     if ($password === '' || $password !== $passwordConfirmation) {
         $this->flashMessageContainer->addMessage(new \TYPO3\Flow\Error\Error('Passwords didn\'t match!', 1435750717));
         return $this->errorAction();
     }
     $this->crowdClient->setPasswordForUser($this->securityContext->getAccount()->getAccountIdentifier(), $password);
     $this->addFlashMessage('Your password has been updated!');
     $this->redirect('resetForm');
 }
 /**
  * @param Token $token
  * @return void
  */
 public function createAction(Token $token = NULL)
 {
     if ($token === NULL) {
         $this->addFlashMessage('The activation link is not valid.', '', Message::SEVERITY_ERROR);
         $this->forward('createError');
     }
     $user = $token->getMeta()['user'];
     $result = $this->crowdClient->addUser($user->getFirstname(), $user->getLastname(), $user->getEmail(), $user->getUsername(), $user->getPassword());
     if (!$result->hasErrors()) {
         $this->addFlashMessage('Your account was created successfully. You can now sing in with your credentials.', 'Account created', Message::SEVERITY_OK);
         $this->redirect('index');
     } else {
         $error = $result->getFirstError();
         $this->addFlashMessage($error->getMessage(), $error->getTitle(), Message::SEVERITY_ERROR);
         $this->forward('createError');
     }
 }