1
0
Fork 0
mirror of synced 2024-05-20 04:32:37 +12:00

Merge branch '1.1.x' of https://github.com/appwrite/appwrite into feat-console-rewrite

This commit is contained in:
Torsten Dittmann 2022-11-15 15:36:25 +01:00
commit ef1e5a9674
10 changed files with 166 additions and 32 deletions

View file

@ -1,19 +1,15 @@
# Version 1.1.0
## Features
- Added new property to projects configuration: `sessionDuration` which allows you to alter the duration of signed in sessions for your project. [#4618](https://github.com/appwrite/appwrite/pull/4618)
- Added new property to projects configuration: `authDuration` which allows you to alter the duration of signed in sessions for your project. [#4618](https://github.com/appwrite/appwrite/pull/4618)
## Bugs
- Fix license detection for Flutter and Dart SDKs [#4435](https://github.com/appwrite/appwrite/pull/4435)
- Fix missing status, buildStderr and buildStderr from get deployment response [#4611](https://github.com/appwrite/appwrite/pull/4611)
- Fix missing `status`, `buildStderr` and `buildStderr` from get deployment response [#4611](https://github.com/appwrite/appwrite/pull/4611)
- Fix project pagination in DB usage aggregation [#4517](https://github.com/appwrite/appwrite/pull/4517)
# Features
- Added Auth Duration API to allow users to set the duration of their sessions. [#4618](https://github.com/appwrite/appwrite/pull/4618)
# Version 1.0.4
- Fix project pagination in DB usage collector [#4517](https://github.com/appwrite/appwrite/pull/4517)
# Version 1.0.3
## Bugs
- Fix document audit deletion [#4429](https://github.com/appwrite/appwrite/pull/4429)

@ -1 +1 @@
Subproject commit 602943f7a6487789f32ea3643e0c299a5b393d25
Subproject commit 0ed6e0c497931f16fcb0750fe351d1d3577a7d97

View file

@ -81,7 +81,7 @@ App::post('/v1/projects')
}
$auth = Config::getParam('auth', []);
$auths = ['limit' => 0];
$auths = ['limit' => 0, 'duration' => Auth::TOKEN_EXPIRATION_LOGIN_LONG];
foreach ($auth as $index => $method) {
$auths[$method['key'] ?? ''] = true;
}
@ -522,7 +522,7 @@ App::patch('/v1/projects/:projectId/auth/duration')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_PROJECT)
->param('projectId', '', new UID(), 'Project unique ID.')
->param('duration', 525600, new Range(0, 525600), 'Project session length in minutes. Max length: 525600 minutes.')
->param('duration', 31536000, new Range(0, 31536000), 'Project session length in seconds. Max length: 31536000 seconds.')
->inject('response')
->inject('dbForConsole')
->action(function (string $projectId, int $duration, Response $response, Database $dbForConsole) {
@ -534,7 +534,7 @@ App::patch('/v1/projects/:projectId/auth/duration')
}
$auths = $project->getAttribute('auths', []);
$auths['duration'] = $duration * 60;
$auths['duration'] = $duration;
$dbForConsole->updateDocument('projects', $project->getId(), $project
->setAttribute('auths', $auths));

View file

@ -306,7 +306,7 @@ $server->onWorkerStart(function (int $workerId) use ($server, $register, $stats,
if ($realtime->hasSubscriber($projectId, 'user:' . $userId)) {
$connection = array_key_first(reset($realtime->subscriptions[$projectId]['user:' . $userId]));
[$consoleDatabase, $returnConsoleDatabase] = getDatabase($register, '_console');
$project = Authorization::skip(fn() => $consoleDatabase->getDocument('projects', $projectId));
$project = Authorization::skip(fn () => $consoleDatabase->getDocument('projects', $projectId));
[$database, $returnDatabase] = getDatabase($register, "_{$project->getInternalId()}");
$user = $database->getDocument('users', $userId);
@ -484,6 +484,7 @@ $server->onOpen(function (int $connection, SwooleRequest $request) use ($server,
$server->onMessage(function (int $connection, string $message) use ($server, $register, $realtime, $containerId) {
try {
$app = new App('UTC');
$response = new Response(new SwooleResponse());
$db = $register->get('dbPool')->get();
$redis = $register->get('redisPool')->get();
@ -493,12 +494,8 @@ $server->onMessage(function (int $connection, string $message) use ($server, $re
$database->setDefaultDatabase(App::getEnv('_APP_DB_SCHEMA', 'appwrite'));
$database->setNamespace("_console");
$projectId = $realtime->connections[$connection]['projectId'];
if ($projectId !== 'console') {
$project = Authorization::skip(fn() => $database->getDocument('projects', $projectId));
$database->setNamespace("_{$project->getInternalId()}");
}
$project = $projectId === 'console' ? $app->getResource('console') : Authorization::skip(fn () => $database->getDocument('projects', $projectId));
$database->setNamespace("_{$project->getInternalId()}");
/*
* Abuse Check
*

View file

@ -7,6 +7,8 @@
<ini name="memory_limit" value="4096M"/>
<!-- Exclude SDK's for performance reasons -->
<exclude-pattern>./app/sdks</exclude-pattern>
<!-- Exclude console -->
<exclude-pattern>./app/console</exclude-pattern>
<!-- Ignore max line width -->
<rule ref="Generic.Files.LineLength">
<exclude-pattern>*</exclude-pattern>

View file

@ -45,7 +45,7 @@ abstract class Migration
'1.0.0' => 'V15',
'1.0.1' => 'V15',
'1.0.3' => 'V15',
'1.1.0' => 'V15',
'1.1.0' => 'V16',
];
/**

View file

@ -0,0 +1,116 @@
<?php
namespace Appwrite\Migration\Version;
use Appwrite\Auth\Auth;
use Appwrite\Migration\Migration;
use Utopia\CLI\Console;
use Utopia\Database\Database;
use Utopia\Database\Document;
class V16 extends Migration
{
public function execute(): void
{
/**
* Disable SubQueries for Performance.
*/
foreach (['subQueryIndexes', 'subQueryPlatforms', 'subQueryDomains', 'subQueryKeys', 'subQueryWebhooks', 'subQuerySessions', 'subQueryTokens', 'subQueryMemberships', 'subqueryVariables'] as $name) {
Database::addFilter(
$name,
fn () => null,
fn () => []
);
}
Console::log('Migrating Project: ' . $this->project->getAttribute('name') . ' (' . $this->project->getId() . ')');
Console::info('Migrating Collections');
$this->migrateCollections();
Console::info('Migrating Documents');
$this->forEachDocument([$this, 'fixDocument']);
}
/**
* Migrate all Collections.
*
* @return void
*/
protected function migrateCollections(): void
{
foreach ($this->collections as $collection) {
$id = $collection['$id'];
Console::log("Migrating Collection \"{$id}\"");
$this->projectDB->setNamespace("_{$this->project->getInternalId()}");
switch ($id) {
case 'sessions':
try {
/**
* Create 'compression' attribute
*/
$this->projectDB->deleteAttribute($id, 'expire');
} catch (\Throwable $th) {
Console::warning("'expire' from {$id}: {$th->getMessage()}");
}
break;
case 'projects':
try {
/**
* Create 'region' attribute
*/
$this->createAttributeFromCollection($this->projectDB, $id, 'region');
} catch (\Throwable $th) {
Console::warning("'region' from {$id}: {$th->getMessage()}");
}
try {
/**
* Create '_key_team' index
*/
$this->createIndexFromCollection($this->projectDB, $id, '_key_team');
} catch (\Throwable $th) {
Console::warning("'_key_team' from {$id}: {$th->getMessage()}");
}
break;
default:
break;
}
usleep(50000);
}
}
/**
* Fix run on each document
*
* @param \Utopia\Database\Document $document
* @return \Utopia\Database\Document
*/
protected function fixDocument(Document $document)
{
switch ($document->getCollection()) {
case 'projects':
/**
* Bump version number.
*/
$document->setAttribute('version', '1.1.0');
/**
* Set default authDuration
*/
$document->setAttribute('auths', array_merge($document->getAttribute('auths', []), [
'duration' => Auth::TOKEN_EXPIRATION_LOGIN_LONG
]));
break;
}
return $document;
}
}

View file

@ -2,6 +2,7 @@
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Auth\Auth;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
use Utopia\Config\Config;
@ -102,10 +103,10 @@ class Project extends Model
'example' => '131102020',
])
->addRule('authDuration', [
'type' => self::TYPE_STRING,
'type' => self::TYPE_INTEGER,
'description' => 'Session duration in seconds.',
'default' => '',
'example' => '30',
'default' => Auth::TOKEN_EXPIRATION_LOGIN_LONG,
'example' => 60,
])
->addRule('authLimit', [
'type' => self::TYPE_INTEGER,
@ -231,7 +232,7 @@ class Project extends Model
$auth = Config::getParam('auth', []);
$document->setAttribute('authLimit', $authValues['limit'] ?? 0);
$document->setAttribute('authDuration', $authValues['duration'] ?? 0);
$document->setAttribute('authDuration', $authValues['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG);
foreach ($auth as $index => $method) {
$key = $method['key'];

View file

@ -85,7 +85,7 @@ class UsageTest extends Scope
#[Retry(count: 1)]
public function testUsersStats(array $data): array
{
sleep(10);
sleep(20);
$projectId = $data['projectId'];
$headers = $data['headers'];
@ -256,7 +256,7 @@ class UsageTest extends Scope
$filesCreate = $data['filesCreate'];
$filesDelete = $data['filesDelete'];
sleep(10);
sleep(20);
// console request
$headers = [
@ -414,7 +414,7 @@ class UsageTest extends Scope
$this->assertEquals('name', $res['body']['key']);
$collectionsUpdate++;
$requestsCount++;
sleep(10);
sleep(20);
for ($i = 0; $i < 10; $i++) {
$name = uniqid() . ' collection';
@ -496,7 +496,7 @@ class UsageTest extends Scope
$documentsRead = $data['documentsRead'];
$documentsDelete = $data['documentsDelete'];
sleep(10);
sleep(20);
// check datbase stats
$headers = [
@ -704,7 +704,7 @@ class UsageTest extends Scope
$executions = $data['executions'];
$failures = $data['failures'];
sleep(10);
sleep(20);
$response = $this->client->call(Client::METHOD_GET, '/functions/' . $functionId . '/usage', $headers, [
'range' => '30d'

View file

@ -417,6 +417,15 @@ class ProjectsConsoleClientTest extends Scope
{
$id = $data['projectId'];
// Check defaults
$response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(Auth::TOKEN_EXPIRATION_LOGIN_LONG, $response['body']['authDuration']); // 1 Year
/**
* Test for SUCCESS
*/
@ -425,7 +434,7 @@ class ProjectsConsoleClientTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'duration' => '1', // Set session duration to 2 minutes
'duration' => 60, // Set session duration to 2 minutes
]);
$this->assertEquals(200, $response['headers']['status-code']);
@ -475,8 +484,21 @@ class ProjectsConsoleClientTest extends Scope
$this->assertEquals(200, $response['headers']['status-code']);
// Check session doesn't expire too soon.
sleep(30);
// Get User
$response = $this->client->call(Client::METHOD_GET, '/account', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'Cookie' => $sessionCookie,
]));
$this->assertEquals(200, $response['headers']['status-code']);
// Wait just over a minute
sleep(65);
sleep(35);
// Get User
$response = $this->client->call(Client::METHOD_GET, '/account', array_merge([
@ -492,7 +514,7 @@ class ProjectsConsoleClientTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'duration' => 525600,
'duration' => Auth::TOKEN_EXPIRATION_LOGIN_LONG,
]);
$this->assertEquals(200, $response['headers']['status-code']);
@ -505,7 +527,7 @@ class ProjectsConsoleClientTest extends Scope
], $this->getHeaders()));
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(31536000, $response['body']['authDuration']); // 1 Year
$this->assertEquals(Auth::TOKEN_EXPIRATION_LOGIN_LONG, $response['body']['authDuration']); // 1 Year
return ['projectId' => $projectId];
}