diff --git a/app/controllers/general.php b/app/controllers/general.php index 84d158714b..747799e369 100644 --- a/app/controllers/general.php +++ b/app/controllers/general.php @@ -292,10 +292,11 @@ App::init(function (App $utopia, Request $request, Response $response, Document $service = $route->getLabel('sdk.namespace', ''); if (!empty($service)) { + $roles = Authorization::getRoles(); if ( array_key_exists($service, $project->getAttribute('services', [])) && !$project->getAttribute('services', [])[$service] - && !Auth::isPrivilegedUser(Authorization::getRoles()) + && !(Auth::isPrivilegedUser($roles) || Auth::isAppUser($roles)) ) { throw new AppwriteException('Service is disabled', 503, AppwriteException::GENERAL_SERVICE_DISABLED); } diff --git a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php index 1154515648..b550456692 100644 --- a/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php +++ b/tests/e2e/Services/Projects/ProjectsConsoleClientTest.php @@ -786,6 +786,104 @@ class ProjectsConsoleClientTest extends Scope } } + /** @depends testUpdateProjectServiceStatusAdmin */ + public function testUpdateProjectServiceStatusServer($data): void + { + $id = $data['projectId']; + + $services = require('app/config/services.php'); + + /** + * Test for Disabled + */ + foreach ($services as $service) { + if (!$service['optional']) { + continue; + } + + $key = $service['key'] ?? ''; + + $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/service', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_console=' . $this->getRoot()['session'], + ]), [ + 'service' => $key, + 'status' => false, + ]); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']['$id']); + + $response = $this->client->call(Client::METHOD_GET, '/projects/' . $id, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_console=' . $this->getRoot()['session'], + ])); + + $this->assertEquals(200, $response['headers']['status-code']); + $this->assertNotEmpty($response['body']['$id']); + $this->assertEquals(false, $response['body']['serviceStatusFor' . ucfirst($key)]); + } + + // Create API Key + $response = $this->client->call(Client::METHOD_POST, '/projects/' . $id . '/keys', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_console=' . $this->getRoot()['session'], + ]), [ + 'name' => 'Key Test', + 'scopes' => ['functions.read', 'teams.write'], + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + $keyId = $response['body']['$id']; + $keySecret = $response['body']['secret']; + + /** + * Request with API Key must succeed + */ + $response = $this->client->call(Client::METHOD_GET, '/functions', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $id, + 'x-appwrite-key' => $keySecret, + ])); + + $this->assertEquals(200, $response['headers']['status-code']); + + $response = $this->client->call(Client::METHOD_POST, '/teams', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $id, + 'x-appwrite-key' => $keySecret, + ]), [ + 'teamId' => 'unique()', + 'name' => 'Arsenal' + ]); + + $this->assertEquals(201, $response['headers']['status-code']); + + // Cleanup + + $response = $this->client->call(Client::METHOD_DELETE, '/projects/' . $id . '/keys/' . $keyId, array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + 'cookie' => 'a_session_console=' . $this->getRoot()['session'], + ]), []); + + $this->assertEquals(204, $response['headers']['status-code']); + + foreach ($services as $service) { + $response = $this->client->call(Client::METHOD_PATCH, '/projects/' . $id . '/service/', array_merge([ + 'content-type' => 'application/json', + 'x-appwrite-project' => $this->getProject()['$id'], + ], $this->getHeaders()), [ + 'service' => $service, + 'status' => true, + ]); + } + } + /** * @depends testCreateProject */