/**
  *
  * @param \Doctrine\ODM\MongoDB\Event\LifecycleEventArgs $eventArgs
  */
 public function prePersist(LifecycleEventArgs $eventArgs)
 {
     $document = $eventArgs->getDocument();
     $documentManager = $eventArgs->getDocumentManager();
     $metadata = $documentManager->getClassMetadata(get_class($document));
     if (isset($metadata->crypt['hash'])) {
         foreach ($metadata->crypt['hash'] as $field => $config) {
             HashService::hashField($field, $document, $metadata);
         }
     }
     if (isset($metadata->crypt['blockCipher'])) {
         foreach ($metadata->crypt['blockCipher'] as $field => $config) {
             BlockCipherService::encryptField($field, $document, $metadata);
         }
     }
 }
 /**
  * This will start the credential reset process for an identity.
  * If the identity is found in the db, a new token is created, and
  * that token is sent to the identity's email.
  *
  * @param type $data
  * @return type
  * @throws Exception\LoginFailedException
  */
 public function create($data)
 {
     $documentManager = $this->options->getDocumentManager();
     $identityMetadata = $documentManager->getClassMetadata($this->options->getIdentityClass());
     $criteria = [];
     if (isset($data['identityName']) && !$data['identityName'] == '') {
         $criteria['identityName'] = $data['identityName'];
     }
     if (isset($data['email']) && $data['email'] != '') {
         $criteria['email'] = BlockCipherService::encryptValue($data['email'], $identityMetadata->crypt['blockCipher']['email']);
     }
     if (count($criteria) == 0) {
         throw new Exception\InvalidArgumentException('Either identityName or email must be provided');
     }
     $identityRepository = $documentManager->getRepository($this->options->getIdentityClass());
     $identity = $identityRepository->findOneBy($criteria);
     if (!isset($identity)) {
         throw new Exception\DocumentNotFoundException();
     }
     // create unique recovery code
     $code = base64_encode(Hash::hash(time(), $identity->getIdentityName()));
     $code = substr($code, 0, strlen($code) - 2);
     $expiry = $this->options->getExpiry();
     // delete any existing tokens for the identity
     $documentManager->createQueryBuilder($this->options->getDocumentClass())->remove()->field('identityName')->equals($identity->getIdentityName())->getQuery()->execute();
     parent::create(['code' => $code, 'identityName' => $identity->getIdentityName(), 'expires' => $expiry + time()]);
     //remove the Location header so the token isn't exposed in the response
     $headers = $this->response->getHeaders();
     $headers->removeHeader($headers->get('Location'));
     $link = '/rest/' . $this->options->getEndpoint() . '/' . $code;
     // Create email body
     $body = new ViewModel(['identityName' => $identity->getIdentityName(), 'link' => $link, 'hours' => $expiry / (60 * 60)]);
     $body->setTemplate('email/forgot-credential');
     // Send the email
     $mail = new Message();
     $mail->setBody($this->options->getEmailRenderer()->render($body))->setFrom($this->options->getMailFrom())->addTo(BlockCipherService::decryptValue($identity->getEmail(), $identityMetadata->crypt['blockCipher']['email']))->setSubject($this->options->getMailSubject());
     $this->options->getMailTransport()->send($mail);
     $this->response->setStatusCode(201);
     return $this->response;
 }
 public function testBlockCipher()
 {
     $documentManager = $this->documentManager;
     $testDoc = new Simple();
     $testDoc->setName('Toby');
     $documentManager->persist($testDoc);
     $documentManager->flush();
     $id = $testDoc->getId();
     $documentManager->clear();
     $repository = $documentManager->getRepository(get_class($testDoc));
     $testDoc = $repository->find($id);
     $this->assertNotEquals('Toby', $testDoc->getName());
     BlockCipherService::decryptDocument($testDoc, $documentManager->getClassMetadata(get_class($testDoc)));
     $this->assertEquals('Toby', $testDoc->getName());
     $testDoc->setName('Lucy');
     $documentManager->flush();
     $documentManager->clear();
     $testDoc = $repository->find($id);
     $this->assertNotEquals('Lucy', $testDoc->getName());
     BlockCipherService::decryptDocument($testDoc, $documentManager->getClassMetadata(get_class($testDoc)));
     $this->assertEquals('Lucy', $testDoc->getName());
 }
 public function testUpdateIdentity()
 {
     $documentManager = $this->documentManager;
     $this->routeMatch->setParam('id', 'lucy');
     $this->request->setMethod(Request::METHOD_PUT);
     $this->request->getHeaders()->addHeader(GenericHeader::fromString('Content-type: application/json'));
     $this->request->setContent('{
         "lastname":"Smiles",
         "email":"*****@*****.**"
     }');
     $result = $this->getController()->dispatch($this->request, $this->response);
     $returnArray = $result->getVariables();
     $this->assertEquals('lucy', $returnArray['identityName']);
     $this->assertEquals('Smiles', $returnArray['lastname']);
     //load the identity from db
     $documentManager->clear();
     $repository = $documentManager->getRepository($this->controller->getOptions()->getDocumentClass());
     $identity = $repository->findOneBy(['identityName' => 'lucy']);
     $this->assertTrue(isset($identity));
     $this->assertEquals('Smiles', $identity->getLastname());
     $this->assertEquals('Lucy', $identity->getFirstname());
     $this->assertNotEquals('*****@*****.**', $identity->getEmail());
     //check that the email can be retireved
     BlockCipherService::decryptDocument($identity, $documentManager->getClassMetadata($this->controller->getOptions()->getDocumentClass()));
     $this->assertEquals('*****@*****.**', $identity->getEmail());
 }