mirror of
https://github.com/appwrite/appwrite
synced 2026-05-23 00:49:02 +00:00
Merge branch '1.6.x' into chore-release-client-sdks
This commit is contained in:
commit
0e56743dca
11 changed files with 68 additions and 6 deletions
1
.env
1
.env
|
|
@ -109,3 +109,4 @@ _APP_MESSAGE_EMAIL_TEST_DSN=
|
|||
_APP_MESSAGE_PUSH_TEST_DSN=
|
||||
_APP_WEBHOOK_MAX_FAILED_ATTEMPTS=10
|
||||
_APP_PROJECT_REGIONS=default
|
||||
_APP_FUNCTIONS_CREATION_ABUSE_LIMIT=5000
|
||||
|
|
|
|||
|
|
@ -71,7 +71,7 @@ App::post('/v1/console/assistant')
|
|||
->param('prompt', '', new Text(2000), 'Prompt. A string containing questions asked to the AI assistant.')
|
||||
->inject('response')
|
||||
->action(function (string $prompt, Response $response) {
|
||||
$ch = curl_init('http://appwrite-assistant:3003/');
|
||||
$ch = curl_init('http://appwrite-assistant:3003/v1/models/assistant/prompt');
|
||||
$responseHeaders = [];
|
||||
$query = json_encode(['prompt' => $prompt]);
|
||||
$headers = ['accept: text/event-stream'];
|
||||
|
|
|
|||
|
|
@ -23,6 +23,8 @@ use Appwrite\Utopia\Response;
|
|||
use Appwrite\Utopia\Response\Model\Rule;
|
||||
use Executor\Executor;
|
||||
use MaxMind\Db\Reader;
|
||||
use Utopia\Abuse\Abuse;
|
||||
use Utopia\Abuse\Adapters\Database\TimeLimit;
|
||||
use Utopia\App;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Config\Config;
|
||||
|
|
@ -187,6 +189,35 @@ App::post('/v1/functions')
|
|||
->action(function (string $functionId, string $name, string $runtime, array $execute, array $events, string $schedule, int $timeout, bool $enabled, bool $logging, string $entrypoint, string $commands, array $scopes, string $installationId, string $providerRepositoryId, string $providerBranch, bool $providerSilentMode, string $providerRootDirectory, string $templateRepository, string $templateOwner, string $templateRootDirectory, string $templateVersion, string $specification, Request $request, Response $response, Database $dbForProject, Document $project, Document $user, Event $queueForEvents, Build $queueForBuilds, Database $dbForPlatform, GitHub $github) use ($redeployVcs) {
|
||||
$functionId = ($functionId == 'unique()') ? ID::unique() : $functionId;
|
||||
|
||||
// Temporary abuse check
|
||||
$abuseCheck = function () use ($project, $dbForProject, $response) {
|
||||
$abuseKey = "projectId:{projectId},url:{url}";
|
||||
$abuseLimit = App::getEnv('_APP_FUNCTIONS_CREATION_ABUSE_LIMIT', 50);
|
||||
$abuseTime = 86400; // 1 day
|
||||
|
||||
$timeLimit = new TimeLimit($abuseKey, $abuseLimit, $abuseTime, $dbForProject);
|
||||
$timeLimit
|
||||
->setParam('{projectId}', $project->getId())
|
||||
->setParam('{url}', '/v1/functions');
|
||||
|
||||
$abuse = new Abuse($timeLimit);
|
||||
$remaining = $timeLimit->remaining();
|
||||
$limit = $timeLimit->limit();
|
||||
$time = (new \DateTime($timeLimit->time()))->getTimestamp() + $abuseTime;
|
||||
|
||||
$response
|
||||
->addHeader('X-RateLimit-Limit', $limit)
|
||||
->addHeader('X-RateLimit-Remaining', $remaining)
|
||||
->addHeader('X-RateLimit-Reset', $time);
|
||||
|
||||
$enabled = System::getEnv('_APP_OPTIONS_ABUSE', 'enabled') !== 'disabled';
|
||||
if ($enabled && $abuse->check()) {
|
||||
throw new Exception(Exception::GENERAL_RATE_LIMIT_EXCEEDED);
|
||||
}
|
||||
};
|
||||
|
||||
$abuseCheck();
|
||||
|
||||
$allowList = \array_filter(\explode(',', System::getEnv('_APP_FUNCTIONS_RUNTIMES', '')));
|
||||
|
||||
if (!empty($allowList) && !\in_array($runtime, $allowList)) {
|
||||
|
|
|
|||
|
|
@ -91,6 +91,15 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
|
|||
$project = Authorization::skip(
|
||||
fn () => $dbForPlatform->getDocument('projects', $projectId)
|
||||
);
|
||||
|
||||
if (!$project->isEmpty() && $project->getId() !== 'console') {
|
||||
$accessedAt = $project->getAttribute('accessedAt', '');
|
||||
if (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_PROJECT_ACCESS)) > $accessedAt) {
|
||||
$project->setAttribute('accessedAt', DateTime::now());
|
||||
Authorization::skip(fn () => $dbForPlatform->updateDocument('projects', $project->getId(), $project));
|
||||
}
|
||||
}
|
||||
|
||||
if (array_key_exists('proxy', $project->getAttribute('services', []))) {
|
||||
$status = $project->getAttribute('services', [])['proxy'];
|
||||
if (!$status) {
|
||||
|
|
|
|||
|
|
@ -195,6 +195,7 @@ services:
|
|||
- _APP_DATABASE_SHARED_TABLES
|
||||
- _APP_DATABASE_SHARED_TABLES_V1
|
||||
- _APP_DATABASE_SHARED_NAMESPACE
|
||||
- _APP_FUNCTIONS_CREATION_ABUSE_LIMIT
|
||||
|
||||
appwrite-console:
|
||||
<<: *x-logging
|
||||
|
|
@ -868,7 +869,7 @@ services:
|
|||
|
||||
appwrite-assistant:
|
||||
container_name: appwrite-assistant
|
||||
image: appwrite/assistant:0.5.0
|
||||
image: appwrite/assistant:0.7.0
|
||||
networks:
|
||||
- appwrite
|
||||
environment:
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ use Utopia\Database\DateTime;
|
|||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Pools\Group;
|
||||
use Utopia\System\System;
|
||||
|
|
@ -39,6 +40,17 @@ abstract class ScheduleBase extends Action
|
|||
->callback(fn (Group $pools, Database $dbForPlatform, callable $getProjectDB) => $this->action($pools, $dbForPlatform, $getProjectDB));
|
||||
}
|
||||
|
||||
protected function updateProjectAccess(Document $project, Database $dbForPlatform): void
|
||||
{
|
||||
if (!$project->isEmpty() && $project->getId() !== 'console') {
|
||||
$accessedAt = $project->getAttribute('accessedAt', '');
|
||||
if (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_PROJECT_ACCESS)) > $accessedAt) {
|
||||
$project->setAttribute('accessedAt', DateTime::now());
|
||||
Authorization::skip(fn () => $dbForPlatform->updateDocument('projects', $project->getId(), $project));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 1. Load all documents from 'schedules' collection to create local copy
|
||||
* 2. Create timer that sync all changes from 'schedules' collection to local copy. Only reading changes thanks to 'resourceUpdatedAt' attribute
|
||||
|
|
|
|||
|
|
@ -57,6 +57,8 @@ class ScheduleExecutions extends ScheduleBase
|
|||
|
||||
$delay = $scheduledAt->getTimestamp() - (new \DateTime())->getTimestamp();
|
||||
|
||||
$this->updateProjectAccess($schedule['project'], $dbForPlatform);
|
||||
|
||||
\go(function () use ($queueForFunctions, $schedule, $delay, $data) {
|
||||
Co::sleep($delay);
|
||||
|
||||
|
|
|
|||
|
|
@ -70,7 +70,7 @@ class ScheduleFunctions extends ScheduleBase
|
|||
}
|
||||
|
||||
foreach ($delayedExecutions as $delay => $scheduleKeys) {
|
||||
\go(function () use ($delay, $scheduleKeys, $pools) {
|
||||
\go(function () use ($delay, $scheduleKeys, $pools, $dbForPlatform) {
|
||||
\sleep($delay); // in seconds
|
||||
|
||||
$queue = $pools->get('queue')->pop();
|
||||
|
|
@ -84,6 +84,8 @@ class ScheduleFunctions extends ScheduleBase
|
|||
|
||||
$schedule = $this->schedules[$scheduleKey];
|
||||
|
||||
$this->updateProjectAccess($schedule['project'], $dbForPlatform);
|
||||
|
||||
$queueForFunctions = new Func($connection);
|
||||
|
||||
$queueForFunctions
|
||||
|
|
|
|||
|
|
@ -45,6 +45,8 @@ class ScheduleMessages extends ScheduleBase
|
|||
$connection = $queue->getResource();
|
||||
$queueForMessaging = new Messaging($connection);
|
||||
|
||||
$this->updateProjectAccess($schedule['project'], $dbForPlatform);
|
||||
|
||||
$queueForMessaging
|
||||
->setType(MESSAGE_SEND_TYPE_EXTERNAL)
|
||||
->setMessageId($schedule['resourceId'])
|
||||
|
|
|
|||
|
|
@ -60,12 +60,13 @@ class Usage extends Action
|
|||
}
|
||||
|
||||
$document = $payload['project'] ?? [];
|
||||
$project = new Document($document);
|
||||
|
||||
if (empty($document)) {
|
||||
if (empty($project->getAttribute('database'))) {
|
||||
var_dump($payload);
|
||||
return;
|
||||
}
|
||||
|
||||
$project = new Document($document);
|
||||
$projectId = $project->getInternalId();
|
||||
foreach ($payload['reduce'] ?? [] as $document) {
|
||||
if (empty($document)) {
|
||||
|
|
@ -80,6 +81,7 @@ class Usage extends Action
|
|||
);
|
||||
}
|
||||
|
||||
|
||||
$this->stats[$projectId]['project'] = [
|
||||
'$id' => $project->getId(),
|
||||
'$internalId' => $project->getInternalId(),
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ class UsageDump extends Action
|
|||
$project = new Document($document);
|
||||
|
||||
if (empty($project->getAttribute('database'))) {
|
||||
var_dump($stats);
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in a new issue