Skip to content

Commit

Permalink
Merge pull request #815 from CakeDC/8.next
Browse files Browse the repository at this point in the history
8.next
  • Loading branch information
steinkel authored Oct 7, 2019
2 parents 3c632c0 + 675aaa7 commit 79602df
Show file tree
Hide file tree
Showing 39 changed files with 203 additions and 54 deletions.
2 changes: 1 addition & 1 deletion .semver
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
:major: 8
:minor: 4
:minor: 5
:patch: 0
:special: ''
6 changes: 4 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
language: php

services:
- postgresql
- mysql
php:
- 5.6
- 7.0
Expand All @@ -10,7 +12,7 @@ sudo: false

env:
matrix:
- DB=mysql db_dsn='mysql://travis@0.0.0.0/cakephp_test'
- DB=mysql db_dsn='mysql://travis@127.0.0.1/cakephp_test'
- DB=pgsql db_dsn='postgres://[email protected]/cakephp_test'
- DB=sqlite db_dsn='sqlite:///:memory:'

Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@ Changelog

Releases for CakePHP 3
-------------
* 8.5.0
* Added new `UsersAuthComponent::EVENT_BEFORE_SOCIAL_LOGIN_REDIRECT`
* Added finder to get existing social account
* Improved social login to updated social account when account already exists
* Improved URLs in template to avoid issue in prefixed routes

* 8.4.0
* Rehash password if needed at login
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ Versions and branches

| CakePHP | CakeDC Users Plugin | Tag | Notes |
| :-------------: | :------------------------: | :--: | :---- |
| 3.7 | [master](https://github.com/cakedc/users/tree/master) | 8.4.0 | stable |
| 3.7 | [master](https://github.com/cakedc/users/tree/master) | 8.5.0 | stable |
| 3.7 | [develop](https://github.com/cakedc/users/tree/develop) | - | unstable |
| ^3.7 | [8.4](https://github.com/cakedc/users/tree/8.next) | 8.4.0 | stable |
| ^3.7 | [8.5](https://github.com/cakedc/users/tree/8.next) | 8.5.0 | stable |
| 3.6 | [8.1](https://github.com/cakedc/users/tree/8.1.0) | 8.1.0 | stable |
| 3.5 | [6.x](https://github.com/cakedc/users/tree/6.x) | 6.0.1 | stable |
| 3.4 | [5.x](https://github.com/cakedc/users/tree/5.x) | 5.2.0 | stable |
Expand Down
20 changes: 17 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,16 @@
"cakedc/auth": "^3.0"
},
"require-dev": {
"phpunit/phpunit": "^5.0",
"cakephp/cakephp-codesniffer": "^2.0",
"phpunit/phpunit": "^5.7.14|^6.0",
"league/oauth2-facebook": "@stable",
"league/oauth2-instagram": "@stable",
"league/oauth2-google": "@stable",
"league/oauth2-linkedin": "@stable",
"luchianenco/oauth2-amazon": "^1.1",
"google/recaptcha": "@stable",
"robthree/twofactorauth": "~1.6",
"yubico/u2flib-server": "^1.0"
"yubico/u2flib-server": "^1.0",
"cakephp/cakephp-codesniffer": "dev-master"
},
"suggest": {
"league/oauth1-client": "Provides Social Authentication with Twitter",
Expand All @@ -62,5 +62,19 @@
"CakeDC\\Users\\Test\\": "tests",
"CakeDC\\Users\\Test\\Fixture\\": "tests"
}
},
"scripts": {
"check": [
"@cs-check",
"@test",
"@stan"
],
"cs-check": "phpcs -p --standard=vendor/cakephp/cakephp-codesniffer/CakePHP src/ tests/",
"cs-fix": "phpcbf --standard=vendor/cakephp/cakephp-codesniffer/CakePHP src/ tests/",
"test": "phpunit --stderr",
"stan": "phpstan analyse src/ && psalm --show-info=false",
"psalm": "psalm --show-info=false",
"stan-setup": "cp composer.json composer.backup && composer require --dev phpstan/phpstan:^0.11 vimeo/psalm:^3.0 && mv composer.backup composer.json",
"test-coverage": "phpunit --stderr --coverage-clover=clover.xml"
}
}
9 changes: 6 additions & 3 deletions config/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@
collection((array)Configure::read('Users.config'))->each(function ($file) {
Configure::load($file);
});

TableRegistry::getTableLocator()->setConfig('Users', ['className' => Configure::read('Users.table')]);
TableRegistry::getTableLocator()->setConfig('CakeDC/Users.Users', ['className' => Configure::read('Users.table')]);
if (!TableRegistry::getTableLocator()->exists('Users')) {
TableRegistry::getTableLocator()->setConfig('Users', ['className' => Configure::read('Users.table')]);
}
if (!TableRegistry::getTableLocator()->exists('CakeDC/Users.Users')) {
TableRegistry::getTableLocator()->setConfig('CakeDC/Users.Users', ['className' => Configure::read('Users.table')]);
}

if (Configure::check('Users.auth')) {
Configure::write('Auth.authenticate.all.userModel', Configure::read('Users.table'));
Expand Down
2 changes: 1 addition & 1 deletion config/users.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
'Profile' => [
// Allow view other users profiles
'viewOthers' => true,
'route' => ['plugin' => 'CakeDC/Users', 'controller' => 'Users', 'action' => 'profile'],
'route' => ['prefix' => false, 'plugin' => 'CakeDC/Users', 'controller' => 'Users', 'action' => 'profile'],
],
'Key' => [
'Session' => [
Expand Down
7 changes: 7 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
parameters:
level: 4
autoload_files:
- tests/bootstrap.php
ignoreErrors:

services:
19 changes: 19 additions & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0"?>
<psalm
allowCoercionFromStringToClassConst="true"
allowStringToStandInForClass="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
<projectFiles>
<directory name="src" />
</projectFiles>

<issueHandlers>
<LessSpecificReturnType errorLevel="info" />
<RedundantConditionGivenDocblockType errorLevel="info" />
<TypeCoercion errorLevel="info" />
<DocblockTypeContradiction errorLevel="info" />
</issueHandlers>
</psalm>
2 changes: 1 addition & 1 deletion src/Auth/DefaultTwoFactorAuthenticationChecker.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
namespace CakeDC\Users\Auth;

use Cake\Core\Configure;
use Cake\Network\Exception\BadRequestException;
use Cake\Http\Exception\BadRequestException;

/**
* Default class to check if two factor authentication is enabled and required
Expand Down
1 change: 1 addition & 0 deletions src/Auth/Social/Mapper/AbstractMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public function __construct($rawData, $mapFields = null)
}
$this->_mapFields = array_merge($this->_defaultMapFields, $this->_mapFields);
}

/**
* Invoke method
*
Expand Down
11 changes: 4 additions & 7 deletions src/Auth/SocialAuthenticate.php
Original file line number Diff line number Diff line change
Expand Up @@ -284,10 +284,11 @@ public function unauthenticated(ServerRequest $request, Response $response)
}

$authParams = $this->getConfig(sprintf('providers.%s.authParams', $request->getParam('provider')), []);
$location = $provider->getAuthorizationUrl($authParams);

$response = $response->withLocation($provider->getAuthorizationUrl($authParams));
$this->dispatchEvent(UsersAuthComponent::EVENT_BEFORE_SOCIAL_LOGIN_REDIRECT, compact('location', 'request'));

return $response;
return $response->withLocation($location);
}

/**
Expand Down Expand Up @@ -368,11 +369,7 @@ protected function _touch(array $data)
$this->_getController()->dispatchEvent(UsersAuthComponent::EVENT_AFTER_REGISTER, compact('user'));
}

if (!empty($user->username)) {
$user = $this->_findUser($user->username);
}

return $user;
return $this->_findUser($user->get(Configure::read('Auth.authenticate.Form.fields.username', 'username')));
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Auth/TwoFactorAuthenticationCheckerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
namespace CakeDC\Users\Auth;

use Cake\Core\Configure;
use Cake\Network\Exception\BadRequestException;
use Cake\Http\Exception\BadRequestException;

/**
* Factory for two authentication checker
Expand Down
2 changes: 1 addition & 1 deletion src/Auth/U2fAuthenticationCheckerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
namespace CakeDC\Users\Auth;

use Cake\Core\Configure;
use Cake\Network\Exception\BadRequestException;
use Cake\Http\Exception\BadRequestException;

/**
* Factory for two authentication checker
Expand Down
1 change: 1 addition & 0 deletions src/Controller/Component/UsersAuthComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class UsersAuthComponent extends Component
const EVENT_AFTER_REGISTER = 'Users.Component.UsersAuth.afterRegister';
const EVENT_BEFORE_LOGOUT = 'Users.Component.UsersAuth.beforeLogout';
const EVENT_AFTER_LOGOUT = 'Users.Component.UsersAuth.afterLogout';
const EVENT_BEFORE_SOCIAL_LOGIN_REDIRECT = 'Users.Component.UsersAuth.beforeSocialLoginRedirect';
const EVENT_BEFORE_SOCIAL_LOGIN_USER_CREATE = 'Users.Component.UsersAuth.beforeSocialLoginUserCreate';
const EVENT_AFTER_CHANGE_PASSWORD = 'Users.Component.UsersAuth.afterResetPassword';
const EVENT_ON_EXPIRED_TOKEN = 'Users.Component.UsersAuth.onExpiredToken';
Expand Down
5 changes: 5 additions & 0 deletions src/Controller/Traits/LinkSocialTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

namespace CakeDC\Users\Controller\Traits;

use CakeDC\Users\Controller\Component\UsersAuthComponent;
use CakeDC\Users\Model\Table\SocialAccountsTable;
use Cake\Core\Configure;
use Cake\Http\Exception\NotFoundException;
Expand Down Expand Up @@ -40,6 +41,10 @@ public function linkSocial($alias = null)
$this->request->getSession()->write('temporary_credentials', $temporaryCredentials);
}
$authUrl = $provider->getAuthorizationUrl($temporaryCredentials);
$this->dispatchEvent(UsersAuthComponent::EVENT_BEFORE_SOCIAL_LOGIN_REDIRECT, [
'location' => $authUrl,
'request' => $this->request,
]);
if (empty($temporaryCredentials)) {
$this->request->session()->write('SocialLink.oauth2state', $provider->getState());
}
Expand Down
1 change: 1 addition & 0 deletions src/Controller/Traits/LoginTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ public function failedSocialLogin($exception, $data, $flash = false)
$this->request->getSession()->write(Configure::read('Users.Key.Session.social'), $data);

return $this->redirect([
'prefix' => false,
'plugin' => 'CakeDC/Users',
'controller' => 'Users',
'action' => 'socialEmail'
Expand Down
9 changes: 8 additions & 1 deletion src/Controller/Traits/PasswordManagementTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,14 @@ public function changePassword($id = null)
$user = $this->getUsersTable()->patchEntity(
$user,
$this->request->getData(),
['validate' => $validator]
[
'validate' => $validator,
'accessibleFields' => [
'current_password' => true,
'password' => true,
'password_confirm' => true,
]
]
);
if ($user->getErrors()) {
$this->Flash->error(__d('CakeDC/Users', 'Password could not be changed'));
Expand Down
1 change: 1 addition & 0 deletions src/Controller/Traits/U2fTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ public function redirectWithQuery($url)

return $this->redirect($url);
}

/**
* U2f entry point
*
Expand Down
71 changes: 51 additions & 20 deletions src/Model/Behavior/SocialBehavior.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@ public function socialLogin(array $data, array $options)
}
} else {
$user = $existingAccount->user;
$accountData = $this->extractAccountData($data);
$this->_table->SocialAccounts->patchEntity($existingAccount, $accountData);
$this->_table->SocialAccounts->save($existingAccount);
}
if (!empty($existingAccount)) {
if (!$existingAccount->active) {
Expand Down Expand Up @@ -121,9 +124,7 @@ protected function _createSocialUser($data, $options = [])
if ($useEmail && empty($email)) {
throw new MissingEmailException(__d('CakeDC/Users', 'Email not present'));
} else {
$existingUser = $this->_table->find()
->where([$this->_table->aliasField('email') => $email])
->first();
$existingUser = $this->_table->find('existingForSocialLogin', compact('email'))->first();
}

$user = $this->_populateUser($data, $existingUser, $useEmail, $validateEmail, $tokenExpiration);
Expand Down Expand Up @@ -155,23 +156,7 @@ protected function _createSocialUser($data, $options = [])
*/
protected function _populateUser($data, $existingUser, $useEmail, $validateEmail, $tokenExpiration)
{
$accountData['username'] = Hash::get($data, 'username');
$accountData['reference'] = Hash::get($data, 'id');
$accountData['avatar'] = Hash::get($data, 'avatar');
$accountData['link'] = Hash::get($data, 'link');

$accountData['avatar'] = str_replace('normal', 'square', $accountData['avatar']);
$accountData['description'] = Hash::get($data, 'bio');
$accountData['token'] = Hash::get($data, 'credentials.token');
$accountData['token_secret'] = Hash::get($data, 'credentials.secret');
$expires = Hash::get($data, 'credentials.expires');
if (!empty($expires)) {
$expiresTime = new DateTime();
$accountData['token_expires'] = $expiresTime->setTimestamp($expires)->format('Y-m-d H:i:s');
} else {
$accountData['token_expires'] = null;
}
$accountData['data'] = serialize(Hash::get($data, 'raw'));
$accountData = $this->extractAccountData($data);
$accountData['active'] = true;

$dataValidated = Hash::get($data, 'validated');
Expand Down Expand Up @@ -258,4 +243,50 @@ public function generateUniqueUsername($username)

return $username;
}

/**
* Prepare a query to retrieve existing entity for social login
*
* @param \Cake\ORM\Query $query The base query.
* @param array $options Find options with email key.
*
* @return \Cake\ORM\Query
*/
public function findExistingForSocialLogin(\Cake\ORM\Query $query, array $options)
{
return $query->where([
$this->_table->aliasField('email') => $options['email']
]);
}

/**
* Extract the account data to insert/update
*
* @param array $data Social data.
*
* @throws \Exception
*/
protected function extractAccountData(array $data)
{
$accountData = [];
$accountData['username'] = Hash::get($data, 'username');
$accountData['reference'] = Hash::get($data, 'id');
$accountData['avatar'] = Hash::get($data, 'avatar');
$accountData['link'] = Hash::get($data, 'link');

$accountData['avatar'] = str_replace('normal', 'square', $accountData['avatar']);
$accountData['description'] = Hash::get($data, 'bio');
$accountData['token'] = Hash::get($data, 'credentials.token');
$accountData['token_secret'] = Hash::get($data, 'credentials.secret');
$expires = Hash::get($data, 'credentials.expires');
if (!empty($expires)) {
$expiresTime = new DateTime();
$accountData['token_expires'] = $expiresTime->setTimestamp($expires)->format('Y-m-d H:i:s');
} else {
$accountData['token_expires'] = null;
}
$accountData['data'] = serialize(Hash::get($data, 'raw'));

return $accountData;
}
}
1 change: 1 addition & 0 deletions src/Shell/UsersShell.php
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,7 @@ protected function _generatedHashedPassword($password)
{
return (new User)->hashPassword($password);
}

//add filters LIKE in username and email to some tasks
// --force to ignore "you are about to do X to Y users"
}
1 change: 1 addition & 0 deletions src/Template/Email/html/reset_password.ctp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

$activationUrl = [
'_full' => true,
'prefix' => false,
'plugin' => 'CakeDC/Users',
'controller' => 'Users',
'action' => 'resetPassword',
Expand Down
1 change: 1 addition & 0 deletions src/Template/Email/html/social_account_validation.ctp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
$text = __d('CakeDC/Users', 'Activate your social login here');
$activationUrl = [
'_full' => true,
'prefix' => false,
'plugin' => 'CakeDC/Users',
'controller' => 'SocialAccounts',
'action' => 'validateAccount',
Expand Down
1 change: 1 addition & 0 deletions src/Template/Email/html/validation.ctp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

$activationUrl = [
'_full' => true,
'prefix' => false,
'plugin' => 'CakeDC/Users',
'controller' => 'Users',
'action' => 'validateEmail',
Expand Down
1 change: 1 addition & 0 deletions src/Template/Email/text/reset_password.ctp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@

$activationUrl = [
'_full' => true,
'prefix' => false,
'plugin' => 'CakeDC/Users',
'controller' => 'Users',
'action' => 'resetPassword',
Expand Down
Loading

0 comments on commit 79602df

Please sign in to comment.