Merge branch 'master' into feat-add-encrypt-param
This commit is contained in:
commit
c3ebdc46e2
9 changed files with 117 additions and 4 deletions
|
@ -323,6 +323,11 @@ return [
|
||||||
'description' => 'The requested range is not satisfiable. Please check the value of the Range header.',
|
'description' => 'The requested range is not satisfiable. Please check the value of the Range header.',
|
||||||
'code' => 416,
|
'code' => 416,
|
||||||
],
|
],
|
||||||
|
Exception::STORAGE_INVALID_APPWRITE_ID => [
|
||||||
|
'name' => Exception::STORAGE_INVALID_APPWRITE_ID,
|
||||||
|
'description' => 'The value for x-appwrite-id header is invalid. Please check the value of the x-appwrite-id header is valid id and not unique().',
|
||||||
|
'code' => 400,
|
||||||
|
],
|
||||||
|
|
||||||
/** Functions */
|
/** Functions */
|
||||||
Exception::FUNCTION_NOT_FOUND => [
|
Exception::FUNCTION_NOT_FOUND => [
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
"emails.magicSession.signature": "Equipa {{project}}",
|
"emails.magicSession.signature": "Equipa {{project}}",
|
||||||
"emails.recovery.subject": "Redefinição de senha",
|
"emails.recovery.subject": "Redefinição de senha",
|
||||||
"emails.recovery.hello": "Olá {{name}}",
|
"emails.recovery.hello": "Olá {{name}}",
|
||||||
"emails.recovery.body": "tilize este link para redefinir a palavra-passe do seu projecto {{project}}",
|
"emails.recovery.body": "Utilize este link para redefinir a palavra-passe do seu projecto {{project}}",
|
||||||
"emails.recovery.footer": "Se não pediu para redefinir a sua palavra-passe, pode ignorar esta mensagem.",
|
"emails.recovery.footer": "Se não pediu para redefinir a sua palavra-passe, pode ignorar esta mensagem.",
|
||||||
"emails.recovery.thanks": "Obrigado",
|
"emails.recovery.thanks": "Obrigado",
|
||||||
"emails.recovery.signature": "Equipa {{project}}",
|
"emails.recovery.signature": "Equipa {{project}}",
|
||||||
|
|
|
@ -450,6 +450,11 @@ App::post('/v1/storage/buckets/:bucketId/files')
|
||||||
throw new Exception(Exception::STORAGE_INVALID_CONTENT_RANGE);
|
throw new Exception(Exception::STORAGE_INVALID_CONTENT_RANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$idValidator = new UID();
|
||||||
|
if (!$idValidator->isValid($request->getHeader('x-appwrite-id'))) {
|
||||||
|
throw new Exception(Exception::STORAGE_INVALID_APPWRITE_ID);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO remove the condition that checks `$end === $fileSize` in next breaking version
|
// TODO remove the condition that checks `$end === $fileSize` in next breaking version
|
||||||
if ($end === $fileSize - 1 || $end === $fileSize) {
|
if ($end === $fileSize - 1 || $end === $fileSize) {
|
||||||
//if it's a last chunks the chunk size might differ, so we set the $chunks and $chunk to -1 notify it's last chunk
|
//if it's a last chunks the chunk size might differ, so we set the $chunks and $chunk to -1 notify it's last chunk
|
||||||
|
|
|
@ -343,11 +343,12 @@ App::delete('/v1/teams/:teamId')
|
||||||
Query::limit(2000), // TODO fix members limit
|
Query::limit(2000), // TODO fix members limit
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// TODO delete all members individually from the user object
|
// Memberships are deleted here instead of in the worker to make sure user permisions are updated instantly
|
||||||
foreach ($memberships as $membership) {
|
foreach ($memberships as $membership) {
|
||||||
if (!$dbForProject->deleteDocument('memberships', $membership->getId())) {
|
if (!$dbForProject->deleteDocument('memberships', $membership->getId())) {
|
||||||
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove membership for team from DB');
|
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove membership for team from DB');
|
||||||
}
|
}
|
||||||
|
$dbForProject->deleteCachedDocument('users', $membership->getAttribute('userId'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$dbForProject->deleteDocument('teams', $teamId)) {
|
if (!$dbForProject->deleteDocument('teams', $teamId)) {
|
||||||
|
|
|
@ -27,7 +27,7 @@ $parseLabel = function (string $label, array $responsePayload, array $requestPar
|
||||||
$parts = explode('.', $match);
|
$parts = explode('.', $match);
|
||||||
|
|
||||||
if (count($parts) !== 2) {
|
if (count($parts) !== 2) {
|
||||||
throw new Exception('Too less or too many parts', 400, Exception::GENERAL_ARGUMENT_INVALID);
|
throw new Exception(Exception::GENERAL_SERVER_ERROR, "The server encountered an error while parsing the label: $label. Please create an issue on GitHub to allow us to investigate further https://github.com/appwrite/appwrite/issues/new/choose");
|
||||||
}
|
}
|
||||||
|
|
||||||
$namespace = $parts[0] ?? '';
|
$namespace = $parts[0] ?? '';
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Use this endpoint to log out the currently logged in user from all their account sessions across all of their different devices. When using the Session ID argument, only the unique session ID provided is deleted.
|
Logout the user. Use 'current' as the session ID to logout on this device, use a session ID to logout on another device. If you're looking to logout the user on all devices, use [Delete Sessions](/docs/client/account#accountDeleteSessions) instead.
|
|
@ -107,6 +107,7 @@ class Exception extends \Exception
|
||||||
public const STORAGE_BUCKET_NOT_FOUND = 'storage_bucket_not_found';
|
public const STORAGE_BUCKET_NOT_FOUND = 'storage_bucket_not_found';
|
||||||
public const STORAGE_INVALID_CONTENT_RANGE = 'storage_invalid_content_range';
|
public const STORAGE_INVALID_CONTENT_RANGE = 'storage_invalid_content_range';
|
||||||
public const STORAGE_INVALID_RANGE = 'storage_invalid_range';
|
public const STORAGE_INVALID_RANGE = 'storage_invalid_range';
|
||||||
|
public const STORAGE_INVALID_APPWRITE_ID = 'storage_invalid_appwrite_id';
|
||||||
|
|
||||||
/** Functions */
|
/** Functions */
|
||||||
public const FUNCTION_NOT_FOUND = 'function_not_found';
|
public const FUNCTION_NOT_FOUND = 'function_not_found';
|
||||||
|
|
|
@ -240,6 +240,29 @@ trait StorageBase
|
||||||
|
|
||||||
$this->assertEquals(400, $failedBucket['headers']['status-code']);
|
$this->assertEquals(400, $failedBucket['headers']['status-code']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test for FAILURE set x-appwrite-id to unique()
|
||||||
|
*/
|
||||||
|
$source = realpath(__DIR__ . '/../../../resources/logo.png');
|
||||||
|
$totalSize = \filesize($source);
|
||||||
|
$res = $this->client->call(Client::METHOD_POST, '/storage/buckets/' . $bucketId . '/files', array_merge([
|
||||||
|
'content-type' => 'multipart/form-data',
|
||||||
|
'x-appwrite-project' => $this->getProject()['$id'],
|
||||||
|
'content-range' => 'bytes 0-' . $size . '/' . $size,
|
||||||
|
'x-appwrite-id' => 'unique()',
|
||||||
|
], $this->getHeaders()), [
|
||||||
|
'fileId' => ID::unique(),
|
||||||
|
'file' => new CURLFile($source, 'image/png', 'logo.png'),
|
||||||
|
'permissions' => [
|
||||||
|
Permission::read(Role::any()),
|
||||||
|
Permission::update(Role::any()),
|
||||||
|
Permission::delete(Role::any()),
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(400, $res['headers']['status-code']);
|
||||||
|
$this->assertEquals('The value for x-appwrite-id header is invalid. Please check the value of the x-appwrite-id header is valid id and not unique().', $res['body']['message']);
|
||||||
|
|
||||||
return ['bucketId' => $bucketId, 'fileId' => $file['body']['$id'], 'largeFileId' => $largeFile['body']['$id'], 'largeBucketId' => $bucket2['body']['$id']];
|
return ['bucketId' => $bucketId, 'fileId' => $file['body']['$id'], 'largeFileId' => $largeFile['body']['$id'], 'largeBucketId' => $bucket2['body']['$id']];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ namespace Tests\E2E\Services\Teams;
|
||||||
|
|
||||||
use Tests\E2E\Client;
|
use Tests\E2E\Client;
|
||||||
use Utopia\Database\Validator\Datetime as DatetimeValidator;
|
use Utopia\Database\Validator\Datetime as DatetimeValidator;
|
||||||
|
use Utopia\Database\Helpers\ID;
|
||||||
|
|
||||||
trait TeamsBaseServer
|
trait TeamsBaseServer
|
||||||
{
|
{
|
||||||
|
@ -281,4 +282,81 @@ trait TeamsBaseServer
|
||||||
$this->assertIsInt($response['body']['total']);
|
$this->assertIsInt($response['body']['total']);
|
||||||
$this->assertEquals(true, $dateValidator->isValid($response['body']['$createdAt']));
|
$this->assertEquals(true, $dateValidator->isValid($response['body']['$createdAt']));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function testTeamDeleteUpdatesUserMembership()
|
||||||
|
{
|
||||||
|
// Array to store the IDs of newly created users
|
||||||
|
$new_users = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new team
|
||||||
|
*/
|
||||||
|
$new_team = $this->client->call(Client::METHOD_POST, '/teams', array_merge([
|
||||||
|
'content-type' => 'application/json',
|
||||||
|
'x-appwrite-project' => $this->getProject()['$id'],
|
||||||
|
], $this->getHeaders()), [
|
||||||
|
'teamId' => ID::unique(),
|
||||||
|
'name' => 'New Team Test',
|
||||||
|
'roles' => ['admin', 'editor'],
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(201, $new_team['headers']['status-code']);
|
||||||
|
$this->assertNotEmpty($new_team['body']['$id']);
|
||||||
|
$this->assertEquals('New Team Test', $new_team['body']['name']);
|
||||||
|
$this->assertGreaterThan(-1, $new_team['body']['total']);
|
||||||
|
$this->assertIsInt($new_team['body']['total']);
|
||||||
|
$this->assertArrayHasKey('prefs', $new_team['body']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the Create Team Membership endpoint
|
||||||
|
* to create 5 new users and add them to the team immediately
|
||||||
|
*/
|
||||||
|
for ($i = 0; $i < 5; $i++) {
|
||||||
|
$new_membership = $this->client->call(Client::METHOD_POST, '/teams/' . $new_team['body']['$id'] . '/memberships', array_merge([
|
||||||
|
'content-type' => 'application/json',
|
||||||
|
'x-appwrite-project' => $this->getProject()['$id'],
|
||||||
|
], $this->getHeaders()), [
|
||||||
|
'email' => 'newuser' . $i . '@localhost.test',
|
||||||
|
'name' => 'New User ' . $i,
|
||||||
|
'roles' => ['admin', 'editor'],
|
||||||
|
'url' => 'http://localhost:5000/join-us#title'
|
||||||
|
]);
|
||||||
|
|
||||||
|
$this->assertEquals(201, $new_membership['headers']['status-code']);
|
||||||
|
$this->assertNotEmpty($new_membership['body']['$id']);
|
||||||
|
$this->assertNotEmpty($new_membership['body']['userId']);
|
||||||
|
$this->assertEquals('New User ' . $i, $new_membership['body']['userName']);
|
||||||
|
$this->assertEquals('newuser' . $i . '@localhost.test', $new_membership['body']['userEmail']);
|
||||||
|
$this->assertNotEmpty($new_membership['body']['teamId']);
|
||||||
|
$this->assertCount(2, $new_membership['body']['roles']);
|
||||||
|
$dateValidator = new DatetimeValidator();
|
||||||
|
$this->assertEquals(true, $dateValidator->isValid($new_membership['body']['joined']));
|
||||||
|
$this->assertEquals(true, $new_membership['body']['confirm']);
|
||||||
|
|
||||||
|
$new_users[] = $new_membership['body']['userId'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete the team
|
||||||
|
*/
|
||||||
|
$team_del_response = $this->client->call(Client::METHOD_DELETE, '/teams/' . $new_team['body']['$id'], array_merge([
|
||||||
|
'content-type' => 'application/json',
|
||||||
|
'x-appwrite-project' => $this->getProject()['$id'],
|
||||||
|
], $this->getHeaders()));
|
||||||
|
|
||||||
|
$this->assertEquals(204, $team_del_response['headers']['status-code']);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check that the team memberships for each of the new users has been deleted
|
||||||
|
*/
|
||||||
|
for ($i = 0; $i < 5; $i++) {
|
||||||
|
$membership = $this->client->call(Client::METHOD_GET, '/users/' . $new_users[$i] . '/memberships', array_merge([
|
||||||
|
'content-type' => 'application/json',
|
||||||
|
'x-appwrite-project' => $this->getProject()['$id'],
|
||||||
|
], $this->getHeaders()));
|
||||||
|
|
||||||
|
$this->assertEquals(200, $membership['headers']['status-code']);
|
||||||
|
$this->assertEquals(0, $membership['body']['total']);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue