Skip to content

Commit

Permalink
Merge pull request #61 from ovr/session-user-dummy
Browse files Browse the repository at this point in the history
Pass session to "getUser" callback.
  • Loading branch information
ADmad authored Jul 2, 2019
2 parents 5816ee3 + 20f83b2 commit f92ac62
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 12 deletions.
13 changes: 10 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,18 +142,25 @@ initiated.
Once a user is authenticated through the provider, the middleware gets the user
profile from the identity provider and using that tries to find the corresponding
user record using the user model. If no user is found it calls the `getUser` method
of your user model. The method recieves social profile model entity as argument
and return an entity for the user. E.g.
of your user model. The method recieves social profile model entity and session
instance as argument and must return an entity for the user.

```php
// src/Model/Table/UsersTable.php

public function getUser(\Cake\Datasource\EntityInterface $profile) {
public function getUser(\Cake\Datasource\EntityInterface $profile, \Cake\Http\Session $session): \Cake\Datatsource\EntityInterface {
// Make sure here that all the required fields are actually present
if (empty($profile->email)) {
throw new \RuntimeException('Could not find email in social profile.');
}

// If you want to associate the social entity with currently logged in user
// use the $session argument to get user id and find matching user entity.
$userId = $session->read('Auth.User.id');
if ($userId) {
return $this->get($userId);
}

// Check if user with same email exists. This avoids creating multiple
// user accounts for different social identities of same user. You should
// probably skip this check if your system doesn't enforce unique email
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"type": "cakephp-plugin",
"require": {
"cakephp/cakephp": "^3.5",
"socialconnect/auth": "^1.12"
"socialconnect/auth": "^1.14"
},
"require-dev": {
"cakephp/chronos": "^1.1",
Expand Down
27 changes: 20 additions & 7 deletions src/Middleware/SocialAuthMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
use SocialConnect\Provider\AccessTokenInterface;
use SocialConnect\Provider\Exception\InvalidResponse;
use SocialConnect\Provider\Session\Session;
use SocialConnect\Provider\Session\SessionInterface;

class SocialAuthMiddleware implements EventDispatcherInterface
{
Expand Down Expand Up @@ -94,6 +95,13 @@ class SocialAuthMiddleware implements EventDispatcherInterface
*/
protected $_service;

/**
* Session for SocialConnect service.
*
* @var \SocialConnect\Provider\Session\SessionInterface
*/
protected $_session;

/**
* User model instance.
*
Expand All @@ -120,14 +128,17 @@ class SocialAuthMiddleware implements EventDispatcherInterface
*
* @param array $config Configuration.
* @param \Cake\Event\EventManager|null $eventManager Event manager instance.
* @param \SocialConnect\Provider\Session\SessionInterface|null $session Session handler for SocialConnect Service
*/
public function __construct(array $config = [], EventManager $eventManager = null)
public function __construct(array $config = [], EventManager $eventManager = null, SessionInterface $session = null)
{
$this->setConfig($config);

if ($eventManager !== null) {
$this->setEventManager($eventManager);
}

$this->_session = $session;
}

/**
Expand Down Expand Up @@ -198,7 +209,7 @@ protected function _handleCallbackAction(ServerRequest $request, Response $respo
);
}

$user = $this->_getUser($profile);
$user = $this->_getUser($profile, $request->getSession());
if (!$user) {
return $response->withLocation(
Router::url($config['loginUrl'], true) . '?error=' . $this->_error
Expand Down Expand Up @@ -285,11 +296,12 @@ protected function _getProfile($providerName, ServerRequest $request)
* Get user record.
*
* @param \Cake\Datasource\EntityInterface $profile Social profile entity
* @param \Cake\Http\Session $session Session instance.
*
* @return array|\Cake\Datasource\EntityInterface|null User array or entity
* on success, null on failure.
*/
protected function _getUser($profile)
protected function _getUser(EntityInterface $profile, $session)
{
$user = null;

Expand All @@ -311,7 +323,7 @@ protected function _getUser($profile)
return null;
}

$user = $this->_getUserEntity($profile);
$user = $this->_getUserEntity($profile, $session);
$profile->set('user_id', $user->id);
}

Expand Down Expand Up @@ -393,14 +405,15 @@ protected function _patchProfile(
* with profile entity. The method should return a persisted user entity.
*
* @param \Cake\Datasource\EntityInterface $profile Social profile entity.
* @param \Cake\Http\Session $session Session instance.
*
* @return \Cake\Datasource\EntityInterface User entity.
*/
protected function _getUserEntity(EntityInterface $profile)
protected function _getUserEntity(EntityInterface $profile, $session)
{
$callbackMethod = $this->getConfig('getUserCallback');

$user = call_user_func([$this->_userModel, $callbackMethod], $profile);
$user = call_user_func([$this->_userModel, $callbackMethod], $profile, $session);

if (!($user instanceof EntityInterface)) {
throw new RuntimeException('"getUserCallback" method must return a user entity.');
Expand Down Expand Up @@ -459,7 +472,7 @@ protected function _getService(ServerRequest $request)

$this->_service = new Service(
$httpClient,
new Session(),
$this->_session ? $this->_session : new Session(),
$serviceConfig
);

Expand Down
3 changes: 2 additions & 1 deletion tests/TestCase/Middleware/SocialAuthMiddlewareTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Cake\Http\ServerRequestFactory;
use Cake\Routing\Router;
use Cake\TestSuite\TestCase;
use SocialConnect\Provider\Session\Dummy;

/**
* Test for SocialAuthMiddleware.
Expand Down Expand Up @@ -80,7 +81,7 @@ public function testLoginUrl()
],
],
],
]);
], null, new Dummy());
$response = $middleware($request, $this->response, $this->_getNext());

$this->assertEquals(302, $response->getStatusCode());
Expand Down

0 comments on commit f92ac62

Please sign in to comment.