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

Commit

Permalink
Auth Flow - Modify code base
Browse files Browse the repository at this point in the history
  • Loading branch information
binal-7span committed Sep 16, 2019
1 parent 9312caa commit 46ec385
Show file tree
Hide file tree
Showing 11 changed files with 539 additions and 122 deletions.
10 changes: 10 additions & 0 deletions migrations/db/schemas/20190912072543_create_user_sessions.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ public function change()
'null' => true,
'default' => null
]);

$table->addColumn('token_type', 'string', [
'null' => true,
'default' => null
]);

$table->addColumn('token', 'string', [
'limit' => 255,
Expand All @@ -60,6 +65,11 @@ public function change()
'null' => true,
'default' => null
]);

$table->addColumn('token_expired_at', 'datetime', [
'null' => true,
'default' => null
]);

$table->create();
}
Expand Down
56 changes: 55 additions & 1 deletion migrations/db/seeds/FieldsSeeder.php
Original file line number Diff line number Diff line change
Expand Up @@ -1606,7 +1606,61 @@ public function run()
'field' => 'enforce_2fa',
'type' => \Directus\Database\Schema\DataTypes::TYPE_BOOLEAN,
'interface' => 'toggle'
]
],

// User Session
// -----------------------------------------------------------------
[
'collection' => 'directus_user_sessions',
'field' => 'id',
'type' => \Directus\Database\Schema\DataTypes::TYPE_INTEGER,
'interface' => 'primary-key',
'locked' => 1,
'required' => 1,
'hidden_detail' => 1
],
[
'collection' => 'directus_user_sessions',
'field' => 'user',
'type' => \Directus\Database\Schema\DataTypes::TYPE_USER,
'interface' => 'user'
],
[
'collection' => 'directus_user_sessions',
'field' => 'token_type',
'type' => \Directus\Database\Schema\DataTypes::TYPE_STRING,
'interface' => 'text-input'
],
[
'collection' => 'directus_user_sessions',
'field' => 'token',
'type' => \Directus\Database\Schema\DataTypes::TYPE_STRING,
'interface' => 'text-input'
],
[
'collection' => 'directus_user_sessions',
'field' => 'ip_address',
'type' => \Directus\Database\Schema\DataTypes::TYPE_STRING,
'interface' => 'text-input'
],
[
'collection' => 'directus_user_sessions',
'field' => 'user_agent',
'type' => \Directus\Database\Schema\DataTypes::TYPE_STRING,
'interface' => 'text-input'
],
[
'collection' => 'directus_user_sessions',
'field' => 'created_on',
'type' => \Directus\Database\Schema\DataTypes::TYPE_DATETIME,
'interface' => 'datetime'
],
[
'collection' => 'directus_user_sessions',
'field' => 'token_expired_at',
'type' => \Directus\Database\Schema\DataTypes::TYPE_DATETIME,
'interface' => 'datetime'
],
];

$files = $this->table('directus_fields');
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php


use Phinx\Migration\AbstractMigration;

class UpdateDirectusUserSessions extends AbstractMigration
{
/**
* Change Method.
*
* Write your reversible migrations using this method.
*
* More information on writing migrations is available here:
* http://docs.phinx.org/en/latest/migrations.html#the-abstractmigration-class
*
* The following commands can be used in this method and Phinx will
* automatically reverse them when rolling back:
*
* createTable
* renameTable
* addColumn
* renameColumn
* addIndex
* addForeignKey
*
* Remember to call "create()" or "update()" and NOT "save()" when working
* with the Table class.
*/
public function change()
{
$table = $this->table('directus_user_sessions');
if (!$table->hasColumn('token_type')) {
$table->addColumn('token_type', 'string', [
'null' => true,
'default' => null
]);
}

if (!$table->hasColumn('token_expired_at')) {
$table->addColumn('token_expired_at', 'datetime', [
'null' => true,
'default' => null
]);
}

$table->save();
}
}
77 changes: 77 additions & 0 deletions migrations/upgrades/seeds/UserSessionFeedSeeder.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?php


use Phinx\Seed\AbstractSeed;

class UserSessionFeedSeeder extends AbstractSeed
{
/**
* Run Method.
*
* Write your database seeder using this method.
*
* More information on writing seeders is available here:
* http://docs.phinx.org/en/latest/seeding.html
*/
public function run()
{
$data = [
// User Session
// -----------------------------------------------------------------
[
'collection' => 'directus_user_sessions',
'field' => 'id',
'type' => \Directus\Database\Schema\DataTypes::TYPE_INTEGER,
'interface' => 'primary-key',
'locked' => 1,
'required' => 1,
'hidden_detail' => 1
],
[
'collection' => 'directus_user_sessions',
'field' => 'user',
'type' => \Directus\Database\Schema\DataTypes::TYPE_USER,
'interface' => 'user'
],
[
'collection' => 'directus_user_sessions',
'field' => 'token_type',
'type' => \Directus\Database\Schema\DataTypes::TYPE_STRING,
'interface' => 'text-input'
],
[
'collection' => 'directus_user_sessions',
'field' => 'token',
'type' => \Directus\Database\Schema\DataTypes::TYPE_STRING,
'interface' => 'text-input'
],
[
'collection' => 'directus_user_sessions',
'field' => 'ip_address',
'type' => \Directus\Database\Schema\DataTypes::TYPE_STRING,
'interface' => 'text-input'
],
[
'collection' => 'directus_user_sessions',
'field' => 'user_agent',
'type' => \Directus\Database\Schema\DataTypes::TYPE_STRING,
'interface' => 'text-input'
],
[
'collection' => 'directus_user_sessions',
'field' => 'created_on',
'type' => \Directus\Database\Schema\DataTypes::TYPE_DATETIME,
'interface' => 'datetime'
],
[
'collection' => 'directus_user_sessions',
'field' => 'token_expired_at',
'type' => \Directus\Database\Schema\DataTypes::TYPE_DATETIME,
'interface' => 'datetime'
],
];

$files = $this->table('directus_fields');
$files->insert($data)->save();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Directus\Database\TableGateway\DirectusPermissionsTableGateway;
use Directus\Exception\UnauthorizedLocationException;
use function Directus\get_request_authorization_token;
use function Directus\get_static_token_based_on_type;
use Directus\Permissions\Acl;
use Directus\Services\AuthService;
use Directus\Services\UsersService;
Expand Down Expand Up @@ -132,7 +133,7 @@ protected function authenticate(Request $request)
{
$user = null;
$authToken = $this->getAuthToken($request);

if ($authToken) {
/** @var AuthService $authService */
$authService = $this->container->get('services')->get('auth');
Expand All @@ -152,7 +153,8 @@ protected function authenticate(Request $request)
*/
protected function getAuthToken(Request $request)
{
return get_request_authorization_token($request);
$authToken = get_request_authorization_token($request);
return get_static_token_based_on_type($authToken);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,13 @@
use Directus\Application\Http\Request;
use Directus\Application\Http\Response;
use Directus\Util\StringUtils;
use Slim\Http\Cookies;
use function Directus\get_directus_setting;
use function Directus\decrypt_static_token;
use function Directus\get_request_authorization_token;
use Directus\Services\UserSessionService;
use Directus\Database\TableGateway\DirectusUserSessionsTableGateway;
use Directus\Util\DateTimeUtils;

class ResponseCacheMiddleware extends AbstractMiddleware
{
Expand Down Expand Up @@ -61,6 +68,38 @@ public function __invoke(Request $request, Response $response, callable $next)
$cache->process($key, $bodyContent, $headers);
}

$authorizationTokenObject = get_request_authorization_token($request);

$accessToken = null;
$userSessionService = new UserSessionService($container);
$userSessionService->destroy([
'token_expired_at < ?' => DateTimeUtils::now()->toString()
]);
if(!empty($authorizationTokenObject['token'])){
$expirationMinutes = get_directus_setting('auto_sign_out');
$expiry = new \DateTimeImmutable('now + '.$expirationMinutes.'minutes');

switch($authorizationTokenObject['type']){
case DirectusUserSessionsTableGateway::TOKEN_COOKIE :
$accessToken = decrypt_static_token($authorizationTokenObject['token']);
$userSession = $userSessionService->find(['token' => $accessToken]);
if($userSession){
$cookie = new Cookies();
$cookie->set('session',['value' => $authorizationTokenObject['token'],'expires' =>$expiry->format(\DateTime::COOKIE),'path'=>'/','httponly' => true]);
$response = $response->withAddedHeader('Set-Cookie',$cookie->toHeaders());
}else{
$response = $response->withoutHeader('Set-Cookie');
}
break;
default :
$userSession = $userSessionService->find(['token' => $authorizationTokenObject['token']]);
break;
}
}
if(isset($userSession)){
$userSessionService->update($userSession['id'],['token_expired_at' => $expiry->format('Y-m-d H:i:s')]);
}

return $response;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

namespace Directus\Database\TableGateway;

use Directus\Permissions\Acl;
use Directus\Util\DateTimeUtils;
use Zend\Db\Adapter\AdapterInterface;
use Zend\Db\Sql\Insert;
use Zend\Db\Sql\Update;
use Zend\Db\Sql\Select;

class DirectusUserSessionsTableGateway extends RelationalTableGateway
{
const TOKEN_COOKIE = 'cookie';
const TOKEN_JWT = 'jwt';

public static $_tableName = 'directus_user_sessions';

public $primaryKeyFieldName = 'id';

/**
* DirectusUserSessionTableGateway constructor.
*
* @param AdapterInterface $adapter
* @param Acl $acl
*/
public function __construct(AdapterInterface $adapter, $acl = null)
{
parent::__construct(self::$_tableName, $adapter, $acl);
}

public function recordSession($data)
{
$sessionData = [
'user' => $data['user'],
'token' => $data['token'],
'token_type' => $data['token_type'],
'token_expired_at' => $data['token_expired_at'],
'created_on' => DateTimeUtils::now()->toString(),
'ip_address' => \Directus\get_request_ip(),
'user_agent' => isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : ''
];

$insert = new Insert($this->getTable());
$insert
->values($sessionData);

$this->insertWith($insert);
return $this->getLastInsertValue();
}

public function updateSession($id,$data)
{
$update = new Update($this->getTable());
$update->set($data);
$update->where([
'id' => $id
]);
$this->updateWith($update);
}

public function fetchSession($condition)
{
$select = new Select($this->getTable());
$select->columns(['*']);
$select->where($condition);
$select->limit(1);
return $this->selectWith($select)->current();
}

}
Loading

0 comments on commit 46ec385

Please sign in to comment.