mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
1098 lines
50 KiB
PHP
1098 lines
50 KiB
PHP
<?php
|
|
|
|
use Appwrite\Event\Delete;
|
|
use Appwrite\Event\Event;
|
|
use Appwrite\Event\Transfer;
|
|
use Appwrite\Extend\Exception;
|
|
use Appwrite\Utopia\Database\Validator\CustomId;
|
|
use Appwrite\Utopia\Database\Validator\Queries\Destinations;
|
|
use Appwrite\Utopia\Database\Validator\Queries\Sources;
|
|
use Appwrite\Utopia\Database\Validator\Queries\Transfers;
|
|
use Utopia\Validator\URL;
|
|
use Appwrite\Utopia\Response;
|
|
use Cron\CronExpression;
|
|
use Utopia\App;
|
|
use Utopia\Database\Database;
|
|
use Utopia\Database\DateTime;
|
|
use Utopia\Database\Document;
|
|
use Utopia\Database\Helpers\ID;
|
|
use Utopia\Database\Query;
|
|
use Utopia\Database\Validator\UID;
|
|
use Utopia\Transfer\Destinations\Appwrite;
|
|
use Utopia\Transfer\Sources\Appwrite as SourcesAppwrite;
|
|
use Utopia\Transfer\Sources\Firebase;
|
|
use Utopia\Transfer\Sources\NHost;
|
|
use Utopia\Transfer\Sources\Supabase;
|
|
use Utopia\Validator\ArrayList;
|
|
use Utopia\Validator\Integer;
|
|
use Utopia\Validator\JSON;
|
|
use Utopia\Validator\Text;
|
|
use Utopia\Validator\WhiteList;
|
|
|
|
include_once __DIR__ . '/../shared/api.php';
|
|
|
|
App::post('/v1/transfers')
|
|
->groups(['api', 'transfers'])
|
|
->desc('Create Transfer')
|
|
->label('scope', 'transfers.write')
|
|
->label('event', 'transfers.[transferId].create')
|
|
->label('audits.event', 'transfers.create')
|
|
->label('audits.resource', 'transfers/{response.$id}')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'create')
|
|
->label('sdk.description', '/docs/references/transfers/create-transfer.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
|
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
|
->label('sdk.response.model', Response::MODEL_TRANSFER)
|
|
->param('transferId', 'unique()', new CustomId(), 'Transfer unique ID. Use \'unique()\' to auto generate a unique ID for this transfer.')
|
|
->param('source', '', new UID(), 'Source UID. [Learn more about sources](https://appwrite.io/docs/transfers/sources)', false)
|
|
->param('destination', '', new UID(), 'Destination UID. [Learn more about destinations](https://appwrite.io/docs/transfers/sources)', false)
|
|
->param('resources', [], new ArrayList(new WhiteList(TRANSFER_RESOURCES)), 'List of resources to transfer. [A list of resources can be found here.](https://appwrite.io/docs/transfers#resources)', false)
|
|
->inject('response')
|
|
->inject('dbForProject')
|
|
->inject('project')
|
|
->inject('user')
|
|
->inject('events')
|
|
->action(function (string $transferId, string $source, string $destination, array $resources, Response $response, Database $dbForProject, Document $project, Document $user, Event $eventsInstance) {
|
|
$cron = !empty($schedule) ? new CronExpression($schedule) : null;
|
|
$next = !empty($schedule) ? DateTime::format($cron->getNextRunDate()) : null;
|
|
|
|
$transferId = ($transferId == 'unique()') ? ID::unique() : $transferId;
|
|
|
|
$transfer = $dbForProject->createDocument('transfers', new Document([
|
|
'$id' => $transferId,
|
|
'status' => 'pending',
|
|
'stage' => 'init',
|
|
'source' => $source,
|
|
'destination' => $destination,
|
|
'resources' => $resources,
|
|
'progress' => json_encode([
|
|
'source' => [],
|
|
'destination' => [],
|
|
]),
|
|
'latestUpdate' => "{}",
|
|
'errorData' => ""
|
|
]));
|
|
|
|
$eventsInstance->setParam('transferId', $transfer->getId());
|
|
|
|
// Trigger Transfer
|
|
$event = new Transfer();
|
|
$event
|
|
->setTransfer($transfer)
|
|
->setProject($project)
|
|
->setUser($user)
|
|
->trigger();
|
|
|
|
$response
|
|
->setStatusCode(Response::STATUS_CODE_CREATED)
|
|
->dynamic($transfer, Response::MODEL_TRANSFER);
|
|
});
|
|
|
|
App::get('/v1/transfers')
|
|
->groups(['api', 'transfers'])
|
|
->desc('List Transfers')
|
|
->label('scope', 'transfers.read')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'list')
|
|
->label('sdk.description', '/docs/references/transfers/list-transfers.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
|
->label('sdk.response.model', Response::MODEL_TRANSFER_LIST)
|
|
->param('queries', [], new Transfers(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/databases#querying-documents). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following attributes: ' . implode(', ', Transfers::ALLOWED_ATTRIBUTES), true)
|
|
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
|
->inject('response')
|
|
->inject('dbForProject')
|
|
->action(function (array $queries, string $search, Response $response, Database $dbForProject) {
|
|
|
|
$queries = Query::parseQueries($queries);
|
|
|
|
if (!empty($search)) {
|
|
$queries[] = Query::search('search', $search);
|
|
}
|
|
|
|
// Get cursor document if there was a cursor query
|
|
$cursor = Query::getByType($queries, Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE);
|
|
$cursor = reset($cursor);
|
|
if ($cursor) {
|
|
/** @var Query $cursor */
|
|
$transferId = $cursor->getValue();
|
|
$cursorDocument = $dbForProject->getDocument('transfers', $transferId);
|
|
|
|
if ($cursorDocument->isEmpty()) {
|
|
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Transfer '{$transferId}' for the 'cursor' value not found.");
|
|
}
|
|
|
|
$cursor->setValue($cursorDocument);
|
|
}
|
|
|
|
$filterQueries = Query::groupByType($queries)['filters'];
|
|
|
|
$response->dynamic(new Document([
|
|
'transfers' => $dbForProject->find('transfers', $queries),
|
|
'total' => $dbForProject->count('transfers', $filterQueries, APP_LIMIT_COUNT),
|
|
]), Response::MODEL_TRANSFER_LIST);
|
|
});
|
|
|
|
App::get('/v1/transfers/:transferId')
|
|
->groups(['api', 'transfers'])
|
|
->desc('Get Transfer')
|
|
->label('scope', 'transfers.read')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'get')
|
|
->label('sdk.description', '/docs/references/transfers/get-transfer.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
|
->label('sdk.response.model', Response::MODEL_TRANSFER)
|
|
->param('transferId', '', new UID(), 'Transfer unique ID.')
|
|
->inject('response')
|
|
->inject('dbForProject')
|
|
->action(function (string $transferId, Response $response, Database $dbForProject) {
|
|
$transfer = $dbForProject->getDocument('transfers', $transferId);
|
|
|
|
if ($transfer->isEmpty()) {
|
|
throw new Exception(Exception::TRANSFER_NOT_FOUND, 'Transfer not found', 404);
|
|
}
|
|
|
|
$response->dynamic($transfer, Response::MODEL_TRANSFER);
|
|
});
|
|
|
|
App::post('/v1/transfers/:transferId')
|
|
->groups(['api', 'transfers'])
|
|
->desc('Retry Transfer')
|
|
->label('scope', 'transfers.write')
|
|
->label('event', 'transfers.[transferId].retry')
|
|
->label('audits.event', 'transfer.retry')
|
|
->label('audits.resource', 'transfer/{request.transferId}')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'retry')
|
|
->label('sdk.description', '/docs/references/transfers/retry-transfer.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
|
->label('sdk.response.model', Response::MODEL_TRANSFER)
|
|
->param('transferId', '', new UID(), 'Transfer unique ID.')
|
|
->inject('response')
|
|
->inject('dbForProject')
|
|
->inject('project')
|
|
->inject('user')
|
|
->inject('events')
|
|
->action(function (string $transferId, Response $response, Database $dbForProject, Document $project, Document $user, Event $eventInstance) {
|
|
$transfer = $dbForProject->getDocument('transfers', $transferId);
|
|
|
|
if ($transfer->isEmpty()) {
|
|
throw new Exception(Exception::TRANSFER_NOT_FOUND);
|
|
}
|
|
|
|
// if ($transfer->getAttribute('status') !== 'failed') {
|
|
// throw new Exception(Exception::TRANSFER_IN_PROGRESS, 'Transfer not failed');
|
|
// }
|
|
|
|
$transfer
|
|
->setAttribute('status', 'pending')
|
|
->setAttribute('dateUpdated', \time());
|
|
|
|
// Trigger Transfer
|
|
$event = new Transfer();
|
|
$event
|
|
->setTransfer($transfer)
|
|
->setProject($project)
|
|
->setUser($user)
|
|
->trigger();
|
|
|
|
$response->noContent();
|
|
});
|
|
|
|
App::delete('/v1/transfers/:transferId')
|
|
->groups(['api', 'transfers'])
|
|
->desc('Delete Transfer')
|
|
->label('scope', 'transfers.write')
|
|
->label('event', 'transfers.[transferId].delete')
|
|
->label('audits.event', 'transfer.delete')
|
|
->label('audits.resource', 'transfer/{request.transferId}')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'delete')
|
|
->label('sdk.description', '/docs/references/functions/delete-transfer.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
|
|
->label('sdk.response.model', Response::MODEL_NONE)
|
|
->param('transferId', '', new UID(), 'Transfer ID.')
|
|
->inject('response')
|
|
->inject('dbForProject')
|
|
->inject('deletes')
|
|
->inject('events')
|
|
->action(function (string $transferId, Response $response, Database $dbForProject, Delete $deletes, Event $events) {
|
|
|
|
$transfer = $dbForProject->getDocument('transfers', $transferId);
|
|
|
|
if ($transfer->isEmpty()) {
|
|
throw new Exception(Exception::TRANSFER_NOT_FOUND, 'Transfer not found', 404);
|
|
}
|
|
|
|
if (!$dbForProject->deleteDocument('transfers', $transfer->getId())) {
|
|
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed to remove transfer from DB', 500);
|
|
}
|
|
|
|
$deletes
|
|
->setType(DELETE_TYPE_DOCUMENT)
|
|
->setDocument($transfer);
|
|
|
|
$events->setParam('transferId', $transfer->getId());
|
|
|
|
$response->noContent();
|
|
});
|
|
|
|
App::get('/v1/transfers/sources')
|
|
->groups(['api', 'transfers'])
|
|
->desc('List Sources')
|
|
->label('scope', 'transfers.read')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'listSources')
|
|
->label('sdk.description', '/docs/references/transfers/list-sources.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
|
->label('sdk.response.model', Response::MODEL_SOURCE_LIST)
|
|
->param('queries', [], new Sources(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/databases#querying-documents). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following attributes: ' . implode(', ', Transfers::ALLOWED_ATTRIBUTES), true)
|
|
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
|
->inject('response')
|
|
->inject('dbForProject')
|
|
->action(function (array $queries, string $search, Response $response, Database $dbForProject) {
|
|
|
|
$queries = Query::parseQueries($queries);
|
|
|
|
if (!empty($search)) {
|
|
$queries[] = Query::search('search', $search);
|
|
}
|
|
|
|
// Get cursor document if there was a cursor query
|
|
$cursor = Query::getByType($queries, Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE);
|
|
$cursor = reset($cursor);
|
|
if ($cursor) {
|
|
/** @var Query $cursor */
|
|
$sourceId = $cursor->getValue();
|
|
$cursorDocument = $dbForProject->getDocument('sources', $sourceId);
|
|
|
|
if ($cursorDocument->isEmpty()) {
|
|
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Source '{$sourceId}' for the 'cursor' value not found.");
|
|
}
|
|
|
|
$cursor->setValue($cursorDocument);
|
|
}
|
|
|
|
$filterQueries = Query::groupByType($queries)['filters'];
|
|
|
|
$response->dynamic(new Document([
|
|
'sources' => $dbForProject->find('sources', $queries),
|
|
'total' => $dbForProject->count('sources', $filterQueries, APP_LIMIT_COUNT),
|
|
]), Response::MODEL_SOURCE_LIST);
|
|
});
|
|
|
|
|
|
|
|
App::get('/v1/transfers/source/:sourceId')
|
|
->groups(['api', 'transfers'])
|
|
->desc('Get Source')
|
|
->label('scope', 'transfers.read')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'getSource')
|
|
->label('sdk.description', '/docs/references/transfers/get-source.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
|
->label('sdk.response.model', Response::MODEL_SOURCE)
|
|
->param('sourceId', '', new UID(), 'Source unique ID.')
|
|
->inject('response')
|
|
->inject('dbForProject')
|
|
->action(function (string $sourceId, Response $response, Database $dbForProject) {
|
|
$source = $dbForProject->getDocument('sources', $sourceId);
|
|
|
|
if ($source->isEmpty()) {
|
|
throw new Exception(Exception::TRANSFER_SOURCE_NOT_FOUND, 'Source not found', 404);
|
|
}
|
|
|
|
$response->dynamic($source, Response::MODEL_SOURCE);
|
|
});
|
|
|
|
App::post('/v1/transfers/source/:sourceId/validate')
|
|
->groups(['api', 'transfers'])
|
|
->desc('Validate Source')
|
|
->label('scope', 'transfers.write')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'validateSource')
|
|
->label('sdk.description', '/docs/references/transfers/validate-source.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
|
->label('sdk.response.model', Response::MODEL_SOURCE_VALIDATION)
|
|
->param('sourceId', '', new UID(), 'Source unique ID.')
|
|
->param('resources', TRANSFER_RESOURCES, new ArrayList(new WhiteList(TRANSFER_RESOURCES)), 'List of resources to test. If none are sent then all resources are tested. [A list of resources can be found here.](https://appwrite.io/docs/transfers#resources)', true)
|
|
->inject('response')
|
|
->inject('dbForProject')
|
|
->action(function (string $sourceId, array $resources, Response $response, Database $dbForProject) {
|
|
$source = $dbForProject->getDocument('sources', $sourceId);
|
|
|
|
if ($source->isEmpty()) {
|
|
throw new Exception(Exception::TRANSFER_SOURCE_NOT_FOUND, 'Source not found', 404);
|
|
}
|
|
|
|
$authData = json_decode($source->getAttribute('data', "{}"), true);
|
|
|
|
try {
|
|
$testAdapter = null;
|
|
|
|
switch ($source['type']) {
|
|
case 'appwrite': {
|
|
$testAdapter = new SourcesAppwrite($authData['project'], $authData['endpoint'], $authData['key']);
|
|
break;
|
|
}
|
|
case 'firebase': {
|
|
$testAdapter = new Firebase($authData['authObject'], Firebase::AUTH_SERVICEACCOUNT);
|
|
break;
|
|
}
|
|
case 'supabase': {
|
|
$testAdapter = new Supabase($authData['url'], $authData['database'], $authData['username'], $authData['password'], $authData['port']);
|
|
break;
|
|
}
|
|
case 'nhost': {
|
|
$testAdapter = new NHost($authData['url'], $authData['database'], $authData['username'], $authData['password'], $authData['port']);
|
|
break;
|
|
}
|
|
default: {
|
|
throw new Exception(Exception::TRANSFER_SOURCE_NOT_FOUND, 'Source not found', 404);
|
|
}
|
|
}
|
|
|
|
$result = $testAdapter->check($resources);
|
|
|
|
$result = array_filter($result, function ($value) {
|
|
return $value !== [];
|
|
});
|
|
|
|
if (count($result) == 0) {
|
|
$source->setAttribute('lastCheck', json_encode([
|
|
'success' => true,
|
|
'message' => 'Source is valid'
|
|
]));
|
|
|
|
return $response->dynamic(new Document([
|
|
'success' => true,
|
|
'message' => 'Source is valid'
|
|
]), Response::MODEL_SOURCE_VALIDATION);
|
|
} else {
|
|
$source->setAttribute('lastCheck', json_encode([
|
|
'success' => false,
|
|
'message' => 'Missing Permissions',
|
|
'errors' => $result
|
|
]));
|
|
|
|
return $response->setStatusCode(401)->dynamic(new Document([
|
|
'success' => false,
|
|
'message' => 'Missing Permissions',
|
|
'errors' => $result
|
|
]), Response::MODEL_SOURCE_VALIDATION);
|
|
}
|
|
} catch (Throwable $e) {
|
|
$source->setAttribute('lastCheck', json_encode([
|
|
'success' => false,
|
|
'message' => 'Missing Permissions',
|
|
'errors' => [
|
|
'Databases' => [$e->getMessage()],
|
|
],
|
|
]));
|
|
|
|
return $response->setStatusCode(401)->dynamic(new Document([
|
|
'success' => false,
|
|
'message' => 'Missing Permissions',
|
|
'errors' => [
|
|
'Databases' => [$e->getMessage()],
|
|
],
|
|
]), Response::MODEL_SOURCE_VALIDATION);
|
|
} finally {
|
|
$dbForProject->updateDocument('sources', $source->getId(), $source);
|
|
}
|
|
});
|
|
|
|
App::delete('/v1/transfers/source/:sourceId')
|
|
->groups(['api', 'transfers'])
|
|
->desc('Delete Source')
|
|
->label('scope', 'transfers.write')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'deleteSource')
|
|
->label('sdk.description', '/docs/references/transfers/delete-source.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
|
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
|
->param('sourceId', '', new UID(), 'Source unique ID.')
|
|
->inject('response')
|
|
->inject('dbForProject')
|
|
->action(function (string $sourceId, Response $response, Database $dbForProject) {
|
|
$source = $dbForProject->getDocument('sources', $sourceId);
|
|
|
|
if ($source->isEmpty()) {
|
|
throw new Exception(Exception::TRANSFER_SOURCE_NOT_FOUND, 'Source not found', 404);
|
|
}
|
|
|
|
$dbForProject->deleteDocument('sources', $source->getId());
|
|
|
|
$response->noContent();
|
|
});
|
|
|
|
App::get('/v1/transfers/destinations')
|
|
->groups(['api', 'transfers'])
|
|
->desc('List Destinations')
|
|
->label('scope', 'transfers.read')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'listDestinations')
|
|
->label('sdk.description', '/docs/references/transfers/list-destinations.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
|
->label('sdk.response.model', Response::MODEL_DESTINATION_LIST)
|
|
->param('queries', [], new Destinations(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/databases#querying-documents). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long. You may filter on the following attributes: ' . implode(', ', Transfers::ALLOWED_ATTRIBUTES), true)
|
|
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
|
|
->inject('response')
|
|
->inject('dbForProject')
|
|
->action(function (array $queries, string $search, Response $response, Database $dbForProject) {
|
|
|
|
$queries = Query::parseQueries($queries);
|
|
|
|
if (!empty($search)) {
|
|
$queries[] = Query::search('search', $search);
|
|
}
|
|
|
|
// Get cursor document if there was a cursor query
|
|
$cursor = Query::getByType($queries, Query::TYPE_CURSORAFTER, Query::TYPE_CURSORBEFORE);
|
|
$cursor = reset($cursor);
|
|
if ($cursor) {
|
|
/** @var Query $cursor */
|
|
$destinationId = $cursor->getValue();
|
|
$cursorDocument = $dbForProject->getDocument('destinations', $destinationId);
|
|
|
|
if ($cursorDocument->isEmpty()) {
|
|
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Source '{$destinationId}' for the 'cursor' value not found.");
|
|
}
|
|
|
|
$cursor->setValue($cursorDocument);
|
|
}
|
|
|
|
$filterQueries = Query::groupByType($queries)['filters'];
|
|
|
|
$response->dynamic(new Document([
|
|
'destinations' => $dbForProject->find('destinations', $queries),
|
|
'total' => $dbForProject->count('destinations', $filterQueries, APP_LIMIT_COUNT),
|
|
]), Response::MODEL_DESTINATION_LIST);
|
|
});
|
|
|
|
App::get('/v1/transfers/destination/:destinationId')
|
|
->groups(['api', 'transfers'])
|
|
->desc('Get Destination')
|
|
->label('scope', 'transfers.read')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'getDestination')
|
|
->label('sdk.description', '/docs/references/transfers/get-destination.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
|
->label('sdk.response.model', Response::MODEL_DESTINATION)
|
|
->param('destinationId', '', new UID(), 'Destination unique ID.')
|
|
->inject('response')
|
|
->inject('dbForProject')
|
|
->action(function (string $desinationId, Response $response, Database $dbForProject) {
|
|
$destination = $dbForProject->getDocument('destinations', $desinationId);
|
|
|
|
if ($destination->isEmpty()) {
|
|
throw new Exception(Exception::TRANSFER_DESTINATION_NOT_FOUND, 'Destination not found', 404);
|
|
}
|
|
|
|
$response->dynamic($destination, Response::MODEL_DESTINATION);
|
|
});
|
|
|
|
App::post('/v1/transfers/destination/:destinationId/validate')
|
|
->groups(['api', 'transfers'])
|
|
->desc('Validate Destination')
|
|
->label('scope', 'transfers.write')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'validateDestination')
|
|
->label('sdk.description', '/docs/references/transfers/validate-destination.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
|
->label('sdk.response.model', Response::MODEL_DESTINATION_VALIDATION)
|
|
->param('destinationId', '', new UID(), 'Destination unique ID.')
|
|
->param('resources', TRANSFER_RESOURCES, new ArrayList(new WhiteList(TRANSFER_RESOURCES)), 'List of resources to test. If none are sent then all resources are tested. [A list of resources can be found here.](https://appwrite.io/docs/transfers#resources)', true)
|
|
->inject('response')
|
|
->inject('dbForProject')
|
|
->action(function (string $destinationId, array $resources, Response $response, Database $dbForProject) {
|
|
$destination = $dbForProject->getDocument('destinations', $destinationId);
|
|
|
|
if ($destination->isEmpty()) {
|
|
throw new Exception(Exception::TRANSFER_DESTINATION_NOT_FOUND, 'Destination not found', 404);
|
|
}
|
|
|
|
$authData = json_decode($destination->getAttribute('data', "{}"), true);
|
|
|
|
try {
|
|
$testAdapter = null;
|
|
|
|
switch ($destination['type']) {
|
|
case 'appwrite': {
|
|
$testAdapter = new Appwrite($authData['projectId'], $authData['endpoint'], $authData['key']);
|
|
break;
|
|
}
|
|
default: {
|
|
throw new Exception(Exception::TRANSFER_DESTINATION_NOT_FOUND, 'Destination not found', 404);
|
|
}
|
|
}
|
|
|
|
$result = $testAdapter->check($resources);
|
|
|
|
$result = array_filter($result, function ($value) {
|
|
return $value !== [];
|
|
});
|
|
|
|
if (count($result) == 0) {
|
|
$destination->setAttribute('lastCheck', json_encode([
|
|
'success' => true,
|
|
'message' => 'Destination is valid'
|
|
]));
|
|
|
|
return $response->dynamic(new Document([
|
|
'success' => true,
|
|
'message' => 'Destination is valid'
|
|
]), Response::MODEL_DESTINATION_VALIDATION);
|
|
} else {
|
|
$destination->setAttribute('lastCheck', json_encode([
|
|
'success' => false,
|
|
'message' => 'Missing Permissions',
|
|
'errors' => $result
|
|
]));
|
|
|
|
return $response->setStatusCode(401)->dynamic(new Document([
|
|
'success' => false,
|
|
'message' => 'Missing Permissions',
|
|
'errors' => $result
|
|
]), Response::MODEL_DESTINATION_VALIDATION);
|
|
}
|
|
} catch (Throwable $e) {
|
|
$destination->setAttribute('lastCheck', json_encode([
|
|
'success' => false,
|
|
'message' => 'Missing Permissions',
|
|
'errors' => [
|
|
'Databases' => [$e->getMessage()],
|
|
],
|
|
]));
|
|
|
|
return $response->setStatusCode(401)->dynamic(new Document([
|
|
'success' => false,
|
|
'message' => 'Missing Permissions',
|
|
'errors' => [
|
|
'Databases' => [$e->getMessage()],
|
|
],
|
|
]), Response::MODEL_DESTINATION_VALIDATION);
|
|
} finally {
|
|
$dbForProject->updateDocument('destinations', $destination->getId(), $destination);
|
|
}
|
|
});
|
|
|
|
App::delete('/v1/transfers/destinations/:destinationId')
|
|
->groups(['api', 'transfers'])
|
|
->desc('Delete Destination')
|
|
->label('scope', 'transfers.write')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'deleteDestination')
|
|
->label('sdk.description', '/docs/references/transfers/delete-destination.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
|
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
|
->label('sdk.response.model', Response::MODEL_NONE)
|
|
->param('destinationId', '', new UID(), 'Destination unique ID.')
|
|
->inject('response')
|
|
->inject('dbForProject')
|
|
->action(function (string $destinationId, Response $response, Database $dbForProject) {
|
|
$destination = $dbForProject->getDocument('destinations', $destinationId);
|
|
|
|
if ($destination->isEmpty()) {
|
|
throw new Exception(Exception::TRANSFER_DESTINATION_NOT_FOUND, 'Destination not found', 404);
|
|
}
|
|
|
|
$dbForProject->deleteDocument('destinations', $destination->getId());
|
|
|
|
$response->noContent();
|
|
});
|
|
|
|
App::post('/v1/transfers/sources/appwrite')
|
|
->groups(['api', 'transfers'])
|
|
->desc('Create Appwrite Source')
|
|
->label('scope', 'transfers.write')
|
|
->label('event', 'transfers.[sourceId].createAppwriteSource')
|
|
->label('audits.event', 'transfers.createAppwriteSource')
|
|
->label('audits.resource', 'sources/{response.$id}')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'createAppwriteSource')
|
|
->label('sdk.description', '/docs/references/transfers/create-appwrite-source.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
|
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
|
->label('sdk.response.model', Response::MODEL_SOURCE)
|
|
->param('sourceId', 'unique()', new CustomId(), 'Source unique ID. Use \'unique()\' to auto generate a unique ID for this source.', true)
|
|
->param('name', '', new Text(256), 'Source Name. Max length: 256 chars.', true)
|
|
->param('projectId', '', new UID(), 'Source Project UID. The UID of the project to transfer.', false)
|
|
->param('endpoint', '', new URL(), 'Source Endpoint. The endpoint of the project to transfer.', false)
|
|
->param('key', '', new Text(100), 'Source Key. The key of the project to transfer.', false)
|
|
->inject('response')
|
|
->inject('dbForProject')
|
|
->inject('project')
|
|
->inject('user')
|
|
->inject('events')
|
|
->action(function (string $sourceId, string $name, string $projectId, string $endpoint, string $key, Response $response, Database $dbForProject, Document $project, Document $user, Event $eventsInstance) {
|
|
$sourceId = ($sourceId == 'unique()') ? ID::unique() : $sourceId;
|
|
|
|
$testAdapter = new SourcesAppwrite($projectId, $endpoint, $key);
|
|
$testAdapter->check(); // Throws exception on failure
|
|
|
|
$source = $dbForProject->createDocument('sources', new Document([
|
|
'$id' => $sourceId,
|
|
'$collection' => ID::custom('sources'),
|
|
'type' => 'appwrite',
|
|
'name' => empty($name) ? 'Appwrite Project: ' . $sourceId : $name,
|
|
'lastCheck' => json_encode([
|
|
'success' => true,
|
|
'message' => 'Source is valid'
|
|
]),
|
|
'data' => json_encode([
|
|
'projectId' => $projectId,
|
|
'endpoint' => $endpoint,
|
|
'key' => $key,
|
|
])
|
|
]));
|
|
|
|
$eventsInstance->setParam('sourceId', $source->getId());
|
|
|
|
$response
|
|
->setStatusCode(Response::STATUS_CODE_CREATED)
|
|
->dynamic($source, Response::MODEL_SOURCE);
|
|
});
|
|
|
|
App::post('/v1/transfers/sources/appwrite/validate')
|
|
->groups(['api', 'transfers'])
|
|
->desc('Validate Appwrite Source')
|
|
->label('scope', 'transfers.write')
|
|
->label('audits.resource', 'sources/{response.$id}')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'validateAppwriteSource')
|
|
->label('sdk.description', '/docs/references/transfers/validate-appwrite-source.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
|
->label('sdk.response.model', Response::MODEL_SOURCE_VALIDATION)
|
|
->param('projectId', '', new UID(), 'Source Project UID. The UID of the project to transfer.', false)
|
|
->param('endpoint', '', new URL(), 'Source Endpoint. The endpoint of the project to transfer.', false)
|
|
->param('key', '', new Text(100), 'Source Key. The key of the project to transfer.', false)
|
|
->inject('response')
|
|
->action(function (string $projectId, string $endpoint, string $key, Response $response) {
|
|
$testAdapter = new SourcesAppwrite($projectId, $endpoint, $key);
|
|
try {
|
|
$testAdapter->check(); // Throws exception on failure
|
|
} catch (Exception $e) {
|
|
return $response->setStatusCode(401)->dynamic(new Document([
|
|
'success' => false,
|
|
'message' => 'Missing Permissions',
|
|
'errors' => [
|
|
'Databases' => [$e->getMessage()],
|
|
],
|
|
]), Response::MODEL_DESTINATION_VALIDATION);
|
|
}
|
|
|
|
|
|
|
|
return $response->json(TRANSFER_RESOURCES);
|
|
});
|
|
|
|
App::post('/v1/transfers/sources/firebase')
|
|
->groups(['api', 'transfers'])
|
|
->desc('Create Firebase Source')
|
|
->label('scope', 'transfers.write')
|
|
->label('event', 'transfers.[sourceId].createFirebaseSource')
|
|
->label('audits.event', 'transfers.createFirebaseSource')
|
|
->label('audits.resource', 'sources/{response.$id}')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'createFirebaseSource')
|
|
->label('sdk.description', '/docs/references/transfers/create-firebase-source.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
|
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
|
->label('sdk.response.model', Response::MODEL_SOURCE)
|
|
->param('sourceId', 'unique()', new CustomId(), 'Source unique ID. Use \'unique()\' to auto generate a unique ID for this source.', true)
|
|
->param('name', '', new Text(256), 'Source Name. Max length: 256 chars.', true)
|
|
->param('serviceAccount', '', new JSON(), 'Firebase Service account with all required scopes, [Learn more about Firebase Transfer](https://appwrite.io/docs/transfers/sources#firebase)', false)
|
|
->inject('response')
|
|
->inject('dbForProject')
|
|
->inject('project')
|
|
->inject('user')
|
|
->inject('events')
|
|
->action(function (string $sourceId, string $name, array $serviceAccount, Response $response, Database $dbForProject, Document $project, Document $user, Event $eventsInstance) {
|
|
$sourceId = ($sourceId == 'unique()') ? ID::unique() : $sourceId;
|
|
|
|
$testAdapter = new Firebase($serviceAccount, Firebase::AUTH_SERVICEACCOUNT);
|
|
$testAdapter->check(); // Throws exception on failure
|
|
|
|
$source = $dbForProject->createDocument('sources', new Document([
|
|
'$id' => $sourceId,
|
|
'$collection' => ID::custom('sources'),
|
|
'type' => 'firebase',
|
|
'name' => empty($name) ? 'Firebase Project ' . $serviceAccount['project_id'] : $name,
|
|
'lastCheck' => json_encode([
|
|
'success' => true,
|
|
'message' => 'Source is valid'
|
|
]),
|
|
'data' => json_encode([
|
|
'serviceAccount' => $serviceAccount,
|
|
])
|
|
]));
|
|
|
|
$eventsInstance->setParam('sourceId', $source->getId());
|
|
|
|
$response
|
|
->setStatusCode(Response::STATUS_CODE_CREATED)
|
|
->dynamic($source, Response::MODEL_SOURCE);
|
|
});
|
|
|
|
App::post('/v1/transfers/sources/firebase/validate')
|
|
->groups(['api', 'transfers'])
|
|
->desc('Validate Firebase Source')
|
|
->label('scope', 'transfers.write')
|
|
->label('audits.resource', 'sources/{response.$id}')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'validateFirebaseSource')
|
|
->label('sdk.description', '/docs/references/transfers/validate-firebase-source.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
|
->label('sdk.response.model', Response::MODEL_SOURCE_VALIDATION)
|
|
->param('serviceAccount', '', new JSON(), 'Firebase Service account with all required scopes, [Learn more about Firebase Transfer](https://appwrite.io/docs/transfers/sources#firebase)', false)
|
|
->inject('response')
|
|
->inject('events')
|
|
->action(function (string $serviceAccount, Response $response, Event $eventsInstance) {
|
|
$testAdapter = new Firebase(json_decode($serviceAccount, true), Firebase::AUTH_SERVICEACCOUNT);
|
|
try {
|
|
$testAdapter->check(); // Throws exception on failure
|
|
} catch (Exception $e) {
|
|
throw new Exception($e->getMessage(), 400);
|
|
}
|
|
|
|
$response->noContent();
|
|
});
|
|
|
|
App::post('/v1/transfers/sources/supabase')
|
|
->groups(['api', 'transfers'])
|
|
->desc('Create Supabase Source')
|
|
->label('scope', 'transfers.write')
|
|
->label('event', 'transfers.[sourceId].createSupabaseSource')
|
|
->label('audits.event', 'transfers.createSupabaseSource')
|
|
->label('audits.resource', 'sources/{response.$id}')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'createSupabaseSource')
|
|
->label('sdk.description', '/docs/references/transfers/create-supabase-source.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
|
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
|
->label('sdk.response.model', Response::MODEL_SOURCE)
|
|
->param('sourceId', 'unique()', new CustomId(), 'Source unique ID. Use \'unique()\' to auto generate a unique ID for this source.', true)
|
|
->param('name', '', new Text(256), 'Source Name. Max length: 256 chars.', true)
|
|
->param('host', '', new Text(100), 'Supabase Database Host. The host of the project to transfer.', false)
|
|
->param('database', 'postgres', new Text(100), 'Supabase Database Name. The name of the database to transfer.', true)
|
|
->param('username', 'postgres', new Text(100), 'Supabase Database Username. The username of the database to transfer.', true)
|
|
->param('password', '', new Text(100), 'Supabase Database Password. The password of the database to transfer.', false)
|
|
->param('port', '5432', new Integer(true), 'Supabase Database Port. The port of the database to transfer.', true)
|
|
->inject('response')
|
|
->inject('dbForProject')
|
|
->inject('project')
|
|
->inject('user')
|
|
->inject('events')
|
|
->action(function (string $sourceId, string $name, string $url, string $database, string $username, string $password, string $port, Response $response, Database $dbForProject, Document $project, Document $user, Event $eventsInstance) {
|
|
$sourceId = ($sourceId == 'unique()') ? ID::unique() : $sourceId;
|
|
|
|
$testAdapter = new Supabase($url, $database, $username, $password, intval($port));
|
|
$testAdapter->check(); // Throws exception on failure
|
|
|
|
$source = $dbForProject->createDocument('sources', new Document([
|
|
'$id' => $sourceId,
|
|
'$collection' => ID::custom('sources'),
|
|
'type' => 'supabase',
|
|
'name' => empty($name) ? 'Supabase Project ' . $sourceId : $name,
|
|
'lastCheck' => json_encode([
|
|
'success' => true,
|
|
'message' => 'Source is valid'
|
|
]),
|
|
'data' => json_encode([
|
|
'url' => $url,
|
|
'database' => $database,
|
|
'username' => $username,
|
|
'password' => $password,
|
|
'port' => intval($port),
|
|
])
|
|
]));
|
|
|
|
$eventsInstance->setParam('sourceId', $source->getId());
|
|
|
|
$response
|
|
->setStatusCode(Response::STATUS_CODE_CREATED)
|
|
->dynamic($source, Response::MODEL_SOURCE);
|
|
});
|
|
|
|
App::post('/v1/transfers/sources/supabase/validate')
|
|
->groups(['api', 'transfers'])
|
|
->desc('Validate Supabase Source')
|
|
->label('scope', 'transfers.write')
|
|
->label('audits.resource', 'sources/{response.$id}')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'validateSupabaseSource')
|
|
->label('sdk.description', '/docs/references/transfers/validate-supabase-source.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
|
->label('sdk.response.model', Response::MODEL_SOURCE_VALIDATION)
|
|
->param('host', '', new Text(100), 'Supabase Database Host. The host of the project to transfer.', false)
|
|
->param('database', 'postgres', new Text(100), 'Supabase Database Name. The name of the database to transfer.', true)
|
|
->param('username', 'postgres', new Text(100), 'Supabase Database Username. The username of the database to transfer.', true)
|
|
->param('password', '', new Text(100), 'Supabase Database Password. The password of the database to transfer.', false)
|
|
->param('port', '5432', new Integer(true), 'Supabase Database Port. The port of the database to transfer.', true)
|
|
->inject('response')
|
|
->action(function (string $host, string $database, string $username, string $password, string $port, Response $response) {
|
|
$testAdapter = new Supabase($host, $database, $username, $password, $port);
|
|
|
|
$result = $testAdapter->check();
|
|
|
|
$result = array_filter($result, function ($value) {
|
|
return $value !== [];
|
|
});
|
|
|
|
if (count($result) == 0) {
|
|
return $response->dynamic(new Document([
|
|
'success' => true,
|
|
'message' => 'Source is valid',
|
|
'errors' => $result
|
|
]), Response::MODEL_SOURCE_VALIDATION);
|
|
} else {
|
|
return $response->setStatusCode(401)->dynamic(new Document([
|
|
'success' => false,
|
|
'message' => 'Missing Permissions',
|
|
'errors' => $result
|
|
]), Response::MODEL_SOURCE_VALIDATION);
|
|
}
|
|
});
|
|
|
|
App::post('/v1/transfers/sources/nhost')
|
|
->groups(['api', 'transfers'])
|
|
->desc('Create Nhost Source')
|
|
->label('scope', 'transfers.write')
|
|
->label('event', 'transfers.[sourceId].createNhostSource')
|
|
->label('audits.event', 'transfers.createNhostSource')
|
|
->label('audits.resource', 'sources/{response.$id}')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'createNhostSource')
|
|
->label('sdk.description', '/docs/references/transfers/create-nhost-source.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
|
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
|
->label('sdk.response.model', Response::MODEL_SOURCE)
|
|
->param('sourceId', 'unique()', new CustomId(), 'Source unique ID. Use \'unique()\' to auto generate a unique ID for this source.', true)
|
|
->param('name', '', new Text(256), 'Source Name. Max length: 256 chars.', true)
|
|
->param('host', '', new Text(100), 'Nhost Database Host. The host of the project to transfer.', false)
|
|
->param('database', 'postgres', new Text(100), 'Nhost Database Name. The name of the database to transfer.', true)
|
|
->param('username', 'postgres', new Text(100), 'Nhost Database Username. The username of the database to transfer.', true)
|
|
->param('password', '', new Text(100), 'Nhost Database Password. The password of the database to transfer.', false)
|
|
->param('port', '5432', new Integer(true), 'Nhost Database Port. The port of the database to transfer.', true)
|
|
->inject('response')
|
|
->inject('dbForProject')
|
|
->inject('project')
|
|
->inject('user')
|
|
->inject('events')
|
|
->action(function (string $sourceId, string $name, string $url, string $database, string $username, string $password, int $port, Response $response, Database $dbForProject, Document $project, Document $user, Event $eventsInstance) {
|
|
$sourceId = ($sourceId == 'unique()') ? ID::unique() : $sourceId;
|
|
|
|
$testAdapter = new NHost($url, $database, $username, $password, $port);
|
|
$testAdapter->check(); // Throws exception on failure
|
|
|
|
$source = $dbForProject->createDocument('sources', new Document([
|
|
'$id' => $sourceId,
|
|
'$collection' => ID::custom('sources'),
|
|
'type' => 'nhost',
|
|
'name' => empty($name) ? 'Nhost Project ' . $sourceId : $name,
|
|
'lastCheck' => json_encode([
|
|
'success' => true,
|
|
'message' => 'Source is valid'
|
|
]),
|
|
'data' => json_encode([
|
|
'url' => $url,
|
|
'database' => $database,
|
|
'username' => $username,
|
|
'password' => $password,
|
|
'port' => $port,
|
|
])
|
|
]));
|
|
|
|
$eventsInstance->setParam('sourceId', $source->getId());
|
|
|
|
$response
|
|
->setStatusCode(Response::STATUS_CODE_CREATED)
|
|
->dynamic($source, Response::MODEL_SOURCE);
|
|
});
|
|
|
|
App::post('/v1/transfers/sources/nhost/validate')
|
|
->groups(['api', 'transfers'])
|
|
->desc('Validate Nhost Source')
|
|
->label('scope', 'transfers.write')
|
|
->label('audits.resource', 'sources/{response.$id}')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'validateNhostSource')
|
|
->label('sdk.description', '/docs/references/transfers/validate-nhost-source.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
|
->label('sdk.response.model', Response::MODEL_SOURCE_VALIDATION)
|
|
->param('host', '', new Text(100), 'Nhost Database Host. The host of the project to validate.', false)
|
|
->param('database', 'postgres', new Text(100), 'Nhost Database Name. The name of the database to validate.', true)
|
|
->param('username', 'postgres', new Text(100), 'Nhost Database Username. The username of the database to validate.', true)
|
|
->param('password', '', new Text(100), 'Nhost Database Password. The password of the database to validate.', false)
|
|
->param('port', '5432', new Integer(true), 'Nhost Database Port. The port of the database to validate.', true)
|
|
->inject('response')
|
|
->action(function (string $url, string $database, string $username, string $password, string $port, Response $response) {
|
|
try {
|
|
$testAdapter = new NHost($url, $database, $username, $password, $port);
|
|
} catch (Throwable $e) {
|
|
return $response->setStatusCode(401)->dynamic(new Document([
|
|
'success' => false,
|
|
'message' => 'Invalid Nhost Source',
|
|
'errors' => [
|
|
'Databases' => [$e->getMessage()],
|
|
]
|
|
]), Response::MODEL_SOURCE_VALIDATION);
|
|
};
|
|
|
|
$result = $testAdapter->check();
|
|
|
|
$result = array_filter($result, function ($value) {
|
|
return $value !== [];
|
|
});
|
|
|
|
if (count($result) == 0) {
|
|
return $response->dynamic(new Document([
|
|
'success' => true,
|
|
'message' => 'Source is valid',
|
|
'errors' => $result
|
|
]), Response::MODEL_SOURCE_VALIDATION);
|
|
} else {
|
|
return $response->setStatusCode(401)->dynamic(new Document([
|
|
'success' => false,
|
|
'message' => 'Missing Permissions',
|
|
'errors' => $result
|
|
]), Response::MODEL_SOURCE_VALIDATION);
|
|
}
|
|
});
|
|
|
|
App::post('/v1/transfers/destinations/appwrite')
|
|
->groups(['api', 'transfers'])
|
|
->desc('Create Appwrite Transfer Destination')
|
|
->label('scope', 'transfers.write')
|
|
->label('event', 'transfers.[sourceId].createAppwriteDestination')
|
|
->label('audits.event', 'transfers.createAppwriteDestination')
|
|
->label('audits.resource', 'sources/{response.$id}')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'createAppwriteDestination')
|
|
->label('sdk.description', '/docs/references/transfers/create-appwrite-source.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
|
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
|
->label('sdk.response.model', Response::MODEL_DESTINATION)
|
|
->param('destinationId', 'unique()', new CustomId(), 'Destination unique ID. Use \'unique()\' to auto generate a unique ID for this source.', true)
|
|
->param('name', '', new Text(256), 'Destination Name. Max length: 256 chars.', true)
|
|
->param('projectId', '', new UID(), 'Destination Project UID. The UID of the project to transfer.', false)
|
|
->param('endpoint', '', new URL(), 'Destination Endpoint. The endpoint of the project to transfer.', false)
|
|
->param('key', '', new Text(1024), 'Destination Key. The key of the project to transfer.', false)
|
|
->inject('response')
|
|
->inject('dbForProject')
|
|
->inject('project')
|
|
->inject('user')
|
|
->inject('events')
|
|
->action(function (string $destinationId, string $name, string $projectId, string $endpoint, string $key, Response $response, Database $dbForProject, Document $project, Document $user, Event $eventsInstance) {
|
|
$destinationId = ($destinationId == 'unique()') ? ID::unique() : $destinationId;
|
|
|
|
$testAdapter = new Appwrite($projectId, $endpoint, $key);
|
|
$result = $testAdapter->check();
|
|
|
|
$result = array_filter($result, function ($value) {
|
|
return $value !== [];
|
|
});
|
|
|
|
if (count($result) > 0) {
|
|
throw new Exception('Missing Permissions', 401);
|
|
}
|
|
|
|
$destination = $dbForProject->createDocument('destinations', new Document([
|
|
'$id' => $destinationId,
|
|
'$collection' => ID::custom('destinations'),
|
|
'type' => 'appwrite',
|
|
'name' => empty($name) ? 'Appwrite Project ' . $destinationId : $name,
|
|
'lastCheck' => json_encode([
|
|
'success' => true,
|
|
'message' => 'Source is valid'
|
|
]),
|
|
'data' => json_encode([
|
|
'projectId' => $projectId,
|
|
'endpoint' => $endpoint,
|
|
'key' => $key,
|
|
])
|
|
]));
|
|
|
|
$eventsInstance->setParam('desinationId', $destination->getId());
|
|
|
|
$response
|
|
->setStatusCode(Response::STATUS_CODE_CREATED)
|
|
->dynamic($destination, Response::MODEL_DESTINATION);
|
|
});
|
|
|
|
App::post('/v1/transfers/destinations/appwrite/validate')
|
|
->groups(['api', 'transfers'])
|
|
->desc('Validate Appwrite Destination')
|
|
->label('scope', 'transfers.write')
|
|
->label('audits.resource', 'sources/{response.$id}')
|
|
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
|
|
->label('sdk.namespace', 'transfers')
|
|
->label('sdk.method', 'validateAppwriteDestination')
|
|
->label('sdk.description', '/docs/references/transfers/validate-appwrite-destination.md')
|
|
->label('sdk.response.code', Response::STATUS_CODE_OK)
|
|
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
|
|
->label('sdk.response.model', Response::MODEL_DESTINATION_VALIDATION)
|
|
->param('projectId', '', new UID(), 'Destination Project UID. The UID of the project to transfer.', false)
|
|
->param('endpoint', '', new URL(), 'Destination Endpoint. The endpoint of the project to transfer.', false)
|
|
->param('key', '', new Text(1024), 'Destination Key. The key of the project to transfer.', false)
|
|
->inject('response')
|
|
->action(function (string $projectId, string $endpoint, string $key, Response $response) {
|
|
$testAdapter = new Appwrite($projectId, $endpoint, $key);
|
|
|
|
$result = $testAdapter->check();
|
|
|
|
$result = array_filter($result, function ($value) {
|
|
return $value !== [];
|
|
});
|
|
|
|
if (count($result) == 0) {
|
|
return $response->dynamic(new Document([
|
|
'success' => true,
|
|
'message' => 'Destination is valid',
|
|
'errors' => $result
|
|
]), Response::MODEL_DESTINATION_VALIDATION);
|
|
} else {
|
|
return $response->setStatusCode(401)->dynamic(new Document([
|
|
'success' => false,
|
|
'message' => 'Missing Permissions',
|
|
'errors' => $result
|
|
]), Response::MODEL_DESTINATION_VALIDATION);
|
|
}
|
|
});
|