2022-09-07 08:43:05 +00:00
< ? php
namespace Appwrite\Migration\Version ;
use Appwrite\Migration\Migration ;
2022-09-08 16:46:18 +00:00
use Appwrite\OpenSSL\OpenSSL ;
2022-09-07 08:43:05 +00:00
use Exception ;
2022-09-12 13:53:00 +00:00
use PDO ;
2022-09-08 16:46:18 +00:00
use Utopia\App ;
2022-09-07 08:43:05 +00:00
use Utopia\CLI\Console ;
2022-09-12 13:53:00 +00:00
use Utopia\Config\Config ;
2022-09-07 08:43:05 +00:00
use Utopia\Database\Database ;
use Utopia\Database\Document ;
2022-12-14 15:42:25 +00:00
use Utopia\Database\Helpers\ID ;
2022-12-14 16:04:06 +00:00
use Utopia\Database\Helpers\Permission ;
use Utopia\Database\Helpers\Role ;
2022-09-07 08:43:05 +00:00
class V15 extends Migration
{
2022-09-12 13:53:00 +00:00
/**
* @ var array < string >
*/
protected array $providers ;
2022-09-07 08:43:05 +00:00
public function execute () : void
{
global $register ;
$this -> pdo = $register -> get ( 'db' );
2022-09-12 13:53:00 +00:00
/**
* Populate providers .
*/
$this -> providers = \array_merge (
[ 'email' , 'anonymous' ],
\array_map (
fn ( $value ) => " oauth- " . $value ,
\array_keys ( Config :: getParam ( 'providers' , []))
)
);
2022-09-07 08:43:05 +00:00
/**
2022-09-09 12:44:04 +00:00
* Disable SubQueries for Performance .
2022-09-07 08:43:05 +00:00
*/
2022-09-09 17:50:05 +00:00
foreach ([ 'subQueryIndexes' , 'subQueryPlatforms' , 'subQueryDomains' , 'subQueryKeys' , 'subQueryWebhooks' , 'subQuerySessions' , 'subQueryTokens' , 'subQueryMemberships' , 'subqueryVariables' ] as $name ) {
2022-09-09 12:44:04 +00:00
Database :: addFilter (
$name ,
fn () => null ,
fn () => []
);
2022-09-07 08:43:05 +00:00
}
2022-09-09 12:44:04 +00:00
Console :: log ( 'Migrating Project: ' . $this -> project -> getAttribute ( 'name' ) . ' (' . $this -> project -> getId () . ')' );
2022-09-12 13:53:00 +00:00
Console :: info ( 'Migrating Stats' );
$this -> migrateStatsMetric ( 'requests' , 'project.$all.network.requests' );
$this -> migrateStatsMetric ( 'network' , 'project.$all.network.bandwidth' );
$this -> migrateStatsMetric ( 'executions' , 'executions.$all.compute.total' );
$this -> migrateStatsMetric ( 'storage.total' , 'project.$all.storage.size' );
2022-09-07 08:43:05 +00:00
Console :: info ( 'Migrating Collections' );
$this -> migrateCollections ();
2022-09-08 16:46:18 +00:00
Console :: info ( 'Migrating Databases' );
$this -> migrateDatabases ();
Console :: info ( 'Migrating Buckets' );
$this -> migrateBuckets ();
Console :: info ( 'Migrating Documents' );
$this -> forEachDocument ([ $this , 'fixDocument' ]);
Console :: info ( " Clean up 'write' Permissions " );
foreach ( $this -> collections as $collection ) {
if ( $collection [ '$collection' ] === Database :: METADATA ) {
$this -> removeWritePermissions ( $collection [ '$id' ]);
}
}
}
2022-09-09 12:44:04 +00:00
/**
* Migrating all Bucket tables .
*
* @ return void
* @ throws \Exception
* @ throws \PDOException
*/
2022-09-08 16:46:18 +00:00
protected function migrateBuckets () : void
{
2022-09-12 13:53:00 +00:00
/**
* Migrating stats for all Buckets .
*/
2022-09-12 13:54:12 +00:00
$this -> migrateStatsMetric ( 'storage.files.total' , 'files.$all.storage.size' );
2022-09-12 13:53:00 +00:00
$this -> migrateStatsMetric ( 'storage.files.count' , 'files.$all.count.total' );
$this -> migrateStatsMetric ( 'storage.buckets.count' , 'buckets.$all.count.total' );
$this -> migrateStatsMetric ( 'storage.buckets.create' , 'buckets.$all.requests.create' );
$this -> migrateStatsMetric ( 'storage.buckets.read' , 'buckets.$all.requests.read' );
$this -> migrateStatsMetric ( 'storage.buckets.update' , 'buckets.$all.requests.update' );
$this -> migrateStatsMetric ( 'storage.buckets.delete' , 'buckets.$all.requests.delete' );
$this -> migrateStatsMetric ( 'storage.files.create' , 'files.$all.requests.create' );
$this -> migrateStatsMetric ( 'storage.files.read' , 'files.$all.requests.read' );
$this -> migrateStatsMetric ( 'storage.files.update' , 'files.$all.requests.update' );
$this -> migrateStatsMetric ( 'storage.files.delete' , 'files.$all.requests.delete' );
2022-09-08 16:46:18 +00:00
foreach ( $this -> documentsIterator ( 'buckets' ) as $bucket ) {
$bucketTable = " bucket_ { $bucket -> getInternalId () } " ;
$this -> createPermissionsColumn ( $bucketTable );
$this -> migrateDateTimeAttribute ( $bucketTable , '_createdAt' );
$this -> migrateDateTimeAttribute ( $bucketTable , '_updatedAt' );
$this -> populatePermissionsAttribute (
document : $bucket ,
addCreatePermission : true
);
if ( ! is_null ( $bucket -> getAttribute ( 'permission' ))) {
$bucket -> setAttribute ( 'fileSecurity' , $bucket -> getAttribute ( 'permissions' ) === 'document' );
}
if ( is_null ( $bucket -> getAttribute ( 'compression' ))) {
$bucket -> setAttribute ( 'compression' , 'none' );
}
$this -> projectDB -> updateDocument ( 'buckets' , $bucket -> getId (), $bucket );
2022-09-12 13:53:00 +00:00
/**
* Migrating stats for every Bucket .
*/
$bucketId = $bucket -> getId ();
$this -> migrateStatsMetric ( " storage.buckets. $bucketId .files.count " , " files. $bucketId .count.total " );
$this -> migrateStatsMetric ( " storage.buckets. $bucketId .files.total " , " files. $bucketId .storage.size " );
$this -> migrateStatsMetric ( " storage.buckets. $bucketId .files.create " , " files. $bucketId .requests.create " );
$this -> migrateStatsMetric ( " storage.buckets. $bucketId .files.read " , " files. $bucketId .requests.read " );
$this -> migrateStatsMetric ( " storage.buckets. $bucketId .files.update " , " files. $bucketId .requests.update " );
$this -> migrateStatsMetric ( " storage.buckets. $bucketId .files.delete " , " files. $bucketId .requests.delete " );
2022-09-08 16:46:18 +00:00
Console :: info ( " Migrating Files of { $bucket -> getId () } ( { $bucket -> getAttribute ( 'name' ) } ) " );
foreach ( $this -> documentsIterator ( $bucketTable ) as $file ) {
$this -> populatePermissionsAttribute (
document : $file ,
table : $bucketTable ,
addCreatePermission : false
);
$this -> projectDB -> updateDocument ( $bucketTable , $file -> getId (), $file );
}
$this -> removeWritePermissions ( $bucketTable );
}
try {
$this -> projectDB -> deleteAttribute ( 'buckets' , 'permission' );
} catch ( \Throwable $th ) {
Console :: warning ( " 'permissions' from buckets: { $th -> getMessage () } " );
}
}
2022-09-09 12:44:04 +00:00
/**
* Migrating all Database and Collection tables .
*
* @ return void
* @ throws \Exception
* @ throws \PDOException
*/
2022-09-08 16:46:18 +00:00
protected function migrateDatabases () : void
{
2022-09-12 13:53:00 +00:00
/**
* Migrating stats for all Databases .
*/
$this -> migrateStatsMetric ( 'databases.count' , 'databases.$all.count.total' );
$this -> migrateStatsMetric ( 'databases.documents.count' , 'documents.$all.count.total' );
$this -> migrateStatsMetric ( 'databases.collections.count' , 'collections.$all.count.total' );
$this -> migrateStatsMetric ( 'databases.create' , 'databases.$all.requests.create' );
$this -> migrateStatsMetric ( 'databases.read' , 'databases.$all.requests.read' );
$this -> migrateStatsMetric ( 'databases.update' , 'databases.$all.requests.update' );
$this -> migrateStatsMetric ( 'databases.delete' , 'databases.$all.requests.delete' );
$this -> migrateStatsMetric ( 'databases.collections.create' , 'collections.$all.requests.create' );
$this -> migrateStatsMetric ( 'databases.collections.read' , 'collections.$all.requests.read' );
$this -> migrateStatsMetric ( 'databases.collections.update' , 'collections.$all.requests.update' );
$this -> migrateStatsMetric ( 'databases.collections.delete' , 'collections.$all.requests.delete' );
$this -> migrateStatsMetric ( 'databases.documents.create' , 'documents.$all.requests.create' );
$this -> migrateStatsMetric ( 'databases.documents.read' , 'documents.$all.requests.read' );
$this -> migrateStatsMetric ( 'databases.documents.update' , 'documents.$all.requests.update' );
$this -> migrateStatsMetric ( 'databases.documents.delete' , 'documents.$all.requests.delete' );
/**
* Migrate every Database .
*/
2022-09-08 16:46:18 +00:00
foreach ( $this -> documentsIterator ( 'databases' ) as $database ) {
$databaseTable = " database_ { $database -> getInternalId () } " ;
$this -> createPermissionsColumn ( $databaseTable );
$this -> migrateDateTimeAttribute ( $databaseTable , '_createdAt' );
$this -> migrateDateTimeAttribute ( $databaseTable , '_updatedAt' );
$this -> populatePermissionsAttribute (
document : $database ,
table : 'databases' ,
addCreatePermission : false
);
$this -> projectDB -> updateDocument ( 'databases' , $database -> getId (), $database );
try {
$this -> createAttributeFromCollection ( $this -> projectDB , $databaseTable , 'documentSecurity' , 'collections' );
} catch ( \Throwable $th ) {
Console :: warning ( " 'documentSecurity' from { $databaseTable } : { $th -> getMessage () } " );
}
2022-09-12 13:53:00 +00:00
/**
* Migrating stats for single Databases .
*/
$databaseId = $database -> getId ();
$this -> migrateStatsMetric ( " databases. $databaseId .collections.count " , " collections. $databaseId .count.total " );
$this -> migrateStatsMetric ( " databases. $databaseId .collections.create " , " collections. $databaseId .requests.create " );
$this -> migrateStatsMetric ( " databases. $databaseId .collections.read " , " collections. $databaseId .requests.read " );
$this -> migrateStatsMetric ( " databases. $databaseId .collections.update " , " collections. $databaseId .requests.update " );
$this -> migrateStatsMetric ( " databases. $databaseId .collections.delete " , " collections. $databaseId .requests.delete " );
$this -> migrateStatsMetric ( " databases. $databaseId .documents.count " , " documents. $databaseId .count.total " );
$this -> migrateStatsMetric ( " databases. $databaseId .documents.create " , " documents. $databaseId .requests.create " );
$this -> migrateStatsMetric ( " databases. $databaseId .documents.read " , " documents. $databaseId .requests.read " );
$this -> migrateStatsMetric ( " databases. $databaseId .documents.update " , " documents. $databaseId .requests.update " );
$this -> migrateStatsMetric ( " databases. $databaseId .documents.delete " , " documents. $databaseId .requests.delete " );
/**
* Migrate every Collection .
*/
2022-09-08 16:46:18 +00:00
Console :: info ( " Migrating Collections of { $database -> getId () } ( { $database -> getAttribute ( 'name' ) } ) " );
foreach ( $this -> documentsIterator ( $databaseTable ) as $collection ) {
$collectionTable = " { $databaseTable } _collection_ { $collection -> getInternalId () } " ;
$this -> createPermissionsColumn ( $collectionTable );
$this -> migrateDateTimeAttribute ( $collectionTable , '_createdAt' );
$this -> migrateDateTimeAttribute ( $collectionTable , '_updatedAt' );
$this -> populatePermissionsAttribute (
document : $collection ,
table : $databaseTable ,
addCreatePermission : true
);
if ( ! is_null ( $collection -> getAttribute ( 'permission' ))) {
$collection -> setAttribute ( 'documentSecurity' , $collection -> getAttribute ( 'permissions' ) === 'document' );
}
$this -> projectDB -> updateDocument ( $databaseTable , $collection -> getId (), $collection );
2022-09-12 13:53:00 +00:00
/**
* Migrating stats for single Collections .
*/
$collectionId = $collection -> getId ();
$this -> migrateStatsMetric ( " databases. { $databaseId } .collections. { $collectionId } .documents.count " , " documents. { $databaseId } / { $collectionId } .count.total " );
$this -> migrateStatsMetric ( " databases. { $databaseId } .collections. { $collectionId } .documents.create " , " documents. { $databaseId } / { $collectionId } .requests.create " );
$this -> migrateStatsMetric ( " databases. { $databaseId } .collections. { $collectionId } .documents.read " , " documents. { $databaseId } / { $collectionId } .requests.read " );
$this -> migrateStatsMetric ( " databases. { $databaseId } .collections. { $collectionId } .documents.update " , " documents. { $databaseId } / { $collectionId } .requests.update " );
$this -> migrateStatsMetric ( " databases. { $databaseId } .collections. { $collectionId } .documents.delete " , " documents. { $databaseId } / { $collectionId } .requests.delete " );
2022-09-08 16:46:18 +00:00
Console :: info ( " Migrating Documents of { $collection -> getId () } ( { $collection -> getAttribute ( 'name' ) } ) " );
2022-09-09 17:50:05 +00:00
$requiredAttributes = array_reduce ( $collection -> getAttribute ( 'attributes' , []), function ( array $carry , Document $item ) {
if ( $item -> getAttribute ( 'required' , false )) {
$carry = array_merge ( $carry , [
$item -> getAttribute ( 'key' ) => $item -> getAttribute ( 'default' )
]);
}
return $carry ;
}, []);
2022-09-08 16:46:18 +00:00
foreach ( $this -> documentsIterator ( $collectionTable ) as $document ) {
2022-09-09 17:50:05 +00:00
foreach ( $document -> getAttributes () as $attribute => $default ) {
if ( array_key_exists ( $attribute , $requiredAttributes )) {
if ( is_null ( $default )) {
Console :: warning ( " Skipping migration for Document { $document -> getId () } in Collection { $collection -> getId () } ( { $collection -> getAttribute ( 'name' ) } ) because of missing required attribute \" { $attribute } \" without default value. " );
continue 2 ;
}
$document -> setAttribute ( $attribute , $default );
}
}
2022-09-08 16:46:18 +00:00
$this -> populatePermissionsAttribute (
document : $document ,
table : $collectionTable ,
addCreatePermission : false
);
2022-09-09 17:50:05 +00:00
2022-09-08 16:46:18 +00:00
$this -> projectDB -> updateDocument ( $collectionTable , $document -> getId (), $document );
}
$this -> removeWritePermissions ( $collectionTable );
}
$this -> removeWritePermissions ( $databaseTable );
try {
$this -> projectDB -> deleteAttribute ( " database_ { $database -> getInternalId () } " , 'permission' );
} catch ( \Throwable $th ) {
Console :: warning ( " 'permission' from { $databaseTable } : { $th -> getMessage () } " );
}
}
}
/**
2022-09-09 12:44:04 +00:00
* Removes all 'write' permissions from a table .
*
* @ param string $table
* @ return void
2022-09-08 16:46:18 +00:00
*/
protected function removeWritePermissions ( string $table ) : void
{
try {
$this -> pdo -> prepare ( " DELETE FROM ` { $this -> projectDB -> getDefaultDatabase () } `.`_ { $this -> project -> getInternalId () } _ { $table } _perms` WHERE _type = 'write' " ) -> execute ();
} catch ( \Throwable $th ) {
Console :: warning ( " Remove 'write' permissions from { $table } : { $th -> getMessage () } " );
}
2022-09-07 08:43:05 +00:00
}
/**
* Returns all columns from the Table .
2022-09-09 12:44:04 +00:00
*
2022-09-07 08:43:05 +00:00
* @ param string $table
* @ return array
* @ throws \Exception
* @ throws \PDOException
*/
protected function getSQLColumnTypes ( string $table ) : array
{
$query = $this -> pdo -> prepare ( " SELECT COLUMN_NAME, DATA_TYPE FROM INFORMATION_SCHEMA.COLUMNS WHERE table_name = '_ { $this -> project -> getInternalId () } _ { $table } ' AND table_schema = ' { $this -> projectDB -> getDefaultDatabase () } ' " );
$query -> execute ();
return array_reduce ( $query -> fetchAll (), function ( array $carry , array $item ) {
$carry [ $item [ 'COLUMN_NAME' ]] = $item [ 'DATA_TYPE' ];
return $carry ;
}, []);
}
/**
2022-09-09 12:44:04 +00:00
* Migrates all Integer colums for timestamps to DateTime .
*
2022-09-07 08:43:05 +00:00
* @ return void
* @ throws \Exception
*/
protected function migrateDateTimeAttribute ( string $table , string $attribute ) : void
{
$columns = $this -> getSQLColumnTypes ( $table );
if ( $columns [ $attribute ] === 'int' ) {
try {
$this -> pdo -> prepare ( " ALTER TABLE IF EXISTS ` { $this -> projectDB -> getDefaultDatabase () } `.`_ { $this -> project -> getInternalId () } _ { $table } ` MODIFY { $attribute } VARCHAR(64) " ) -> execute ();
2022-09-08 16:46:18 +00:00
$this -> pdo -> prepare ( " UPDATE ` { $this -> projectDB -> getDefaultDatabase () } `.`_ { $this -> project -> getInternalId () } _ { $table } ` SET { $attribute } = IF( { $attribute } = 0, NULL, FROM_UNIXTIME( { $attribute } )) " ) -> execute ();
$columns [ $attribute ] = 'varchar' ;
2022-09-07 08:43:05 +00:00
} catch ( \Throwable $th ) {
Console :: warning ( $th -> getMessage ());
}
}
if ( $columns [ $attribute ] === 'varchar' ) {
try {
$this -> pdo -> prepare ( " ALTER TABLE IF EXISTS ` { $this -> projectDB -> getDefaultDatabase () } `.`_ { $this -> project -> getInternalId () } _ { $table } ` MODIFY { $attribute } DATETIME(3) " ) -> execute ();
} catch ( \Throwable $th ) {
Console :: warning ( $th -> getMessage ());
}
}
2022-09-08 16:46:18 +00:00
/**
* Skip adding filter on internal attributes .
*/
if ( ! str_starts_with ( $attribute , '_' )) {
try {
/**
* Add datetime filter .
*/
$this -> projectDB -> updateAttributeFilters ( $table , ID :: custom ( $attribute ), [ 'datetime' ]);
/**
* Change data type to DateTime .
*/
$this -> projectDB -> updateAttribute (
collection : $table ,
id : $attribute ,
type : Database :: VAR_DATETIME ,
signed : false
);
} catch ( \Throwable $th ) {
Console :: warning ( " Add 'datetime' filter to ' { $attribute } ' from { $table } : { $th -> getMessage () } " );
}
}
$this -> projectDB -> deleteCachedCollection ( $table );
}
2022-09-09 12:44:04 +00:00
/**
* Create the '_permissions' column to a table .
*
* @ param string $table
* @ return void
* @ throws \Exception
* @ throws \PDOException
*/
2022-09-08 16:46:18 +00:00
protected function createPermissionsColumn ( string $table ) : void
{
$columns = $this -> getSQLColumnTypes ( $table );
if ( ! array_key_exists ( '_permissions' , $columns )) {
try {
$this -> pdo -> prepare ( " ALTER TABLE IF EXISTS ` { $this -> projectDB -> getDefaultDatabase () } `.`_ { $this -> project -> getInternalId () } _ { $table } ` ADD `_permissions` MEDIUMTEXT DEFAULT NULL " ) -> execute ();
} catch ( \Throwable $th ) {
Console :: warning ( " Add '_permissions' column to ' { $table } ': { $th -> getMessage () } " );
}
}
}
2022-09-09 12:44:04 +00:00
/**
* Populate '$permissions' from '$read' and '$write' .
*
* @ param \Utopia\Database\Document $document
* @ param null | string $table
* @ param bool $addCreatePermission
* @ return void
* @ throws \Exception
* @ throws \PDOException
*/
2022-09-08 16:46:18 +00:00
protected function populatePermissionsAttribute ( Document & $document , ? string $table = null , bool $addCreatePermission = true ) : void
{
$table ? ? = $document -> getCollection ();
$query = $this -> pdo -> prepare ( " SELECT * FROM ` { $this -> projectDB -> getDefaultDatabase () } `.`_ { $this -> project -> getInternalId () } _ { $table } _perms` WHERE _document = ' { $document -> getId () } ' " );
$query -> execute ();
$results = $query -> fetchAll ();
$permissions = [];
foreach ( $results as $result ) {
$type = $result [ '_type' ];
2022-09-09 12:44:04 +00:00
$permission = $this -> migratePermission ( $result [ '_permission' ]);
2022-09-08 16:46:18 +00:00
if ( $type === 'write' ) {
2022-09-12 09:55:54 +00:00
/**
2022-09-14 10:19:52 +00:00
* Migrate write permissions from 'any' to 'users' .
2022-09-12 09:55:54 +00:00
*/
2022-09-14 10:19:52 +00:00
if ( $permission === 'any' ) {
$permission = 'users' ;
2022-09-12 09:55:54 +00:00
}
2022-09-08 16:46:18 +00:00
$permissions [] = " update( \" { $permission } \" ) " ;
$permissions [] = " delete( \" { $permission } \" ) " ;
if ( $addCreatePermission ) {
$permissions [] = " create( \" { $permission } \" ) " ;
}
} else {
$permissions [] = " { $type } ( \" { $permission } \" ) " ;
}
}
$document -> setAttribute ( '$permissions' , $permissions );
2022-09-07 08:43:05 +00:00
}
2022-09-09 12:44:04 +00:00
/**
* Migrates a permission string
*
* @ param string $permission
* @ return string
*/
protected function migratePermission ( string $permission ) : string
{
return match ( $permission ) {
'role:all' => 'any' ,
'role:guest' => 'guests' ,
2022-09-13 16:54:03 +00:00
'role:member' => 'users' ,
2022-09-09 12:44:04 +00:00
default => $permission
};
}
2022-09-07 08:43:05 +00:00
/**
* Migrate all Collections .
*
* @ return void
*/
protected function migrateCollections () : void
{
foreach ( $this -> collections as $collection ) {
$id = $collection [ '$id' ];
2022-09-09 12:44:04 +00:00
Console :: log ( " Migrating Collection \" { $id } \" " );
2022-09-07 08:43:05 +00:00
$this -> projectDB -> setNamespace ( " _ { $this -> project -> getInternalId () } " );
switch ( $id ) {
case '_metadata' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
2022-09-09 12:44:04 +00:00
Console :: log ( 'Created new Collection "cache" collection' );
2022-09-08 16:46:18 +00:00
$this -> createCollection ( 'cache' );
2022-09-09 12:44:04 +00:00
Console :: log ( 'Created new Collection "variables" collection' );
2022-09-08 16:46:18 +00:00
$this -> createCollection ( 'variables' );
$this -> projectDB -> deleteCachedCollection ( $id );
2022-09-07 08:43:05 +00:00
break ;
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
case 'abuse' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
2022-09-14 17:40:03 +00:00
$this -> migrateDateTimeAttribute ( $id , 'time' );
2022-09-07 08:43:05 +00:00
break ;
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
case 'attributes' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
2022-09-08 16:46:18 +00:00
break ;
2022-09-07 08:43:05 +00:00
case 'audit' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
2022-09-29 19:13:51 +00:00
$this -> migrateDateTimeAttribute ( $id , 'time' );
2022-09-07 08:43:05 +00:00
break ;
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
case 'buckets' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
2022-09-08 16:46:18 +00:00
try {
/**
* Create 'compression' attribute
*/
$this -> createAttributeFromCollection ( $this -> projectDB , $id , 'compression' );
} catch ( \Throwable $th ) {
Console :: warning ( " 'compression' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create 'fileSecurity' attribute
*/
$this -> createAttributeFromCollection ( $this -> projectDB , $id , 'fileSecurity' );
} catch ( \Throwable $th ) {
Console :: warning ( " 'fileSecurity' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_enabled' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_enabled' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_enabled' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_name' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_name' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_name' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_fileSecurity' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_fileSecurity' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_fileSecurity' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_maximumFileSize' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_maximumFileSize' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_maximumFileSize' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_encryption' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_encryption' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_encryption' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_antivirus' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_antivirus' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_antivirus' from { $id } : { $th -> getMessage () } " );
}
2022-09-07 08:43:05 +00:00
break ;
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
case 'builds' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
2022-09-08 16:46:18 +00:00
$this -> migrateDateTimeAttribute ( $id , 'startTime' );
$this -> migrateDateTimeAttribute ( $id , 'endTime' );
2022-09-07 08:43:05 +00:00
break ;
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
case 'certificates' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
2022-09-08 16:46:18 +00:00
$this -> migrateDateTimeAttribute ( $id , 'issueDate' );
$this -> migrateDateTimeAttribute ( $id , 'renewDate' );
$this -> migrateDateTimeAttribute ( $id , 'updated' );
2022-09-07 08:43:05 +00:00
break ;
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
case 'databases' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
break ;
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
case 'deployments' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
2022-09-08 16:46:18 +00:00
try {
/**
* Create '_key_entrypoint' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_entrypoint' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_entrypoint' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_size' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_size' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_size' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_buildId' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_buildId' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_buildId' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_activate' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_activate' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_activate' from { $id } : { $th -> getMessage () } " );
}
2022-09-07 08:43:05 +00:00
break ;
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
case 'domains' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
2022-09-08 16:46:18 +00:00
$this -> migrateDateTimeAttribute ( $id , 'updated' );
2022-09-07 08:43:05 +00:00
break ;
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
case 'executions' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
2022-09-08 16:46:18 +00:00
try {
/**
* Create 'stdout' attribute
*/
$this -> createAttributeFromCollection ( $this -> projectDB , $id , 'stdout' );
} catch ( \Throwable $th ) {
Console :: warning ( " 'stdout' from { $id } : { $th -> getMessage () } " );
}
2022-09-12 09:55:54 +00:00
try {
/**
* Rename 'time' to 'duration'
*/
$this -> projectDB -> renameAttribute ( $id , 'time' , 'duration' );
} catch ( \Throwable $th ) {
Console :: warning ( " 'duration' from { $id } : { $th -> getMessage () } " );
}
2022-09-08 16:46:18 +00:00
try {
/**
* Create '_key_trigger' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_trigger' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_trigger' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_status' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_status' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_status' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_statusCode' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_statusCode' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_statusCode' from { $id } : { $th -> getMessage () } " );
}
try {
/**
2022-09-12 09:55:54 +00:00
* Create '_key_duration' index
2022-09-08 16:46:18 +00:00
*/
2022-09-12 09:55:54 +00:00
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_duration' );
2022-09-08 16:46:18 +00:00
} catch ( \Throwable $th ) {
2022-09-12 09:55:54 +00:00
Console :: warning ( " '_key_duration' from { $id } : { $th -> getMessage () } " );
2022-09-08 16:46:18 +00:00
}
2022-09-07 08:43:05 +00:00
break ;
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
case 'functions' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
2022-09-08 16:46:18 +00:00
$this -> migrateDateTimeAttribute ( $id , 'scheduleNext' );
$this -> migrateDateTimeAttribute ( $id , 'schedulePrevious' );
/**
2022-09-09 12:44:04 +00:00
* Migrate function variables into a new table .
2022-09-08 16:46:18 +00:00
*/
2022-09-09 12:44:04 +00:00
Console :: log ( " Migrating Collection \" { $id } \" Variables " );
2022-09-12 13:53:00 +00:00
foreach ( $this -> documentsIterator ( $id ) as $function ) {
2022-09-14 07:12:17 +00:00
$vars = $function -> getAttribute ( 'vars' , []);
if ( ! is_array ( $vars )) {
continue ;
}
foreach ( $vars as $key => $value ) {
2022-09-09 12:44:04 +00:00
if ( $value instanceof Document ) {
continue ;
}
2022-09-12 14:06:05 +00:00
2022-09-08 16:46:18 +00:00
$variableId = ID :: unique ();
$variable = new Document ([
'$id' => $variableId ,
'$permissions' => [
Permission :: read ( Role :: any ()),
Permission :: update ( Role :: any ()),
Permission :: delete ( Role :: any ()),
],
'functionId' => $function -> getId (),
'functionInternalId' => $function -> getInternalId (),
2022-09-12 14:06:05 +00:00
'key' => ( string ) $key ,
'value' => ( string ) $value ,
2022-09-08 16:46:18 +00:00
'search' => implode ( ' ' , [ $variableId , $key , $function -> getId ()])
]);
$this -> projectDB -> createDocument ( 'variables' , $variable );
}
$this -> projectDB -> deleteAttribute ( 'functions' , 'vars' );
$this -> createAttributeFromCollection ( $this -> projectDB , 'functions' , 'vars' );
}
2022-09-14 08:21:32 +00:00
try {
/**
* Create 'scheduleUpdatedAt' attribute
*/
$this -> createAttributeFromCollection ( $this -> projectDB , $id , 'scheduleUpdatedAt' );
} catch ( \Throwable $th ) {
Console :: warning ( " 'scheduleUpdatedAt' from { $id } : { $th -> getMessage () } " );
}
2022-09-14 07:26:22 +00:00
try {
/**
* Create 'enabled' attribute
*/
@ $this -> projectDB -> deleteAttribute ( $id , 'status' );
$this -> createAttributeFromCollection ( $this -> projectDB , $id , 'enabled' );
} catch ( \Throwable $th ) {
Console :: warning ( " 'enabled' from { $id } : { $th -> getMessage () } " );
}
2022-09-08 16:46:18 +00:00
try {
/**
* Create '_key_name' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_name' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_name' from { $id } : { $th -> getMessage () } " );
}
try {
/**
2022-09-14 07:26:22 +00:00
* Create '_key_enabled' index
2022-09-08 16:46:18 +00:00
*/
2022-09-14 07:26:22 +00:00
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_enabled' );
2022-09-08 16:46:18 +00:00
} catch ( \Throwable $th ) {
2022-09-14 07:26:22 +00:00
Console :: warning ( " '_key_enabled' from { $id } : { $th -> getMessage () } " );
2022-09-08 16:46:18 +00:00
}
try {
/**
* Create '_key_runtime' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_runtime' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_runtime' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_deployment' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_deployment' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_deployment' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_schedule' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_schedule' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_schedule' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_scheduleNext' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_scheduleNext' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_scheduleNext' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_schedulePrevious' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_schedulePrevious' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_schedulePrevious' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_timeout' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_timeout' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_timeout' from { $id } : { $th -> getMessage () } " );
}
2022-09-07 08:43:05 +00:00
break ;
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
case 'indexes' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
break ;
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
case 'keys' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
2022-09-08 16:46:18 +00:00
$this -> migrateDateTimeAttribute ( $id , 'expire' );
2022-09-09 12:44:04 +00:00
try {
/**
* Update 'expire' default value
*/
$this -> projectDB -> updateAttributeDefault ( 'keys' , 'expire' , null );
} catch ( \Throwable $th ) {
Console :: warning ( " 'expire' from { $id } : { $th -> getMessage () } " );
}
2022-09-08 16:46:18 +00:00
try {
/**
* Create 'accessedAt' attribute
*/
$this -> createAttributeFromCollection ( $this -> projectDB , $id , 'accessedAt' );
} catch ( \Throwable $th ) {
Console :: warning ( " 'accessedAt' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create 'sdks' attribute
*/
$this -> createAttributeFromCollection ( $this -> projectDB , $id , 'sdks' );
} catch ( \Throwable $th ) {
Console :: warning ( " 'sdks' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_accessedAt' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_accessedAt' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_accessedAt' from { $id } : { $th -> getMessage () } " );
}
2022-09-07 08:43:05 +00:00
break ;
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
case 'memberships' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
2022-09-08 16:46:18 +00:00
$this -> migrateDateTimeAttribute ( $id , 'invited' );
$this -> migrateDateTimeAttribute ( $id , 'joined' );
try {
/**
* Create '_key_userId' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_userId' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_userId' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_teamId' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_teamId' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_teamId' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_invited' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_invited' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_invited' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_joined' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_joined' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_joined' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_confirm' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_confirm' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_confirm' from { $id } : { $th -> getMessage () } " );
}
2022-09-07 08:43:05 +00:00
break ;
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
case 'platforms' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
break ;
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
case 'projects' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
2022-09-08 16:46:18 +00:00
try {
/**
* Create '_key_name' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_name' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_name' from { $id } : { $th -> getMessage () } " );
}
2022-09-07 08:43:05 +00:00
break ;
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
case 'realtime' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
2022-09-08 16:46:18 +00:00
$this -> migrateDateTimeAttribute ( $id , 'timestamp' );
2022-09-07 08:43:05 +00:00
break ;
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
case 'sessions' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
2022-09-08 16:46:18 +00:00
$this -> migrateDateTimeAttribute ( $id , 'expire' );
$this -> migrateDateTimeAttribute ( $id , 'providerAccessTokenExpiry' );
2022-09-07 08:43:05 +00:00
break ;
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
case 'stats' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
2022-09-08 16:46:18 +00:00
$this -> migrateDateTimeAttribute ( $id , 'time' );
try {
/**
* Re - Create '_key_metric' index
*/
@ $this -> projectDB -> deleteIndex ( $id , '_key_metric' );
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_period_time' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_period_time' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Re - Create '_key_metric_period' index
*/
@ $this -> projectDB -> deleteIndex ( $id , '_key_metric_period' );
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_metric_period_time' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_metric_period_time' from { $id } : { $th -> getMessage () } " );
}
2022-09-07 08:43:05 +00:00
break ;
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
case 'teams' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
2022-09-08 16:46:18 +00:00
try {
/**
* Create '_key_name' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_name' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_name' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_total' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_total' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_total' from { $id } : { $th -> getMessage () } " );
}
2022-09-07 08:43:05 +00:00
break ;
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
case 'tokens' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
2022-09-08 16:46:18 +00:00
$this -> migrateDateTimeAttribute ( $id , 'expire' );
2022-09-07 08:43:05 +00:00
break ;
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
case 'users' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
2022-09-08 16:46:18 +00:00
$this -> migrateDateTimeAttribute ( $id , 'registration' );
$this -> migrateDateTimeAttribute ( $id , 'passwordUpdate' );
try {
/**
* Create 'hash' attribute
*/
$this -> createAttributeFromCollection ( $this -> projectDB , $id , 'hash' );
} catch ( \Throwable $th ) {
Console :: warning ( " 'hash' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create 'hashOptions' attribute
*/
$this -> createAttributeFromCollection ( $this -> projectDB , $id , 'hashOptions' );
} catch ( \Throwable $th ) {
Console :: warning ( " 'hashOptions' from { $id } : { $th -> getMessage () } " );
}
/**
* Update user password before adding encrypt filter .
*/
2022-09-09 12:44:04 +00:00
Console :: log ( " Migrating Collection \" { $id } \" Passwords " );
2022-09-08 16:46:18 +00:00
foreach ( $this -> documentsIterator ( 'users' ) as $user ) {
/**
* Skip when no password .
*/
if ( is_null ( $user -> getAttribute ( 'password' ))) {
continue ;
}
2022-09-14 10:10:27 +00:00
/**
* Skip if hash is set to default value .
*/
2022-09-14 11:02:14 +00:00
if ( in_array ( $user -> getAttribute ( 'hash' ), [ 'bcrypt' , 'argon2' ])) {
2022-09-14 10:10:27 +00:00
continue ;
}
2022-09-08 16:46:18 +00:00
/**
* Skip when password is JSON .
*/
json_decode ( $user -> getAttribute ( 'password' ));
if ( json_last_error () === JSON_ERROR_NONE ) {
continue ;
}
/**
* Add default hash .
*/
$user -> setAttribute ( 'hash' , 'bcrypt' );
/**
* Add default hash options .
*/
$user -> setAttribute ( 'hashOptions' , json_encode ([ 'cost' => 8 ]));
/**
* Encrypt hashed password .
*/
$user -> setAttribute ( 'password' , $this -> encryptFilter ( $user -> getAttribute ( 'password' )));
2022-09-09 12:44:04 +00:00
/**
* Migrate permissions .
*/
$this -> populatePermissionsAttribute ( $user , addCreatePermission : false );
2022-09-08 16:46:18 +00:00
$this -> projectDB -> updateDocument ( 'users' , $user -> getId (), $user );
}
try {
/**
* Add datetime filter to password .
*/
$this -> projectDB -> updateAttributeFilters ( $id , 'password' , [ 'encrypt' ]);
} catch ( \Throwable $th ) {
Console :: warning ( " Add 'encrypt' filter to 'password' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_name' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_name' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_name' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_status' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_status' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_status' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_passwordUpdate' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_passwordUpdate' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_passwordUpdate' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_registration' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_registration' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_registration' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_emailVerification' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_emailVerification' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_emailVerification' from { $id } : { $th -> getMessage () } " );
}
try {
/**
* Create '_key_phoneVerification' index
*/
$this -> createIndexFromCollection ( $this -> projectDB , $id , '_key_phoneVerification' );
} catch ( \Throwable $th ) {
Console :: warning ( " '_key_phoneVerification' from { $id } : { $th -> getMessage () } " );
}
2022-09-12 13:53:00 +00:00
$this -> migrateStatsMetric ( 'users.count' , 'users.$all.requests.count' );
$this -> migrateStatsMetric ( 'users.create' , 'users.$all.requests.create' );
$this -> migrateStatsMetric ( 'users.read' , 'users.$all.requests.read' );
$this -> migrateStatsMetric ( 'users.update' , 'users.$all.requests.update' );
$this -> migrateStatsMetric ( 'users.delete' , 'users.$all.requests.delete' );
$this -> migrateStatsMetric ( 'users.sessions.create' , 'sessions.$all.requests.create' );
$this -> migrateStatsMetric ( 'users.sessions.delete' , 'sessions.$all.requests.delete' );
foreach ( $this -> providers as $provider ) {
$this -> migrateStatsMetric ( " users.sessions. { $provider } .create " , " sessions. $provider .requests.create " );
}
2022-09-07 08:43:05 +00:00
break ;
2022-09-08 16:46:18 +00:00
2022-09-07 08:43:05 +00:00
case 'webhooks' :
2022-09-08 16:46:18 +00:00
$this -> createPermissionsColumn ( $id );
2022-09-07 08:43:05 +00:00
$this -> migrateDateTimeAttribute ( $id , '_createdAt' );
$this -> migrateDateTimeAttribute ( $id , '_updatedAt' );
break ;
default :
2022-09-09 09:38:54 +00:00
break ;
2022-09-07 08:43:05 +00:00
}
usleep ( 50000 );
}
}
/**
* Fix run on each document
*
* @ param \Utopia\Database\Document $document
* @ return \Utopia\Database\Document
*/
protected function fixDocument ( Document $document )
{
switch ( $document -> getCollection ()) {
2022-09-08 16:46:18 +00:00
case 'cache' :
case 'variables' :
2022-09-09 12:44:04 +00:00
case 'users' :
/**
* skipping migration for 'cache' and 'variables' .
* 'users' already migrated .
*/
2022-09-08 16:46:18 +00:00
return null ;
2022-09-09 12:44:04 +00:00
case '_metadata' :
/**
* Populate permissions attribute .
*/
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
break ;
case 'abuse' :
/**
* Populate permissions attribute .
*/
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
break ;
case 'attributes' :
/**
* Populate permissions attribute .
*/
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
break ;
case 'audit' :
/**
* Populate permissions attribute .
*/
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
break ;
case 'buckets' :
/**
* Populate permissions attribute .
*
* Note : Buckets need to migrate 'create' permissions .
*/
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
break ;
case 'builds' :
/**
* Populate permissions attribute .
*/
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
break ;
case 'certificates' :
/**
* Populate permissions attribute .
*/
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
break ;
case 'databases' :
/**
* Populate permissions attribute .
*/
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
break ;
case 'deployments' :
/**
* Populate permissions attribute .
*/
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
break ;
case 'domains' :
/**
* Populate permissions attribute .
*/
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
break ;
case 'executions' :
/**
* Populate permissions attribute .
*/
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
break ;
case 'functions' :
/**
* Populate permissions attribute .
*/
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
/**
* Migrate execute permissions .
*/
$document -> setAttribute ( 'execute' , array_map (
2022-09-14 11:57:02 +00:00
function ( string $permission ) {
$permission = $this -> migratePermission ( $permission );
if ( $permission === 'any' ) {
$permission = 'users' ;
}
return $permission ;
},
2022-09-09 12:44:04 +00:00
$document -> getAttribute ( 'execute' , [])
));
2022-09-14 07:26:22 +00:00
/**
* Set 'enabled' default .
*/
$document -> setAttribute ( 'enabled' , true );
2022-09-12 13:53:00 +00:00
/**
* Migrate functions stats .
*/
$functionId = $document -> getId ();
$this -> migrateStatsMetric ( " functions. $functionId .executions " , " executions. $functionId .compute.total " );
$this -> migrateStatsMetric ( " functions. $functionId .failures " , " executions. $functionId .compute.failure " );
$this -> migrateStatsMetric ( " functions. $functionId .compute " , " executions. $functionId .compute.time " );
2022-09-09 12:44:04 +00:00
break ;
case 'indexes' :
/**
* Populate permissions attribute .
*/
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
break ;
case 'keys' :
/**
* Populate permissions attribute .
*/
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
break ;
case 'memberships' :
/**
* Populate permissions attribute .
*/
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
break ;
case 'platforms' :
/**
* Populate permissions attribute .
*/
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
break ;
2022-09-07 08:43:05 +00:00
case 'projects' :
/**
2022-09-08 16:46:18 +00:00
* Populate permissions attribute .
2022-09-07 08:43:05 +00:00
*/
2022-09-08 16:46:18 +00:00
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
2022-09-07 08:43:05 +00:00
/**
2022-09-08 16:46:18 +00:00
* Bump version number .
2022-09-07 08:43:05 +00:00
*/
2022-09-14 09:00:13 +00:00
$document -> setAttribute ( 'version' , '1.0.0' );
2022-09-07 08:43:05 +00:00
break ;
2022-09-09 12:44:04 +00:00
case 'realtime' :
2022-09-07 08:43:05 +00:00
/**
2022-09-08 16:46:18 +00:00
* Populate permissions attribute .
2022-09-07 08:43:05 +00:00
*/
2022-09-08 16:46:18 +00:00
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
2022-09-09 12:44:04 +00:00
2022-09-09 09:38:54 +00:00
break ;
case 'sessions' :
2022-09-09 12:44:04 +00:00
/**
* Populate permissions attribute .
*/
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
break ;
case 'stats' :
/**
* Populate permissions attribute .
*/
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
break ;
case 'teams' :
/**
* Populate permissions attribute .
*/
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
break ;
case 'tokens' :
/**
* Populate permissions attribute .
*/
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
break ;
case 'users' :
/**
* Populate permissions attribute .
*/
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
break ;
case 'webhooks' :
/**
* Populate permissions attribute .
*/
$this -> populatePermissionsAttribute ( $document , addCreatePermission : false );
2022-09-07 08:43:05 +00:00
break ;
}
return $document ;
}
2022-09-08 16:46:18 +00:00
2022-09-12 13:53:00 +00:00
protected function migrateStatsMetric ( string $from , string $to ) : void
{
try {
$from = $this -> pdo -> quote ( $from );
$to = $this -> pdo -> quote ( $to );
$this -> pdo -> prepare ( " UPDATE ` { $this -> projectDB -> getDefaultDatabase () } `.`_ { $this -> project -> getInternalId () } _stats` SET metric = { $to } WHERE metric = { $from } " ) -> execute ();
} catch ( \Throwable $th ) {
Console :: warning ( " Migrating steps from { $this -> projectDB -> getDefaultDatabase () } `.`_ { $this -> project -> getInternalId () } _stats: " . $th -> getMessage ());
}
}
2022-09-09 12:44:04 +00:00
/**
* Filter from the 'encrypt' filter .
*
* @ param string $value
* @ return string | false
*/
protected function encryptFilter ( string $value ) : string
2022-09-08 16:46:18 +00:00
{
$key = App :: getEnv ( '_APP_OPENSSL_KEY_V1' );
$iv = OpenSSL :: randomPseudoBytes ( OpenSSL :: cipherIVLength ( OpenSSL :: CIPHER_AES_128_GCM ));
$tag = null ;
return json_encode ([
'data' => OpenSSL :: encrypt ( $value , OpenSSL :: CIPHER_AES_128_GCM , $key , 0 , $iv , $tag ),
'method' => OpenSSL :: CIPHER_AES_128_GCM ,
'iv' => \bin2hex ( $iv ),
'tag' => \bin2hex ( $tag ? ? '' ),
'version' => '1' ,
]);
}
2022-09-07 08:43:05 +00:00
}