Skip to content

Commit 568fc0c

Browse files
committed
Merge branch '9.next'
2 parents 845b5f2 + 910d32c commit 568fc0c

File tree

15 files changed

+187
-70
lines changed

15 files changed

+187
-70
lines changed

.github/codecov.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
codecov:
2+
require_ci_to_pass: yes
3+
4+
coverage:
5+
range: "90...100"
6+
7+
comment: false

.github/workflows/ci.yml

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
6+
pull_request:
7+
branches:
8+
- '*'
9+
10+
jobs:
11+
testsuite:
12+
runs-on: ubuntu-20.04
13+
strategy:
14+
fail-fast: false
15+
matrix:
16+
php-version: ['7.3', '7.4', '8.0']
17+
db-type: [sqlite, mysql, pgsql]
18+
prefer-lowest: ['']
19+
20+
steps:
21+
- name: Setup MySQL latest
22+
if: matrix.db-type == 'mysql'
23+
run: docker run --rm --name=mysqld -e MYSQL_ROOT_PASSWORD=root -e MYSQL_DATABASE=cakephp -p 3306:3306 -d mysql --default-authentication-plugin=mysql_native_password --disable-log-bin
24+
25+
- name: Setup PostgreSQL latest
26+
if: matrix.db-type == 'pgsql'
27+
run: docker run --rm --name=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=cakephp -p 5432:5432 -d postgres
28+
29+
- uses: actions/checkout@v2
30+
31+
- name: Setup PHP
32+
uses: shivammathur/setup-php@v2
33+
with:
34+
php-version: ${{ matrix.php-version }}
35+
extensions: mbstring, intl, apcu, sqlite, pdo_sqlite, pdo_${{ matrix.db-type }}, ${{ matrix.db-type }}
36+
ini-values: apc.enable_cli = 1
37+
coverage: pcov
38+
39+
- name: Get composer cache directory
40+
id: composer-cache
41+
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
42+
43+
- name: Get date part for cache key
44+
id: key-date
45+
run: echo "::set-output name=date::$(date +'%Y-%m')"
46+
47+
- name: Cache composer dependencies
48+
uses: actions/cache@v1
49+
with:
50+
path: ${{ steps.composer-cache.outputs.dir }}
51+
key: ${{ runner.os }}-composer-${{ steps.key-date.outputs.date }}-${{ hashFiles('composer.json') }}-${{ matrix.prefer-lowest }}
52+
53+
- name: composer install
54+
run: |
55+
if ${{ matrix.prefer-lowest == 'prefer-lowest' }}; then
56+
composer update --prefer-lowest --prefer-stable
57+
else
58+
composer update
59+
fi
60+
61+
- name: Setup problem matchers for PHPUnit
62+
if: matrix.php-version == '7.4' && matrix.db-type == 'mysql'
63+
run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
64+
65+
- name: Run PHPUnit
66+
run: |
67+
if [[ ${{ matrix.db-type }} == 'sqlite' ]]; then export DB_URL='sqlite:///:memory:'; fi
68+
if [[ ${{ matrix.db-type }} == 'mysql' ]]; then export DB_URL='mysql://root:root@127.0.0.1/cakephp?encoding=utf8'; fi
69+
if [[ ${{ matrix.db-type }} == 'pgsql' ]]; then export DB_URL='postgres://postgres:postgres@127.0.0.1/postgres'; fi
70+
if [[ ${{ matrix.php-version }} == '7.4' ]]; then
71+
export CODECOVERAGE=1 && vendor/bin/phpunit --verbose --coverage-clover=coverage.xml
72+
else
73+
vendor/bin/phpunit
74+
fi
75+
76+
- name: Submit code coverage
77+
if: matrix.php-version == '7.4'
78+
uses: codecov/codecov-action@v1
79+
80+
cs-stan:
81+
name: Coding Standard & Static Analysis
82+
runs-on: ubuntu-20.04
83+
84+
steps:
85+
- uses: actions/checkout@v2
86+
87+
- name: Setup PHP
88+
uses: shivammathur/setup-php@v2
89+
with:
90+
php-version: '7.3'
91+
extensions: mbstring, intl, apcu
92+
coverage: none
93+
94+
- name: Get composer cache directory
95+
id: composer-cache
96+
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
97+
98+
- name: Get date part for cache key
99+
id: key-date
100+
run: echo "::set-output name=date::$(date +'%Y-%m')"
101+
102+
- name: Cache composer dependencies
103+
uses: actions/cache@v1
104+
with:
105+
path: ${{ steps.composer-cache.outputs.dir }}
106+
key: ${{ runner.os }}-composer-${{ steps.key-date.outputs.date }}-${{ hashFiles('composer.json') }}-${{ matrix.prefer-lowest }}
107+
108+
- name: composer install
109+
run: composer stan-setup
110+
111+
- name: Run PHP CodeSniffer
112+
run: composer cs-check
113+
114+
# - name: Run psalm
115+
# if: success() || failure()
116+
# run: vendor/bin/psalm.phar --output-format=github
117+
118+
- name: Run phpstan
119+
if: success() || failure()
120+
run: composer stan

.travis.yml

Lines changed: 0 additions & 59 deletions
This file was deleted.

Docs/Documentation/Events.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,17 @@ own business, for example
3434
$this->register();
3535
$this->render('register');
3636
}
37+
38+
39+
How to make an autologin using `EVENT_AFTER_EMAIL_TOKEN_VALIDATION` event
40+
41+
```php
42+
EventManager::instance()->on(
43+
\CakeDC\Users\Plugin::EVENT_AFTER_EMAIL_TOKEN_VALIDATION,
44+
function($event){
45+
$users = $this->getTableLocator()->get('Users');
46+
$user = $users->get($event->getData('user')->id);
47+
$this->Authentication->setIdentity($user);
48+
}
49+
);
50+
```

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
CakeDC Users Plugin
22
===================
33

4-
[![Build Status](https://secure.travis-ci.org/CakeDC/users.png?branch=master)](http://travis-ci.org/CakeDC/users)
4+
[![Build Status](https://img.shields.io/github/workflow/status/CakeDC/users/CI/master?style=flat-square)](https://github.com/CakeDC/users/actions?query=workflow%3ACI+branch%3Amaster)
55
[![Coverage Status](https://img.shields.io/codecov/c/gh/CakeDC/users.svg?style=flat-square)](https://codecov.io/gh/CakeDC/users)
66
[![Downloads](https://poser.pugx.org/CakeDC/users/d/total.png)](https://packagist.org/packages/CakeDC/users)
77
[![Latest Version](https://poser.pugx.org/CakeDC/users/v/stable.png)](https://packagist.org/packages/CakeDC/users)

src/Controller/Traits/UserValidationTrait.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,10 @@ public function validate($type = null, $token = null)
4242
try {
4343
$result = $this->getUsersTable()->validate($token, 'activateUser');
4444
if ($result) {
45+
$event = $this->dispatchEvent(Plugin::EVENT_AFTER_EMAIL_TOKEN_VALIDATION, ['user' => $result]);
46+
if (!empty($event) && is_array($event->getResult())) {
47+
return $this->redirect($event->getResult());
48+
}
4549
$this->Flash->success(__d('cake_d_c/users', 'User account validated successfully'));
4650
} else {
4751
$this->Flash->error(__d('cake_d_c/users', 'User account could not be validated'));

src/Model/Behavior/LinkSocialBehavior.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,9 @@ protected function populateSocialAccount($socialAccount, $data)
114114
$accountData['reference'] = $data['id'] ?? null;
115115
$accountData['avatar'] = $data['avatar'] ?? null;
116116
$accountData['link'] = $data['link'] ?? null;
117-
$accountData['avatar'] = str_replace('normal', 'square', $accountData['avatar']);
117+
if ($accountData['avatar'] ?? null) {
118+
$accountData['avatar'] = str_replace('normal', 'square', $accountData['avatar']);
119+
}
118120
$accountData['description'] = $data['bio'] ?? null;
119121
$accountData['token'] = $data['credentials']['token'] ?? null;
120122
$accountData['token_secret'] = $data['credentials']['secret'] ?? null;

src/Model/Behavior/SocialBehavior.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,9 @@ protected function extractAccountData(array $data)
286286
$accountData['avatar'] = $data['avatar'] ?? null;
287287
$accountData['link'] = $data['link'] ?? null;
288288

289-
$accountData['avatar'] = str_replace('normal', 'square', $accountData['avatar']);
289+
if ($accountData['avatar'] ?? null) {
290+
$accountData['avatar'] = str_replace('normal', 'square', $accountData['avatar']);
291+
}
290292
$accountData['description'] = $data['bio'] ?? null;
291293
$accountData['token'] = $data['credentials']['token'] ?? null;
292294
$accountData['token_secret'] = $data['credentials']['secret'] ?? null;

src/Model/Entity/User.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
* @property bool $is_superuser
2828
* @property \Cake\I18n\Time $token_expires
2929
* @property string $token
30+
* @property string $api_token
3031
* @property array $additional_data
3132
* @property \CakeDC\Users\Model\Entity\SocialAccount[] $social_accounts
3233
*/

src/Plugin.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ class Plugin extends BasePlugin implements AuthenticationServiceProviderInterfac
4242
public const EVENT_SOCIAL_LOGIN_EXISTING_ACCOUNT = 'Users.Global.socialLoginExistingAccount';
4343
public const EVENT_ON_EXPIRED_TOKEN = 'Users.Global.onExpiredToken';
4444
public const EVENT_AFTER_RESEND_TOKEN_VALIDATION = 'Users.Global.afterResendTokenValidation';
45+
public const EVENT_AFTER_EMAIL_TOKEN_VALIDATION = 'Users.Global.afterEmailTokenValidation';
4546

4647
/**
4748
* Returns an authentication service instance.

src/Shell/UsersShell.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,12 @@ public function changeApiToken()
220220
'api_token' => $token,
221221
];
222222
$savedUser = $this->_updateUser($username, $data);
223+
if (!$savedUser) {
224+
$this->err(__d('cake_d_c/users', 'User was not saved, check validation errors'));
225+
}
226+
/**
227+
* @var \CakeDC\Users\Model\Entity\User $savedUser
228+
*/
223229
$this->out(__d('cake_d_c/users', 'Api token changed for user: {0}', $username));
224230
$this->out(__d('cake_d_c/users', 'New token: {0}', $savedUser->api_token));
225231
}

tests/TestCase/Controller/Traits/Integration/LoginTraitIntegrationTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public function testRedirectToLogin()
5656
{
5757
$this->enableRetainFlashMessages();
5858
$this->get('/pages/home');
59-
$this->assertRedirect('/login?redirect=http%3A%2F%2Flocalhost%2Fpages%2Fhome');
59+
$this->assertRedirectContains('/login?redirect=http%3A%2F%2Flocalhost%2Fpages%2Fhome');
6060
$this->assertFlashMessage('You are not authorized to access that location.');
6161
}
6262

@@ -197,7 +197,7 @@ public function testLoginPostRequestRightPasswordIsEnabledOTP()
197197
'username' => 'user-2',
198198
'password' => '12345',
199199
]);
200-
$this->assertRedirect('/verify');
200+
$this->assertRedirectContains('/verify');
201201
}
202202

203203
/**
@@ -215,7 +215,7 @@ public function testLoginPostRequestRightPasswordIsEnabledU2f()
215215
'username' => 'user-2',
216216
'password' => '12345',
217217
]);
218-
$this->assertRedirect('/users/u2f');
218+
$this->assertRedirectContains('/users/u2f');
219219
}
220220

221221
/**

tests/TestCase/Controller/Traits/Integration/PasswordManagementTraitIntegrationTest.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ public function testRequestResetPassword()
4545
}
4646

4747
/**
48-
* Test login action with post request
48+
* Test reset password workflow
4949
*
5050
* @return void
5151
*/
@@ -70,7 +70,6 @@ public function testRequestResetPasswordPostValidEmail()
7070
$this->assertRedirect('/users/change-password');
7171

7272
$fieldName = Configure::read('Users.Key.Session.resetPasswordUserId');
73-
$this->assertSession($userAfter->id, $fieldName);
7473
$this->session([
7574
$fieldName => $userAfter->id,
7675
]);

tests/TestCase/Controller/Traits/UserValidationTraitTest.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,26 @@ public function testValidateHappyEmail()
5656
$this->assertTrue($user->active);
5757
}
5858

59+
/**
60+
* test
61+
*
62+
* @return void
63+
*/
64+
public function testValidateHappyEmailWithAfterEmailTokenValidationEvent()
65+
{
66+
$event = new Event('event');
67+
$event->setResult([
68+
'action' => 'newAction',
69+
]);
70+
$this->Trait->expects($this->once())
71+
->method('dispatchEvent')
72+
->will($this->returnValue($event));
73+
$this->Trait->expects($this->once())
74+
->method('redirect')
75+
->with(['action' => 'newAction']);
76+
$this->Trait->validate('email', 'token-3');
77+
}
78+
5979
/**
6080
* test
6181
*

tests/TestCase/Controller/UsersControllerTest.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public function testUnauthorizedRedirectCustomCallable()
5151
],
5252
]);
5353
$this->get('/users/index');
54-
$this->assertRedirect('/my/custom/url/');
54+
$this->assertRedirectContains('/my/custom/url/');
5555
}
5656

5757
/**
@@ -67,7 +67,7 @@ public function testUnauthorizedRedirectNotLogged()
6767
],
6868
]);
6969
$this->get('/users/index');
70-
$this->assertRedirect('/login?redirect=http%3A%2F%2Flocalhost%2Fusers%2Findex');
70+
$this->assertRedirectContains('/login?redirect=http%3A%2F%2Flocalhost%2Fusers%2Findex');
7171
}
7272

7373
/**
@@ -89,6 +89,6 @@ public function testUnauthorizedRedirectLogged()
8989
],
9090
]);
9191
$this->get('/users/index');
92-
$this->assertRedirect('/profile');
92+
$this->assertRedirectContains('/profile');
9393
}
9494
}

0 commit comments

Comments
 (0)