Skip to content
This repository has been archived by the owner on Jan 15, 2021. It is now read-only.

Commit

Permalink
Adding doc blocks, re-factoring some more code
Browse files Browse the repository at this point in the history
  • Loading branch information
Florian Krämer committed Apr 1, 2016
1 parent 322f4ec commit 43a92ff
Show file tree
Hide file tree
Showing 5 changed files with 136 additions and 113 deletions.
21 changes: 21 additions & 0 deletions src/Mailer/UsersMailer.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ public function verificationEmail($user, array $options = []) {
$this->set('user', $user);
}

/**
* Sends the password reset token
*
* @param \Burzum\UserTools\Model\Entity\User
* @param array $options
* @return void
*/
public function passwordResetToken($user, array $options = []) {
$defaults = [
'to' => empty($user->email) ? '' : $user->email,
Expand All @@ -32,6 +39,13 @@ public function passwordResetToken($user, array $options = []) {
$this->set('user', $user);
}

/**
* Sends the new password email
*
* @param \Burzum\UserTools\Model\Entity\User
* @param array $options
* @return void
*/
public function sendNewPasswordEmail($user, array $options = []) {
$defaults = [
'to' => empty($user->email) ? '' : $user->email,
Expand All @@ -42,11 +56,18 @@ public function sendNewPasswordEmail($user, array $options = []) {
$this->set('user', $user);
}

/**
* Sets the options from the array to the corresponding mailer methods
*
* @param array
* @return void
*/
protected function _applyOptions($options) {
foreach ($options as $method => $value) {
if (method_exists($this, $method)) {
$this->{$method}($value);
}
}
}

}
114 changes: 19 additions & 95 deletions src/Model/Behavior/UserBehavior.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
*/
namespace Burzum\UserTools\Model\Behavior;

use Burzum\UserTools\Model\PasswordAndTokenTrait;
use Burzum\UserTools\Model\UserValidationTrait;
use Cake\Auth\PasswordHasherFactory;
use Cake\Core\Configure;
Expand All @@ -29,6 +30,7 @@ class UserBehavior extends Behavior {
use EventDispatcherTrait;
use MailerAwareTrait;
use UserValidationTrait;
use PasswordAndTokenTrait;

/**
* Default config
Expand Down Expand Up @@ -465,73 +467,6 @@ public function resetPassword(Entity $user) {
return false;
}

/**
* Generates a random password that is more or less user friendly.
*
* @param int $length Password length, default is 8
* @param array $options Options array.
* @return string
*/
public function generatePassword($length = 8, $options = []) {
$options = $this->_passwordDictionary($options);
$password = '';

srand((double) microtime() * 1000000);
for ($i = 0; $i < $length; $i++) {
$password .=
$options['cons'][mt_rand(0, count($options['cons']) - 1)] .
$options['vowels'][mt_rand(0, count($options['vowels']) - 1)];
}

return substr($password, 0, $length);
}

/**
* The dictionary of vowels and consonants for the password generation.
*
* @param array $options
* @return array
*/
public function _passwordDictionary(array $options = []) {
$defaults = [
'vowels' => [
'a', 'e', 'i', 'o', 'u'
],
'cons' => [
'b', 'c', 'd', 'g', 'h', 'j', 'k', 'l', 'm', 'n',
'p', 'r', 's', 't', 'u', 'v', 'w', 'tr', 'cr', 'br', 'fr', 'th',
'dr', 'ch', 'ph', 'wr', 'st', 'sp', 'sw', 'pr', 'sl', 'cl'
]
];
if (isset($options['cons'])) {
unset($defaults['cons']);
}
if (isset($options['vowels'])) {
unset($defaults['vowels']);
}
return Hash::merge($defaults, $options);
}

/**
* Generate token used by the user registration system
*
* @param integer $length Token Length
* @param string $chars
* @return string
*/
public function generateToken($length = 10, $chars = '0123456789abcdefghijklmnopqrstuvwxyz') {
$token = '';
$i = 0;
while ($i < $length) {
$char = substr($chars, mt_rand(0, strlen($chars) - 1), 1);
if (!stristr($token, $char)) {
$token .= $char;
$i++;
}
}
return $token;
}

/**
* Removes all users from the user table that did not complete the registration
*
Expand Down Expand Up @@ -559,10 +494,10 @@ public function removeExpiredRegistrations($conditions = []) {
/**
* Changes the password for an user.
*
* @param \Cake\ORM\Entity $entity User entity
* @param \Cake\Datasource\EntityInterface $entity User entity
* @return boolean
*/
public function changePassword(Entity $entity) {
public function changePassword(EntityInterface $entity) {
if ($entity->errors()) {
return false;
}
Expand Down Expand Up @@ -663,20 +598,26 @@ protected function _getUser($value, $options = []) {
* more secure approach is to have the user manually enter a new password and
* only send him an URL with a token.
*
* @param string $email
* @param array $options
* @param string|EntityInterface $email The user entity or the email
* @param array $options Optional options array, use it to pass config options.
* @throws \Cake\Datasource\Exception\RecordNotFoundException
* @return boolean
*/
public function sendNewPassword($email, $options = []) {
$result = $this->_table->find()
->where([
$this->_table->alias() . '.' . $this->_field('email') => $email
])
->first();
if (empty($result)) {
throw new RecordNotFoundException(__d('user_tools', 'Invalid user'));
if ($email instanceof EntityInterface) {
$result = $email;
$email = $result->{$this->_field('email')};
} else {
$result = $this->_table->find()
->where([
$this->_table->alias() . '.' . $this->_field('email') => $email
])
->first();
if (empty($result)) {
throw new RecordNotFoundException(__d('user_tools', 'Invalid user'));
}
}

$result->password = $result->clear_password = $this->generatePassword();
$result->password = $this->hashPassword($result->password);
$this->_table->save($result, ['validate' => false]);
Expand Down Expand Up @@ -732,21 +673,4 @@ public function sendVerificationEmail(EntityInterface $user, $options = []) {
$this->getMailer($this->config('mailer'))->send('verificationEmail', $user, $options);
}

/**
* Compares the value of two fields.
*
* @param mixed $value
* @param string $field
* @param Entity $context
* @return boolean
*/
public function compareFields($value, $field, $context) {
if (!isset($context['data'][$field])) {
return true;
}
if ($value === $context['data'][$field]) {
return true;
}
return false;
}
}
76 changes: 76 additions & 0 deletions src/Model/PasswordAndTokenTrait.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php
namespace Burzum\UserTools\Model;

use Cake\Utility\Hash;
use Cake\Validation\Validator;

trait PasswordAndTokenTrait {

/**
* Generates a random password that is more or less user friendly.
*
* @param int $length Password length, default is 8
* @param array $options Options array.
* @return string
*/
public function generatePassword($length = 8, $options = []) {
$options = $this->_passwordDictionary($options);
$password = '';

srand((double) microtime() * 1000000);
for ($i = 0; $i < $length; $i++) {
$password .=
$options['cons'][mt_rand(0, count($options['cons']) - 1)] .
$options['vowels'][mt_rand(0, count($options['vowels']) - 1)];
}

return substr($password, 0, $length);
}

/**
* The dictionary of vowels and consonants for the password generation.
*
* @param array $options
* @return array
*/
public function _passwordDictionary(array $options = []) {
$defaults = [
'vowels' => [
'a', 'e', 'i', 'o', 'u'
],
'cons' => [
'b', 'c', 'd', 'g', 'h', 'j', 'k', 'l', 'm', 'n',
'p', 'r', 's', 't', 'u', 'v', 'w', 'tr', 'cr', 'br', 'fr', 'th',
'dr', 'ch', 'ph', 'wr', 'st', 'sp', 'sw', 'pr', 'sl', 'cl'
]
];
if (isset($options['cons'])) {
unset($defaults['cons']);
}
if (isset($options['vowels'])) {
unset($defaults['vowels']);
}
return Hash::merge($defaults, $options);
}

/**
* Generate token used by the user registration system
*
* @param integer $length Token Length
* @param string $chars
* @return string
*/
public function generateToken($length = 10, $chars = '0123456789abcdefghijklmnopqrstuvwxyz') {
$token = '';
$i = 0;
while ($i < $length) {
$char = substr($chars, mt_rand(0, strlen($chars) - 1), 1);
if (!stristr($token, $char)) {
$token .= $char;
$i++;
}
}
return $token;
}

}
21 changes: 20 additions & 1 deletion src/Model/UserValidationTrait.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php
namespace Burzum\UserTools\Model;

use RuntimeException;
use Cake\Validation\Validator;

trait UserValidationTrait {
Expand Down Expand Up @@ -200,7 +201,7 @@ protected function validationOldPassword($validator) {
*/
public function validateOldPassword($value, $field, $context) {
if (Configure::read('debug') > 0 && empty($context['data'][$this->_table->primaryKey()])) {
throw new \RuntimeException('The user id is required as well to validate the old password!');
throw new RuntimeException('The user id is required as well to validate the old password!');
}

$result = $this->_table->find()
Expand All @@ -218,4 +219,22 @@ public function validateOldPassword($value, $field, $context) {
return $this->passwordHasher()->check($value, $result->password);
}

/**
* Compares the value of two fields.
*
* @param mixed $value
* @param string $field
* @param Entity $context
* @return boolean
*/
public function compareFields($value, $field, $context) {
if (!isset($context['data'][$field])) {
return true;
}
if ($value === $context['data'][$field]) {
return true;
}
return false;
}

}
17 changes: 0 additions & 17 deletions tests/TestCase/Model/Behavior/UserBehaviorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -276,23 +276,6 @@ public function testPasswordHasher() {
$this->assertTrue(is_a($result, '\Cake\Auth\DefaultPasswordHasher'));
}

/**
* testSendEmail
*
* @return void
*/
public function testSendEmail() {
$this->UserBehavior->expects($this->any())
->method('getMailInstance')
->will($this->returnValue($this->MockEmail));

$this->MockEmail->expects($this->at(0))
->method('send')
->will($this->returnValue(true));

$this->UserBehavior->sendEmail();
}

/**
* @expectedException \Cake\Datasource\Exception\RecordNotFoundException
*/
Expand Down

0 comments on commit 43a92ff

Please sign in to comment.