mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Verify apiKey ownership to safely take DB fast path for SourceAppwrite
This commit is contained in:
@@ -204,17 +204,37 @@ class Migrations extends Action
|
||||
if (! empty($credentials['projectId'])) {
|
||||
$this->sourceProject = $this->dbForPlatform->getDocument('projects', $credentials['projectId']);
|
||||
|
||||
// For Appwrite -> Appwrite, "project exists locally with this id" is not
|
||||
// enough to take the DB fast path: a destination project deliberately
|
||||
// created with the source's projectId (to preserve cross-references like
|
||||
// createdBy/userId) would collide. Verify the user-supplied apiKey actually
|
||||
// belongs to the local project — only then is it safe to read direct.
|
||||
$isLocalSource = false;
|
||||
if (
|
||||
$source === SourceAppwrite::getName()
|
||||
&& $destination === DestinationAppwrite::getName()
|
||||
&& !$this->sourceProject->isEmpty()
|
||||
&& !empty($credentials['apiKey'])
|
||||
) {
|
||||
$keyDoc = $this->dbForPlatform->findOne('keys', [
|
||||
Query::equal('secret', [$credentials['apiKey']]),
|
||||
Query::equal('projectInternalId', [$this->sourceProject->getSequence()]),
|
||||
]);
|
||||
$isLocalSource = $keyDoc !== false && !$keyDoc->isEmpty();
|
||||
}
|
||||
|
||||
$sourceRegion = $this->sourceProject->getAttribute('region', 'default');
|
||||
$destinationRegion = $this->project->getAttribute('region', 'default');
|
||||
$useAppwriteApiSource = $source === SourceAppwrite::getName()
|
||||
&& $destination === DestinationAppwrite::getName()
|
||||
&& ($this->sourceProject->isEmpty() || $sourceRegion !== $destinationRegion);
|
||||
&& (!$isLocalSource || $sourceRegion !== $destinationRegion);
|
||||
|
||||
if (! $useAppwriteApiSource) {
|
||||
if ($this->sourceProject->isEmpty()) {
|
||||
throw new Exception(Exception::MIGRATION_SOURCE_PROJECT_NOT_FOUND);
|
||||
}
|
||||
$projectDB = call_user_func($this->getProjectDB, $this->sourceProject);
|
||||
} elseif ($this->sourceProject->isEmpty()) {
|
||||
} elseif (!$isLocalSource) {
|
||||
// External source — processMigration defaults missing endpoint/apiKey to this
|
||||
// instance, which would silently self-call with the destination's key. Require
|
||||
// explicit credentials so the failure mode is clear.
|
||||
|
||||
Reference in New Issue
Block a user