1
0
Fork 0
mirror of synced 2024-06-30 04:00:34 +12:00

Merge branch 'feat-git-integration' of github.com:appwrite/appwrite into feat-usage-rollback

 Conflicts:
	composer.lock
This commit is contained in:
shimon 2023-08-20 18:07:57 +03:00
commit e86286e7e3
29 changed files with 129 additions and 60 deletions

View file

@ -66,7 +66,7 @@ docker run -it --rm \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
--entrypoint="install" \
appwrite/appwrite:1.3.8
appwrite/appwrite:1.4.0
```
### Windows
@ -78,7 +78,7 @@ docker run -it --rm ^
--volume //var/run/docker.sock:/var/run/docker.sock ^
--volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^
--entrypoint="install" ^
appwrite/appwrite:1.3.8
appwrite/appwrite:1.4.0
```
#### PowerShell
@ -88,7 +88,7 @@ docker run -it --rm `
--volume /var/run/docker.sock:/var/run/docker.sock `
--volume ${pwd}/appwrite:/usr/src/code/appwrite:rw `
--entrypoint="install" `
appwrite/appwrite:1.3.8
appwrite/appwrite:1.4.0
```
运行后,可以在浏览器上访问 http://localhost 找到 Appwrite 控制台。在非 Linux 的本机主机上完成安装后,服务器可能需要几分钟才能启动。

View file

@ -75,7 +75,7 @@ docker run -it --rm \
--volume /var/run/docker.sock:/var/run/docker.sock \
--volume "$(pwd)"/appwrite:/usr/src/code/appwrite:rw \
--entrypoint="install" \
appwrite/appwrite:1.3.8
appwrite/appwrite:1.4.0
```
### Windows
@ -87,7 +87,7 @@ docker run -it --rm ^
--volume //var/run/docker.sock:/var/run/docker.sock ^
--volume "%cd%"/appwrite:/usr/src/code/appwrite:rw ^
--entrypoint="install" ^
appwrite/appwrite:1.3.8
appwrite/appwrite:1.4.0
```
#### PowerShell
@ -97,7 +97,7 @@ docker run -it --rm `
--volume /var/run/docker.sock:/var/run/docker.sock `
--volume ${pwd}/appwrite:/usr/src/code/appwrite:rw `
--entrypoint="install" `
appwrite/appwrite:1.3.8
appwrite/appwrite:1.4.0
```
Once the Docker installation is complete, go to http://localhost to access the Appwrite console from your browser. Please note that on non-Linux native hosts, the server might take a few minutes to start after completing the installation.

View file

@ -9,6 +9,7 @@
| 1.1.x | :white_check_mark: |
| 1.2.x | :white_check_mark: |
| 1.3.x | :white_check_mark: |
| 1.4.x | :white_check_mark: |
## Reporting a Vulnerability

View file

@ -1216,14 +1216,14 @@ $commonCollections = [
'type' => Database::INDEX_FULLTEXT,
'attributes' => ['name'],
'lengths' => [],
'orders' => [Database::ORDER_ASC],
'orders' => [],
],
[
'$id' => ID::custom('_key_search'),
'type' => Database::INDEX_FULLTEXT,
'attributes' => ['search'],
'lengths' => [],
'orders' => [Database::ORDER_ASC],
'orders' => [],
],
[
'$id' => ID::custom('_key_enabled'),
@ -2050,7 +2050,7 @@ $projectCollections = array_merge([
'type' => Database::INDEX_FULLTEXT,
'attributes' => ['search'],
'lengths' => [],
'orders' => [Database::ORDER_ASC],
'orders' => [],
],
[
'$id' => ID::custom('_key_name'),
@ -2910,7 +2910,7 @@ $projectCollections = array_merge([
'array' => false,
'filters' => [],
],
],
],
'indexes' => [
[
'$id' => '_key_accessedAt',
@ -3007,22 +3007,22 @@ $projectCollections = array_merge([
'type' => Database::INDEX_KEY,
'attributes' => ['resourceInternalId'],
'lengths' => [Database::LENGTH_KEY],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => '_key_resourceId',
'type' => Database::INDEX_KEY,
'attributes' => ['resourceId'],
'lengths' => [Database::LENGTH_KEY],
'orders' => [Database::ORDER_ASC],
'orders' => [],
],
[
'$id' => '_key_resourceType',
'type' => Database::INDEX_KEY,
'attributes' => ['resourceType'],
'lengths' => [100],
'lengths' => [],
'orders' => [Database::ORDER_ASC],
],
[
'$id' => '_key_resourceId_resourceType',
'type' => Database::INDEX_KEY,
'attributes' => ['resourceId', 'resourceType'],
'lengths' => [Database::LENGTH_KEY, 100],
'orders' => [Database::ORDER_ASC, Database::ORDER_ASC],
],
[
'$id' => '_key_uniqueKey',
'type' => Database::INDEX_UNIQUE,
@ -3579,7 +3579,7 @@ $consoleCollections = array_merge([
[
'$id' => ID::custom('_key_region_resourceType_resourceUpdatedAt'),
'type' => Database::INDEX_KEY,
'attributes' => ['region', 'resourceType','resourceUpdatedAt'],
'attributes' => ['region', 'resourceType', 'resourceUpdatedAt'],
'lengths' => [],
'orders' => [],
],
@ -4185,7 +4185,7 @@ $consoleCollections = array_merge([
'$id' => '_key_resourceType',
'type' => Database::INDEX_KEY,
'attributes' => ['resourceType'],
'lengths' => [100],
'lengths' => [],
'orders' => [Database::ORDER_ASC],
],
],
@ -4821,7 +4821,7 @@ $bucketCollections = [
'type' => Database::INDEX_FULLTEXT,
'attributes' => ['search'],
'lengths' => [],
'orders' => [Database::ORDER_ASC],
'orders' => [],
],
[
'$id' => ID::custom('_key_bucket'),

View file

@ -631,6 +631,11 @@ return [
'description' => 'Host is not trusted. Add a custom domain to your project first.',
'code' => 404,
],
Exception::ROUTER_DOMAIN_NOT_CONFIGURED => [
'name' => Exception::ROUTER_DOMAIN_NOT_CONFIGURED,
'description' => 'Please configure domain environment variables before using Appwrite outside of localhost.',
'code' => 500,
],
Exception::RULE_RESOURCE_NOT_FOUND => [
'name' => Exception::RULE_RESOURCE_NOT_FOUND,
'description' => 'Resource could not be found. Check resourceId and resourceType.',

View file

@ -61,7 +61,6 @@ return [
Auth::USER_ROLE_GUESTS => [
'label' => 'Guests',
'scopes' => [
'none',
'public',
'home',
'console',
@ -77,22 +76,22 @@ return [
],
Auth::USER_ROLE_USERS => [
'label' => 'Users',
'scopes' => \array_merge($member, [ 'none' ]),
'scopes' => \array_merge($member),
],
Auth::USER_ROLE_ADMIN => [
'label' => 'Admin',
'scopes' => \array_merge($admins, [ 'none' ]),
'scopes' => \array_merge($admins),
],
Auth::USER_ROLE_DEVELOPER => [
'label' => 'Developer',
'scopes' => \array_merge($admins, [ 'none' ]),
'scopes' => \array_merge($admins),
],
Auth::USER_ROLE_OWNER => [
'label' => 'Owner',
'scopes' => \array_merge($member, $admins, [ 'none' ]),
'scopes' => \array_merge($member, $admins),
],
Auth::USER_ROLE_APPS => [
'label' => 'Applications',
'scopes' => ['health.read', 'graphql', 'none'],
'scopes' => ['health.read', 'graphql'],
],
];

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

@ -1 +1 @@
Subproject commit f0f0b050fc51871206a4bb729f1c11592f7e8c2f
Subproject commit 495a9c25302bb79156773ef0668b3eef07ce3dd1

View file

@ -30,11 +30,17 @@ App::get('/v1/console/variables')
->inject('response')
->action(function (Response $response) {
$isVcsEnabled = !empty(App::getEnv('_APP_VCS_GITHUB_APP_NAME', '')) && !empty(App::getEnv('_APP_VCS_GITHUB_PRIVATE_KEY', '')) && !empty(App::getEnv('_APP_VCS_GITHUB_APP_ID', '')) && !empty(App::getEnv('_APP_VCS_GITHUB_CLIENT_ID', '')) && !empty(App::getEnv('_APP_VCS_GITHUB_CLIENT_SECRET', ''));
$isAssistantEnabled = !empty(App::getEnv('_APP_ASSISTANT_OPENAI_API_KEY', ''));
$variables = new Document([
'_APP_DOMAIN_TARGET' => App::getEnv('_APP_DOMAIN_TARGET'),
'_APP_STORAGE_LIMIT' => +App::getEnv('_APP_STORAGE_LIMIT'),
'_APP_FUNCTIONS_SIZE_LIMIT' => +App::getEnv('_APP_FUNCTIONS_SIZE_LIMIT'),
'_APP_USAGE_STATS' => App::getEnv('_APP_USAGE_STATS'),
'_APP_VCS_ENABLED' => $isVcsEnabled,
'_APP_ASSISTANT_ENABLED' => $isAssistantEnabled
]);
$response->dynamic($variables, Response::MODEL_CONSOLE_VARIABLES);

View file

@ -761,6 +761,7 @@ App::put('/v1/functions/:functionId')
$live = true;
if (
$function->getAttribute('name') !== $name ||
$function->getAttribute('entrypoint') !== $entrypoint ||
$function->getAttribute('commands') !== $commands ||
$function->getAttribute('providerRootDirectory') !== $providerRootDirectory ||

View file

@ -33,8 +33,8 @@ App::post('/v1/proxy/rules')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_PROXY_RULE)
->param('domain', null, new ValidatorDomain(), 'Domain name.')
->param('resourceType', null, new WhiteList(['api', 'function']), 'Action definition for the rule. Possible values are "api", "function", or "redirect"')
->param('resourceId', '', new UID(), 'ID of resource for the action type. If resourceType is "api" or "url", leave empty. If resourceType is "function", provide ID of the function.', true)
->param('resourceType', null, new WhiteList(['api', 'function']), 'Action definition for the rule. Possible values are "api", "function"')
->param('resourceId', '', new UID(), 'ID of resource for the action type. If resourceType is "api", leave empty. If resourceType is "function", provide ID of the function.', true)
->inject('response')
->inject('project')
->inject('events')

View file

@ -60,7 +60,7 @@ function router(App $utopia, Database $dbForConsole, SwooleRequest $swooleReques
$mainDomain = App::getEnv('_APP_DOMAIN', '');
if ($mainDomain === 'localhost') {
throw new AppwriteException(AppwriteException::GENERAL_SERVER_ERROR, 'Please configure domain environment variables before using Appwrite outside of localhost.');
throw new AppwriteException(AppwriteException::ROUTER_DOMAIN_NOT_CONFIGURED);
} else {
throw new AppwriteException(AppwriteException::ROUTER_HOST_NOT_FOUND);
}

View file

@ -20,13 +20,12 @@ use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Swoole\Files;
use Appwrite\Utopia\Request;
// use Swoole\Runtime;
use Swoole\Runtime;
use Utopia\Logger\Log;
use Utopia\Logger\Log\User;
use Utopia\Pools\Group;
// TODO: Needed for VCS:
// Runtime::enableCoroutine(SWOOLE_HOOK_ALL);
Runtime::enableCoroutine(SWOOLE_HOOK_NATIVE_CURL);
$http = new Server("0.0.0.0", App::getEnv('PORT', 80));

View file

@ -187,7 +187,7 @@ const APP_AUTH_TYPE_ADMIN = 'Admin';
// Response related
const MAX_OUTPUT_CHUNK_SIZE = 2 * 1024 * 1024; // 2MB
// Function headers
const FUNCTION_ALLOWLIST_HEADERS_REQUEST = ['content-type', 'agent', 'content-length'];
const FUNCTION_ALLOWLIST_HEADERS_REQUEST = ['content-type', 'agent', 'content-length', 'host'];
const FUNCTION_ALLOWLIST_HEADERS_RESPONSE = ['content-type', 'content-length'];
// Usage metrics
const METRIC_TEAMS = 'teams';

View file

@ -177,7 +177,7 @@ class BuildsV1 extends Worker
$gitCloneCommand = $github->generateCloneCommand($cloneOwner, $cloneRepository, $branchName, $tmpDirectory, $rootDirectory);
$stdout = '';
$stderr = '';
Console::execute('mkdir -p /tmp/builds/' . $buildId, '', $stdout, $stderr);
Console::execute('mkdir -p /tmp/builds/' . \escapeshellcmd($buildId), '', $stdout, $stderr);
$exit = Console::execute($gitCloneCommand, '', $stdout, $stderr);
if ($exit !== 0) {
@ -196,7 +196,7 @@ class BuildsV1 extends Worker
if (!empty($templateRepositoryName) && !empty($templateOwnerName) && !empty($templateBranch)) {
// Clone template repo
$tmpTemplateDirectory = '/tmp/builds/' . $buildId . '/template';
$tmpTemplateDirectory = '/tmp/builds/' . \escapeshellcmd($buildId) . '/template';
$gitCloneCommandForTemplate = $github->generateCloneCommand($templateOwnerName, $templateRepositoryName, $templateBranch, $tmpTemplateDirectory, $templateRootDirectory);
$exit = Console::execute($gitCloneCommandForTemplate, '', $stdout, $stderr);
@ -212,7 +212,7 @@ class BuildsV1 extends Worker
Console::execute('cp -rfn ' . $tmpTemplateDirectory . '/' . $templateRootDirectory . '/* ' . $tmpDirectory . '/' . $rootDirectory, '', $stdout, $stderr);
// Commit and push
$exit = Console::execute('git config --global user.email "security@appwrite.io" && git config --global user.name "Appwrite" && cd ' . $tmpDirectory . ' && git add . && git commit -m "Create \'' . $function->getAttribute('name', '') . '\' function" && git push origin ' . $branchName, '', $stdout, $stderr);
$exit = Console::execute('git config --global user.email "security@appwrite.io" && git config --global user.name "Appwrite" && cd ' . $tmpDirectory . ' && git add . && git commit -m "Create \'' . \escapeshellcmd($function->getAttribute('name', '')) . '\' function" && git push origin ' . \escapeshellcmd($branchName), '', $stdout, $stderr);
if ($exit !== 0) {
throw new \Exception('Unable to push code repository: ' . $stderr);
@ -252,7 +252,7 @@ class BuildsV1 extends Worker
);
}
Console::execute('tar --exclude code.tar.gz -czf /tmp/builds/' . $buildId . '/code.tar.gz -C /tmp/builds/' . $buildId . '/code' . (empty($rootDirectory) ? '' : '/' . $rootDirectory) . ' .', '', $stdout, $stderr);
Console::execute('tar --exclude code.tar.gz -czf /tmp/builds/' . \escapeshellcmd($buildId) . '/code.tar.gz -C /tmp/builds/' . \escapeshellcmd($buildId) . '/code' . (empty($rootDirectory) ? '' : '/' . $rootDirectory) . ' .', '', $stdout, $stderr);
$deviceFunctions = $this->getFunctionsDevice($project->getId());
@ -267,7 +267,7 @@ class BuildsV1 extends Worker
throw new \Exception("Unable to move file");
}
Console::execute('rm -rf /tmp/builds/' . $buildId, '', $stdout, $stderr);
Console::execute('rm -rf /tmp/builds/' . \escapeshellcmd($buildId), '', $stdout, $stderr);
$source = $path;

View file

@ -72,8 +72,6 @@ services:
- traefik.http.routers.appwrite_api_https.rule=PathPrefix(`/`)
- traefik.http.routers.appwrite_api_https.service=appwrite_api
- traefik.http.routers.appwrite_api_https.tls=true
- traefik.http.routers.appwrite_api_https.tls.domains[0].main=$_APP_DOMAIN_FUNCTIONS
- traefik.http.routers.appwrite_api_https.tls.domains[0].sans=*.$_APP_DOMAIN_FUNCTIONS
volumes:
- appwrite-uploads:/storage/uploads:rw
- appwrite-cache:/storage/cache:rw
@ -182,6 +180,7 @@ services:
- _APP_VCS_GITHUB_CLIENT_ID
- _APP_MIGRATIONS_FIREBASE_CLIENT_ID
- _APP_MIGRATIONS_FIREBASE_CLIENT_SECRET
- _APP_ASSISTANT_OPENAI_API_KEY
appwrite-realtime:
entrypoint: realtime
@ -770,8 +769,7 @@ services:
appwrite-assistant:
container_name: appwrite-assistant
hostname: appwrite-assistant
image: appwrite/assistant:0.1.1
platform: linux/amd64
image: appwrite/assistant:0.1.2
networks:
- appwrite
environment:

View file

@ -7,6 +7,8 @@
<ini name="memory_limit" value="4096M"/>
<!-- Exclude SDK's for performance reasons -->
<exclude-pattern>./app/sdks</exclude-pattern>
<!-- Exclude functions as they are in different languages -->
<exclude-pattern>./tests/resources/functions</exclude-pattern>
<!-- Exclude console -->
<exclude-pattern>./app/console</exclude-pattern>
<!-- Ignore max line width -->

View file

@ -195,6 +195,7 @@ class Exception extends \Exception
/** Router */
public const ROUTER_HOST_NOT_FOUND = 'router_host_not_found';
public const ROUTER_DOMAIN_NOT_CONFIGURED = 'router_domain_not_configured';
/** Proxy */
public const RULE_RESOURCE_NOT_FOUND = 'rule_resource_not_found';

View file

@ -51,7 +51,7 @@ class SDKs extends Action
$production = ($git) ? (Console::confirm('Type "Appwrite" to push code to production git repos') == 'Appwrite') : false;
$message = ($git) ? Console::confirm('Please enter your commit message:') : '';
if (!in_array($version, ['0.6.x', '0.7.x', '0.8.x', '0.9.x', '0.10.x', '0.11.x', '0.12.x', '0.13.x', '0.14.x', '0.15.x', '1.0.x', '1.1.x', '1.2.x', '1.3.x', 'latest'])) {
if (!in_array($version, ['0.6.x', '0.7.x', '0.8.x', '0.9.x', '0.10.x', '0.11.x', '0.12.x', '0.13.x', '0.14.x', '0.15.x', '1.0.x', '1.1.x', '1.2.x', '1.3.x', '1.4.x', 'latest'])) {
throw new Exception('Unknown version given');
}

View file

@ -263,6 +263,8 @@ class Response extends SwooleResponse
public const MODEL_PERMISSIONS = 'permissions';
public const MODEL_RULE = 'rule';
public const MODEL_TASK = 'task';
public const MODEL_DOMAIN = 'domain';
public const MODEL_DOMAIN_LIST = 'domainList';
// Tests (keep last)
public const MODEL_MOCK = 'mock';

View file

@ -81,6 +81,7 @@ class V12 extends Filter
case Response::MODEL_WEBHOOK_LIST:
case Response::MODEL_KEY_LIST:
case Response::MODEL_PLATFORM_LIST:
case Response::MODEL_DOMAIN_LIST:
case Response::MODEL_COUNTRY_LIST:
case Response::MODEL_CONTINENT_LIST:
case Response::MODEL_LANGUAGE_LIST:

View file

@ -33,6 +33,18 @@ class ConsoleVariables extends Model
'description' => 'Defines if usage stats are enabled. This value is set to \'enabled\' by default, to disable the usage stats set the value to \'disabled\'.',
'default' => '',
'example' => 'enabled',
])
->addRule('_APP_VCS_ENABLED', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Defines if VCS (Version Control System) is enabled.',
'default' => false,
'example' => true,
])
->addRule('_APP_ASSISTANT_ENABLED', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Defines if AI assistant is enabled.',
'default' => false,
'example' => true,
]);
}

View file

@ -111,6 +111,12 @@ class Func extends Model
'default' => '',
'example' => 'npm install',
])
->addRule('version', [
'type' => self::TYPE_STRING,
'description' => 'Version of Open Runtimes used for the function.',
'default' => 'v3',
'example' => 'v2',
])
->addRule('installationId', [
'type' => self::TYPE_STRING,
'description' => 'Function VCS (Version Control System) installation id.',

View file

@ -178,7 +178,9 @@ class Executor
array $headers,
string $runtimeEntrypoint = null,
) {
$headers['host'] = App::getEnv('_APP_DOMAIN', '');
if(empty($headers['host'])) {
$headers['host'] = App::getEnv('_APP_DOMAIN', '');
}
$runtimeId = "$projectId-$deploymentId";
$route = '/runtimes/' . $runtimeId . '/execution';

View file

@ -2,17 +2,17 @@ module.exports = async(context) => {
context.log('Amazing Function Log');
return context.res.json({
'APPWRITE_FUNCTION_ID' : process.env.APPWRITE_FUNCTION_ID ? ? '',
'APPWRITE_FUNCTION_NAME' : process.env.APPWRITE_FUNCTION_NAME ? ? '',
'APPWRITE_FUNCTION_DEPLOYMENT' : process.env.APPWRITE_FUNCTION_DEPLOYMENT ? ? '',
'APPWRITE_FUNCTION_TRIGGER' : context.req.headers['x-appwrite-trigger'] ? ? '',
'APPWRITE_FUNCTION_ID' : process.env.APPWRITE_FUNCTION_ID ?? '',
'APPWRITE_FUNCTION_NAME' : process.env.APPWRITE_FUNCTION_NAME ?? '',
'APPWRITE_FUNCTION_DEPLOYMENT' : process.env.APPWRITE_FUNCTION_DEPLOYMENT ?? '',
'APPWRITE_FUNCTION_TRIGGER' : context.req.headers['x-appwrite-trigger'] ?? '',
'APPWRITE_FUNCTION_RUNTIME_NAME' : process.env.APPWRITE_FUNCTION_RUNTIME_NAME,
'APPWRITE_FUNCTION_RUNTIME_VERSION' : process.env.APPWRITE_FUNCTION_RUNTIME_VERSION,
'APPWRITE_FUNCTION_EVENT' : context.req.headers['x-appwrite-event'] ? ? '',
'APPWRITE_FUNCTION_EVENT_DATA' : context.req.bodyRaw ? ? '',
'APPWRITE_FUNCTION_DATA' : context.req.bodyRaw ? ? '',
'APPWRITE_FUNCTION_USER_ID' : context.req.headers['x-appwrite-user-id'] ? ? '',
'APPWRITE_FUNCTION_JWT' : context.req.headers['x-appwrite-user-jwt'] ? ? '',
'APPWRITE_FUNCTION_EVENT' : context.req.headers['x-appwrite-event'] ?? '',
'APPWRITE_FUNCTION_EVENT_DATA' : context.req.bodyRaw ?? '',
'APPWRITE_FUNCTION_DATA' : context.req.bodyRaw ?? '',
'APPWRITE_FUNCTION_USER_ID' : context.req.headers['x-appwrite-user-id'] ?? '',
'APPWRITE_FUNCTION_JWT' : context.req.headers['x-appwrite-user-jwt'] ?? '',
'APPWRITE_FUNCTION_PROJECT_ID' : process.env.APPWRITE_FUNCTION_PROJECT_ID,
'CUSTOM_VARIABLE' : process.env.CUSTOM_VARIABLE
});

View file

@ -562,6 +562,40 @@ class V15Test extends TestCase
$this->assertEquals($expected, $result);
}
/**
* @dataProvider createdAtUpdatedAtProvider
*/
public function testDomain(array $content, array $expected): void
{
$model = Response::MODEL_DOMAIN;
$result = $this->filter->parse($content, $model);
$this->assertEquals($expected, $result);
}
/**
* @dataProvider createdAtUpdatedAtProvider
*/
public function testDomainList(array $content, array $expected): void
{
$model = Response::MODEL_DOMAIN_LIST;
$content = [
'domains' => [$content],
'total' => 1,
];
$expected = [
'domains' => [$expected],
'total' => 1,
];
$result = $this->filter->parse($content, $model);
$this->assertEquals($expected, $result);
}
public function executionProvider(): array
{
return [