Merge pull request #4831 from appwrite/feat-user-session-limits
feat (projects): auth session limit
This commit is contained in:
commit
e05fbb23a9
7 changed files with 234 additions and 36 deletions
|
@ -140,7 +140,7 @@ App::post('/v1/account')
|
||||||
App::post('/v1/account/sessions/email')
|
App::post('/v1/account/sessions/email')
|
||||||
->alias('/v1/account/sessions')
|
->alias('/v1/account/sessions')
|
||||||
->desc('Create Email Session')
|
->desc('Create Email Session')
|
||||||
->groups(['api', 'account', 'auth'])
|
->groups(['api', 'account', 'auth', 'session'])
|
||||||
->label('event', 'users.[userId].sessions.[sessionId].create')
|
->label('event', 'users.[userId].sessions.[sessionId].create')
|
||||||
->label('scope', 'public')
|
->label('scope', 'public')
|
||||||
->label('auth.type', 'emailPassword')
|
->label('auth.type', 'emailPassword')
|
||||||
|
@ -365,7 +365,7 @@ App::post('/v1/account/sessions/oauth2/callback/:provider/:projectId')
|
||||||
|
|
||||||
App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
App::get('/v1/account/sessions/oauth2/:provider/redirect')
|
||||||
->desc('OAuth2 Redirect')
|
->desc('OAuth2 Redirect')
|
||||||
->groups(['api', 'account'])
|
->groups(['api', 'account', 'session'])
|
||||||
->label('error', __DIR__ . '/../../views/general/error.phtml')
|
->label('error', __DIR__ . '/../../views/general/error.phtml')
|
||||||
->label('event', 'users.[userId].sessions.[sessionId].create')
|
->label('event', 'users.[userId].sessions.[sessionId].create')
|
||||||
->label('scope', 'public')
|
->label('scope', 'public')
|
||||||
|
@ -739,7 +739,7 @@ App::post('/v1/account/sessions/magic-url')
|
||||||
|
|
||||||
App::put('/v1/account/sessions/magic-url')
|
App::put('/v1/account/sessions/magic-url')
|
||||||
->desc('Create Magic URL session (confirmation)')
|
->desc('Create Magic URL session (confirmation)')
|
||||||
->groups(['api', 'account'])
|
->groups(['api', 'account', 'session'])
|
||||||
->label('scope', 'public')
|
->label('scope', 'public')
|
||||||
->label('event', 'users.[userId].sessions.[sessionId].create')
|
->label('event', 'users.[userId].sessions.[sessionId].create')
|
||||||
->label('audits.event', 'session.update')
|
->label('audits.event', 'session.update')
|
||||||
|
@ -981,7 +981,7 @@ App::post('/v1/account/sessions/phone')
|
||||||
|
|
||||||
App::put('/v1/account/sessions/phone')
|
App::put('/v1/account/sessions/phone')
|
||||||
->desc('Create Phone Session (confirmation)')
|
->desc('Create Phone Session (confirmation)')
|
||||||
->groups(['api', 'account'])
|
->groups(['api', 'account', 'session'])
|
||||||
->label('scope', 'public')
|
->label('scope', 'public')
|
||||||
->label('event', 'users.[userId].sessions.[sessionId].create')
|
->label('event', 'users.[userId].sessions.[sessionId].create')
|
||||||
->label('usage.metric', 'sessions.{scope}.requests.create')
|
->label('usage.metric', 'sessions.{scope}.requests.create')
|
||||||
|
@ -1096,7 +1096,7 @@ App::put('/v1/account/sessions/phone')
|
||||||
|
|
||||||
App::post('/v1/account/sessions/anonymous')
|
App::post('/v1/account/sessions/anonymous')
|
||||||
->desc('Create Anonymous Session')
|
->desc('Create Anonymous Session')
|
||||||
->groups(['api', 'account', 'auth'])
|
->groups(['api', 'account', 'auth', 'session'])
|
||||||
->label('event', 'users.[userId].sessions.[sessionId].create')
|
->label('event', 'users.[userId].sessions.[sessionId].create')
|
||||||
->label('scope', 'public')
|
->label('scope', 'public')
|
||||||
->label('auth.type', 'anonymous')
|
->label('auth.type', 'anonymous')
|
||||||
|
|
|
@ -81,7 +81,7 @@ App::post('/v1/projects')
|
||||||
}
|
}
|
||||||
|
|
||||||
$auth = Config::getParam('auth', []);
|
$auth = Config::getParam('auth', []);
|
||||||
$auths = ['limit' => 0, 'duration' => Auth::TOKEN_EXPIRATION_LOGIN_LONG];
|
$auths = ['limit' => 0, 'maxSessions' => APP_LIMIT_USER_SESSIONS_DEFAULT, 'duration' => Auth::TOKEN_EXPIRATION_LOGIN_LONG];
|
||||||
foreach ($auth as $index => $method) {
|
foreach ($auth as $index => $method) {
|
||||||
$auths[$method['key'] ?? ''] = true;
|
$auths[$method['key'] ?? ''] = true;
|
||||||
}
|
}
|
||||||
|
@ -576,6 +576,37 @@ App::patch('/v1/projects/:projectId/auth/:method')
|
||||||
$response->dynamic($project, Response::MODEL_PROJECT);
|
$response->dynamic($project, Response::MODEL_PROJECT);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
App::patch('/v1/projects/:projectId/auth/max-sessions')
|
||||||
|
->desc('Update Project users limit')
|
||||||
|
->groups(['api', 'projects'])
|
||||||
|
->label('scope', 'projects.write')
|
||||||
|
->label('sdk.auth', [APP_AUTH_TYPE_ADMIN])
|
||||||
|
->label('sdk.namespace', 'projects')
|
||||||
|
->label('sdk.method', 'updateAuthLimit')
|
||||||
|
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
||||||
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
||||||
|
->label('sdk.response.model', Response::MODEL_PROJECT)
|
||||||
|
->param('projectId', '', new UID(), 'Project unique ID.')
|
||||||
|
->param('limit', false, new Range(1, APP_LIMIT_USER_SESSIONS_MAX), 'Set the max number of users allowed in this project. Value allowed is between 1-' . APP_LIMIT_USER_SESSIONS_MAX . '. Default is ' . APP_LIMIT_USER_SESSIONS_DEFAULT)
|
||||||
|
->inject('response')
|
||||||
|
->inject('dbForConsole')
|
||||||
|
->action(function (string $projectId, int $limit, Response $response, Database $dbForConsole) {
|
||||||
|
|
||||||
|
$project = $dbForConsole->getDocument('projects', $projectId);
|
||||||
|
|
||||||
|
if ($project->isEmpty()) {
|
||||||
|
throw new Exception(Exception::PROJECT_NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
|
$auths = $project->getAttribute('auths', []);
|
||||||
|
$auths['maxSessions'] = $limit;
|
||||||
|
|
||||||
|
$dbForConsole->updateDocument('projects', $project->getId(), $project
|
||||||
|
->setAttribute('auths', $auths));
|
||||||
|
|
||||||
|
$response->dynamic($project, Response::MODEL_PROJECT);
|
||||||
|
});
|
||||||
|
|
||||||
App::delete('/v1/projects/:projectId')
|
App::delete('/v1/projects/:projectId')
|
||||||
->desc('Delete Project')
|
->desc('Delete Project')
|
||||||
->groups(['api', 'projects'])
|
->groups(['api', 'projects'])
|
||||||
|
|
|
@ -318,6 +318,45 @@ App::init()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Limit user session
|
||||||
|
*
|
||||||
|
* Delete older sessions if the number of sessions have crossed
|
||||||
|
* the session limit set for the project
|
||||||
|
*/
|
||||||
|
App::shutdown()
|
||||||
|
->groups(['session'])
|
||||||
|
->inject('utopia')
|
||||||
|
->inject('request')
|
||||||
|
->inject('response')
|
||||||
|
->inject('project')
|
||||||
|
->inject('dbForProject')
|
||||||
|
->action(function (App $utopia, Request $request, Response $response, Document $project, Database $dbForProject) {
|
||||||
|
$sessionLimit = $project->getAttribute('auths', [])['maxSessions'] ?? APP_LIMIT_USER_SESSIONS_DEFAULT;
|
||||||
|
$session = $response->getPayload();
|
||||||
|
$userId = $session['userId'] ?? '';
|
||||||
|
if (empty($userId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$user = $dbForProject->getDocument('users', $userId);
|
||||||
|
if ($user->isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$sessions = $user->getAttribute('sessions', []);
|
||||||
|
$count = \count($sessions);
|
||||||
|
if ($count <= $sessionLimit) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ($i = 0; $i < ($count - $sessionLimit); $i++) {
|
||||||
|
$session = array_shift($sessions);
|
||||||
|
$dbForProject->deleteDocument('sessions', $session->getId());
|
||||||
|
}
|
||||||
|
$dbForProject->deleteCachedDocument('users', $userId);
|
||||||
|
});
|
||||||
|
|
||||||
App::shutdown()
|
App::shutdown()
|
||||||
->groups(['api'])
|
->groups(['api'])
|
||||||
->inject('utopia')
|
->inject('utopia')
|
||||||
|
|
|
@ -84,6 +84,8 @@ const APP_MODE_ADMIN = 'admin';
|
||||||
const APP_PAGING_LIMIT = 12;
|
const APP_PAGING_LIMIT = 12;
|
||||||
const APP_LIMIT_COUNT = 5000;
|
const APP_LIMIT_COUNT = 5000;
|
||||||
const APP_LIMIT_USERS = 10000;
|
const APP_LIMIT_USERS = 10000;
|
||||||
|
const APP_LIMIT_USER_SESSIONS_MAX = 100;
|
||||||
|
const APP_LIMIT_USER_SESSIONS_DEFAULT = 10;
|
||||||
const APP_LIMIT_ANTIVIRUS = 20000000; //20MB
|
const APP_LIMIT_ANTIVIRUS = 20000000; //20MB
|
||||||
const APP_LIMIT_ENCRYPTION = 20000000; //20MB
|
const APP_LIMIT_ENCRYPTION = 20000000; //20MB
|
||||||
const APP_LIMIT_COMPRESSION = 20000000; //20MB
|
const APP_LIMIT_COMPRESSION = 20000000; //20MB
|
||||||
|
|
61
composer.lock
generated
61
composer.lock
generated
|
@ -805,16 +805,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "laravel/pint",
|
"name": "laravel/pint",
|
||||||
"version": "v1.2.0",
|
"version": "v1.2.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/laravel/pint.git",
|
"url": "https://github.com/laravel/pint.git",
|
||||||
"reference": "1d276e4c803397a26cc337df908f55c2a4e90d86"
|
"reference": "e60e2112ee779ce60f253695b273d1646a17d6f1"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/laravel/pint/zipball/1d276e4c803397a26cc337df908f55c2a4e90d86",
|
"url": "https://api.github.com/repos/laravel/pint/zipball/e60e2112ee779ce60f253695b273d1646a17d6f1",
|
||||||
"reference": "1d276e4c803397a26cc337df908f55c2a4e90d86",
|
"reference": "e60e2112ee779ce60f253695b273d1646a17d6f1",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -826,10 +826,10 @@
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"friendsofphp/php-cs-fixer": "^3.11.0",
|
"friendsofphp/php-cs-fixer": "^3.11.0",
|
||||||
"illuminate/view": "^9.27",
|
"illuminate/view": "^9.32.0",
|
||||||
"laravel-zero/framework": "^9.1.3",
|
"laravel-zero/framework": "^9.2.0",
|
||||||
"mockery/mockery": "^1.5.0",
|
"mockery/mockery": "^1.5.1",
|
||||||
"nunomaduro/larastan": "^2.2",
|
"nunomaduro/larastan": "^2.2.0",
|
||||||
"nunomaduro/termwind": "^1.14.0",
|
"nunomaduro/termwind": "^1.14.0",
|
||||||
"pestphp/pest": "^1.22.1"
|
"pestphp/pest": "^1.22.1"
|
||||||
},
|
},
|
||||||
|
@ -867,7 +867,7 @@
|
||||||
"issues": "https://github.com/laravel/pint/issues",
|
"issues": "https://github.com/laravel/pint/issues",
|
||||||
"source": "https://github.com/laravel/pint"
|
"source": "https://github.com/laravel/pint"
|
||||||
},
|
},
|
||||||
"time": "2022-09-13T15:07:15+00:00"
|
"time": "2022-11-29T16:25:20+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "matomo/device-detector",
|
"name": "matomo/device-detector",
|
||||||
|
@ -1461,16 +1461,16 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "symfony/deprecation-contracts",
|
"name": "symfony/deprecation-contracts",
|
||||||
"version": "v3.1.1",
|
"version": "v3.2.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/symfony/deprecation-contracts.git",
|
"url": "https://github.com/symfony/deprecation-contracts.git",
|
||||||
"reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918"
|
"reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918",
|
"url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/1ee04c65529dea5d8744774d474e7cbd2f1206d3",
|
||||||
"reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918",
|
"reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
|
@ -1479,7 +1479,7 @@
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"extra": {
|
"extra": {
|
||||||
"branch-alias": {
|
"branch-alias": {
|
||||||
"dev-main": "3.1-dev"
|
"dev-main": "3.3-dev"
|
||||||
},
|
},
|
||||||
"thanks": {
|
"thanks": {
|
||||||
"name": "symfony/contracts",
|
"name": "symfony/contracts",
|
||||||
|
@ -1508,7 +1508,7 @@
|
||||||
"description": "A generic function and convention to trigger deprecation notices",
|
"description": "A generic function and convention to trigger deprecation notices",
|
||||||
"homepage": "https://symfony.com",
|
"homepage": "https://symfony.com",
|
||||||
"support": {
|
"support": {
|
||||||
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.1"
|
"source": "https://github.com/symfony/deprecation-contracts/tree/v3.2.0"
|
||||||
},
|
},
|
||||||
"funding": [
|
"funding": [
|
||||||
{
|
{
|
||||||
|
@ -1524,7 +1524,7 @@
|
||||||
"type": "tidelift"
|
"type": "tidelift"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"time": "2022-02-25T11:15:52+00:00"
|
"time": "2022-11-25T10:21:52+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "utopia-php/abuse",
|
"name": "utopia-php/abuse",
|
||||||
|
@ -1945,24 +1945,25 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "utopia-php/framework",
|
"name": "utopia-php/framework",
|
||||||
"version": "0.25.0",
|
"version": "0.25.1",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/utopia-php/framework.git",
|
"url": "https://github.com/utopia-php/framework.git",
|
||||||
"reference": "c524f681254255c8204fbf7919c53bf3b4982636"
|
"reference": "2391b397135586b2100d39e338827bef8d2f4ad0"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/utopia-php/framework/zipball/c524f681254255c8204fbf7919c53bf3b4982636",
|
"url": "https://api.github.com/repos/utopia-php/framework/zipball/2391b397135586b2100d39e338827bef8d2f4ad0",
|
||||||
"reference": "c524f681254255c8204fbf7919c53bf3b4982636",
|
"reference": "2391b397135586b2100d39e338827bef8d2f4ad0",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=8.0.0"
|
"php": ">=8.0.0"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
|
"laravel/pint": "^1.2",
|
||||||
"phpunit/phpunit": "^9.5.25",
|
"phpunit/phpunit": "^9.5.25",
|
||||||
"vimeo/psalm": "^4.27.0"
|
"vimeo/psalm": "4.27.0"
|
||||||
},
|
},
|
||||||
"type": "library",
|
"type": "library",
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
@ -1982,9 +1983,9 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/utopia-php/framework/issues",
|
"issues": "https://github.com/utopia-php/framework/issues",
|
||||||
"source": "https://github.com/utopia-php/framework/tree/0.25.0"
|
"source": "https://github.com/utopia-php/framework/tree/0.25.1"
|
||||||
},
|
},
|
||||||
"time": "2022-11-02T09:49:57+00:00"
|
"time": "2022-11-23T18:22:23+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "utopia-php/image",
|
"name": "utopia-php/image",
|
||||||
|
@ -3291,21 +3292,21 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpspec/prophecy",
|
"name": "phpspec/prophecy",
|
||||||
"version": "v1.15.0",
|
"version": "v1.16.0",
|
||||||
"source": {
|
"source": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/phpspec/prophecy.git",
|
"url": "https://github.com/phpspec/prophecy.git",
|
||||||
"reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13"
|
"reference": "be8cac52a0827776ff9ccda8c381ac5b71aeb359"
|
||||||
},
|
},
|
||||||
"dist": {
|
"dist": {
|
||||||
"type": "zip",
|
"type": "zip",
|
||||||
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
|
"url": "https://api.github.com/repos/phpspec/prophecy/zipball/be8cac52a0827776ff9ccda8c381ac5b71aeb359",
|
||||||
"reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13",
|
"reference": "be8cac52a0827776ff9ccda8c381ac5b71aeb359",
|
||||||
"shasum": ""
|
"shasum": ""
|
||||||
},
|
},
|
||||||
"require": {
|
"require": {
|
||||||
"doctrine/instantiator": "^1.2",
|
"doctrine/instantiator": "^1.2",
|
||||||
"php": "^7.2 || ~8.0, <8.2",
|
"php": "^7.2 || 8.0.* || 8.1.* || 8.2.*",
|
||||||
"phpdocumentor/reflection-docblock": "^5.2",
|
"phpdocumentor/reflection-docblock": "^5.2",
|
||||||
"sebastian/comparator": "^3.0 || ^4.0",
|
"sebastian/comparator": "^3.0 || ^4.0",
|
||||||
"sebastian/recursion-context": "^3.0 || ^4.0"
|
"sebastian/recursion-context": "^3.0 || ^4.0"
|
||||||
|
@ -3352,9 +3353,9 @@
|
||||||
],
|
],
|
||||||
"support": {
|
"support": {
|
||||||
"issues": "https://github.com/phpspec/prophecy/issues",
|
"issues": "https://github.com/phpspec/prophecy/issues",
|
||||||
"source": "https://github.com/phpspec/prophecy/tree/v1.15.0"
|
"source": "https://github.com/phpspec/prophecy/tree/v1.16.0"
|
||||||
},
|
},
|
||||||
"time": "2021-12-08T12:19:24+00:00"
|
"time": "2022-11-29T15:06:56+00:00"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "phpunit/php-code-coverage",
|
"name": "phpunit/php-code-coverage",
|
||||||
|
|
|
@ -114,6 +114,12 @@ class Project extends Model
|
||||||
'default' => 0,
|
'default' => 0,
|
||||||
'example' => 100,
|
'example' => 100,
|
||||||
])
|
])
|
||||||
|
->addRule('authSessionsLimit', [
|
||||||
|
'type' => self::TYPE_INTEGER,
|
||||||
|
'description' => 'Max sessions allowed per user. 100 maximum.',
|
||||||
|
'default' => 10,
|
||||||
|
'example' => 10,
|
||||||
|
])
|
||||||
->addRule('providers', [
|
->addRule('providers', [
|
||||||
'type' => Response::MODEL_PROVIDER,
|
'type' => Response::MODEL_PROVIDER,
|
||||||
'description' => 'List of Providers.',
|
'description' => 'List of Providers.',
|
||||||
|
@ -233,6 +239,7 @@ class Project extends Model
|
||||||
|
|
||||||
$document->setAttribute('authLimit', $authValues['limit'] ?? 0);
|
$document->setAttribute('authLimit', $authValues['limit'] ?? 0);
|
||||||
$document->setAttribute('authDuration', $authValues['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG);
|
$document->setAttribute('authDuration', $authValues['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG);
|
||||||
|
$document->setAttribute('authSessionLimit', $authValues['maxSessions'] ?? APP_LIMIT_USER_SESSIONS_DEFAULT);
|
||||||
|
|
||||||
foreach ($auth as $index => $method) {
|
foreach ($auth as $index => $method) {
|
||||||
$key = $method['key'];
|
$key = $method['key'];
|
||||||
|
|
|
@ -874,6 +874,124 @@ class ProjectsConsoleClientTest extends Scope
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @depends testUpdateProjectAuthLimit
|
||||||
|
*/
|
||||||
|
public function testUpdateProjectAuthSessionLimit($data): array
|
||||||
|
{
|
||||||
|
$id = $data['projectId'] ?? '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for failure
|
||||||
|
*/
|
||||||
|
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/max-sessions', array_merge([
|
||||||
|
'content-type' => 'application/json',
|
||||||
|
'x-appwrite-project' => $this->getProject()['$id'],
|
||||||
|
], $this->getHeaders()), [
|
||||||
|
'limit' => 0,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(400, $response['headers']['status-code']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for SUCCESS
|
||||||
|
*/
|
||||||
|
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/max-sessions', array_merge([
|
||||||
|
'content-type' => 'application/json',
|
||||||
|
'x-appwrite-project' => $this->getProject()['$id'],
|
||||||
|
], $this->getHeaders()), [
|
||||||
|
'limit' => 1,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(200, $response['headers']['status-code']);
|
||||||
|
$this->assertNotEmpty($response['body']['$id']);
|
||||||
|
$this->assertNotEmpty($response['body']['$id']);
|
||||||
|
|
||||||
|
$email = uniqid() . 'user@localhost.test';
|
||||||
|
$password = 'password';
|
||||||
|
$name = 'User Name';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create new user
|
||||||
|
*/
|
||||||
|
$response = $this->client->call(Client::METHOD_POST, '/account', array_merge([
|
||||||
|
'origin' => 'http://localhost',
|
||||||
|
'content-type' => 'application/json',
|
||||||
|
'x-appwrite-project' => $id,
|
||||||
|
]), [
|
||||||
|
'userId' => ID::unique(),
|
||||||
|
'email' => $email,
|
||||||
|
'password' => $password,
|
||||||
|
'name' => $name,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(201, $response['headers']['status-code']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create new session
|
||||||
|
*/
|
||||||
|
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([
|
||||||
|
'origin' => 'http://localhost',
|
||||||
|
'content-type' => 'application/json',
|
||||||
|
'x-appwrite-project' => $id,
|
||||||
|
]), [
|
||||||
|
'email' => $email,
|
||||||
|
'password' => $password,
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
$this->assertEquals(201, $response['headers']['status-code']);
|
||||||
|
$sessionId1 = $response['body']['$id'];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create new session
|
||||||
|
*/
|
||||||
|
$response = $this->client->call(Client::METHOD_POST, '/account/sessions/email', array_merge([
|
||||||
|
'origin' => 'http://localhost',
|
||||||
|
'content-type' => 'application/json',
|
||||||
|
'x-appwrite-project' => $id,
|
||||||
|
]), [
|
||||||
|
'email' => $email,
|
||||||
|
'password' => $password,
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
$this->assertEquals(201, $response['headers']['status-code']);
|
||||||
|
$sessionCookie = $response['headers']['set-cookie'];
|
||||||
|
$sessionId2 = $response['body']['$id'];
|
||||||
|
|
||||||
|
// request was called in parallel and test failed
|
||||||
|
sleep(5);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List sessions
|
||||||
|
*/
|
||||||
|
$response = $this->client->call(Client::METHOD_GET, '/account/sessions', [
|
||||||
|
'origin' => 'http://localhost',
|
||||||
|
'content-type' => 'application/json',
|
||||||
|
'x-appwrite-project' => $id,
|
||||||
|
'Cookie' => $sessionCookie,
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(200, $response['headers']['status-code']);
|
||||||
|
$sessions = $response['body']['sessions'];
|
||||||
|
|
||||||
|
$this->assertEquals(1, count($sessions));
|
||||||
|
$this->assertEquals($sessionId2, $sessions[0]['$id']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset Limit
|
||||||
|
*/
|
||||||
|
$response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/auth/max-sessions', array_merge([
|
||||||
|
'content-type' => 'application/json',
|
||||||
|
'x-appwrite-project' => $this->getProject()['$id'],
|
||||||
|
], $this->getHeaders()), [
|
||||||
|
'limit' => 10,
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
public function testUpdateProjectServiceStatusAdmin(): array
|
public function testUpdateProjectServiceStatusAdmin(): array
|
||||||
{
|
{
|
||||||
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
|
$team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
|
||||||
|
|
Loading…
Reference in a new issue