Merge remote-tracking branch 'origin/1.6.x' into feat-pool-adapter

This commit is contained in:
Jake Barnby 2025-04-16 13:55:55 +12:00
commit d10757e69f
No known key found for this signature in database
GPG key ID: C437A8CC85B96E9C
5 changed files with 144 additions and 58 deletions

View file

@ -238,34 +238,36 @@ App::init()
subject: 'keys'
);
if ($dbKey) {
$accessedAt = $dbKey->getAttribute('accessedAt', '');
if (!$dbKey) {
throw new Exception(Exception::USER_UNAUTHORIZED);
}
if (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_KEY_ACCESS)) > $accessedAt) {
$dbKey->setAttribute('accessedAt', DateTime::now());
$accessedAt = $dbKey->getAttribute('accessedAt', '');
if (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_KEY_ACCESS)) > $accessedAt) {
$dbKey->setAttribute('accessedAt', DateTime::now());
$dbForPlatform->updateDocument('keys', $dbKey->getId(), $dbKey);
$dbForPlatform->purgeCachedDocument('projects', $project->getId());
}
$sdkValidator = new WhiteList($servers, true);
$sdk = $request->getHeader('x-sdk-name', 'UNKNOWN');
if ($sdkValidator->isValid($sdk)) {
$sdks = $dbKey->getAttribute('sdks', []);
if (!in_array($sdk, $sdks)) {
$sdks[] = $sdk;
$dbKey->setAttribute('sdks', $sdks);
/** Update access time as well */
$dbKey->setAttribute('accessedAt', Datetime::now());
$dbForPlatform->updateDocument('keys', $dbKey->getId(), $dbKey);
$dbForPlatform->purgeCachedDocument('projects', $project->getId());
}
$sdkValidator = new WhiteList($servers, true);
$sdk = $request->getHeader('x-sdk-name', 'UNKNOWN');
if ($sdkValidator->isValid($sdk)) {
$sdks = $dbKey->getAttribute('sdks', []);
if (!in_array($sdk, $sdks)) {
$sdks[] = $sdk;
$dbKey->setAttribute('sdks', $sdks);
/** Update access time as well */
$dbKey->setAttribute('accessedAt', Datetime::now());
$dbForPlatform->updateDocument('keys', $dbKey->getId(), $dbKey);
$dbForPlatform->purgeCachedDocument('projects', $project->getId());
}
}
$queueForAudits->setUser($user);
}
$queueForAudits->setUser($user);
}
} // Admin User Authentication
elseif (($project->getId() === 'console' && !$team->isEmpty() && !$user->isEmpty()) || ($project->getId() !== 'console' && !$user->isEmpty() && $mode === APP_MODE_ADMIN)) {

34
composer.lock generated
View file

@ -1365,16 +1365,16 @@
},
{
"name": "open-telemetry/sdk",
"version": "1.2.3",
"version": "1.2.4",
"source": {
"type": "git",
"url": "https://github.com/opentelemetry-php/sdk.git",
"reference": "0e7804c176c4b09d95b7985400aa38ce544cb7fc"
"reference": "47fcb66ae5328c5a799195247b1dce551d85873e"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/opentelemetry-php/sdk/zipball/0e7804c176c4b09d95b7985400aa38ce544cb7fc",
"reference": "0e7804c176c4b09d95b7985400aa38ce544cb7fc",
"url": "https://api.github.com/repos/opentelemetry-php/sdk/zipball/47fcb66ae5328c5a799195247b1dce551d85873e",
"reference": "47fcb66ae5328c5a799195247b1dce551d85873e",
"shasum": ""
},
"require": {
@ -1451,7 +1451,7 @@
"issues": "https://github.com/open-telemetry/opentelemetry-php/issues",
"source": "https://github.com/open-telemetry/opentelemetry-php"
},
"time": "2025-04-08T09:55:41+00:00"
"time": "2025-04-15T07:02:07+00:00"
},
{
"name": "open-telemetry/sem-conv",
@ -3351,16 +3351,16 @@
},
{
"name": "utopia-php/cli",
"version": "0.15.1",
"version": "0.15.2",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/cli.git",
"reference": "d69bbe51a6a94dc4e5bcdd542b5938038b985a65"
"reference": "da00ff6b8b29a826a1794002ae43442cdf3a0f5f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/cli/zipball/d69bbe51a6a94dc4e5bcdd542b5938038b985a65",
"reference": "d69bbe51a6a94dc4e5bcdd542b5938038b985a65",
"url": "https://api.github.com/repos/utopia-php/cli/zipball/da00ff6b8b29a826a1794002ae43442cdf3a0f5f",
"reference": "da00ff6b8b29a826a1794002ae43442cdf3a0f5f",
"shasum": ""
},
"require": {
@ -3394,9 +3394,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/cli/issues",
"source": "https://github.com/utopia-php/cli/tree/0.15.1"
"source": "https://github.com/utopia-php/cli/tree/0.15.2"
},
"time": "2024-10-04T13:55:36+00:00"
"time": "2025-04-15T10:08:48+00:00"
},
{
"name": "utopia-php/compression",
@ -4767,16 +4767,16 @@
"packages-dev": [
{
"name": "appwrite/sdk-generator",
"version": "0.40.11",
"version": "0.40.12",
"source": {
"type": "git",
"url": "https://github.com/appwrite/sdk-generator.git",
"reference": "0ec5f4a60c15e33e208bc3444ba6148b1d0f0027"
"reference": "182ec17848f81b78c336379bac94ff92b7a73365"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/0ec5f4a60c15e33e208bc3444ba6148b1d0f0027",
"reference": "0ec5f4a60c15e33e208bc3444ba6148b1d0f0027",
"url": "https://api.github.com/repos/appwrite/sdk-generator/zipball/182ec17848f81b78c336379bac94ff92b7a73365",
"reference": "182ec17848f81b78c336379bac94ff92b7a73365",
"shasum": ""
},
"require": {
@ -4812,9 +4812,9 @@
"description": "Appwrite PHP library for generating API SDKs for multiple programming languages and platforms",
"support": {
"issues": "https://github.com/appwrite/sdk-generator/issues",
"source": "https://github.com/appwrite/sdk-generator/tree/0.40.11"
"source": "https://github.com/appwrite/sdk-generator/tree/0.40.12"
},
"time": "2025-03-26T10:53:16+00:00"
"time": "2025-04-02T23:36:11+00:00"
},
{
"name": "doctrine/annotations",

View file

@ -148,7 +148,7 @@ class UsageTest extends Scope
);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(31, count($response['body']));
$this->assertGreaterThanOrEqual(31, count($response['body']));
$this->validateDates($response['body']['network']);
$this->validateDates($response['body']['requests']);
$this->validateDates($response['body']['users']);
@ -327,7 +327,7 @@ class UsageTest extends Scope
]
);
$this->assertEquals(31, count($response['body']));
$this->assertGreaterThanOrEqual(31, count($response['body']));
$this->assertEquals(1, count($response['body']['requests']));
$this->assertEquals($requestsTotal, $response['body']['requests'][array_key_last($response['body']['requests'])]['value']);
$this->validateDates($response['body']['requests']);
@ -548,7 +548,7 @@ class UsageTest extends Scope
]
);
$this->assertEquals(31, count($response['body']));
$this->assertGreaterThanOrEqual(31, count($response['body']));
$this->assertEquals(1, count($response['body']['requests']));
$this->assertEquals(1, count($response['body']['network']));
$this->assertEquals($requestsTotal, $response['body']['requests'][array_key_last($response['body']['requests'])]['value']);

View file

@ -90,6 +90,12 @@ trait DatabasesBase
*/
public function testConsoleProject(array $data)
{
if ($this->getSide() === 'server') {
// Server side can't get past the invalid key check anyway
$this->expectNotToPerformAssertions();
return;
}
$response = $this->client->call(
Client::METHOD_GET,
'/databases/console/collections/' . $data['moviesId'] . '/documents',

View file

@ -2786,32 +2786,35 @@ class ProjectsConsoleClientTest extends Scope
*/
public function testValidateProjectKey($data): void
{
$id = $data['projectId'] ?? '';
$projectId = $data['projectId'] ?? '';
$teamId = $data['teamId'] ?? '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/keys', array_merge([
// Expiring key
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $projectId . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Key Test',
'scopes' => ['health.read'],
'scopes' => ['users.write'],
'expire' => DateTime::addSeconds(new \DateTime(), 3600),
]);
$response = $this->client->call(Client::METHOD_GET, '/health', [
$response = $this->client->call(Client::METHOD_POST, '/users', [
'content-type' => 'application/json',
'x-appwrite-project' => $id,
'x-appwrite-project' => $projectId,
'x-appwrite-key' => $response['body']['secret']
], []);
], [
'userId' => ID::unique(),
]);
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(201, $response['headers']['status-code']);
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/keys', array_merge([
// No expiry
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $projectId . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
@ -2822,7 +2825,7 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/health', [
'content-type' => 'application/json',
'x-appwrite-project' => $id,
'x-appwrite-project' => $projectId,
'x-appwrite-key' => $response['body']['secret']
], []);
@ -2831,7 +2834,9 @@ class ProjectsConsoleClientTest extends Scope
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/keys', array_merge([
// Expired key
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $projectId . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
@ -2842,9 +2847,82 @@ class ProjectsConsoleClientTest extends Scope
$response = $this->client->call(Client::METHOD_GET, '/health', [
'content-type' => 'application/json',
'x-appwrite-project' => $id,
'x-appwrite-project' => $projectId,
'x-appwrite-key' => $response['body']['secret']
], []);
]);
$this->assertEquals(401, $response['headers']['status-code']);
// Invalid key
$bucket = $this->client->call(Client::METHOD_POST, '/storage/buckets', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-mode' => 'admin',
], $this->getHeaders()), [
'bucketId' => ID::unique(),
'name' => 'Test Bucket',
]);
$this->assertEquals(201, $bucket['headers']['status-code']);
$this->assertNotEmpty($bucket['body']['$id']);
$bucketId = $bucket['body']['$id'];
$response = $this->client->call(Client::METHOD_GET, "/storage/buckets/{$bucketId}/files", [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-key' => 'invalid-key'
]);
$this->assertEquals(401, $response['headers']['status-code']);
// Invalid scopes
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $projectId . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Key Test',
'scopes' => ['teams.read'],
'expire' => DateTime::addSeconds(new \DateTime(), 3600),
]);
$response = $this->client->call(Client::METHOD_GET, '/users', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-key' => $response['body']['secret']
]);
$this->assertEquals(401, $response['headers']['status-code']);
// Invalid key from different project
$response = $this->client->call(Client::METHOD_POST, '/projects', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'projectId' => ID::unique(),
'name' => 'Project Test 2',
'teamId' => $teamId,
'region' => System::getEnv('_APP_REGION', 'default')
]);
$this->assertEquals(201, $response['headers']['status-code']);
$project2Id = $response['body']['$id'];
$response = $this->client->call(Client::METHOD_POST, '/projects/' . $project2Id . '/keys', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'name' => 'Key Test',
'scopes' => ['health.read'],
'expire' => DateTime::addSeconds(new \DateTime(), 3600),
]);
$response = $this->client->call(Client::METHOD_GET, '/health', [
'content-type' => 'application/json',
'x-appwrite-project' => $projectId,
'x-appwrite-key' => $response['body']['secret']
]);
$this->assertEquals(401, $response['headers']['status-code']);
}