mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Compare commits
25
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e2a6b5b2f | ||
|
|
50cf415359 | ||
|
|
4d46879497 | ||
|
|
ad4fdea0a3 | ||
|
|
596498896e | ||
|
|
2b7d915578 | ||
|
|
d9772e29cc | ||
|
|
455c292313 | ||
|
|
97fb4cb4b6 | ||
|
|
0cee469d73 | ||
|
|
ba723de735 | ||
|
|
6565f2ff91 | ||
|
|
06c6fac915 | ||
|
|
3a813d8554 | ||
|
|
e6d4f4e3a1 | ||
|
|
d1170836b8 | ||
|
|
86ea75026f | ||
|
|
4350bda137 | ||
|
|
01958a0f4e | ||
|
|
b338ed9a2c | ||
|
|
5a557e5602 | ||
|
|
ed9d64b25f | ||
|
|
28061ccb21 | ||
|
|
854a4aca82 | ||
|
|
29111e5dea |
@@ -1,5 +1,6 @@
|
||||
<?php
|
||||
|
||||
use Ahc\Jwt\JWT;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Migration;
|
||||
use Appwrite\Extend\Exception;
|
||||
@@ -691,6 +692,44 @@ Http::get('/v1/migrations/:migrationId')
|
||||
$response->dynamic($migration, Response::MODEL_MIGRATION);
|
||||
});
|
||||
|
||||
Http::get('/v1/migrations/appwrite/settings-key')
|
||||
->groups(['api', 'migrations'])
|
||||
->desc('Generate console API key for settings migration')
|
||||
->label('scope', 'migrations.read')
|
||||
->label('sdk', new Method(
|
||||
namespace: 'migrations',
|
||||
group: null,
|
||||
name: 'getAppwriteSettingsKey',
|
||||
description: '/docs/references/migrations/migration-appwrite-settings-key.md',
|
||||
auth: [AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: Response::STATUS_CODE_OK,
|
||||
model: Response::MODEL_NONE,
|
||||
)
|
||||
]
|
||||
))
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->action(function (Response $response, Document $project) {
|
||||
$targetProjectId = $project->getId();
|
||||
|
||||
if (empty($targetProjectId)) {
|
||||
throw new Exception(Exception::PROJECT_NOT_FOUND);
|
||||
}
|
||||
|
||||
$jwt = new JWT(System::getEnv('_APP_OPENSSL_KEY_V1'), 'HS256', 120, 0);
|
||||
$consoleKey = $jwt->encode([
|
||||
'projectId' => 'console',
|
||||
'scopes' => ['platforms.read', 'keys.read'],
|
||||
'targetProjectId' => $targetProjectId,
|
||||
]);
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_OK)
|
||||
->json(['key' => API_KEY_DYNAMIC . '_' . $consoleKey]);
|
||||
});
|
||||
|
||||
Http::get('/v1/migrations/appwrite/report')
|
||||
->groups(['api', 'migrations'])
|
||||
->desc('Get Appwrite migration report')
|
||||
|
||||
@@ -273,6 +273,18 @@ Http::init()
|
||||
|
||||
$scopes = \array_unique($scopes);
|
||||
|
||||
// Migration-scoped keys (with targetProjectId) can only access routes
|
||||
// that have a :projectId param matching the key's target project.
|
||||
// This allows any /v1/projects/:projectId/* endpoint to be used during
|
||||
// migration without needing per-route labels, while blocking all other routes.
|
||||
if (!empty($apiKey) && !empty($apiKey->getTargetProjectId())) {
|
||||
$pathValues = $route->getPathValues($request);
|
||||
$routeProjectId = $pathValues['projectId'] ?? '';
|
||||
if (empty($routeProjectId) || $routeProjectId !== $apiKey->getTargetProjectId()) {
|
||||
throw new Exception(Exception::GENERAL_UNAUTHORIZED_SCOPE);
|
||||
}
|
||||
}
|
||||
|
||||
$authorization->addRole($role);
|
||||
foreach ($user->getRoles($authorization) as $authRole) {
|
||||
$authorization->addRole($authRole);
|
||||
|
||||
+1
-1
@@ -65,7 +65,7 @@
|
||||
"utopia-php/locale": "0.8.*",
|
||||
"utopia-php/logger": "0.6.*",
|
||||
"utopia-php/messaging": "0.20.*",
|
||||
"utopia-php/migration": "1.5.*",
|
||||
"utopia-php/migration": "dev-feat-platform-key-migration as 1.5.0",
|
||||
"utopia-php/platform": "0.7.*",
|
||||
"utopia-php/pools": "1.*",
|
||||
"utopia-php/preloader": "0.2.*",
|
||||
|
||||
Generated
+25
-16
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "bc64aa37fc3ab6fa2acf7ac8f5456e9f",
|
||||
"content-hash": "2a3d7f252197be6405480a267c738ea8",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
@@ -3797,16 +3797,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/database",
|
||||
"version": "5.1.1",
|
||||
"version": "5.1.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/database.git",
|
||||
"reference": "94815bfa605282096272625827d0314f9ed99066"
|
||||
"reference": "1530a1c7608daf31f412f8f9a487a3b2eadd83af"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/94815bfa605282096272625827d0314f9ed99066",
|
||||
"reference": "94815bfa605282096272625827d0314f9ed99066",
|
||||
"url": "https://api.github.com/repos/utopia-php/database/zipball/1530a1c7608daf31f412f8f9a487a3b2eadd83af",
|
||||
"reference": "1530a1c7608daf31f412f8f9a487a3b2eadd83af",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -3849,9 +3849,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/database/issues",
|
||||
"source": "https://github.com/utopia-php/database/tree/5.1.1"
|
||||
"source": "https://github.com/utopia-php/database/tree/5.1.2"
|
||||
},
|
||||
"time": "2026-02-12T11:44:58+00:00"
|
||||
"time": "2026-02-13T01:41:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/detector",
|
||||
@@ -4464,16 +4464,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/migration",
|
||||
"version": "1.5.2",
|
||||
"version": "dev-feat-platform-key-migration",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/migration.git",
|
||||
"reference": "93904948f6dd07491821615fd9b9acbcaadec12e"
|
||||
"reference": "d4d2b891bd3a09919c5f93330bb5380250dad43b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/migration/zipball/93904948f6dd07491821615fd9b9acbcaadec12e",
|
||||
"reference": "93904948f6dd07491821615fd9b9acbcaadec12e",
|
||||
"url": "https://api.github.com/repos/utopia-php/migration/zipball/d4d2b891bd3a09919c5f93330bb5380250dad43b",
|
||||
"reference": "d4d2b891bd3a09919c5f93330bb5380250dad43b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4513,9 +4513,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/migration/issues",
|
||||
"source": "https://github.com/utopia-php/migration/tree/1.5.2"
|
||||
"source": "https://github.com/utopia-php/migration/tree/feat-platform-key-migration"
|
||||
},
|
||||
"time": "2026-02-11T06:19:35+00:00"
|
||||
"time": "2026-02-12T22:46:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/mongo",
|
||||
@@ -8887,9 +8887,18 @@
|
||||
"time": "2024-03-07T20:33:40+00:00"
|
||||
}
|
||||
],
|
||||
"aliases": [],
|
||||
"aliases": [
|
||||
{
|
||||
"package": "utopia-php/migration",
|
||||
"version": "dev-feat-platform-key-migration",
|
||||
"alias": "1.5.0",
|
||||
"alias_normalized": "1.5.0.0"
|
||||
}
|
||||
],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": {},
|
||||
"stability-flags": {
|
||||
"utopia-php/migration": 20
|
||||
},
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
@@ -8913,5 +8922,5 @@
|
||||
"platform-overrides": {
|
||||
"php": "8.3"
|
||||
},
|
||||
"plugin-api-version": "2.9.0"
|
||||
"plugin-api-version": "2.6.0"
|
||||
}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
Generate a short-lived console-scoped API key for settings migration. This key allows the migration source to access project platforms and keys on the source instance.
|
||||
@@ -28,6 +28,7 @@ class Key
|
||||
protected bool $projectCheckDisabled = false,
|
||||
protected bool $previewAuthDisabled = false,
|
||||
protected bool $deploymentStatusIgnored = false,
|
||||
protected string $targetProjectId = '',
|
||||
) {
|
||||
}
|
||||
|
||||
@@ -103,6 +104,11 @@ class Key
|
||||
return $this->projectCheckDisabled;
|
||||
}
|
||||
|
||||
public function getTargetProjectId(): string
|
||||
{
|
||||
return $this->targetProjectId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode the given secret key into a Key object, containing the project ID, type, role, scopes, and name.
|
||||
* Can be a stored API key or a dynamic key (JWT).
|
||||
@@ -161,7 +167,14 @@ class Key
|
||||
$projectCheckDisabled = $payload['projectCheckDisabled'] ?? false;
|
||||
$previewAuthDisabled = $payload['previewAuthDisabled'] ?? false;
|
||||
$deploymentStatusIgnored = $payload['deploymentStatusIgnored'] ?? false;
|
||||
$scopes = \array_merge($payload['scopes'] ?? [], $scopes);
|
||||
$targetProjectId = $payload['targetProjectId'] ?? '';
|
||||
|
||||
// Keys with targetProjectId are restricted — only use explicit JWT scopes
|
||||
if (!empty($targetProjectId)) {
|
||||
$scopes = $payload['scopes'] ?? [];
|
||||
} else {
|
||||
$scopes = \array_merge($payload['scopes'] ?? [], $scopes);
|
||||
}
|
||||
|
||||
if (!$projectCheckDisabled && $projectId !== $project->getId()) {
|
||||
return $guestKey;
|
||||
@@ -181,7 +194,8 @@ class Key
|
||||
$bannerDisabled,
|
||||
$projectCheckDisabled,
|
||||
$previewAuthDisabled,
|
||||
$deploymentStatusIgnored
|
||||
$deploymentStatusIgnored,
|
||||
$targetProjectId
|
||||
);
|
||||
case API_KEY_STANDARD:
|
||||
$key = $project->find(
|
||||
|
||||
@@ -246,6 +246,8 @@ class Migrations extends Action
|
||||
$credentials['destinationApiKey'],
|
||||
$this->dbForProject,
|
||||
Config::getParam('collections', [])['databases']['collections'],
|
||||
$this->dbForPlatform,
|
||||
$this->project->getSequence(),
|
||||
),
|
||||
DestinationCSV::getName() => new DestinationCSV(
|
||||
$this->deviceForFiles,
|
||||
|
||||
@@ -53,6 +53,18 @@ class MigrationReport extends Model
|
||||
'default' => 0,
|
||||
'example' => 20,
|
||||
])
|
||||
->addRule(Resource::TYPE_PLATFORM, [
|
||||
'type' => self::TYPE_INTEGER,
|
||||
'description' => 'Number of platforms to be migrated.',
|
||||
'default' => 0,
|
||||
'example' => 5,
|
||||
])
|
||||
->addRule(Resource::TYPE_KEY, [
|
||||
'type' => self::TYPE_INTEGER,
|
||||
'description' => 'Number of API keys to be migrated.',
|
||||
'default' => 0,
|
||||
'example' => 10,
|
||||
])
|
||||
->addRule('size', [
|
||||
'type' => self::TYPE_INTEGER,
|
||||
'description' => 'Size of files to be migrated in mb.',
|
||||
|
||||
Reference in New Issue
Block a user