1
0
Fork 0
mirror of synced 2024-06-14 08:44:49 +12:00

Implement Variable Session Duration

This commit is contained in:
Bradley Schofield 2022-10-31 14:54:15 +00:00
parent 1b0abf4643
commit d34359fd49
14 changed files with 58 additions and 20 deletions

View file

@ -633,6 +633,17 @@ $collections = [
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('sessionDuration'),
'type' => Database::VAR_INTEGER,
'format' => '',
'size' => 32,
'signed' => true,
'required' => false,
'default' => 525600, // 1 Year
'array' => false,
'filters' => [],
],
[
'$id' => ID::custom('services'),
'type' => Database::VAR_STRING,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -165,10 +165,11 @@ App::post('/v1/account/sessions/email')
->inject('request')
->inject('response')
->inject('dbForProject')
->inject('project')
->inject('locale')
->inject('geodb')
->inject('events')
->action(function (string $email, string $password, Request $request, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Event $events) {
->action(function (string $email, string $password, Request $request, Response $response, Database $dbForProject, Document $project, Locale $locale, Reader $geodb, Event $events) {
$email = \strtolower($email);
$protocol = $request->getProtocol();
@ -185,9 +186,11 @@ App::post('/v1/account/sessions/email')
throw new Exception(Exception::USER_BLOCKED); // User is in status blocked
}
$sessionDuration = ($project->getAttribute('sessionDuration', null) * 60) ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
$detector = new Detector($request->getUserAgent('UNKNOWN'));
$record = $geodb->get($request->getIP());
$expire = DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_LOGIN_LONG);
$expire = DateTime::addSeconds(new \DateTime(), $sessionDuration);
$secret = Auth::tokenGenerator();
$session = new Document(array_merge(
[
@ -525,10 +528,11 @@ App::get('/v1/account/sessions/oauth2/:provider/redirect')
}
// Create session token, verify user account and update OAuth2 ID and Access Token
$sessionDuration = ($project->getAttribute('sessionDuration', null) * 60) ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
$detector = new Detector($request->getUserAgent('UNKNOWN'));
$record = $geodb->get($request->getIP());
$secret = Auth::tokenGenerator();
$expire = DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_LOGIN_LONG);
$expire = DateTime::addSeconds(new \DateTime(), $sessionDuration);
$session = new Document(array_merge([
'$id' => ID::unique(),
@ -759,10 +763,11 @@ App::put('/v1/account/sessions/magic-url')
->inject('request')
->inject('response')
->inject('dbForProject')
->inject('project')
->inject('locale')
->inject('geodb')
->inject('events')
->action(function (string $userId, string $secret, Request $request, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Event $events) {
->action(function (string $userId, string $secret, Request $request, Response $response, Database $dbForProject, Document $project, Locale $locale, Reader $geodb, Event $events) {
/** @var Utopia\Database\Document $user */
@ -778,10 +783,11 @@ App::put('/v1/account/sessions/magic-url')
throw new Exception(Exception::USER_INVALID_TOKEN);
}
$sessionDuration = ($project->getAttribute('sessionDuration', null) * 60) ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
$detector = new Detector($request->getUserAgent('UNKNOWN'));
$record = $geodb->get($request->getIP());
$secret = Auth::tokenGenerator();
$expire = DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_LOGIN_LONG);
$expire = DateTime::addSeconds(new \DateTime(), $sessionDuration);
$session = new Document(array_merge(
[
@ -996,10 +1002,11 @@ App::put('/v1/account/sessions/phone')
->inject('request')
->inject('response')
->inject('dbForProject')
->inject('project')
->inject('locale')
->inject('geodb')
->inject('events')
->action(function (string $userId, string $secret, Request $request, Response $response, Database $dbForProject, Locale $locale, Reader $geodb, Event $events) {
->action(function (string $userId, string $secret, Request $request, Response $response, Database $dbForProject, Document $project, Locale $locale, Reader $geodb, Event $events) {
$user = Authorization::skip(fn() => $dbForProject->getDocument('users', $userId));
@ -1013,10 +1020,11 @@ App::put('/v1/account/sessions/phone')
throw new Exception(Exception::USER_INVALID_TOKEN);
}
$sessionDuration = ($project->getAttribute('sessionDuration', null) * 60) ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
$detector = new Detector($request->getUserAgent('UNKNOWN'));
$record = $geodb->get($request->getIP());
$secret = Auth::tokenGenerator();
$expire = DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_LOGIN_LONG);
$expire = DateTime::addSeconds(new \DateTime(), $sessionDuration);
$session = new Document(array_merge(
[
@ -1164,11 +1172,11 @@ App::post('/v1/account/sessions/anonymous')
])));
// Create session token
$sessionDuration = ($project->getAttribute('sessionDuration', null) * 60) ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
$detector = new Detector($request->getUserAgent('UNKNOWN'));
$record = $geodb->get($request->getIP());
$secret = Auth::tokenGenerator();
$expire = DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_LOGIN_LONG);
$expire = DateTime::addSeconds(new \DateTime(), $sessionDuration);
$session = new Document(array_merge(
[

View file

@ -32,6 +32,7 @@ use Appwrite\Utopia\Database\Validator\Queries\Projects;
use Utopia\Validator\ArrayList;
use Utopia\Validator\Boolean;
use Utopia\Validator\Hostname;
use Utopia\Validator\Integer;
use Utopia\Validator\Range;
use Utopia\Validator\Text;
use Utopia\Validator\WhiteList;
@ -67,10 +68,11 @@ App::post('/v1/projects')
->param('legalCity', '', new Text(256), 'Project legal City. Max length: 256 chars.', true)
->param('legalAddress', '', new Text(256), 'Project legal Address. Max length: 256 chars.', true)
->param('legalTaxId', '', new Text(256), 'Project legal Tax ID. Max length: 256 chars.', true)
->param('sessionDuration', 525600, new Integer(), 'Session duration in minutes. Defaults to 1 year', true)
->inject('response')
->inject('dbForConsole')
->inject('dbForProject')
->action(function (string $projectId, string $name, string $teamId, string $description, string $logo, string $url, string $legalName, string $legalCountry, string $legalState, string $legalCity, string $legalAddress, string $legalTaxId, Response $response, Database $dbForConsole, Database $dbForProject) {
->action(function (string $projectId, string $name, string $teamId, string $description, string $logo, string $url, string $legalName, string $legalCountry, string $legalState, string $legalCity, string $legalAddress, string $legalTaxId, int $sessionDuration, Response $response, Database $dbForConsole, Database $dbForProject) {
$team = $dbForConsole->getDocument('teams', $teamId);
@ -112,6 +114,7 @@ App::post('/v1/projects')
'legalCity' => $legalCity,
'legalAddress' => $legalAddress,
'legalTaxId' => ID::custom($legalTaxId),
'sessionDuration' => $sessionDuration,
'services' => new stdClass(),
'platforms' => null,
'authProviders' => [],
@ -374,9 +377,10 @@ App::patch('/v1/projects/:projectId')
->param('legalCity', '', new Text(256), 'Project legal city. Max length: 256 chars.', true)
->param('legalAddress', '', new Text(256), 'Project legal address. Max length: 256 chars.', true)
->param('legalTaxId', '', new Text(256), 'Project legal tax ID. Max length: 256 chars.', true)
->param('sessionDuration', null, new Integer(true), 'Project session length in minutes. Max length: 525600 minutes.', true)
->inject('response')
->inject('dbForConsole')
->action(function (string $projectId, string $name, string $description, string $logo, string $url, string $legalName, string $legalCountry, string $legalState, string $legalCity, string $legalAddress, string $legalTaxId, Response $response, Database $dbForConsole) {
->action(function (string $projectId, string $name, string $description, string $logo, string $url, string $legalName, string $legalCountry, string $legalState, string $legalCity, string $legalAddress, string $legalTaxId, int $sessionDuration, Response $response, Database $dbForConsole) {
$project = $dbForConsole->getDocument('projects', $projectId);
@ -384,6 +388,10 @@ App::patch('/v1/projects/:projectId')
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
if ($sessionDuration < 0 || $sessionDuration > 525600) {
throw new Exception('Session length must be between 0 and 525600 minutes');
}
$project = $dbForConsole->updateDocument('projects', $project->getId(), $project
->setAttribute('name', $name)
->setAttribute('description', $description)
@ -395,6 +403,7 @@ App::patch('/v1/projects/:projectId')
->setAttribute('legalCity', $legalCity)
->setAttribute('legalAddress', $legalAddress)
->setAttribute('legalTaxId', $legalTaxId)
->setAttribute('sessionDuration', $sessionDuration)
->setAttribute('search', implode(' ', [$projectId, $name])));
$response->dynamic($project, Response::MODEL_PROJECT);

View file

@ -677,9 +677,10 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
->inject('response')
->inject('user')
->inject('dbForProject')
->inject('project')
->inject('geodb')
->inject('events')
->action(function (string $teamId, string $membershipId, string $userId, string $secret, Request $request, Response $response, Document $user, Database $dbForProject, Reader $geodb, Event $events) {
->action(function (string $teamId, string $membershipId, string $userId, string $secret, Request $request, Response $response, Document $user, Database $dbForProject, Document $project, Reader $geodb, Event $events) {
$protocol = $request->getProtocol();
$membership = $dbForProject->getDocument('memberships', $membershipId);
@ -731,7 +732,8 @@ App::patch('/v1/teams/:teamId/memberships/:membershipId/status')
$detector = new Detector($request->getUserAgent('UNKNOWN'));
$record = $geodb->get($request->getIP());
$expire = DateTime::addSeconds(new \DateTime(), Auth::TOKEN_EXPIRATION_LOGIN_LONG);
$sessionDuration = ($project->getAttribute('sessionDuration', null) * 60) ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
$expire = DateTime::addSeconds(new \DateTime(), $sessionDuration);
$secret = Auth::tokenGenerator();
$session = new Document(array_merge([
'$id' => ID::unique(),

View file

@ -917,6 +917,7 @@ App::setResource('console', function () {
'legalCity' => '',
'legalAddress' => '',
'legalTaxId' => '',
'sessionDuration' => 525600, // 1 Year in minutes
'auths' => [
'limit' => (App::getEnv('_APP_CONSOLE_WHITELIST_ROOT', 'enabled') === 'enabled') ? 1 : 0, // limit signup to 1 user
],

View file

@ -99,7 +99,7 @@ $cli
{
(new Delete())
->setType(DELETE_TYPE_SESSIONS)
->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * Auth::TOKEN_EXPIRATION_LOGIN_LONG))
->setDatetime(DateTime::addSeconds(new \DateTime(), -1 * Auth::TOKEN_EXPIRATION_LOGIN_LONG)) //TODO: Update to use project session expiration instead of default.
->trigger();
}

View file

@ -101,6 +101,12 @@ class Project extends Model
'default' => '',
'example' => '131102020',
])
->addRule('sessionDuration', [
'type' => self::TYPE_STRING,
'description' => 'Session duration in minutes.',
'default' => '',
'example' => '30',
])
->addRule('authLimit', [
'type' => self::TYPE_INTEGER,
'description' => 'Max users allowed. 0 is unlimited.',

View file

@ -53,6 +53,7 @@ trait ProjectCustom
'legalCity' => '',
'legalAddress' => '',
'legalTaxId' => '',
'sessionDuration' => 525600
]);
$this->assertEquals(201, $project['headers']['status-code']);