mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Merge branch '1.9.x' into add-codex-plugin
This commit is contained in:
@@ -37,6 +37,13 @@ class Authentik extends OAuth2
|
||||
return 'authentik';
|
||||
}
|
||||
|
||||
public function verifyCredentials(): void
|
||||
{
|
||||
if (empty($this->getAuthentikDomain())) {
|
||||
throw new \Exception('Authentik endpoint is required.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
||||
@@ -37,6 +37,13 @@ class FusionAuth extends OAuth2
|
||||
return 'fusionauth';
|
||||
}
|
||||
|
||||
public function verifyCredentials(): void
|
||||
{
|
||||
if (empty($this->getFusionAuthDomain())) {
|
||||
throw new \Exception('FusionAuth endpoint is required.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
||||
@@ -37,6 +37,17 @@ class Keycloak extends OAuth2
|
||||
return 'keycloak';
|
||||
}
|
||||
|
||||
public function verifyCredentials(): void
|
||||
{
|
||||
if (empty($this->getKeycloakDomain())) {
|
||||
throw new \Exception('Keycloak endpoint is required.');
|
||||
}
|
||||
|
||||
if (empty($this->getKeycloakRealm())) {
|
||||
throw new \Exception('Keycloak realm name is required.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
|
||||
@@ -36,6 +36,13 @@ class Microsoft extends OAuth2
|
||||
return 'microsoft';
|
||||
}
|
||||
|
||||
public function verifyCredentials(): void
|
||||
{
|
||||
if (empty($this->getTenantID())) {
|
||||
throw new \Exception('Microsoft tenant is required.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
@@ -201,7 +208,7 @@ class Microsoft extends OAuth2
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts the Tenant Id from the JSON stored in appSecret. Defaults to 'common' as a fallback
|
||||
* Extracts the Tenant Id from the JSON stored in appSecret.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -209,6 +216,6 @@ class Microsoft extends OAuth2
|
||||
{
|
||||
$secret = $this->getAppSecret();
|
||||
|
||||
return $secret['tenantID'] ?? 'common';
|
||||
return $secret['tenantID'] ?? '';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,146 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Event;
|
||||
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Queue\Publisher;
|
||||
use Utopia\System\System;
|
||||
|
||||
class Build extends Event
|
||||
{
|
||||
protected string $type = '';
|
||||
protected ?Document $resource = null;
|
||||
protected ?Document $deployment = null;
|
||||
protected ?Document $template = null;
|
||||
|
||||
public function __construct(protected Publisher $publisher)
|
||||
{
|
||||
parent::__construct($publisher);
|
||||
|
||||
$this
|
||||
->setQueue(System::getEnv('_APP_BUILDS_QUEUE_NAME', Event::BUILDS_QUEUE_NAME))
|
||||
->setClass(System::getEnv('_APP_BUILDS_CLASS_NAME', Event::BUILDS_CLASS_NAME));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets template for the build event.
|
||||
*
|
||||
* @param Document $template
|
||||
* @return self
|
||||
*/
|
||||
public function setTemplate(Document $template): self
|
||||
{
|
||||
$this->template = $template;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets resource document for the build event.
|
||||
*
|
||||
* @param Document $resource
|
||||
* @return self
|
||||
*/
|
||||
public function setResource(Document $resource): self
|
||||
{
|
||||
$this->resource = $resource;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns set resource document for the build event.
|
||||
*
|
||||
* @return null|Document
|
||||
*/
|
||||
public function getResource(): ?Document
|
||||
{
|
||||
return $this->resource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets deployment for the build event.
|
||||
*
|
||||
* @param Document $deployment
|
||||
* @return self
|
||||
*/
|
||||
public function setDeployment(Document $deployment): self
|
||||
{
|
||||
$this->deployment = $deployment;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns set deployment for the build event.
|
||||
*
|
||||
* @return null|Document
|
||||
*/
|
||||
public function getDeployment(): ?Document
|
||||
{
|
||||
return $this->deployment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets type for the build event.
|
||||
*
|
||||
* @param string $type Can be `BUILD_TYPE_DEPLOYMENT` or `BUILD_TYPE_RETRY`.
|
||||
* @return self
|
||||
*/
|
||||
public function setType(string $type): self
|
||||
{
|
||||
$this->type = $type;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns set type for the function event.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType(): string
|
||||
{
|
||||
return $this->type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepare payload for queue.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function preparePayload(): array
|
||||
{
|
||||
$platform = $this->platform;
|
||||
if (empty($platform)) {
|
||||
$platform = Config::getParam('platform', []);
|
||||
}
|
||||
|
||||
return [
|
||||
'project' => $this->project,
|
||||
'resource' => $this->resource,
|
||||
'deployment' => $this->deployment,
|
||||
'type' => $this->type,
|
||||
'template' => $this->template,
|
||||
'platform' => $platform,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Resets event.
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function reset(): self
|
||||
{
|
||||
$this->type = '';
|
||||
$this->resource = null;
|
||||
$this->deployment = null;
|
||||
$this->template = null;
|
||||
$this->platform = [];
|
||||
parent::reset();
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Event\Message;
|
||||
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Document;
|
||||
|
||||
final class Build extends Base
|
||||
{
|
||||
public function __construct(
|
||||
public readonly Document $project,
|
||||
public readonly Document $resource,
|
||||
public readonly Document $deployment,
|
||||
public readonly string $type,
|
||||
public readonly ?Document $template = null,
|
||||
public readonly array $platform = [],
|
||||
) {
|
||||
}
|
||||
|
||||
public function toArray(): array
|
||||
{
|
||||
$platform = !empty($this->platform) ? $this->platform : Config::getParam('platform', []);
|
||||
|
||||
return [
|
||||
'project' => $this->project->getArrayCopy(),
|
||||
'resource' => $this->resource->getArrayCopy(),
|
||||
'deployment' => $this->deployment->getArrayCopy(),
|
||||
'type' => $this->type,
|
||||
'template' => $this->template?->getArrayCopy(),
|
||||
'platform' => $platform,
|
||||
];
|
||||
}
|
||||
|
||||
public static function fromArray(array $data): static
|
||||
{
|
||||
return new self(
|
||||
project: new Document($data['project'] ?? []),
|
||||
resource: new Document($data['resource'] ?? []),
|
||||
deployment: new Document($data['deployment'] ?? []),
|
||||
type: $data['type'] ?? '',
|
||||
template: !empty($data['template']) ? new Document($data['template']) : null,
|
||||
platform: $data['platform'] ?? [],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Event\Publisher;
|
||||
|
||||
use Appwrite\Event\Message\Build as BuildMessage;
|
||||
use Utopia\Queue\Publisher;
|
||||
use Utopia\Queue\Queue;
|
||||
|
||||
readonly class Build extends Base
|
||||
{
|
||||
public function __construct(
|
||||
Publisher $publisher,
|
||||
protected Queue $queue
|
||||
) {
|
||||
parent::__construct($publisher);
|
||||
}
|
||||
|
||||
public function enqueue(BuildMessage $message, ?Queue $queue = null): string|bool
|
||||
{
|
||||
return $this->publish($queue ?? $this->queue, $message);
|
||||
}
|
||||
|
||||
public function getSize(bool $failed = false, ?Queue $queue = null): int
|
||||
{
|
||||
return $this->getQueueSize($queue ?? $this->queue, $failed);
|
||||
}
|
||||
}
|
||||
@@ -178,6 +178,7 @@ class Exception extends \Exception
|
||||
public const string FUNCTION_RUNTIME_UNSUPPORTED = 'function_runtime_unsupported';
|
||||
public const string FUNCTION_ENTRYPOINT_MISSING = 'function_entrypoint_missing';
|
||||
public const string FUNCTION_SYNCHRONOUS_TIMEOUT = 'function_synchronous_timeout';
|
||||
public const string FUNCTION_ASYNCHRONOUS_TIMEOUT = 'function_asynchronous_timeout';
|
||||
public const string FUNCTION_TEMPLATE_NOT_FOUND = 'function_template_not_found';
|
||||
public const string FUNCTION_RUNTIME_NOT_DETECTED = 'function_runtime_not_detected';
|
||||
public const string FUNCTION_EXECUTE_PERMISSION_MISSING = 'function_execute_permission_missing';
|
||||
@@ -192,6 +193,7 @@ class Exception extends \Exception
|
||||
public const string BUILD_ALREADY_COMPLETED = 'build_already_completed';
|
||||
public const string BUILD_CANCELED = 'build_canceled';
|
||||
public const string BUILD_FAILED = 'build_failed';
|
||||
public const string BUILD_TIMEOUT = 'build_timeout';
|
||||
|
||||
/** Execution */
|
||||
public const string EXECUTION_NOT_FOUND = 'execution_not_found';
|
||||
@@ -346,6 +348,10 @@ class Exception extends \Exception
|
||||
public const string MIGRATION_IN_PROGRESS = 'migration_in_progress';
|
||||
public const string MIGRATION_PROVIDER_ERROR = 'migration_provider_error';
|
||||
public const string MIGRATION_DATABASE_TYPE_UNSUPPORTED = 'migration_database_type_unsupported';
|
||||
public const string MIGRATION_SOURCE_PROJECT_ID_REQUIRED = 'migration_source_project_id_required';
|
||||
public const string MIGRATION_SOURCE_PROJECT_NOT_FOUND = 'migration_source_project_not_found';
|
||||
public const string MIGRATION_SOURCE_TYPE_INVALID = 'migration_source_type_invalid';
|
||||
public const string MIGRATION_DESTINATION_TYPE_INVALID = 'migration_destination_type_invalid';
|
||||
|
||||
/** Realtime */
|
||||
public const string REALTIME_MESSAGE_FORMAT_INVALID = 'realtime_message_format_invalid';
|
||||
|
||||
@@ -96,6 +96,7 @@ abstract class Migration
|
||||
'1.9.1' => 'V24',
|
||||
'1.9.2' => 'V24',
|
||||
'1.9.3' => 'V24',
|
||||
'1.9.4' => 'V24',
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
|
||||
namespace Appwrite\Platform\Modules\Compute;
|
||||
|
||||
use Appwrite\Event\Build;
|
||||
use Appwrite\Event\Message\Build as BuildMessage;
|
||||
use Appwrite\Event\Publisher\Build as BuildPublisher;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Filter\BranchDomain as BranchDomainFilter;
|
||||
use Appwrite\Platform\Action;
|
||||
@@ -57,7 +58,7 @@ class Base extends Action
|
||||
return $allowedSpecifications[0] ?? APP_COMPUTE_SPECIFICATION_DEFAULT;
|
||||
}
|
||||
|
||||
public function redeployVcsFunction(Request $request, Document $function, Document $project, Document $installation, Database $dbForProject, Build $queueForBuilds, Document $template, GitHub $github, bool $activate, string $referenceType = 'branch', string $reference = ''): Document
|
||||
public function redeployVcsFunction(Request $request, Document $function, Document $project, Document $installation, Database $dbForProject, BuildPublisher $publisherForBuilds, Document $template, GitHub $github, bool $activate, array $platform = [], string $referenceType = 'branch', string $reference = ''): Document
|
||||
{
|
||||
$deploymentId = ID::unique();
|
||||
$entrypoint = $function->getAttribute('entrypoint', '');
|
||||
@@ -150,16 +151,19 @@ class Base extends Action
|
||||
'latestDeploymentStatus' => $deployment->getAttribute('status', ''),
|
||||
]));
|
||||
|
||||
$queueForBuilds
|
||||
->setType(BUILD_TYPE_DEPLOYMENT)
|
||||
->setResource($function)
|
||||
->setDeployment($deployment)
|
||||
->setTemplate($template);
|
||||
$publisherForBuilds->enqueue(new BuildMessage(
|
||||
project: $project,
|
||||
resource: $function,
|
||||
deployment: $deployment,
|
||||
type: BUILD_TYPE_DEPLOYMENT,
|
||||
template: $template,
|
||||
platform: $platform,
|
||||
));
|
||||
|
||||
return $deployment;
|
||||
}
|
||||
|
||||
public function redeployVcsSite(Request $request, Document $site, Document $project, Document $installation, Database $dbForProject, Database $dbForPlatform, Build $queueForBuilds, Document $template, GitHub $github, bool $activate, Authorization $authorization, array $platform, string $referenceType = 'branch', string $reference = ''): Document
|
||||
public function redeployVcsSite(Request $request, Document $site, Document $project, Document $installation, Database $dbForProject, Database $dbForPlatform, BuildPublisher $publisherForBuilds, Document $template, GitHub $github, bool $activate, Authorization $authorization, array $platform, string $referenceType = 'branch', string $reference = ''): Document
|
||||
{
|
||||
$deploymentId = ID::unique();
|
||||
$providerInstallationId = $installation->getAttribute('providerInstallationId', '');
|
||||
@@ -358,11 +362,14 @@ class Base extends Action
|
||||
|
||||
$this->updateEmptyManualRule($project, $site, $deployment, $dbForPlatform, $authorization);
|
||||
|
||||
$queueForBuilds
|
||||
->setType(BUILD_TYPE_DEPLOYMENT)
|
||||
->setResource($site)
|
||||
->setDeployment($deployment)
|
||||
->setTemplate($template);
|
||||
$publisherForBuilds->enqueue(new BuildMessage(
|
||||
project: $project,
|
||||
resource: $site,
|
||||
deployment: $deployment,
|
||||
type: BUILD_TYPE_DEPLOYMENT,
|
||||
template: $template,
|
||||
platform: $platform,
|
||||
));
|
||||
|
||||
return $deployment;
|
||||
}
|
||||
|
||||
@@ -54,9 +54,9 @@ class XList extends Action
|
||||
$actions = OAuth2Base::getProviderActions();
|
||||
|
||||
$providers = [];
|
||||
foreach ($actions as $providerId => $updateClass) {
|
||||
$config = $providersConfig[$providerId] ?? null;
|
||||
if ($config === null) {
|
||||
foreach ($providersConfig as $providerId => $config) {
|
||||
$updateClass = $actions[$providerId] ?? null;
|
||||
if ($updateClass === null) {
|
||||
continue;
|
||||
}
|
||||
if (!($config['enabled'] ?? false)) {
|
||||
|
||||
@@ -18,21 +18,21 @@ class XList extends Action
|
||||
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'listKeyScopes';
|
||||
return 'listConsoleProjectScopes';
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_GET)
|
||||
->setHttpPath('/v1/console/scopes/key')
|
||||
->desc('List key scopes')
|
||||
->setHttpPath('/v1/console/scopes/project')
|
||||
->desc('List project scopes')
|
||||
->groups(['api'])
|
||||
->label('scope', 'public')
|
||||
->label('sdk', new Method(
|
||||
namespace: 'console',
|
||||
group: 'console',
|
||||
name: 'listKeyScopes',
|
||||
name: 'listProjectScopes',
|
||||
description: 'List all scopes available for project API keys, along with a description for each scope.',
|
||||
auth: [AuthType::ADMIN],
|
||||
responses: [
|
||||
@@ -56,6 +56,8 @@ class XList extends Action
|
||||
$scopes[] = new Document([
|
||||
'$id' => $scopeId,
|
||||
'description' => $scope['description'] ?? '',
|
||||
'category' => $scope['category'] ?? '',
|
||||
'deprecated' => $scope['deprecated'] ?? false,
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
+9
-3
@@ -241,6 +241,10 @@ abstract class Action extends UtopiaAction
|
||||
? UtopiaResponse::MODEL_ATTRIBUTE_INTEGER
|
||||
: UtopiaResponse::MODEL_COLUMN_INTEGER,
|
||||
|
||||
Database::VAR_BIGINT => $isCollections
|
||||
? UtopiaResponse::MODEL_ATTRIBUTE_BIGINT
|
||||
: UtopiaResponse::MODEL_COLUMN_BIGINT,
|
||||
|
||||
Database::VAR_FLOAT => $isCollections
|
||||
? UtopiaResponse::MODEL_ATTRIBUTE_FLOAT
|
||||
: UtopiaResponse::MODEL_COLUMN_FLOAT,
|
||||
@@ -540,6 +544,7 @@ abstract class Action extends UtopiaAction
|
||||
|
||||
switch ($attribute->getAttribute('format')) {
|
||||
case APP_DATABASE_ATTRIBUTE_INT_RANGE:
|
||||
case APP_DATABASE_ATTRIBUTE_BIGINT_RANGE:
|
||||
case APP_DATABASE_ATTRIBUTE_FLOAT_RANGE:
|
||||
$min ??= $attribute->getAttribute('formatOptions')['min'];
|
||||
$max ??= $attribute->getAttribute('formatOptions')['max'];
|
||||
@@ -548,14 +553,15 @@ abstract class Action extends UtopiaAction
|
||||
throw new Exception($this->getInvalidValueException(), 'Minimum value must be lesser than maximum value');
|
||||
}
|
||||
|
||||
if ($attribute->getAttribute('format') === APP_DATABASE_ATTRIBUTE_INT_RANGE) {
|
||||
$validator = new Range($min, $max, Database::VAR_INTEGER);
|
||||
} else {
|
||||
if ($attribute->getAttribute('format') === APP_DATABASE_ATTRIBUTE_FLOAT_RANGE) {
|
||||
$validator = new Range($min, $max, Database::VAR_FLOAT);
|
||||
|
||||
if (!is_null($default)) {
|
||||
$default = \floatval($default);
|
||||
}
|
||||
} else {
|
||||
// intRange and bigintRange share the same integer range semantics
|
||||
$validator = new Range($min, $max, Range::TYPE_INTEGER);
|
||||
}
|
||||
|
||||
if (!is_null($default) && !$validator->isValid($default)) {
|
||||
|
||||
+117
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\BigInt;
|
||||
|
||||
use Appwrite\Event\Database as EventDatabase;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Action;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Deprecated;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response as UtopiaResponse;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Database\Validator\Key;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Http\Adapter\Swoole\Response as SwooleResponse;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Integer;
|
||||
use Utopia\Validator\Nullable;
|
||||
use Utopia\Validator\Range;
|
||||
|
||||
class Create extends Action
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'createBigIntAttribute';
|
||||
}
|
||||
|
||||
protected function getResponseModel(): string|array
|
||||
{
|
||||
return UtopiaResponse::MODEL_ATTRIBUTE_BIGINT;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(self::HTTP_REQUEST_METHOD_POST)
|
||||
->setHttpPath('/v1/databases/:databaseId/collections/:collectionId/attributes/bigint')
|
||||
->desc('Create bigint attribute')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', 'collections.write')
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create')
|
||||
->label('audits.event', 'attribute.create')
|
||||
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
|
||||
->label('sdk', new Method(
|
||||
namespace: $this->getSDKNamespace(),
|
||||
group: $this->getSDKGroup(),
|
||||
name: self::getName(),
|
||||
description: '/docs/references/databases/create-bigint-attribute.md',
|
||||
auth: [AuthType::ADMIN, AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: SwooleResponse::STATUS_CODE_ACCEPTED,
|
||||
model: $this->getResponseModel(),
|
||||
)
|
||||
],
|
||||
deprecated: new Deprecated(
|
||||
since: '1.8.0',
|
||||
replaceWith: 'tablesDB.createBigIntColumn',
|
||||
),
|
||||
))
|
||||
->param('databaseId', '', fn (Database $dbForProject) => new UID($dbForProject->getAdapter()->getMaxUIDLength()), 'Database ID.', false, ['dbForProject'])
|
||||
->param('collectionId', '', fn (Database $dbForProject) => new UID($dbForProject->getAdapter()->getMaxUIDLength()), 'Collection ID.', false, ['dbForProject'])
|
||||
->param('key', '', fn (Database $dbForProject) => new Key(false, $dbForProject->getAdapter()->getMaxUIDLength()), 'Attribute Key.', false, ['dbForProject'])
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
->param('min', null, new Nullable(new Integer(false, 64)), 'Minimum value', true)
|
||||
->param('max', null, new Nullable(new Integer(false, 64)), 'Maximum value', true)
|
||||
->param('default', null, new Nullable(new Integer(false, 64)), 'Default value. Cannot be set when attribute is required.', true)
|
||||
->param('array', false, new Boolean(), 'Is attribute an array?', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForDatabase')
|
||||
->inject('queueForEvents')
|
||||
->inject('authorization')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?int $min, ?int $max, ?int $default, bool $array, UtopiaResponse $response, Database $dbForProject, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $authorization): void
|
||||
{
|
||||
$min ??= \PHP_INT_MIN;
|
||||
$max ??= \PHP_INT_MAX;
|
||||
|
||||
if ($min > $max) {
|
||||
throw new Exception($this->getInvalidValueException(), 'Minimum value must be lesser than maximum value');
|
||||
}
|
||||
|
||||
$validator = new Range($min, $max, Range::TYPE_INTEGER);
|
||||
if (!\is_null($default) && !$validator->isValid($default)) {
|
||||
throw new Exception($this->getInvalidValueException(), $validator->getDescription());
|
||||
}
|
||||
|
||||
$attribute = $this->createAttribute($databaseId, $collectionId, new Document([
|
||||
'key' => $key,
|
||||
'type' => Database::VAR_BIGINT,
|
||||
'size' => 8,
|
||||
'required' => $required,
|
||||
'default' => $default,
|
||||
'array' => $array,
|
||||
'format' => APP_DATABASE_ATTRIBUTE_BIGINT_RANGE,
|
||||
'formatOptions' => ['min' => $min, 'max' => $max],
|
||||
]), $response, $dbForProject, $queueForDatabase, $queueForEvents, $authorization);
|
||||
|
||||
$formatOptions = $attribute->getAttribute('formatOptions', []);
|
||||
if (!empty($formatOptions)) {
|
||||
$attribute->setAttribute('min', \intval($formatOptions['min']));
|
||||
$attribute->setAttribute('max', \intval($formatOptions['max']));
|
||||
}
|
||||
|
||||
$response
|
||||
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
|
||||
->dynamic($attribute, $this->getResponseModel());
|
||||
}
|
||||
}
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\BigInt;
|
||||
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Action;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\ContentType;
|
||||
use Appwrite\SDK\Deprecated;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response as UtopiaResponse;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Database\Validator\Key;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Http\Adapter\Swoole\Response as SwooleResponse;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Integer;
|
||||
use Utopia\Validator\Nullable;
|
||||
|
||||
class Update extends Action
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'updateBigIntAttribute';
|
||||
}
|
||||
|
||||
protected function getResponseModel(): string|array
|
||||
{
|
||||
return UtopiaResponse::MODEL_ATTRIBUTE_BIGINT;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH)
|
||||
->setHttpPath('/v1/databases/:databaseId/collections/:collectionId/attributes/bigint/:key')
|
||||
->desc('Update bigint attribute')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', 'collections.write')
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].update')
|
||||
->label('audits.event', 'attribute.update')
|
||||
->label('audits.resource', 'database/{request.databaseId}/collection/{request.collectionId}')
|
||||
->label('sdk', new Method(
|
||||
namespace: $this->getSDKNamespace(),
|
||||
group: $this->getSDKGroup(),
|
||||
name: self::getName(),
|
||||
description: '/docs/references/databases/update-bigint-attribute.md',
|
||||
auth: [AuthType::ADMIN, AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: SwooleResponse::STATUS_CODE_OK,
|
||||
model: $this->getResponseModel(),
|
||||
)
|
||||
],
|
||||
contentType: ContentType::JSON,
|
||||
deprecated: new Deprecated(
|
||||
since: '1.8.0',
|
||||
replaceWith: 'tablesDB.updateBigIntColumn',
|
||||
),
|
||||
))
|
||||
->param('databaseId', '', fn (Database $dbForProject) => new UID($dbForProject->getAdapter()->getMaxUIDLength()), 'Database ID.', false, ['dbForProject'])
|
||||
->param('collectionId', '', fn (Database $dbForProject) => new UID($dbForProject->getAdapter()->getMaxUIDLength()), 'Collection ID.', false, ['dbForProject'])
|
||||
->param('key', '', fn (Database $dbForProject) => new Key(false, $dbForProject->getAdapter()->getMaxUIDLength()), 'Attribute Key.', false, ['dbForProject'])
|
||||
->param('required', null, new Boolean(), 'Is attribute required?')
|
||||
->param('min', null, new Nullable(new Integer(false, 64)), 'Minimum value', true)
|
||||
->param('max', null, new Nullable(new Integer(false, 64)), 'Maximum value', true)
|
||||
->param('default', null, new Nullable(new Integer(false, 64)), 'Default value. Cannot be set when attribute is required.')
|
||||
->param('newKey', null, fn (Database $dbForProject) => new Nullable(new Key(false, $dbForProject->getAdapter()->getMaxUIDLength())), 'New Attribute Key.', true, ['dbForProject'])
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('authorization')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(string $databaseId, string $collectionId, string $key, ?bool $required, ?int $min, ?int $max, ?int $default, ?string $newKey, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents, Authorization $authorization): void
|
||||
{
|
||||
$attribute = $this->updateAttribute(
|
||||
databaseId: $databaseId,
|
||||
collectionId: $collectionId,
|
||||
key: $key,
|
||||
dbForProject: $dbForProject,
|
||||
queueForEvents: $queueForEvents,
|
||||
authorization: $authorization,
|
||||
type: Database::VAR_BIGINT,
|
||||
default: $default,
|
||||
required: $required,
|
||||
min: $min,
|
||||
max: $max,
|
||||
newKey: $newKey
|
||||
);
|
||||
|
||||
$formatOptions = $attribute->getAttribute('formatOptions', []);
|
||||
if (!empty($formatOptions)) {
|
||||
$attribute->setAttribute('min', \intval($formatOptions['min']));
|
||||
$attribute->setAttribute('max', \intval($formatOptions['max']));
|
||||
}
|
||||
|
||||
$response
|
||||
->setStatusCode(SwooleResponse::STATUS_CODE_OK)
|
||||
->dynamic($attribute, $this->getResponseModel());
|
||||
}
|
||||
}
|
||||
@@ -290,13 +290,15 @@ class Create extends Action
|
||||
}
|
||||
|
||||
if (isset($attribute['min']) || isset($attribute['max'])) {
|
||||
$format = $type === Database::VAR_INTEGER
|
||||
? APP_DATABASE_ATTRIBUTE_INT_RANGE
|
||||
: APP_DATABASE_ATTRIBUTE_FLOAT_RANGE;
|
||||
$format = match($type) {
|
||||
Database::VAR_INTEGER => APP_DATABASE_ATTRIBUTE_INT_RANGE,
|
||||
Database::VAR_BIGINT => APP_DATABASE_ATTRIBUTE_BIGINT_RANGE,
|
||||
default => APP_DATABASE_ATTRIBUTE_FLOAT_RANGE,
|
||||
};
|
||||
|
||||
$formatOptions = [
|
||||
'min' => $attribute['min'] ?? ($type === Database::VAR_INTEGER ? \PHP_INT_MIN : -\PHP_FLOAT_MAX),
|
||||
'max' => $attribute['max'] ?? ($type === Database::VAR_INTEGER ? \PHP_INT_MAX : \PHP_FLOAT_MAX),
|
||||
'min' => $attribute['min'] ?? ($type === Database::VAR_INTEGER || $type === Database::VAR_BIGINT ? \PHP_INT_MIN : -\PHP_FLOAT_MAX),
|
||||
'max' => $attribute['max'] ?? ($type === Database::VAR_INTEGER || $type === Database::VAR_BIGINT ? \PHP_INT_MAX : \PHP_FLOAT_MAX),
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\BigInt;
|
||||
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\BigInt\Create as BigIntCreate;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response as UtopiaResponse;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Validator\Key;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Http\Adapter\Swoole\Response as SwooleResponse;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Integer;
|
||||
use Utopia\Validator\Nullable;
|
||||
|
||||
class Create extends BigIntCreate
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'createBigIntColumn';
|
||||
}
|
||||
|
||||
protected function getResponseModel(): string|array
|
||||
{
|
||||
return UtopiaResponse::MODEL_COLUMN_BIGINT;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(self::HTTP_REQUEST_METHOD_POST)
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/bigint')
|
||||
->desc('Create bigint column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
|
||||
->label('audits.event', 'column.create')
|
||||
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
|
||||
->label('sdk', new Method(
|
||||
namespace: $this->getSDKNamespace(),
|
||||
group: $this->getSDKGroup(),
|
||||
name: self::getName(),
|
||||
description: '/docs/references/tablesdb/create-bigint-column.md',
|
||||
auth: [AuthType::ADMIN, AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: SwooleResponse::STATUS_CODE_ACCEPTED,
|
||||
model: $this->getResponseModel(),
|
||||
)
|
||||
]
|
||||
))
|
||||
->param('databaseId', '', fn (Database $dbForProject) => new UID($dbForProject->getAdapter()->getMaxUIDLength()), 'Database ID.', false, ['dbForProject'])
|
||||
->param('tableId', '', fn (Database $dbForProject) => new UID($dbForProject->getAdapter()->getMaxUIDLength()), 'Table ID.', false, ['dbForProject'])
|
||||
->param('key', '', fn (Database $dbForProject) => new Key(false, $dbForProject->getAdapter()->getMaxUIDLength()), 'Column Key.', false, ['dbForProject'])
|
||||
->param('required', null, new Boolean(), 'Is column required?')
|
||||
->param('min', null, new Nullable(new Integer(false, 64)), 'Minimum value', true)
|
||||
->param('max', null, new Nullable(new Integer(false, 64)), 'Maximum value', true)
|
||||
->param('default', null, new Nullable(new Integer(false, 64)), 'Default value. Cannot be set when column is required.', true)
|
||||
->param('array', false, new Boolean(), 'Is column an array?', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForDatabase')
|
||||
->inject('queueForEvents')
|
||||
->inject('authorization')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\BigInt;
|
||||
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\BigInt\Update as BigIntUpdate;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\ContentType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response as UtopiaResponse;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Validator\Key;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Http\Adapter\Swoole\Response as SwooleResponse;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\Integer;
|
||||
use Utopia\Validator\Nullable;
|
||||
|
||||
class Update extends BigIntUpdate
|
||||
{
|
||||
public static function getName(): string
|
||||
{
|
||||
return 'updateBigIntColumn';
|
||||
}
|
||||
|
||||
protected function getResponseModel(): string|array
|
||||
{
|
||||
return UtopiaResponse::MODEL_COLUMN_BIGINT;
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(self::HTTP_REQUEST_METHOD_PATCH)
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/bigint/:key')
|
||||
->desc('Update bigint column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
|
||||
->label('audits.event', 'column.update')
|
||||
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
|
||||
->label('sdk', new Method(
|
||||
namespace: $this->getSDKNamespace(),
|
||||
group: $this->getSDKGroup(),
|
||||
name: self::getName(),
|
||||
description: '/docs/references/tablesdb/update-bigint-column.md',
|
||||
auth: [AuthType::ADMIN, AuthType::KEY],
|
||||
responses: [
|
||||
new SDKResponse(
|
||||
code: SwooleResponse::STATUS_CODE_OK,
|
||||
model: $this->getResponseModel(),
|
||||
)
|
||||
],
|
||||
contentType: ContentType::JSON
|
||||
))
|
||||
->param('databaseId', '', fn (Database $dbForProject) => new UID($dbForProject->getAdapter()->getMaxUIDLength()), 'Database ID.', false, ['dbForProject'])
|
||||
->param('tableId', '', fn (Database $dbForProject) => new UID($dbForProject->getAdapter()->getMaxUIDLength()), 'Table ID.', false, ['dbForProject'])
|
||||
->param('key', '', fn (Database $dbForProject) => new Key(false, $dbForProject->getAdapter()->getMaxUIDLength()), 'Column Key.', false, ['dbForProject'])
|
||||
->param('required', null, new Boolean(), 'Is column required?')
|
||||
->param('min', null, new Nullable(new Integer(false, 64)), 'Minimum value', true)
|
||||
->param('max', null, new Nullable(new Integer(false, 64)), 'Maximum value', true)
|
||||
->param('default', null, new Nullable(new Integer(false, 64)), 'Default value. Cannot be set when column is required.')
|
||||
->param('newKey', null, fn (Database $dbForProject) => new Nullable(new Key(false, $dbForProject->getAdapter()->getMaxUIDLength())), 'New Column Key.', true, ['dbForProject'])
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('authorization')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -34,7 +34,7 @@ class Create extends BooleanCreate
|
||||
->desc('Create boolean column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('audits.event', 'column.create')
|
||||
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ class Update extends BooleanUpdate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/boolean/:key')
|
||||
->desc('Update boolean column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
|
||||
->label('audits.event', 'column.update')
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ class Create extends DatetimeCreate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/datetime')
|
||||
->desc('Create datetime column')
|
||||
->groups(['api', 'database'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
|
||||
->label('audits.event', 'column.create')
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ class Update extends DatetimeUpdate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/datetime/:key')
|
||||
->desc('Update dateTime column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
|
||||
->label('audits.event', 'column.update')
|
||||
|
||||
@@ -33,7 +33,7 @@ class Delete extends AttributesDelete
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/:key')
|
||||
->desc('Delete column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
|
||||
->label('audits.event', 'column.delete')
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ class Create extends EmailCreate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/email')
|
||||
->desc('Create email column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
|
||||
->label('audits.event', 'column.create')
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ class Update extends EmailUpdate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/email/:key')
|
||||
->desc('Update email column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
|
||||
->label('audits.event', 'column.update')
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ class Create extends EnumCreate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/enum')
|
||||
->desc('Create enum column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
|
||||
->label('audits.event', 'column.create')
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ class Update extends EnumUpdate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/enum/:key')
|
||||
->desc('Update enum column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
|
||||
->label('audits.event', 'column.update')
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ class Create extends FloatCreate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/float')
|
||||
->desc('Create float column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
|
||||
->label('audits.event', 'column.create')
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ class Update extends FloatUpdate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/float/:key')
|
||||
->desc('Update float column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
|
||||
->label('audits.event', 'column.update')
|
||||
|
||||
@@ -42,7 +42,7 @@ class Get extends AttributesGet
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/:key')
|
||||
->desc('Get column')
|
||||
->groups(['api', 'database'])
|
||||
->label('scope', ['tables.read', 'collections.read'])
|
||||
->label('scope', ['tables.read', 'collections.read', 'columns.read', 'attributes.read'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('sdk', new Method(
|
||||
namespace: $this->getSDKNamespace(),
|
||||
|
||||
@@ -34,7 +34,7 @@ class Create extends IPCreate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/ip')
|
||||
->desc('Create IP address column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
|
||||
->label('audits.event', 'column.create')
|
||||
|
||||
@@ -35,7 +35,7 @@ class Update extends IPUpdate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/ip/:key')
|
||||
->desc('Update IP address column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
|
||||
->label('audits.event', 'column.update')
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ class Create extends IntegerCreate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/integer')
|
||||
->desc('Create integer column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
|
||||
->label('audits.event', 'column.create')
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ class Update extends IntegerUpdate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/integer/:key')
|
||||
->desc('Update integer column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
|
||||
->label('audits.event', 'column.update')
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ class Create extends LineCreate
|
||||
->desc('Create line column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('audits.event', 'column.create')
|
||||
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ class Update extends LineUpdate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/line/:key')
|
||||
->desc('Update line column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
|
||||
->label('audits.event', 'column.update')
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ class Create extends LongtextCreate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/longtext')
|
||||
->desc('Create longtext column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
|
||||
->label('audits.event', 'column.create')
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ class Update extends LongtextUpdate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/longtext/:key')
|
||||
->desc('Update longtext column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
|
||||
->label('audits.event', 'column.update')
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ class Create extends MediumtextCreate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/mediumtext')
|
||||
->desc('Create mediumtext column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
|
||||
->label('audits.event', 'column.create')
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ class Update extends MediumtextUpdate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/mediumtext/:key')
|
||||
->desc('Update mediumtext column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
|
||||
->label('audits.event', 'column.update')
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ class Create extends PointCreate
|
||||
->desc('Create point column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('audits.event', 'column.create')
|
||||
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ class Update extends PointUpdate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/point/:key')
|
||||
->desc('Update point column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
|
||||
->label('audits.event', 'column.update')
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ class Create extends PolygonCreate
|
||||
->desc('Create polygon column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('audits.event', 'column.create')
|
||||
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ class Update extends PolygonUpdate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/polygon/:key')
|
||||
->desc('Update polygon column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
|
||||
->label('audits.event', 'column.update')
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ class Create extends RelationshipCreate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/relationship')
|
||||
->desc('Create relationship column')
|
||||
->groups(['api', 'database'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
|
||||
->label('audits.event', 'column.create')
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ class Update extends RelationshipUpdate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/:key/relationship')
|
||||
->desc('Update relationship column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
|
||||
->label('audits.event', 'column.update')
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ class Create extends StringCreate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/string')
|
||||
->desc('Create string column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
|
||||
->label('audits.event', 'column.create')
|
||||
|
||||
+1
-1
@@ -37,7 +37,7 @@ class Update extends StringUpdate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/string/:key')
|
||||
->desc('Update string column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
|
||||
->label('audits.event', 'column.update')
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ class Create extends TextCreate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/text')
|
||||
->desc('Create text column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
|
||||
->label('audits.event', 'column.create')
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ class Update extends TextUpdate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/text/:key')
|
||||
->desc('Update text column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
|
||||
->label('audits.event', 'column.update')
|
||||
|
||||
@@ -34,7 +34,7 @@ class Create extends URLCreate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/url')
|
||||
->desc('Create URL column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
|
||||
->label('audits.event', 'column.create')
|
||||
|
||||
@@ -35,7 +35,7 @@ class Update extends URLUpdate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/url/:key')
|
||||
->desc('Update URL column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
|
||||
->label('audits.event', 'column.update')
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ class Create extends VarcharCreate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/varchar')
|
||||
->desc('Create varchar column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].create')
|
||||
->label('audits.event', 'column.create')
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ class Update extends VarcharUpdate
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns/varchar/:key')
|
||||
->desc('Update varchar column')
|
||||
->groups(['api', 'database', 'schema'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'columns.write', 'attributes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].columns.[columnId].update')
|
||||
->label('audits.event', 'column.update')
|
||||
|
||||
@@ -33,7 +33,7 @@ class XList extends AttributesXList
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/columns')
|
||||
->desc('List columns')
|
||||
->groups(['api', 'database'])
|
||||
->label('scope', ['tables.read', 'collections.read'])
|
||||
->label('scope', ['tables.read', 'collections.read', 'columns.read', 'attributes.read'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('sdk', new Method(
|
||||
namespace: $this->getSDKNamespace(),
|
||||
|
||||
@@ -37,7 +37,7 @@ class Create extends IndexCreate
|
||||
->desc('Create index')
|
||||
->groups(['api', 'database'])
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].indexes.[indexId].create')
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'indexes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('audits.event', 'index.create')
|
||||
->label('audits.resource', 'database/{request.databaseId}/table/{request.tableId}')
|
||||
|
||||
@@ -36,7 +36,7 @@ class Delete extends IndexDelete
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/indexes/:key')
|
||||
->desc('Delete index')
|
||||
->groups(['api', 'database'])
|
||||
->label('scope', ['tables.write', 'collections.write'])
|
||||
->label('scope', ['tables.write', 'collections.write', 'indexes.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('event', 'databases.[databaseId].tables.[tableId].indexes.[indexId].update')
|
||||
->label('audits.event', 'index.delete')
|
||||
|
||||
@@ -32,7 +32,7 @@ class Get extends IndexGet
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/indexes/:key')
|
||||
->desc('Get index')
|
||||
->groups(['api', 'database'])
|
||||
->label('scope', ['tables.read', 'collections.read'])
|
||||
->label('scope', ['tables.read', 'collections.read', 'indexes.read'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('sdk', new Method(
|
||||
namespace: $this->getSDKNamespace(),
|
||||
|
||||
@@ -33,7 +33,7 @@ class XList extends IndexXList
|
||||
->setHttpPath('/v1/tablesdb/:databaseId/tables/:tableId/indexes')
|
||||
->desc('List indexes')
|
||||
->groups(['api', 'database'])
|
||||
->label('scope', ['tables.read', 'collections.read'])
|
||||
->label('scope', ['tables.read', 'collections.read', 'indexes.read'])
|
||||
->label('resourceType', RESOURCE_TYPE_DATABASES)
|
||||
->label('sdk', new Method(
|
||||
namespace: $this->getSDKNamespace(),
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Appwrite\Platform\Modules\Databases\Services\Registry;
|
||||
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\BigInt\Create as CreateBigIntAttribute;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\BigInt\Update as UpdateBigIntAttribute;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Boolean\Create as CreateBooleanAttribute;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Boolean\Update as UpdateBooleanAttribute;
|
||||
use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Attributes\Datetime\Create as CreateDatetimeAttribute;
|
||||
@@ -171,6 +173,10 @@ class Legacy extends Base
|
||||
$service->addAction(CreateIntegerAttribute::getName(), new CreateIntegerAttribute());
|
||||
$service->addAction(UpdateIntegerAttribute::getName(), new UpdateIntegerAttribute());
|
||||
|
||||
// Attribute: BigInt
|
||||
$service->addAction(CreateBigIntAttribute::getName(), new CreateBigIntAttribute());
|
||||
$service->addAction(UpdateBigIntAttribute::getName(), new UpdateBigIntAttribute());
|
||||
|
||||
// Attribute: IP
|
||||
$service->addAction(CreateIPAttribute::getName(), new CreateIPAttribute());
|
||||
$service->addAction(UpdateIPAttribute::getName(), new UpdateIPAttribute());
|
||||
|
||||
@@ -5,6 +5,8 @@ namespace Appwrite\Platform\Modules\Databases\Services\Registry;
|
||||
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Create as CreateTablesDatabase;
|
||||
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Delete as DeleteTablesDatabase;
|
||||
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Get as GetTablesDatabase;
|
||||
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\BigInt\Create as CreateBigInt;
|
||||
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\BigInt\Update as UpdateBigInt;
|
||||
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Boolean\Create as CreateBoolean;
|
||||
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Boolean\Update as UpdateBoolean;
|
||||
use Appwrite\Platform\Modules\Databases\Http\TablesDB\Tables\Columns\Datetime\Create as CreateDatetime;
|
||||
@@ -151,6 +153,10 @@ class TablesDB extends Base
|
||||
$service->addAction(CreateInteger::getName(), new CreateInteger());
|
||||
$service->addAction(UpdateInteger::getName(), new UpdateInteger());
|
||||
|
||||
// Column: BigInt
|
||||
$service->addAction(CreateBigInt::getName(), new CreateBigInt());
|
||||
$service->addAction(UpdateBigInt::getName(), new UpdateBigInt());
|
||||
|
||||
// Column: IP
|
||||
$service->addAction(CreateIP::getName(), new CreateIP());
|
||||
$service->addAction(UpdateIP::getName(), new UpdateIP());
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
namespace Appwrite\Platform\Modules\Functions\Http\Deployments;
|
||||
|
||||
use Appwrite\Event\Build;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Message\Build as BuildMessage;
|
||||
use Appwrite\Event\Publisher\Build as BuildPublisher;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\ContentType;
|
||||
@@ -87,9 +88,10 @@ class Create extends Action
|
||||
->inject('project')
|
||||
->inject('deviceForFunctions')
|
||||
->inject('deviceForLocal')
|
||||
->inject('queueForBuilds')
|
||||
->inject('publisherForBuilds')
|
||||
->inject('plan')
|
||||
->inject('authorization')
|
||||
->inject('platform')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
@@ -106,9 +108,10 @@ class Create extends Action
|
||||
Document $project,
|
||||
Device $deviceForFunctions,
|
||||
Device $deviceForLocal,
|
||||
Build $queueForBuilds,
|
||||
BuildPublisher $publisherForBuilds,
|
||||
array $plan,
|
||||
Authorization $authorization
|
||||
Authorization $authorization,
|
||||
array $platform
|
||||
) {
|
||||
$activate = \strval($activate) === 'true' || \strval($activate) === '1';
|
||||
|
||||
@@ -175,15 +178,8 @@ class Create extends Action
|
||||
throw new Exception(Exception::STORAGE_INVALID_CONTENT_RANGE);
|
||||
}
|
||||
|
||||
// TODO remove the condition that checks `$end === $fileSize` in next breaking version
|
||||
if ($end === $fileSize - 1 || $end === $fileSize) {
|
||||
//if it's a last chunks the chunk size might differ, so we set the $chunks and $chunk to notify it's last chunk
|
||||
$chunks = $chunk = -1;
|
||||
} else {
|
||||
// Calculate total number of chunks based on the chunk size i.e ($rangeEnd - $rangeStart)
|
||||
$chunks = (int) ceil($fileSize / ($end + 1 - $start));
|
||||
$chunk = (int) ($start / ($end + 1 - $start)) + 1;
|
||||
}
|
||||
$chunks = (int) ceil($fileSize / APP_LIMIT_UPLOAD_CHUNK_SIZE);
|
||||
$chunk = (int) ($start / APP_LIMIT_UPLOAD_CHUNK_SIZE) + 1;
|
||||
}
|
||||
|
||||
if (!$fileSizeValidator->isValid($fileSize) && $functionSizeLimit !== 0) { // Check if file size is exceeding allowed limit
|
||||
@@ -202,15 +198,14 @@ class Create extends Action
|
||||
$metadata = ['content_type' => $deviceForLocal->getFileMimeType($fileTmpName)];
|
||||
if (!$deployment->isEmpty()) {
|
||||
$chunks = $deployment->getAttribute('sourceChunksTotal', 1);
|
||||
$uploaded = $deployment->getAttribute('sourceChunksUploaded', 0);
|
||||
$metadata = $deployment->getAttribute('sourceMetadata', []);
|
||||
if ($chunk === -1) {
|
||||
$chunk = $chunks;
|
||||
}
|
||||
} else {
|
||||
// Guard against manually setting range header for single chunk upload
|
||||
if ($chunks === -1) {
|
||||
$chunks = 1;
|
||||
$chunk = 1;
|
||||
|
||||
if ($uploaded === $chunks) {
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_ACCEPTED)
|
||||
->dynamic($deployment, Response::MODEL_DEPLOYMENT);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,6 +253,8 @@ class Create extends Action
|
||||
'sourcePath' => $path,
|
||||
'sourceSize' => $fileSize,
|
||||
'totalSize' => $fileSize,
|
||||
'sourceChunksTotal' => $chunks,
|
||||
'sourceChunksUploaded' => $chunksUploaded,
|
||||
'activate' => $activate,
|
||||
'sourceMetadata' => $metadata,
|
||||
'type' => $type
|
||||
@@ -272,15 +269,19 @@ class Create extends Action
|
||||
} else {
|
||||
$deployment = $dbForProject->updateDocument('deployments', $deploymentId, new Document([
|
||||
'sourceSize' => $fileSize,
|
||||
'sourceChunksUploaded' => $chunksUploaded,
|
||||
'sourceMetadata' => $metadata,
|
||||
]));
|
||||
}
|
||||
|
||||
// Start the build
|
||||
$queueForBuilds
|
||||
->setType(BUILD_TYPE_DEPLOYMENT)
|
||||
->setResource($function)
|
||||
->setDeployment($deployment);
|
||||
$publisherForBuilds->enqueue(new BuildMessage(
|
||||
project: $project,
|
||||
resource: $function,
|
||||
deployment: $deployment,
|
||||
type: BUILD_TYPE_DEPLOYMENT,
|
||||
platform: $platform,
|
||||
));
|
||||
} else {
|
||||
if ($deployment->isEmpty()) {
|
||||
$deployment = $dbForProject->createDocument('deployments', new Document([
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
namespace Appwrite\Platform\Modules\Functions\Http\Deployments\Duplicate;
|
||||
|
||||
use Appwrite\Event\Build;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Message\Build as BuildMessage;
|
||||
use Appwrite\Event\Publisher\Build as BuildPublisher;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
@@ -61,8 +62,10 @@ class Create extends Action
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForBuilds')
|
||||
->inject('publisherForBuilds')
|
||||
->inject('deviceForFunctions')
|
||||
->inject('project')
|
||||
->inject('platform')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
@@ -73,8 +76,10 @@ class Create extends Action
|
||||
Response $response,
|
||||
Database $dbForProject,
|
||||
Event $queueForEvents,
|
||||
Build $queueForBuilds,
|
||||
Device $deviceForFunctions
|
||||
BuildPublisher $publisherForBuilds,
|
||||
Device $deviceForFunctions,
|
||||
Document $project,
|
||||
array $platform
|
||||
) {
|
||||
$function = $dbForProject->getDocument('functions', $functionId);
|
||||
|
||||
@@ -127,10 +132,13 @@ class Create extends Action
|
||||
'latestDeploymentStatus' => $function->getAttribute('latestDeploymentStatus'),
|
||||
]));
|
||||
|
||||
$queueForBuilds
|
||||
->setType(BUILD_TYPE_DEPLOYMENT)
|
||||
->setResource($function)
|
||||
->setDeployment($deployment);
|
||||
$publisherForBuilds->enqueue(new BuildMessage(
|
||||
project: $project,
|
||||
resource: $function,
|
||||
deployment: $deployment,
|
||||
type: BUILD_TYPE_DEPLOYMENT,
|
||||
platform: $platform,
|
||||
));
|
||||
|
||||
$queueForEvents
|
||||
->setParam('functionId', $function->getId())
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
namespace Appwrite\Platform\Modules\Functions\Http\Deployments\Template;
|
||||
|
||||
use Appwrite\Event\Build;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Message\Build as BuildMessage;
|
||||
use Appwrite\Event\Publisher\Build as BuildPublisher;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Platform\Modules\Compute\Base;
|
||||
use Appwrite\SDK\AuthType;
|
||||
@@ -76,9 +77,10 @@ class Create extends Base
|
||||
->inject('dbForPlatform')
|
||||
->inject('queueForEvents')
|
||||
->inject('project')
|
||||
->inject('queueForBuilds')
|
||||
->inject('publisherForBuilds')
|
||||
->inject('gitHub')
|
||||
->inject('authorization')
|
||||
->inject('platform')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
@@ -96,9 +98,10 @@ class Create extends Base
|
||||
Database $dbForPlatform,
|
||||
Event $queueForEvents,
|
||||
Document $project,
|
||||
Build $queueForBuilds,
|
||||
BuildPublisher $publisherForBuilds,
|
||||
GitHub $github,
|
||||
Authorization $authorization
|
||||
Authorization $authorization,
|
||||
array $platform
|
||||
) {
|
||||
$function = $dbForProject->getDocument('functions', $functionId);
|
||||
|
||||
@@ -127,10 +130,11 @@ class Create extends Base
|
||||
project: $project,
|
||||
installation: $installation,
|
||||
dbForProject: $dbForProject,
|
||||
queueForBuilds: $queueForBuilds,
|
||||
publisherForBuilds: $publisherForBuilds,
|
||||
template: $template,
|
||||
github: $github,
|
||||
activate: $activate,
|
||||
platform: $platform,
|
||||
referenceType: $type,
|
||||
reference: $reference
|
||||
);
|
||||
@@ -184,11 +188,14 @@ class Create extends Base
|
||||
|
||||
$this->updateEmptyManualRule($project, $function, $deployment, $dbForPlatform, $authorization);
|
||||
|
||||
$queueForBuilds
|
||||
->setType(BUILD_TYPE_DEPLOYMENT)
|
||||
->setResource($function)
|
||||
->setDeployment($deployment)
|
||||
->setTemplate($template);
|
||||
$publisherForBuilds->enqueue(new BuildMessage(
|
||||
project: $project,
|
||||
resource: $function,
|
||||
deployment: $deployment,
|
||||
type: BUILD_TYPE_DEPLOYMENT,
|
||||
template: $template,
|
||||
platform: $platform,
|
||||
));
|
||||
|
||||
$queueForEvents
|
||||
->setParam('functionId', $function->getId())
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace Appwrite\Platform\Modules\Functions\Http\Deployments\Vcs;
|
||||
|
||||
use Appwrite\Event\Build;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Publisher\Build as BuildPublisher;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Platform\Modules\Compute\Base;
|
||||
use Appwrite\SDK\AuthType;
|
||||
@@ -70,8 +70,9 @@ class Create extends Base
|
||||
->inject('dbForPlatform')
|
||||
->inject('project')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForBuilds')
|
||||
->inject('publisherForBuilds')
|
||||
->inject('gitHub')
|
||||
->inject('platform')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
@@ -86,8 +87,9 @@ class Create extends Base
|
||||
Database $dbForPlatform,
|
||||
Document $project,
|
||||
Event $queueForEvents,
|
||||
Build $queueForBuilds,
|
||||
BuildPublisher $publisherForBuilds,
|
||||
GitHub $github,
|
||||
array $platform,
|
||||
) {
|
||||
$function = $dbForProject->getDocument('functions', $functionId);
|
||||
|
||||
@@ -105,10 +107,11 @@ class Create extends Base
|
||||
project: $project,
|
||||
installation: $installation,
|
||||
dbForProject: $dbForProject,
|
||||
queueForBuilds: $queueForBuilds,
|
||||
publisherForBuilds: $publisherForBuilds,
|
||||
template: $template,
|
||||
github: $github,
|
||||
activate: $activate,
|
||||
platform: $platform,
|
||||
reference: $reference,
|
||||
referenceType: $type
|
||||
);
|
||||
|
||||
@@ -17,6 +17,7 @@ use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Usage\Context;
|
||||
use Appwrite\Utopia\Database\Documents\User;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Executor\Exception\Timeout as ExecutorTimeout;
|
||||
use Executor\Executor;
|
||||
use MaxMind\Db\Reader;
|
||||
use Utopia\Auth\Proofs\Token;
|
||||
@@ -60,7 +61,7 @@ class Create extends Base
|
||||
->setHttpPath('/v1/functions/:functionId/executions')
|
||||
->desc('Create execution')
|
||||
->groups(['api', 'functions'])
|
||||
->label('scope', 'execution.write')
|
||||
->label('scope', ['executions.write', 'execution.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_FUNCTIONS)
|
||||
->label('event', 'functions.[functionId].executions.[executionId].create')
|
||||
->label('sdk', new Method(
|
||||
@@ -417,25 +418,29 @@ class Create extends Base
|
||||
$source = $deployment->getAttribute('buildPath', '');
|
||||
$extension = str_ends_with($source, '.tar') ? 'tar' : 'tar.gz';
|
||||
$command = $version === 'v2' ? '' : "cp /tmp/code.$extension /mnt/code/code.$extension && nohup helpers/start.sh \"$command\"";
|
||||
$executionResponse = $executor->createExecution(
|
||||
projectId: $project->getId(),
|
||||
deploymentId: $deployment->getId(),
|
||||
body: \strlen($body) > 0 ? $body : null,
|
||||
variables: $vars,
|
||||
timeout: $function->getAttribute('timeout', 0),
|
||||
image: $runtime['image'],
|
||||
source: $source,
|
||||
entrypoint: $deployment->getAttribute('entrypoint', ''),
|
||||
version: $version,
|
||||
path: $path,
|
||||
method: $method,
|
||||
headers: $headers,
|
||||
runtimeEntrypoint: $command,
|
||||
cpus: $spec['cpus'] ?? APP_COMPUTE_CPUS_DEFAULT,
|
||||
memory: $spec['memory'] ?? APP_COMPUTE_MEMORY_DEFAULT,
|
||||
logging: $function->getAttribute('logging', true),
|
||||
requestTimeout: 30
|
||||
);
|
||||
try {
|
||||
$executionResponse = $executor->createExecution(
|
||||
projectId: $project->getId(),
|
||||
deploymentId: $deployment->getId(),
|
||||
body: \strlen($body) > 0 ? $body : null,
|
||||
variables: $vars,
|
||||
timeout: $function->getAttribute('timeout', 0),
|
||||
image: $runtime['image'],
|
||||
source: $source,
|
||||
entrypoint: $deployment->getAttribute('entrypoint', ''),
|
||||
version: $version,
|
||||
path: $path,
|
||||
method: $method,
|
||||
headers: $headers,
|
||||
runtimeEntrypoint: $command,
|
||||
cpus: $spec['cpus'] ?? APP_COMPUTE_CPUS_DEFAULT,
|
||||
memory: $spec['memory'] ?? APP_COMPUTE_MEMORY_DEFAULT,
|
||||
logging: $function->getAttribute('logging', true),
|
||||
requestTimeout: 30
|
||||
);
|
||||
} catch (ExecutorTimeout $th) {
|
||||
throw new AppwriteException(AppwriteException::FUNCTION_SYNCHRONOUS_TIMEOUT, previous: $th);
|
||||
}
|
||||
|
||||
$headersFiltered = [];
|
||||
foreach ($executionResponse['headers'] as $key => $value) {
|
||||
|
||||
@@ -35,7 +35,7 @@ class Delete extends Base
|
||||
->setHttpPath('/v1/functions/:functionId/executions/:executionId')
|
||||
->desc('Delete execution')
|
||||
->groups(['api', 'functions'])
|
||||
->label('scope', 'execution.write')
|
||||
->label('scope', ['executions.write', 'execution.write'])
|
||||
->label('resourceType', RESOURCE_TYPE_FUNCTIONS)
|
||||
->label('event', 'functions.[functionId].executions.[executionId].delete')
|
||||
->label('audits.event', 'executions.delete')
|
||||
|
||||
@@ -31,7 +31,7 @@ class Get extends Base
|
||||
->setHttpPath('/v1/functions/:functionId/executions/:executionId')
|
||||
->desc('Get execution')
|
||||
->groups(['api', 'functions'])
|
||||
->label('scope', 'execution.read')
|
||||
->label('scope', ['executions.read', 'execution.read'])
|
||||
->label('resourceType', RESOURCE_TYPE_FUNCTIONS)
|
||||
->label('sdk', new Method(
|
||||
namespace: 'functions',
|
||||
|
||||
@@ -39,7 +39,7 @@ class XList extends Base
|
||||
->setHttpPath('/v1/functions/:functionId/executions')
|
||||
->desc('List executions')
|
||||
->groups(['api', 'functions'])
|
||||
->label('scope', 'execution.read')
|
||||
->label('scope', ['executions.read', 'execution.read'])
|
||||
->label('resourceType', RESOURCE_TYPE_FUNCTIONS)
|
||||
->label('sdk', new Method(
|
||||
namespace: 'functions',
|
||||
|
||||
@@ -2,9 +2,10 @@
|
||||
|
||||
namespace Appwrite\Platform\Modules\Functions\Http\Functions;
|
||||
|
||||
use Appwrite\Event\Build;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Func;
|
||||
use Appwrite\Event\Message\Build as BuildMessage;
|
||||
use Appwrite\Event\Publisher\Build as BuildPublisher;
|
||||
use Appwrite\Event\Realtime;
|
||||
use Appwrite\Event\Validator\FunctionEvent;
|
||||
use Appwrite\Event\Webhook;
|
||||
@@ -115,7 +116,7 @@ class Create extends Base
|
||||
->inject('timelimit')
|
||||
->inject('project')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForBuilds')
|
||||
->inject('publisherForBuilds')
|
||||
->inject('queueForRealtime')
|
||||
->inject('queueForWebhooks')
|
||||
->inject('queueForFunctions')
|
||||
@@ -157,7 +158,7 @@ class Create extends Base
|
||||
callable $timelimit,
|
||||
Document $project,
|
||||
Event $queueForEvents,
|
||||
Build $queueForBuilds,
|
||||
BuildPublisher $publisherForBuilds,
|
||||
Realtime $queueForRealtime,
|
||||
Webhook $queueForWebhooks,
|
||||
Func $queueForFunctions,
|
||||
@@ -326,10 +327,11 @@ class Create extends Base
|
||||
project: $project,
|
||||
installation: $installation,
|
||||
dbForProject: $dbForProject,
|
||||
queueForBuilds: $queueForBuilds,
|
||||
publisherForBuilds: $publisherForBuilds,
|
||||
template: $template,
|
||||
github: $github,
|
||||
activate: true,
|
||||
platform: $platform,
|
||||
reference: $providerBranch,
|
||||
referenceType: 'branch'
|
||||
);
|
||||
@@ -367,11 +369,14 @@ class Create extends Base
|
||||
'latestDeploymentStatus' => $deployment->getAttribute('status', ''),
|
||||
]));
|
||||
|
||||
$queueForBuilds
|
||||
->setType(BUILD_TYPE_DEPLOYMENT)
|
||||
->setResource($function)
|
||||
->setDeployment($deployment)
|
||||
->setTemplate($template);
|
||||
$publisherForBuilds->enqueue(new BuildMessage(
|
||||
project: $project,
|
||||
resource: $function,
|
||||
deployment: $deployment,
|
||||
type: BUILD_TYPE_DEPLOYMENT,
|
||||
template: $template,
|
||||
platform: $platform,
|
||||
));
|
||||
}
|
||||
|
||||
$functionsDomain = $platform['functionsDomain'];
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
namespace Appwrite\Platform\Modules\Functions\Http\Functions;
|
||||
|
||||
use Appwrite\Event\Build;
|
||||
use Appwrite\Event\Event;
|
||||
use Appwrite\Event\Publisher\Build as BuildPublisher;
|
||||
use Appwrite\Event\Validator\FunctionEvent;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Platform\Modules\Compute\Base;
|
||||
@@ -105,11 +105,12 @@ class Update extends Base
|
||||
->inject('dbForProject')
|
||||
->inject('project')
|
||||
->inject('queueForEvents')
|
||||
->inject('queueForBuilds')
|
||||
->inject('publisherForBuilds')
|
||||
->inject('dbForPlatform')
|
||||
->inject('gitHub')
|
||||
->inject('executor')
|
||||
->inject('authorization')
|
||||
->inject('platform')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
@@ -139,11 +140,12 @@ class Update extends Base
|
||||
Database $dbForProject,
|
||||
Document $project,
|
||||
Event $queueForEvents,
|
||||
Build $queueForBuilds,
|
||||
BuildPublisher $publisherForBuilds,
|
||||
Database $dbForPlatform,
|
||||
GitHub $github,
|
||||
Executor $executor,
|
||||
Authorization $authorization
|
||||
Authorization $authorization,
|
||||
array $platform
|
||||
) {
|
||||
// TODO: If only branch changes, re-deploy
|
||||
$function = $dbForProject->getDocument('functions', $functionId);
|
||||
@@ -281,7 +283,7 @@ class Update extends Base
|
||||
|
||||
// Redeploy logic
|
||||
if (!$isConnected && !empty($providerRepositoryId)) {
|
||||
$this->redeployVcsFunction($request, $function, $project, $installation, $dbForProject, $queueForBuilds, new Document(), $github, true);
|
||||
$this->redeployVcsFunction($request, $function, $project, $installation, $dbForProject, $publisherForBuilds, new Document(), $github, true, $platform);
|
||||
}
|
||||
|
||||
// Inform scheduler if function is still active
|
||||
|
||||
@@ -2,11 +2,13 @@
|
||||
|
||||
namespace Appwrite\Platform\Modules\Functions\Http\Variables;
|
||||
|
||||
use Appwrite\Event\Event as QueueEvent;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Platform\Modules\Compute\Base;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Database\Validator\CustomId;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\DateTime;
|
||||
@@ -38,6 +40,7 @@ class Create extends Base
|
||||
->groups(['api', 'functions'])
|
||||
->label('scope', 'functions.write')
|
||||
->label('resourceType', RESOURCE_TYPE_FUNCTIONS)
|
||||
->label('event', 'variables.[variableId].create')
|
||||
->label('audits.event', 'variable.create')
|
||||
->label('audits.resource', 'function/{request.functionId}')
|
||||
->label('sdk', new Method(
|
||||
@@ -56,10 +59,12 @@ class Create extends Base
|
||||
]
|
||||
))
|
||||
->param('functionId', '', fn (Database $dbForProject) => new UID($dbForProject->getAdapter()->getMaxUIDLength()), 'Function unique ID.', false, ['dbForProject'])
|
||||
->param('variableId', '', fn (Database $dbForProject) => new CustomId(false, $dbForProject->getAdapter()->getMaxUIDLength()), 'Variable ID. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.', false, ['dbForProject'])
|
||||
->param('key', null, new Text(Database::LENGTH_KEY), 'Variable key. Max length: ' . Database::LENGTH_KEY . ' chars.', false)
|
||||
->param('value', null, new Text(8192, 0), 'Variable value. Max length: 8192 chars.', false)
|
||||
->param('secret', true, new Boolean(), 'Secret variables can be updated or deleted, but only functions can read them during build and runtime.', true)
|
||||
->inject('response')
|
||||
->inject('queueForEvents')
|
||||
->inject('dbForProject')
|
||||
->inject('dbForPlatform')
|
||||
->inject('project')
|
||||
@@ -69,10 +74,12 @@ class Create extends Base
|
||||
|
||||
public function action(
|
||||
string $functionId,
|
||||
string $variableId,
|
||||
string $key,
|
||||
string $value,
|
||||
bool $secret,
|
||||
Response $response,
|
||||
QueueEvent $queueForEvents,
|
||||
Database $dbForProject,
|
||||
Database $dbForPlatform,
|
||||
Document $project,
|
||||
@@ -84,7 +91,7 @@ class Create extends Base
|
||||
throw new Exception(Exception::FUNCTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
$variableId = ID::unique();
|
||||
$variableId = ($variableId === 'unique()') ? ID::unique() : $variableId;
|
||||
|
||||
$teamId = $project->getAttribute('teamId', '');
|
||||
$variable = new Document([
|
||||
@@ -120,6 +127,8 @@ class Create extends Base
|
||||
'active' => $schedule->getAttribute('active'),
|
||||
])));
|
||||
|
||||
$queueForEvents->setParam('variableId', $variable->getId());
|
||||
|
||||
$response
|
||||
->setStatusCode(Response::STATUS_CODE_CREATED)
|
||||
->dynamic($variable, Response::MODEL_VARIABLE);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Appwrite\Platform\Modules\Functions\Http\Variables;
|
||||
|
||||
use Appwrite\Event\Event as QueueEvent;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Platform\Modules\Compute\Base;
|
||||
use Appwrite\SDK\AuthType;
|
||||
@@ -35,6 +36,7 @@ class Delete extends Base
|
||||
->groups(['api', 'functions'])
|
||||
->label('scope', 'functions.write')
|
||||
->label('resourceType', RESOURCE_TYPE_FUNCTIONS)
|
||||
->label('event', 'variables.[variableId].delete')
|
||||
->label('audits.event', 'variable.delete')
|
||||
->label('audits.resource', 'function/{request.functionId}')
|
||||
->label('sdk', new Method(
|
||||
@@ -56,6 +58,7 @@ class Delete extends Base
|
||||
->param('functionId', '', fn (Database $dbForProject) => new UID($dbForProject->getAdapter()->getMaxUIDLength()), 'Function unique ID.', false, ['dbForProject'])
|
||||
->param('variableId', '', fn (Database $dbForProject) => new UID($dbForProject->getAdapter()->getMaxUIDLength()), 'Variable unique ID.', false, ['dbForProject'])
|
||||
->inject('response')
|
||||
->inject('queueForEvents')
|
||||
->inject('dbForProject')
|
||||
->inject('dbForPlatform')
|
||||
->inject('authorization')
|
||||
@@ -66,6 +69,7 @@ class Delete extends Base
|
||||
string $functionId,
|
||||
string $variableId,
|
||||
Response $response,
|
||||
QueueEvent $queueForEvents,
|
||||
Database $dbForProject,
|
||||
Database $dbForPlatform,
|
||||
Authorization $authorization
|
||||
@@ -98,6 +102,8 @@ class Delete extends Base
|
||||
'active' => $schedule->getAttribute('active'),
|
||||
])));
|
||||
|
||||
$queueForEvents->setParam('variableId', $variable->getId());
|
||||
|
||||
$response->noContent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace Appwrite\Platform\Modules\Functions\Http\Variables;
|
||||
|
||||
use Appwrite\Event\Event as QueueEvent;
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\Platform\Modules\Compute\Base;
|
||||
use Appwrite\SDK\AuthType;
|
||||
@@ -38,6 +39,7 @@ class Update extends Base
|
||||
->groups(['api', 'functions'])
|
||||
->label('scope', 'functions.write')
|
||||
->label('resourceType', RESOURCE_TYPE_FUNCTIONS)
|
||||
->label('event', 'variables.[variableId].update')
|
||||
->label('audits.event', 'variable.update')
|
||||
->label('audits.resource', 'function/{request.functionId}')
|
||||
->label('sdk', new Method(
|
||||
@@ -57,10 +59,11 @@ class Update extends Base
|
||||
))
|
||||
->param('functionId', '', fn (Database $dbForProject) => new UID($dbForProject->getAdapter()->getMaxUIDLength()), 'Function unique ID.', false, ['dbForProject'])
|
||||
->param('variableId', '', fn (Database $dbForProject) => new UID($dbForProject->getAdapter()->getMaxUIDLength()), 'Variable unique ID.', false, ['dbForProject'])
|
||||
->param('key', null, new Text(255), 'Variable key. Max length: 255 chars.', false)
|
||||
->param('key', null, new Nullable(new Text(255, 0)), 'Variable key. Max length: 255 chars.', true)
|
||||
->param('value', null, new Nullable(new Text(8192, 0)), 'Variable value. Max length: 8192 chars.', true)
|
||||
->param('secret', null, new Nullable(new Boolean()), 'Secret variables can be updated or deleted, but only functions can read them during build and runtime.', true)
|
||||
->inject('response')
|
||||
->inject('queueForEvents')
|
||||
->inject('dbForProject')
|
||||
->inject('dbForPlatform')
|
||||
->inject('authorization')
|
||||
@@ -70,10 +73,11 @@ class Update extends Base
|
||||
public function action(
|
||||
string $functionId,
|
||||
string $variableId,
|
||||
string $key,
|
||||
?string $key,
|
||||
?string $value,
|
||||
?bool $secret,
|
||||
Response $response,
|
||||
QueueEvent $queueForEvents,
|
||||
Database $dbForProject,
|
||||
Database $dbForPlatform,
|
||||
Authorization $authorization
|
||||
@@ -93,19 +97,27 @@ class Update extends Base
|
||||
throw new Exception(Exception::VARIABLE_CANNOT_UNSET_SECRET);
|
||||
}
|
||||
|
||||
$variable
|
||||
->setAttribute('key', $key)
|
||||
->setAttribute('value', $value ?? $variable->getAttribute('value'))
|
||||
->setAttribute('secret', $secret ?? $variable->getAttribute('secret'))
|
||||
->setAttribute('search', implode(' ', [$variableId, $function->getId(), $key, 'function']));
|
||||
if (\is_null($key) && \is_null($value) && \is_null($secret)) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID);
|
||||
}
|
||||
|
||||
$updates = new Document();
|
||||
|
||||
if (!\is_null($key)) {
|
||||
$updates->setAttribute('key', $key);
|
||||
$updates->setAttribute('search', implode(' ', [$variableId, $function->getId(), $key, 'function']));
|
||||
}
|
||||
|
||||
if (!\is_null($value)) {
|
||||
$updates->setAttribute('value', $value);
|
||||
}
|
||||
|
||||
if (!\is_null($secret)) {
|
||||
$updates->setAttribute('secret', $secret);
|
||||
}
|
||||
|
||||
try {
|
||||
$dbForProject->updateDocument('variables', $variable->getId(), new Document([
|
||||
'key' => $key,
|
||||
'value' => $value ?? $variable->getAttribute('value'),
|
||||
'secret' => $secret ?? $variable->getAttribute('secret'),
|
||||
'search' => implode(' ', [$variableId, $function->getId(), $key, 'function']),
|
||||
]));
|
||||
$variable = $dbForProject->updateDocument('variables', $variable->getId(), $updates);
|
||||
} catch (DuplicateException $th) {
|
||||
throw new Exception(Exception::VARIABLE_ALREADY_EXISTS);
|
||||
}
|
||||
@@ -125,6 +137,8 @@ class Update extends Base
|
||||
'active' => $schedule->getAttribute('active'),
|
||||
])));
|
||||
|
||||
$queueForEvents->setParam('variableId', $variable->getId());
|
||||
|
||||
$response->dynamic($variable, Response::MODEL_VARIABLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,12 +7,18 @@ use Appwrite\Platform\Modules\Compute\Base;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Variables;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception\Order as OrderException;
|
||||
use Utopia\Database\Exception\Query as QueryException;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Query\Cursor;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\Validator\Boolean;
|
||||
|
||||
class XList extends Base
|
||||
{
|
||||
@@ -51,22 +57,74 @@ class XList extends Base
|
||||
)
|
||||
)
|
||||
->param('functionId', '', fn (Database $dbForProject) => new UID($dbForProject->getAdapter()->getMaxUIDLength()), 'Function unique ID.', false, ['dbForProject'])
|
||||
->param('queries', [], new Variables(), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). 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(', ', Variables::ALLOWED_ATTRIBUTES), true)
|
||||
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(string $functionId, Response $response, Database $dbForProject)
|
||||
{
|
||||
/**
|
||||
* @param array<string> $queries
|
||||
*/
|
||||
public function action(
|
||||
string $functionId,
|
||||
array $queries,
|
||||
bool $includeTotal,
|
||||
Response $response,
|
||||
Database $dbForProject
|
||||
) {
|
||||
$function = $dbForProject->getDocument('functions', $functionId);
|
||||
|
||||
if ($function->isEmpty()) {
|
||||
throw new Exception(Exception::FUNCTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
try {
|
||||
$queries = Query::parseQueries($queries);
|
||||
} catch (QueryException $e) {
|
||||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
$queries[] = Query::equal('resourceType', ['function']);
|
||||
$queries[] = Query::equal('resourceInternalId', [$function->getSequence()]);
|
||||
$queries[] = Query::orderAsc();
|
||||
|
||||
$cursor = Query::getCursorQueries($queries, false);
|
||||
$cursor = \reset($cursor);
|
||||
|
||||
if ($cursor !== false) {
|
||||
$validator = new Cursor();
|
||||
if (!$validator->isValid($cursor)) {
|
||||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $validator->getDescription());
|
||||
}
|
||||
|
||||
$variableId = $cursor->getValue();
|
||||
$cursorDocument = $dbForProject->findOne('variables', [
|
||||
Query::equal('$id', [$variableId]),
|
||||
Query::equal('resourceType', ['function']),
|
||||
Query::equal('resourceInternalId', [$function->getSequence()]),
|
||||
]);
|
||||
|
||||
if ($cursorDocument->isEmpty()) {
|
||||
throw new Exception(Exception::GENERAL_CURSOR_NOT_FOUND, "Variable '{$variableId}' for the 'cursor' value not found.");
|
||||
}
|
||||
|
||||
$cursor->setValue($cursorDocument);
|
||||
}
|
||||
|
||||
$filterQueries = Query::groupByType($queries)['filters'];
|
||||
|
||||
try {
|
||||
$variables = $dbForProject->find('variables', $queries);
|
||||
$total = $includeTotal ? $dbForProject->count('variables', $filterQueries, APP_LIMIT_COUNT) : 0;
|
||||
} catch (OrderException $e) {
|
||||
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'variables' => $function->getAttribute('vars', []),
|
||||
'total' => \count($function->getAttribute('vars', [])),
|
||||
'variables' => $variables,
|
||||
'total' => $total,
|
||||
]), Response::MODEL_VARIABLE_LIST);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,11 +10,13 @@ use Appwrite\Event\Publisher\Screenshot;
|
||||
use Appwrite\Event\Publisher\Usage as UsagePublisher;
|
||||
use Appwrite\Event\Realtime;
|
||||
use Appwrite\Event\Webhook;
|
||||
use Appwrite\Extend\Exception as AppwriteException;
|
||||
use Appwrite\Filter\BranchDomain as BranchDomainFilter;
|
||||
use Appwrite\Usage\Context;
|
||||
use Appwrite\Utopia\Response\Model\Deployment;
|
||||
use Appwrite\Vcs\Comment;
|
||||
use Exception;
|
||||
use Executor\Exception\Timeout as ExecutorTimeout;
|
||||
use Executor\Executor;
|
||||
use Swoole\Coroutine as Co;
|
||||
use Utopia\Cache\Cache;
|
||||
@@ -34,6 +36,7 @@ use Utopia\Detector\Detector\Rendering;
|
||||
use Utopia\Logger\Log;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Queue\Message;
|
||||
use Utopia\Span\Span;
|
||||
use Utopia\Storage\Device;
|
||||
use Utopia\Storage\Device\Local;
|
||||
use Utopia\System\System;
|
||||
@@ -183,6 +186,12 @@ class Builds extends Action
|
||||
array $platform,
|
||||
int $timeout
|
||||
): void {
|
||||
Span::add('projectId', $project->getId());
|
||||
Span::add('resourceId', $resource->getId());
|
||||
Span::add('resourceType', $resource->getCollection());
|
||||
Span::add('deploymentId', $deployment->getId());
|
||||
Span::add('timeout', $timeout);
|
||||
|
||||
Console::info('Deployment action started');
|
||||
|
||||
$startTime = DateTime::now();
|
||||
@@ -223,8 +232,12 @@ class Builds extends Action
|
||||
|
||||
$version = $this->getVersion($resource);
|
||||
$runtime = $this->getRuntime($resource, $version);
|
||||
Span::add('runtime', $resource->getAttribute($resource->getCollection() === 'sites' ? 'buildRuntime' : 'runtime', ''));
|
||||
Span::add('version', $version);
|
||||
|
||||
$spec = Config::getParam('specifications')[$resource->getAttribute('buildSpecification', APP_COMPUTE_SPECIFICATION_DEFAULT)];
|
||||
Span::add('cpus', (float) ($spec['cpus'] ?? APP_COMPUTE_CPUS_DEFAULT));
|
||||
Span::add('memory', (int) ($spec['memory'] ?? APP_COMPUTE_MEMORY_DEFAULT));
|
||||
|
||||
// Realtime preparation
|
||||
$event = "{$resource->getCollection()}.[{$resourceKey}].deployments.[deploymentId].update";
|
||||
@@ -720,6 +733,9 @@ class Builds extends Action
|
||||
);
|
||||
|
||||
Console::log('createRuntime finished');
|
||||
} catch (ExecutorTimeout $error) {
|
||||
Console::warning('createRuntime timed out');
|
||||
$err = new AppwriteException(AppwriteException::BUILD_TIMEOUT, previous: $error);
|
||||
} catch (\Throwable $error) {
|
||||
Console::warning('createRuntime failed');
|
||||
$err = $error;
|
||||
@@ -1147,13 +1163,11 @@ class Builds extends Action
|
||||
$message = \str_replace('{APPWRITE_DETECTION_SEPARATOR_START}', '', $message);
|
||||
$message = \str_replace('{APPWRITE_DETECTION_SEPARATOR_END}', '', $message);
|
||||
|
||||
// Combine with previous logs if deployment got past build process
|
||||
$previousLogs = '';
|
||||
if (! is_null($deployment->getAttribute('buildSize', null))) {
|
||||
$previousLogs = $deployment->getAttribute('buildLogs', '');
|
||||
if (! empty($previousLogs)) {
|
||||
$message = $previousLogs . "\n" . $message;
|
||||
}
|
||||
// Append error to whatever build logs were already streamed
|
||||
$deployment = $dbForProject->getDocument('deployments', $deploymentId);
|
||||
$previousLogs = $deployment->getAttribute('buildLogs', '');
|
||||
if (! empty($previousLogs)) {
|
||||
$message = $previousLogs . "\n" . $message;
|
||||
}
|
||||
|
||||
$endTime = DateTime::now();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Appwrite\Platform\Modules\Health\Http\Health\Queue\Builds;
|
||||
|
||||
use Appwrite\Event\Build;
|
||||
use Appwrite\Event\Publisher\Build as BuildPublisher;
|
||||
use Appwrite\Platform\Modules\Health\Http\Health\Queue\Base;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\ContentType;
|
||||
@@ -42,16 +42,16 @@ class Get extends Base
|
||||
contentType: ContentType::JSON
|
||||
))
|
||||
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
|
||||
->inject('queueForBuilds')
|
||||
->inject('publisherForBuilds')
|
||||
->inject('response')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(int|string $threshold, Build $queueForBuilds, Response $response): void
|
||||
public function action(int|string $threshold, BuildPublisher $publisherForBuilds, Response $response): void
|
||||
{
|
||||
$threshold = (int) $threshold;
|
||||
|
||||
$size = $queueForBuilds->getSize();
|
||||
$size = $publisherForBuilds->getSize();
|
||||
|
||||
$this->assertQueueThreshold($size, $threshold);
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
namespace Appwrite\Platform\Modules\Health\Http\Health\Queue\Failed;
|
||||
|
||||
use Appwrite\Event\Build;
|
||||
use Appwrite\Event\Database;
|
||||
use Appwrite\Event\Delete;
|
||||
use Appwrite\Event\Event;
|
||||
@@ -10,6 +9,7 @@ use Appwrite\Event\Func;
|
||||
use Appwrite\Event\Mail;
|
||||
use Appwrite\Event\Messaging;
|
||||
use Appwrite\Event\Publisher\Audit;
|
||||
use Appwrite\Event\Publisher\Build as BuildPublisher;
|
||||
use Appwrite\Event\Publisher\Certificate;
|
||||
use Appwrite\Event\Publisher\Migration as MigrationPublisher;
|
||||
use Appwrite\Event\Publisher\Screenshot;
|
||||
@@ -83,7 +83,7 @@ class Get extends Base
|
||||
->inject('publisherForUsage')
|
||||
->inject('queueForWebhooks')
|
||||
->inject('publisherForCertificates')
|
||||
->inject('queueForBuilds')
|
||||
->inject('publisherForBuilds')
|
||||
->inject('queueForMessaging')
|
||||
->inject('publisherForMigrations')
|
||||
->inject('publisherForScreenshots')
|
||||
@@ -103,7 +103,7 @@ class Get extends Base
|
||||
UsagePublisher $publisherForUsage,
|
||||
Webhook $queueForWebhooks,
|
||||
Certificate $publisherForCertificates,
|
||||
Build $queueForBuilds,
|
||||
BuildPublisher $publisherForBuilds,
|
||||
Messaging $queueForMessaging,
|
||||
MigrationPublisher $publisherForMigrations,
|
||||
Screenshot $publisherForScreenshots,
|
||||
@@ -120,7 +120,7 @@ class Get extends Base
|
||||
System::getEnv('_APP_STATS_USAGE_QUEUE_NAME', Event::STATS_USAGE_QUEUE_NAME) => $publisherForUsage,
|
||||
System::getEnv('_APP_WEBHOOK_QUEUE_NAME', Event::WEBHOOK_QUEUE_NAME) => $queueForWebhooks,
|
||||
System::getEnv('_APP_CERTIFICATES_QUEUE_NAME', Event::CERTIFICATES_QUEUE_NAME) => $publisherForCertificates,
|
||||
System::getEnv('_APP_BUILDS_QUEUE_NAME', Event::BUILDS_QUEUE_NAME) => $queueForBuilds,
|
||||
System::getEnv('_APP_BUILDS_QUEUE_NAME', Event::BUILDS_QUEUE_NAME) => $publisherForBuilds,
|
||||
System::getEnv('_APP_SCREENSHOTS_QUEUE_NAME', Event::SCREENSHOTS_QUEUE_NAME) => $publisherForScreenshots,
|
||||
System::getEnv('_APP_MESSAGING_QUEUE_NAME', Event::MESSAGING_QUEUE_NAME) => $queueForMessaging,
|
||||
System::getEnv('_APP_MIGRATIONS_QUEUE_NAME', Event::MIGRATIONS_QUEUE_NAME) => $publisherForMigrations,
|
||||
|
||||
@@ -13,6 +13,7 @@ use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Migration\Destinations\OnDuplicate;
|
||||
use Utopia\Migration\Sources\Appwrite as AppwriteSource;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
@@ -57,6 +58,7 @@ class Create extends Action
|
||||
->param('endpoint', '', new URL(), 'Source Appwrite endpoint')
|
||||
->param('projectId', '', fn (Database $dbForProject) => new UID($dbForProject->getAdapter()->getMaxUIDLength()), 'Source Project ID', false, ['dbForProject'])
|
||||
->param('apiKey', '', new Text(512), 'Source API Key')
|
||||
->param('onDuplicate', OnDuplicate::Fail->value, new WhiteList(OnDuplicate::values()), 'Behavior when a row with an existing $id is encountered. "fail" (default): abort on first conflict. "skip": silently ignore. "overwrite": replace existing row.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('project')
|
||||
@@ -71,6 +73,7 @@ class Create extends Action
|
||||
string $endpoint,
|
||||
string $projectId,
|
||||
string $apiKey,
|
||||
string $onDuplicate,
|
||||
Response $response,
|
||||
Database $dbForProject,
|
||||
Document $project,
|
||||
@@ -93,6 +96,9 @@ class Create extends Action
|
||||
'statusCounters' => '{}',
|
||||
'resourceData' => '{}',
|
||||
'errors' => [],
|
||||
'options' => [
|
||||
'onDuplicate' => $onDuplicate,
|
||||
],
|
||||
]));
|
||||
|
||||
$queueForEvents->setParam('migrationId', $migration->getId());
|
||||
|
||||
@@ -20,6 +20,7 @@ use Utopia\Database\Document;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Migration\Destinations\OnDuplicate;
|
||||
use Utopia\Migration\Resource;
|
||||
use Utopia\Migration\Sources\Appwrite as AppwriteSource;
|
||||
use Utopia\Migration\Sources\CSV;
|
||||
@@ -29,6 +30,7 @@ use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\Storage\Device;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
class Create extends Action
|
||||
{
|
||||
@@ -67,6 +69,7 @@ class Create extends Action
|
||||
->param('fileId', '', fn (Database $dbForProject) => new UID($dbForProject->getAdapter()->getMaxUIDLength()), 'File ID.', false, ['dbForProject'])
|
||||
->param('resourceId', null, new CompoundUID(), 'Composite ID in the format {databaseId:collectionId}, identifying a collection within a database.')
|
||||
->param('internalFile', false, new Boolean(), 'Is the file stored in an internal bucket?', true)
|
||||
->param('onDuplicate', OnDuplicate::Fail->value, new WhiteList(OnDuplicate::values()), 'Behavior when a row with an existing $id is encountered. "fail" (default): abort on first conflict. "skip": silently ignore. "overwrite": replace existing row.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('dbForPlatform')
|
||||
@@ -85,6 +88,7 @@ class Create extends Action
|
||||
string $fileId,
|
||||
string $resourceId,
|
||||
bool $internalFile,
|
||||
string $onDuplicate,
|
||||
Response $response,
|
||||
Database $dbForProject,
|
||||
Database $dbForPlatform,
|
||||
@@ -183,6 +187,7 @@ class Create extends Action
|
||||
'options' => [
|
||||
'path' => $newPath,
|
||||
'size' => $fileSize,
|
||||
'onDuplicate' => $onDuplicate,
|
||||
],
|
||||
]));
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ use Utopia\Database\Document;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Database\Validator\UID;
|
||||
use Utopia\Migration\Destinations\OnDuplicate;
|
||||
use Utopia\Migration\Resource;
|
||||
use Utopia\Migration\Sources\Appwrite as AppwriteSource;
|
||||
use Utopia\Migration\Sources\JSON as JSONSource;
|
||||
@@ -29,6 +30,7 @@ use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\Storage\Device;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\Boolean;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
class Create extends Action
|
||||
{
|
||||
@@ -66,6 +68,7 @@ class Create extends Action
|
||||
->param('fileId', '', new UID(), 'File ID.')
|
||||
->param('resourceId', null, new CompoundUID(), 'Composite ID in the format {databaseId:collectionId}, identifying a collection within a database.')
|
||||
->param('internalFile', false, new Boolean(), 'Is the file stored in an internal bucket?', true)
|
||||
->param('onDuplicate', OnDuplicate::Fail->value, new WhiteList(OnDuplicate::values()), 'Behavior when a row with an existing $id is encountered. "fail" (default): abort on first conflict. "skip": silently ignore. "overwrite": replace existing row.', true)
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
->inject('dbForPlatform')
|
||||
@@ -84,6 +87,7 @@ class Create extends Action
|
||||
string $fileId,
|
||||
string $resourceId,
|
||||
bool $internalFile,
|
||||
string $onDuplicate,
|
||||
Response $response,
|
||||
Database $dbForProject,
|
||||
Database $dbForPlatform,
|
||||
@@ -183,6 +187,7 @@ class Create extends Action
|
||||
'options' => [
|
||||
'path' => $newPath,
|
||||
'size' => $fileSize,
|
||||
'onDuplicate' => $onDuplicate,
|
||||
],
|
||||
]));
|
||||
|
||||
|
||||
+6
-7
@@ -1,6 +1,6 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Platform\Modules\Project\Http\Project\Keys\Standard;
|
||||
namespace Appwrite\Platform\Modules\Project\Http\Project\Keys;
|
||||
|
||||
use Appwrite\Event\Event as QueueEvent;
|
||||
use Appwrite\Extend\Exception;
|
||||
@@ -30,17 +30,16 @@ class Create extends Base
|
||||
|
||||
public static function getName()
|
||||
{
|
||||
return 'createStandardProjectKey';
|
||||
return 'createProjectKey';
|
||||
}
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this
|
||||
->setHttpMethod(Action::HTTP_REQUEST_METHOD_POST)
|
||||
->setHttpPath('/v1/project/keys/standard')
|
||||
->httpAlias('/v1/project/keys')
|
||||
->setHttpPath('/v1/project/keys')
|
||||
->httpAlias('/v1/projects/:projectId/keys')
|
||||
->desc('Create standard project key')
|
||||
->desc('Create project key')
|
||||
->groups(['api', 'project'])
|
||||
->label('scope', 'keys.write')
|
||||
->label('event', 'keys.[keyId].create')
|
||||
@@ -49,9 +48,9 @@ class Create extends Base
|
||||
->label('sdk', new Method(
|
||||
namespace: 'project',
|
||||
group: 'keys',
|
||||
name: 'createStandardKey',
|
||||
name: 'createKey',
|
||||
description: <<<EOT
|
||||
Create a new standard API key. It's recommended to have multiple API keys with strict scopes for separate functions within your project.
|
||||
Create a new API key. It's recommended to have multiple API keys with strict scopes for separate functions within your project.
|
||||
|
||||
You can also create an ephemeral API key if you need a short-lived key instead.
|
||||
EOT,
|
||||
@@ -59,7 +59,7 @@ class Create extends Base
|
||||
],
|
||||
))
|
||||
->param('scopes', [], new ArrayList(new WhiteList(array_keys(Config::getParam('projectScopes')), true), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Key scopes list. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' scopes are allowed.', optional: false)
|
||||
->param('duration', 900, new Range(1, 3600), 'Time in seconds before ephemeral key expires. Default duration is 900 seconds, and maximum is 3600 seconds.', true)
|
||||
->param('duration', null, new Range(1, 3600), 'Time in seconds before ephemeral key expires. Maximum duration is 3600 seconds.', optional: false, example: 600)
|
||||
->inject('response')
|
||||
->inject('queueForEvents')
|
||||
->inject('project')
|
||||
|
||||
@@ -146,13 +146,14 @@ class Update extends Base
|
||||
{
|
||||
$providerId = static::getProviderId();
|
||||
$oAuthProviders = $project->getAttribute('oAuthProviders', []);
|
||||
$storedSecret = $this->decodeStoredSecret($project);
|
||||
|
||||
return new Document([
|
||||
'$id' => $providerId,
|
||||
'enabled' => $oAuthProviders[$providerId . 'Enabled'] ?? false,
|
||||
static::getClientIdParamName() => $oAuthProviders[$providerId . 'Appid'] ?? '',
|
||||
'keyId' => '',
|
||||
'teamId' => '',
|
||||
'keyId' => $storedSecret['keyID'] ?? '',
|
||||
'teamId' => $storedSecret['teamID'] ?? '',
|
||||
'p8File' => '',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ class Update extends Base
|
||||
))
|
||||
->param(static::getClientIdParamName(), null, new Nullable(new Text(256, 0)), static::getClientIdDescription(), optional: true)
|
||||
->param(static::getClientSecretParamName(), null, new Nullable(new Text(512, 0)), static::getClientSecretDescription(), optional: true)
|
||||
->param('endpoint', '', new Text(256, 1), 'Domain of Authentik instance. For example: example.authentik.com', optional: false)
|
||||
->param('endpoint', null, new Nullable(new Text(256, 0)), 'Domain of Authentik instance. For example: example.authentik.com', optional: true)
|
||||
->param('enabled', null, new Nullable(new Boolean()), 'OAuth2 sign-in method status. Set to true to enable new session creation. Setting to true will trigger end-to-end credentials validation, and will throw if the credentials are invalid.', true)
|
||||
->inject('response')
|
||||
->inject('dbForPlatform')
|
||||
@@ -138,7 +138,7 @@ class Update extends Base
|
||||
public function handle(
|
||||
?string $clientId,
|
||||
?string $clientSecret,
|
||||
string $endpoint,
|
||||
?string $endpoint,
|
||||
?bool $enabled,
|
||||
Response $response,
|
||||
Database $dbForPlatform,
|
||||
@@ -151,7 +151,7 @@ class Update extends Base
|
||||
|
||||
// The secret is stored as JSON `{"clientSecret": "...", "authentikDomain": "..."}`
|
||||
// to match the shape Authentik's OAuth2 adapter expects (getAuthentikDomain()).
|
||||
// The `endpoint` param is required on every call, so it's always written.
|
||||
// The `endpoint` param is optional; if omitted, the existing stored endpoint is preserved.
|
||||
// `clientSecret` is optional; if omitted, the existing stored secret is preserved.
|
||||
$storedRaw = $project->getAttribute('oAuthProviders', [])[$providerId . 'Secret'] ?? '';
|
||||
$existing = [];
|
||||
@@ -160,7 +160,7 @@ class Update extends Base
|
||||
}
|
||||
$encodedSecret = \json_encode([
|
||||
'clientSecret' => $clientSecret ?? ($existing['clientSecret'] ?? ''),
|
||||
'authentikDomain' => $endpoint,
|
||||
'authentikDomain' => $endpoint ?? ($existing['authentikDomain'] ?? ''),
|
||||
]);
|
||||
|
||||
$project = $this->persistCredentials($project, $dbForPlatform, $authorization, $clientId, $encodedSecret, $enabled);
|
||||
|
||||
@@ -105,7 +105,7 @@ class Update extends Base
|
||||
))
|
||||
->param(static::getClientIdParamName(), null, new Nullable(new Text(256, 0)), static::getClientIdDescription(), optional: true)
|
||||
->param(static::getClientSecretParamName(), null, new Nullable(new Text(512, 0)), static::getClientSecretDescription(), optional: true)
|
||||
->param('endpoint', '', new Text(256, 1), 'Domain of FusionAuth instance. For example: example.fusionauth.io', optional: false)
|
||||
->param('endpoint', null, new Nullable(new Text(256, 0)), 'Domain of FusionAuth instance. For example: example.fusionauth.io', optional: true)
|
||||
->param('enabled', null, new Nullable(new Boolean()), 'OAuth2 sign-in method status. Set to true to enable new session creation. Setting to true will trigger end-to-end credentials validation, and will throw if the credentials are invalid.', true)
|
||||
->inject('response')
|
||||
->inject('dbForPlatform')
|
||||
@@ -138,7 +138,7 @@ class Update extends Base
|
||||
public function handle(
|
||||
?string $clientId,
|
||||
?string $clientSecret,
|
||||
string $endpoint,
|
||||
?string $endpoint,
|
||||
?bool $enabled,
|
||||
Response $response,
|
||||
Database $dbForPlatform,
|
||||
@@ -151,7 +151,7 @@ class Update extends Base
|
||||
|
||||
// The secret is stored as JSON `{"clientSecret": "...", "fusionAuthDomain": "..."}`
|
||||
// to match the shape FusionAuth's OAuth2 adapter expects (getFusionAuthDomain()).
|
||||
// The `endpoint` param is required on every call, so it's always written.
|
||||
// The `endpoint` param is optional; if omitted, the existing stored endpoint is preserved.
|
||||
// `clientSecret` is optional; if omitted, the existing stored secret is preserved.
|
||||
$storedRaw = $project->getAttribute('oAuthProviders', [])[$providerId . 'Secret'] ?? '';
|
||||
$existing = [];
|
||||
@@ -160,7 +160,7 @@ class Update extends Base
|
||||
}
|
||||
$encodedSecret = \json_encode([
|
||||
'clientSecret' => $clientSecret ?? ($existing['clientSecret'] ?? ''),
|
||||
'fusionAuthDomain' => $endpoint,
|
||||
'fusionAuthDomain' => $endpoint ?? ($existing['fusionAuthDomain'] ?? ''),
|
||||
]);
|
||||
|
||||
$project = $this->persistCredentials($project, $dbForPlatform, $authorization, $clientId, $encodedSecret, $enabled);
|
||||
|
||||
@@ -11,7 +11,7 @@ use Utopia\Config\Config;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
class Get extends Action
|
||||
{
|
||||
@@ -86,28 +86,28 @@ class Get extends Action
|
||||
)
|
||||
]
|
||||
))
|
||||
->param('provider', '', new Text(128), 'OAuth2 provider key. For example: github, google, apple.')
|
||||
->param('providerId', '', new WhiteList(\array_keys(Config::getParam('oAuthProviders', [])), true), 'OAuth2 provider key. For example: github, google, apple.', aliases: ['provider'])
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(
|
||||
string $provider,
|
||||
string $providerId,
|
||||
Response $response,
|
||||
Document $project,
|
||||
): void {
|
||||
$providers = Config::getParam('oAuthProviders', []);
|
||||
if (!\array_key_exists($provider, $providers) || !($providers[$provider]['enabled'] ?? false)) {
|
||||
if (!\array_key_exists($providerId, $providers) || !($providers[$providerId]['enabled'] ?? false)) {
|
||||
throw new Exception(Exception::PROJECT_PROVIDER_UNSUPPORTED);
|
||||
}
|
||||
|
||||
$actions = Base::getProviderActions();
|
||||
if (!isset($actions[$provider])) {
|
||||
if (!isset($actions[$providerId])) {
|
||||
throw new Exception(Exception::PROJECT_PROVIDER_UNSUPPORTED);
|
||||
}
|
||||
|
||||
$updateClass = $actions[$provider];
|
||||
$updateClass = $actions[$providerId];
|
||||
$action = new $updateClass();
|
||||
|
||||
$response->dynamic($action->buildReadResponse($project), $updateClass::getResponseModel());
|
||||
|
||||
@@ -35,7 +35,7 @@ class Update extends Base
|
||||
|
||||
public static function getClientIdName(): string
|
||||
{
|
||||
return 'OAuth 2 app Client ID, or App ID';
|
||||
return 'OAuth2 app Client ID, or App ID';
|
||||
}
|
||||
|
||||
public static function getClientIdExample(): string
|
||||
|
||||
@@ -111,8 +111,8 @@ class Update extends Base
|
||||
))
|
||||
->param(static::getClientIdParamName(), null, new Nullable(new Text(256, 0)), static::getClientIdDescription(), optional: true)
|
||||
->param(static::getClientSecretParamName(), null, new Nullable(new Text(512, 0)), static::getClientSecretDescription(), optional: true)
|
||||
->param('endpoint', '', new Text(256, 1), 'Domain of Keycloak instance. For example: keycloak.example.com', optional: false)
|
||||
->param('realmName', '', new Text(256, 1), 'Keycloak realm name. For example: appwrite-realm', optional: false)
|
||||
->param('endpoint', null, new Nullable(new Text(256, 0)), 'Domain of Keycloak instance. For example: keycloak.example.com', optional: true)
|
||||
->param('realmName', null, new Nullable(new Text(256, 0)), 'Keycloak realm name. For example: appwrite-realm', optional: true)
|
||||
->param('enabled', null, new Nullable(new Boolean()), 'OAuth2 sign-in method status. Set to true to enable new session creation. Setting to true will trigger end-to-end credentials validation, and will throw if the credentials are invalid.', true)
|
||||
->inject('response')
|
||||
->inject('dbForPlatform')
|
||||
@@ -147,8 +147,8 @@ class Update extends Base
|
||||
public function handle(
|
||||
?string $clientId,
|
||||
?string $clientSecret,
|
||||
string $endpoint,
|
||||
string $realmName,
|
||||
?string $endpoint,
|
||||
?string $realmName,
|
||||
?bool $enabled,
|
||||
Response $response,
|
||||
Database $dbForPlatform,
|
||||
@@ -161,7 +161,7 @@ class Update extends Base
|
||||
|
||||
// The secret is stored as JSON `{"clientSecret": "...", "keycloakDomain": "...", "keycloakRealm": "..."}`
|
||||
// to match the shape Keycloak's OAuth2 adapter expects (getKeycloakDomain(), getKeycloakRealm()).
|
||||
// The `endpoint` and `realmName` params are required on every call, so they're always written.
|
||||
// The `endpoint` and `realmName` params are optional; if omitted, existing stored values are preserved.
|
||||
// `clientSecret` is optional; if omitted, the existing stored secret is preserved.
|
||||
$storedRaw = $project->getAttribute('oAuthProviders', [])[$providerId . 'Secret'] ?? '';
|
||||
$existing = [];
|
||||
@@ -170,8 +170,8 @@ class Update extends Base
|
||||
}
|
||||
$encodedSecret = \json_encode([
|
||||
'clientSecret' => $clientSecret ?? ($existing['clientSecret'] ?? ''),
|
||||
'keycloakDomain' => $endpoint,
|
||||
'keycloakRealm' => $realmName,
|
||||
'keycloakDomain' => $endpoint ?? ($existing['keycloakDomain'] ?? ''),
|
||||
'keycloakRealm' => $realmName ?? ($existing['keycloakRealm'] ?? ''),
|
||||
]);
|
||||
|
||||
$project = $this->persistCredentials($project, $dbForPlatform, $authorization, $clientId, $encodedSecret, $enabled);
|
||||
|
||||
@@ -115,7 +115,7 @@ class Update extends Base
|
||||
))
|
||||
->param(static::getClientIdParamName(), null, new Nullable(new Text(256, 0)), static::getClientIdDescription(), optional: true)
|
||||
->param(static::getClientSecretParamName(), null, new Nullable(new Text(512, 0)), static::getClientSecretDescription(), optional: true)
|
||||
->param('tenant', '', new Text(256, 1), 'Microsoft Entra ID tenant identifier. Use \'common\', \'organizations\', \'consumers\' or a specific tenant ID. For example: common', optional: false)
|
||||
->param('tenant', null, new Nullable(new Text(256, 0)), 'Microsoft Entra ID tenant identifier. Use \'common\', \'organizations\', \'consumers\' or a specific tenant ID. For example: common', true)
|
||||
->param('enabled', null, new Nullable(new Boolean()), 'OAuth2 sign-in method status. Set to true to enable new session creation. Setting to true will trigger end-to-end credentials validation, and will throw if the credentials are invalid.', true)
|
||||
->inject('response')
|
||||
->inject('dbForPlatform')
|
||||
@@ -148,7 +148,7 @@ class Update extends Base
|
||||
public function handle(
|
||||
?string $applicationId,
|
||||
?string $applicationSecret,
|
||||
string $tenant,
|
||||
?string $tenant,
|
||||
?bool $enabled,
|
||||
Response $response,
|
||||
Database $dbForPlatform,
|
||||
@@ -161,7 +161,7 @@ class Update extends Base
|
||||
|
||||
// The secret is stored as JSON `{"clientSecret": "...", "tenantID": "..."}`
|
||||
// to match the shape Microsoft's OAuth2 adapter expects (getTenantID()).
|
||||
// The `tenant` param is required on every call, so it's always written.
|
||||
// The `tenant` param is optional; if omitted, the existing stored tenant is preserved.
|
||||
// `applicationSecret` is optional; if omitted, the existing stored secret is preserved.
|
||||
$storedRaw = $project->getAttribute('oAuthProviders', [])[$providerId . 'Secret'] ?? '';
|
||||
$existing = [];
|
||||
@@ -170,7 +170,7 @@ class Update extends Base
|
||||
}
|
||||
$encodedSecret = \json_encode([
|
||||
'clientSecret' => $applicationSecret ?? ($existing['clientSecret'] ?? ''),
|
||||
'tenantID' => $tenant,
|
||||
'tenantID' => $tenant ?? ($existing['tenantID'] ?? ''),
|
||||
]);
|
||||
|
||||
$project = $this->persistCredentials($project, $dbForPlatform, $authorization, $applicationId, $encodedSecret, $enabled);
|
||||
|
||||
@@ -82,13 +82,13 @@ class Update extends Base
|
||||
'hint' => '',
|
||||
],
|
||||
[
|
||||
'$id' => 'tokenUrl',
|
||||
'$id' => 'tokenURL',
|
||||
'name' => 'Token URL',
|
||||
'example' => 'https://myoauth.com/oauth2/token',
|
||||
'hint' => '',
|
||||
],
|
||||
[
|
||||
'$id' => 'userInfoUrl',
|
||||
'$id' => 'userInfoURL',
|
||||
'name' => 'User Info URL',
|
||||
'example' => 'https://myoauth.com/oauth2/userinfo',
|
||||
'hint' => '',
|
||||
@@ -127,8 +127,8 @@ class Update extends Base
|
||||
->param(static::getClientSecretParamName(), null, new Nullable(new Text(512, 0)), static::getClientSecretDescription(), optional: true)
|
||||
->param('wellKnownURL', null, new Nullable(new URL(allowEmpty: true)), 'OpenID Connect well-known configuration URL. When provided, authorization, token, and user info endpoints can be discovered automatically. For example: https://myoauth.com/.well-known/openid-configuration', optional: true)
|
||||
->param('authorizationURL', null, new Nullable(new URL(allowEmpty: true)), 'OpenID Connect authorization endpoint URL. Required when wellKnownURL is not provided. For example: https://myoauth.com/oauth2/authorize', optional: true)
|
||||
->param('tokenUrl', null, new Nullable(new URL(allowEmpty: true)), 'OpenID Connect token endpoint URL. Required when wellKnownURL is not provided. For example: https://myoauth.com/oauth2/token', optional: true)
|
||||
->param('userInfoUrl', null, new Nullable(new URL(allowEmpty: true)), 'OpenID Connect user info endpoint URL. Required when wellKnownURL is not provided. For example: https://myoauth.com/oauth2/userinfo', optional: true)
|
||||
->param('tokenURL', null, new Nullable(new URL(allowEmpty: true)), 'OpenID Connect token endpoint URL. Required when wellKnownURL is not provided. For example: https://myoauth.com/oauth2/token', optional: true, aliases: ['tokenUrl'])
|
||||
->param('userInfoURL', null, new Nullable(new URL(allowEmpty: true)), 'OpenID Connect user info endpoint URL. Required when wellKnownURL is not provided. For example: https://myoauth.com/oauth2/userinfo', optional: true, aliases: ['userInfoUrl'])
|
||||
->param('enabled', null, new Nullable(new Boolean()), 'OAuth2 sign-in method status. Set to true to enable new session creation. Setting to true will trigger end-to-end credentials validation, and will throw if the credentials are invalid.', true)
|
||||
->inject('response')
|
||||
->inject('dbForPlatform')
|
||||
@@ -151,8 +151,8 @@ class Update extends Base
|
||||
static::getClientSecretParamName() => '',
|
||||
'wellKnownURL' => $decoded['wellKnownEndpoint'] ?? '',
|
||||
'authorizationURL' => $decoded['authorizationEndpoint'] ?? '',
|
||||
'tokenUrl' => $decoded['tokenEndpoint'] ?? '',
|
||||
'userInfoUrl' => $decoded['userInfoEndpoint'] ?? '',
|
||||
'tokenURL' => $decoded['tokenEndpoint'] ?? '',
|
||||
'userInfoURL' => $decoded['userInfoEndpoint'] ?? '',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -174,8 +174,8 @@ class Update extends Base
|
||||
?string $clientSecret,
|
||||
?string $wellKnownURL,
|
||||
?string $authorizationURL,
|
||||
?string $tokenUrl,
|
||||
?string $userInfoUrl,
|
||||
?string $tokenURL,
|
||||
?string $userInfoURL,
|
||||
?bool $enabled,
|
||||
Response $response,
|
||||
Database $dbForPlatform,
|
||||
@@ -201,8 +201,8 @@ class Update extends Base
|
||||
'clientSecret' => $clientSecret ?? ($existing['clientSecret'] ?? ''),
|
||||
'wellKnownEndpoint' => $wellKnownURL ?? ($existing['wellKnownEndpoint'] ?? ''),
|
||||
'authorizationEndpoint' => $authorizationURL ?? ($existing['authorizationEndpoint'] ?? ''),
|
||||
'tokenEndpoint' => $tokenUrl ?? ($existing['tokenEndpoint'] ?? ''),
|
||||
'userInfoEndpoint' => $userInfoUrl ?? ($existing['userInfoEndpoint'] ?? ''),
|
||||
'tokenEndpoint' => $tokenURL ?? ($existing['tokenEndpoint'] ?? ''),
|
||||
'userInfoEndpoint' => $userInfoURL ?? ($existing['userInfoEndpoint'] ?? ''),
|
||||
];
|
||||
|
||||
// When enabling, require either wellKnownEndpoint alone, or all three
|
||||
@@ -215,7 +215,7 @@ class Update extends Base
|
||||
&& !empty($merged['userInfoEndpoint']);
|
||||
|
||||
if (!$hasWellKnown && !$hasAllDiscovery) {
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Enabling OpenID Connect requires either wellKnownURL, or all of authorizationURL, tokenUrl, and userInfoUrl.');
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'Enabling OpenID Connect requires either wellKnownURL, or all of authorizationURL, tokenURL, and userInfoURL.');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,14 +2,21 @@
|
||||
|
||||
namespace Appwrite\Platform\Modules\Project\Http\Project\OAuth2;
|
||||
|
||||
use Appwrite\Extend\Exception;
|
||||
use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception\Query as QueryException;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Queries;
|
||||
use Utopia\Database\Validator\Query\Limit;
|
||||
use Utopia\Database\Validator\Query\Offset;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
use Utopia\Validator\Boolean;
|
||||
|
||||
class XList extends Action
|
||||
{
|
||||
@@ -43,15 +50,28 @@ class XList extends Action
|
||||
)
|
||||
]
|
||||
))
|
||||
->param('queries', [], new Queries([new Limit(), new Offset()]), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Only supported methods are limit and offset', true)
|
||||
->param('total', true, new Boolean(true), 'When set to false, the total count returned will be 0 and will not be calculated.', true)
|
||||
->inject('response')
|
||||
->inject('project')
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string> $queries
|
||||
*/
|
||||
public function action(
|
||||
array $queries,
|
||||
bool $includeTotal,
|
||||
Response $response,
|
||||
Document $project,
|
||||
): void {
|
||||
try {
|
||||
$queries = Query::parseQueries($queries);
|
||||
} catch (QueryException $e) {
|
||||
throw new Exception(Exception::GENERAL_QUERY_INVALID, $e->getMessage());
|
||||
}
|
||||
|
||||
$providers = Config::getParam('oAuthProviders', []);
|
||||
$actions = Base::getProviderActions();
|
||||
|
||||
@@ -66,8 +86,16 @@ class XList extends Action
|
||||
$documents[] = $action->buildReadResponse($project);
|
||||
}
|
||||
|
||||
$total = $includeTotal ? \count($documents) : 0;
|
||||
|
||||
$grouped = Query::groupByType($queries);
|
||||
$offset = $grouped['offset'] ?? 0;
|
||||
$limit = $grouped['limit'] ?? null;
|
||||
|
||||
$documents = \array_slice($documents, $offset, $limit);
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'total' => \count($documents),
|
||||
'total' => $total,
|
||||
'providers' => $documents,
|
||||
]), Response::MODEL_OAUTH2_PROVIDER_LIST);
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ class Get extends Action
|
||||
->setHttpPath('/v1/project/policies/:policyId')
|
||||
->desc('Get project policy')
|
||||
->groups(['api', 'project'])
|
||||
->label('scope', 'policies.read')
|
||||
->label('scope', ['policies.read', 'project.policies.read'])
|
||||
->label('sdk', new Method(
|
||||
namespace: 'project',
|
||||
group: 'policies',
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ class Update extends Action
|
||||
->httpAlias('/v1/projects/:projectId/auth/memberships-privacy')
|
||||
->desc('Update membership privacy policy')
|
||||
->groups(['api', 'project'])
|
||||
->label('scope', 'policies.write')
|
||||
->label('scope', ['policies.write', 'project.policies.write'])
|
||||
->label('event', 'projects.[projectId].policies.[policy].update')
|
||||
->label('audits.event', 'projects.[projectId].policies.[policy].update')
|
||||
->label('audits.resource', 'project/{response.$id}')
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ class Update extends Action
|
||||
->httpAlias('/v1/projects/:projectId/auth/password-dictionary')
|
||||
->desc('Update password dictionary policy')
|
||||
->groups(['api', 'project'])
|
||||
->label('scope', 'policies.write')
|
||||
->label('scope', ['policies.write', 'project.policies.write'])
|
||||
->label('event', 'projects.[projectId].policies.[policy].update')
|
||||
->label('audits.event', 'projects.[projectId].policies.[policy].update')
|
||||
->label('audits.resource', 'project/{response.$id}')
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@ class Update extends Action
|
||||
->httpAlias('/v1/projects/:projectId/auth/password-history')
|
||||
->desc('Update password history policy')
|
||||
->groups(['api', 'project'])
|
||||
->label('scope', 'policies.write')
|
||||
->label('scope', ['policies.write', 'project.policies.write'])
|
||||
->label('event', 'projects.[projectId].policies.[policy].update')
|
||||
->label('audits.event', 'projects.[projectId].policies.[policy].update')
|
||||
->label('audits.resource', 'project/{response.$id}')
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ class Update extends Action
|
||||
->httpAlias('/v1/projects/:projectId/auth/personal-data')
|
||||
->desc('Update password personal data policy')
|
||||
->groups(['api', 'project'])
|
||||
->label('scope', 'policies.write')
|
||||
->label('scope', ['policies.write', 'project.policies.write'])
|
||||
->label('event', 'projects.[projectId].policies.[policy].update')
|
||||
->label('audits.event', 'projects.[projectId].policies.[policy].update')
|
||||
->label('audits.resource', 'project/{response.$id}')
|
||||
|
||||
@@ -31,7 +31,7 @@ class Update extends Action
|
||||
->httpAlias('/v1/projects/:projectId/auth/session-alerts')
|
||||
->desc('Update session alert policy')
|
||||
->groups(['api', 'project'])
|
||||
->label('scope', 'policies.write')
|
||||
->label('scope', ['policies.write', 'project.policies.write'])
|
||||
->label('event', 'projects.[projectId].policies.[policy].update')
|
||||
->label('audits.event', 'projects.[projectId].policies.[policy].update')
|
||||
->label('audits.resource', 'project/{response.$id}')
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ class Update extends Action
|
||||
->httpAlias('/v1/projects/:projectId/auth/duration')
|
||||
->desc('Update session duration policy')
|
||||
->groups(['api', 'project'])
|
||||
->label('scope', 'policies.write')
|
||||
->label('scope', ['policies.write', 'project.policies.write'])
|
||||
->label('event', 'projects.[projectId].policies.[policy].update')
|
||||
->label('audits.event', 'projects.[projectId].policies.[policy].update')
|
||||
->label('audits.resource', 'project/{response.$id}')
|
||||
|
||||
+1
-1
@@ -31,7 +31,7 @@ class Update extends Action
|
||||
->httpAlias('/v1/projects/:projectId/auth/session-invalidation')
|
||||
->desc('Update session invalidation policy')
|
||||
->groups(['api', 'project'])
|
||||
->label('scope', 'policies.write')
|
||||
->label('scope', ['policies.write', 'project.policies.write'])
|
||||
->label('event', 'projects.[projectId].policies.[policy].update')
|
||||
->label('audits.event', 'projects.[projectId].policies.[policy].update')
|
||||
->label('audits.resource', 'project/{response.$id}')
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user