Fix bugs, add old api key test

This commit is contained in:
Matej Bačo
2024-05-16 08:39:15 +00:00
parent 37176e7865
commit 2e1f67245d
7 changed files with 98 additions and 14 deletions
+1 -1
View File
@@ -1148,7 +1148,7 @@ App::post('/v1/projects/:projectId/keys')
'expire' => $expire,
'sdks' => [],
'accessedAt' => null,
'secret' => \bin2hex(\random_bytes(128)),
'secret' => API_KEY_STANDARD . '_' . \bin2hex(\random_bytes(128)),
]);
$key = $dbForConsole->createDocument('keys', $key);
+50
View File
@@ -6,6 +6,7 @@ use Appwrite\Extend\Exception;
use Appwrite\Utopia\Request;
use Appwrite\Utopia\Response;
use Utopia\App;
use Utopia\Config\Config;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Helpers\ID;
@@ -154,6 +155,55 @@ App::patch('/v1/mock/functions-v2')
$response->noContent();
});
App::post('/v1/mock/api-key-unprefixed')
->desc('Create API Key (without standard prefix)')
->groups(['mock', 'api', 'projects'])
->label('scope', 'projects.write')
->label('docs', false)
->param('projectId', '', new UID(), 'Project ID.')
->inject('response')
->inject('dbForConsole')
->action(function (string $projectId, Response $response, Database $dbForConsole) {
$isDevelopment = System::getEnv('_APP_ENV', 'development') === 'development';
if (!$isDevelopment) {
throw new Exception(Exception::GENERAL_NOT_IMPLEMENTED);
}
$project = $dbForConsole->getDocument('projects', $projectId);
if ($project->isEmpty()) {
throw new Exception(Exception::PROJECT_NOT_FOUND);
}
$scopes = array_keys(Config::getParam('scopes'));
$key = new Document([
'$id' => ID::unique(),
'$permissions' => [
Permission::read(Role::any()),
Permission::update(Role::any()),
Permission::delete(Role::any()),
],
'projectInternalId' => $project->getInternalId(),
'projectId' => $project->getId(),
'name' => 'Outdated key',
'scopes' => $scopes,
'expire' => null,
'sdks' => [],
'accessedAt' => null,
'secret' => \bin2hex(\random_bytes(128)),
]);
$key = $dbForConsole->createDocument('keys', $key);
$dbForConsole->purgeCachedDocument('projects', $project->getId());
$response
->setStatusCode(Response::STATUS_CODE_CREATED)
->dynamic($key, Response::MODEL_KEY);
});
App::get('/v1/mock/github/callback')
->desc('Create installation document using GitHub installation id')
->groups(['mock', 'api', 'vcs'])
+8 -2
View File
@@ -206,7 +206,12 @@ App::init()
throw new Exception(Exception::USER_API_KEY_AND_SESSION_SET);
}
[ $keyType, $authKey ] = \explode('_', $apiKey, 2);
if(!\str_contains($apiKey, '_')) {
$keyType = API_KEY_STANDARD;
$authKey = $apiKey;
} else {
[ $keyType, $authKey ] = \explode('_', $apiKey, 2);
}
if($keyType === API_KEY_DYNAMIC) {
// Dynamic key
@@ -239,10 +244,11 @@ App::init()
Authorization::setDefaultStatus(false); // Cancel security segmentation for API keys.
}
} elseif($keyType === API_KEY_STANDARD) {
// No underline means no prefix. Backwards compatibility.
// Regular key
// Check if given key match project API keys
$key = $project->find('secret', $authKey, 'keys');
$key = $project->find('secret', $apiKey, 'keys');
if ($key) {
$user = new Document([
'$id' => '',
@@ -4,7 +4,6 @@ namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
use Utopia\Database\Document;
class Key extends Model
{
@@ -94,10 +93,4 @@ class Key extends Model
{
return Response::MODEL_KEY;
}
public function filter(Document $document): Document
{
$document->setAttribute('secret', API_KEY_STANDARD . '_' . $document->getAttribute('secret', ''));
return $document;
}
}
@@ -1296,8 +1296,6 @@ class DatabasesCustomServerTest extends Scope
'x-appwrite-key' => $this->getProject()['apiKey'],
], $this->getHeaders()));
\var_dump($attributes['body']);
$this->assertEquals(0, $attributes['body']['total']);
}
@@ -1444,8 +1444,6 @@ class FunctionsCustomServerTest extends Scope
'async' => false
]);
\var_dump($execution);
$this->assertEquals(201, $execution['headers']['status-code']);
$this->assertEquals('completed', $execution['body']['status']);
$this->assertEquals(200, $execution['body']['responseStatusCode']);
@@ -2704,6 +2704,45 @@ class ProjectsConsoleClientTest extends Scope
return $data;
}
/**
* @depends testCreateProject
*/
public function testCreateProjectKeyOutdated($data): void
{
$id = $data['projectId'] ?? '';
$response = $this->client->call(Client::METHOD_POST, '/mock/api-key-unprefixed', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'projectId' => $id
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertContains('users.read', $response['body']['scopes']);
$this->assertNotEmpty($response['body']['secret']);
$this->assertStringStartsNotWith(API_KEY_STANDARD . '_', $response['body']['secret']);
$keyId = $response['body']['$id'];
$secret = $response['body']['secret'];
$response = $this->client->call(Client::METHOD_GET, '/users', [
'content-type' => 'application/json',
'x-appwrite-project' => $id,
'x-appwrite-key' => $secret
], []);
$this->assertEquals(200, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $id . '/keys/' . $keyId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), []);
$this->assertEquals(204, $response['headers']['status-code']);
$this->assertEmpty($response['body']);
}
// Platforms
/**