1
0
Fork 0
mirror of synced 2024-05-20 12:42:39 +12:00

Tests - work in progress

This commit is contained in:
Eldad Fux 2020-01-11 15:58:02 +02:00
parent 2181683c13
commit f5f074eb86
29 changed files with 2381 additions and 159 deletions

View file

@ -4,11 +4,11 @@
* Upgraded core API PHP version to 7.4
* New database rule validation options
* Update docs example with auth info
* Allow non-web platform skip origin header
* Limited to console UI to show max 5 alerts at the same time
* Limited console dashboard to show max 5 alerts at the same time
* Added new webhooks events
* Normnailized all webhooks event names
* Normailized all webhooks event names
* Merged Auth and Account service for making the API more REST compatible
## Bug Fixes

View file

@ -211,7 +211,7 @@ $utopia->shutdown(function () use ($response, $request, $webhook, $audit, $usage
if (!empty($webhook->getParam('event'))) {
$webhook->trigger();
}
if (!empty($audit->getParam('event'))) {
$audit->trigger();
}
@ -361,7 +361,7 @@ $utopia->get('/humans.txt')
);
$utopia->get('/v1/info') // This is only visible to gods
->label('scope', 'god')
->label('scope', 'god')
->label('docs', false)
->action(
function () use ($response, $user, $project, $version, $env) { //TODO CONSIDER BLOCKING THIS ACTION TO ROLE GOD
@ -410,7 +410,7 @@ $utopia->get('/v1/proxy')
}
);
$utopia->get('/v1/open-api-2.json')
$utopia->get('/v1/open-api-2.json')
->label('scope', 'public')
->label('docs', false)
->param('platform', 'client', function () {return new WhiteList(['client', 'server']);}, 'Choose target platform.', true)
@ -740,6 +740,7 @@ $utopia->get('/v1/debug')
->action(
function () use ($response, $request, $utopia, $domain, $services) {
$output = [
'scopes' => [],
'webhooks' => [],
'methods' => [],
'routes' => [],
@ -767,6 +768,10 @@ $utopia->get('/v1/debug')
continue;
}
if ($route->getLabel('scope', false)) {
$output['scopes'][$route->getLabel('scope', false)] = $route->getMethod().' '.$route->getURL();
}
if ($route->getLabel('sdk.description', false)) {
if(!realpath(__DIR__.'/../'.$route->getLabel('sdk.description', false))) {
throw new Exception('Docs file ('.$route->getLabel('sdk.description', false).') is missing', 500);
@ -802,6 +807,7 @@ $utopia->get('/v1/debug')
}
}
ksort($output['scopes']);
ksort($output['webhooks']);
ksort($output['methods']);
ksort($output['routes']);

View file

@ -15,7 +15,7 @@
<a href="{{redirect}}">{{redirect}}</a>
<br />
<br />
If you didnt ask to reset your password, you can ignore this message.
If you didn't ask to reset your password, you can ignore this message.
<br />
<br />
Thanks,

View file

@ -1,8 +1,10 @@
<?php
global $utopia, $register, $request, $response, $user, $audit, $webhook, $project, $domain, $projectDB, $providers, $clients;
global $utopia, $register, $request, $response, $user, $audit,
$webhook, $project, $domain, $projectDB, $providers, $clients;
use Utopia\Exception;
use Utopia\Response;
use Utopia\Validator\Text;
use Utopia\Validator\Email;
use Utopia\Validator\WhiteList;
@ -24,6 +26,20 @@ use OpenSSL\OpenSSL;
include_once __DIR__ . '/../shared/api.php';
$oauthKeys = [];
$utopia->init(function() use ($providers, &$oauthKeys) {
foreach ($providers as $key => $provider) {
if (!$provider['enabled']) {
continue;
}
$oauthKeys[] = 'oauth'.ucfirst($key);
$oauthKeys[] = 'oauth'.ucfirst($key).'AccessToken';
}
});
$utopia->get('/v1/account')
->desc('Get Account')
->label('scope', 'account')
@ -31,18 +47,7 @@ $utopia->get('/v1/account')
->label('sdk.method', 'getAccount')
->label('sdk.description', '/docs/references/account/get.md')
->action(
function () use ($response, &$user, $providers) {
$oauthKeys = [];
foreach ($providers as $key => $provider) {
if (!$provider['enabled']) {
continue;
}
$oauthKeys[] = 'oauth'.ucfirst($key);
$oauthKeys[] = 'oauth'.ucfirst($key).'AccessToken';
}
function () use ($response, &$user, $oauthKeys) {
$response->json(array_merge($user->getArrayCopy(array_merge(
[
'$uid',
@ -109,7 +114,7 @@ $utopia->get('/v1/account/sessions')
$dd->parse();
$sessions[$index] = [
'id' => $token->getUid(),
'$uid' => $token->getUid(),
'OS' => $dd->getOs(),
'client' => $dd->getClient(),
'device' => $dd->getDevice(),
@ -146,6 +151,7 @@ $utopia->get('/v1/account/logs')
function () use ($response, $register, $project, $user) {
$adapter = new AuditAdapter($register->get('db'));
$adapter->setNamespace('app_'.$project->getUid());
$audit = new Audit($adapter);
$countries = Locale::getText('countries');
@ -220,7 +226,7 @@ $utopia->post('/v1/account')
->param('password', '', function () { return new Password(); }, 'User password')
->param('name', '', function () { return new Text(100); }, 'User name', true)
->action(
function ($email, $password, $name) use ($request, $response, $providers, $audit, $projectDB, $project, $webhook) {
function ($email, $password, $name) use ($register, $request, $response, $audit, $projectDB, $project, $webhook, $oauthKeys) {
if ('console' === $project->getUid()) {
$whitlistEmails = $project->getAttribute('authWhitelistEmails');
$whitlistIPs = $project->getAttribute('authWhitelistIPs');
@ -276,14 +282,6 @@ $utopia->post('/v1/account')
throw new Exception('Failed saving user to DB', 500);
}
Authorization::setRole('user:'.$user->getUid());
$user = $projectDB->createDocument($user->getArrayCopy());
if (false === $user) {
throw new Exception('Failed saving tokens to DB', 500);
}
$webhook
->setParam('payload', [
'name' => $name,
@ -297,26 +295,17 @@ $utopia->post('/v1/account')
->setParam('resource', 'users/'.$user->getUid())
;
$oauthKeys = [];
foreach ($providers as $key => $provider) {
if (!$provider['enabled']) {
continue;
}
$oauthKeys[] = 'oauth'.ucfirst($key);
$oauthKeys[] = 'oauth'.ucfirst($key).'AccessToken';
}
$response->json(array_merge($user->getArrayCopy(array_merge(
[
'$uid',
'email',
'registration',
'name',
],
$oauthKeys
)), ['roles' => Authorization::getRoles()]));
$response
->setStatusCode(Response::STATUS_CODE_CREATED)
->json(array_merge($user->getArrayCopy(array_merge(
[
'$uid',
'email',
'registration',
'name',
],
$oauthKeys
)), ['roles' => Authorization::getRoles()]));
}
);
@ -342,11 +331,11 @@ $utopia->post('/v1/account/sessions')
],
]);
if (!$profile || !Auth::passwordVerify($password, $profile->getAttribute('password'))) {
if (false == $profile || !Auth::passwordVerify($password, $profile->getAttribute('password'))) {
$audit
//->setParam('userId', $profile->getUid())
->setParam('event', 'account.sesssions.failed')
->setParam('resource', 'users/'.$profile->getUid())
->setParam('resource', 'users/'.($profile ? $profile->getUid() : ''))
;
throw new Exception('Invalid credentials', 401); // Wrong password or username
@ -354,8 +343,7 @@ $utopia->post('/v1/account/sessions')
$expiry = time() + Auth::TOKEN_EXPIRATION_LOGIN_LONG;
$secret = Auth::tokenGenerator();
$profile->setAttribute('tokens', new Document([
$session = new Document([
'$collection' => Database::SYSTEM_COLLECTION_TOKENS,
'$permissions' => ['read' => ['user:'.$profile->getUid()], 'write' => ['user:'.$profile->getUid()]],
'type' => Auth::TOKEN_TYPE_LOGIN,
@ -363,10 +351,18 @@ $utopia->post('/v1/account/sessions')
'expire' => $expiry,
'userAgent' => $request->getServer('HTTP_USER_AGENT', 'UNKNOWN'),
'ip' => $request->getIP(),
]), Document::SET_TYPE_APPEND);
]);
Authorization::setRole('user:'.$profile->getUid());
$session = $projectDB->createDocument($session->getArrayCopy());
if (false === $session) {
throw new Exception('Failed saving session to DB', 500);
}
$profile->setAttribute('tokens', $session, Document::SET_TYPE_APPEND);
$profile = $projectDB->updateDocument($profile->getArrayCopy());
if (false === $profile) {
@ -382,15 +378,15 @@ $utopia->post('/v1/account/sessions')
$audit
->setParam('userId', $profile->getUid())
->setParam('event', 'account.sesssions.create')
->setParam('event', 'account.sessions.create')
->setParam('resource', 'users/'.$profile->getUid())
;
$response
->addCookie(Auth::$cookieName, Auth::encodeSession($profile->getUid(), $secret), $expiry, '/', COOKIE_DOMAIN, ('https' == $request->getServer('REQUEST_SCHEME', 'https')), true, COOKIE_SAMESITE);
$response
->json(array('result' => 'success'));
->addCookie(Auth::$cookieName, Auth::encodeSession($profile->getUid(), $secret), $expiry, '/', COOKIE_DOMAIN, ('https' == $request->getServer('REQUEST_SCHEME', 'https')), true, COOKIE_SAMESITE)
->setStatusCode(Response::STATUS_CODE_CREATED)
->json($session->getArrayCopy(['$uid', 'type', 'expire']))
;
}
);
@ -583,20 +579,21 @@ $utopia->get('/v1/account/sessions/oauth/:provider/redirect')
$secret = Auth::tokenGenerator();
$expiry = time() + Auth::TOKEN_EXPIRATION_LOGIN_LONG;
$session = new Document([
'$collection' => Database::SYSTEM_COLLECTION_TOKENS,
'$permissions' => ['read' => ['user:'.$user['$uid']], 'write' => ['user:'.$user['$uid']]],
'type' => Auth::TOKEN_TYPE_LOGIN,
'secret' => Auth::hash($secret), // On way hash encryption to protect DB leak
'expire' => $expiry,
'userAgent' => $request->getServer('HTTP_USER_AGENT', 'UNKNOWN'),
'ip' => $request->getIP(),
]);
$user
->setAttribute('oauth'.ucfirst($provider), $oauthID)
->setAttribute('oauth'.ucfirst($provider).'AccessToken', $accessToken)
->setAttribute('status', Auth::USER_STATUS_ACTIVATED)
->setAttribute('tokens', new Document([
'$collection' => Database::SYSTEM_COLLECTION_TOKENS,
'$permissions' => ['read' => ['user:'.$user['$uid']], 'write' => ['user:'.$user['$uid']]],
'type' => Auth::TOKEN_TYPE_LOGIN,
'secret' => Auth::hash($secret), // On way hash encryption to protect DB leak
'expire' => $expiry,
'userAgent' => $request->getServer('HTTP_USER_AGENT', 'UNKNOWN'),
'ip' => $request->getIP(),
]), Document::SET_TYPE_APPEND)
->setAttribute('tokens', $session, Document::SET_TYPE_APPEND)
;
Authorization::setRole('user:'.$user->getUid());
@ -631,7 +628,7 @@ $utopia->patch('/v1/account/name')
->label('sdk.description', '/docs/references/account/update-name.md')
->param('name', '', function () { return new Text(100); }, 'User name')
->action(
function ($name) use ($response, $user, $projectDB, $audit) {
function ($name) use ($response, $user, $projectDB, $audit, $oauthKeys) {
$user = $projectDB->updateDocument(array_merge($user->getArrayCopy(), [
'name' => $name,
]));
@ -645,7 +642,15 @@ $utopia->patch('/v1/account/name')
->setParam('resource', 'users/'.$user->getUid())
;
$response->json(array('result' => 'success'));
$response->json(array_merge($user->getArrayCopy(array_merge(
[
'$uid',
'email',
'registration',
'name',
],
$oauthKeys
)), ['roles' => Authorization::getRoles()]));
}
);
@ -659,7 +664,7 @@ $utopia->patch('/v1/account/password')
->param('password', '', function () { return new Password(); }, 'New password')
->param('old-password', '', function () { return new Password(); }, 'Old password')
->action(
function ($password, $oldPassword) use ($response, $user, $projectDB, $audit) {
function ($password, $oldPassword) use ($response, $user, $projectDB, $audit, $oauthKeys) {
if (!Auth::passwordVerify($oldPassword, $user->getAttribute('password'))) { // Double check user password
throw new Exception('Invalid credentials', 401);
}
@ -677,7 +682,15 @@ $utopia->patch('/v1/account/password')
->setParam('resource', 'users/'.$user->getUid())
;
$response->json(array('result' => 'success'));
$response->json(array_merge($user->getArrayCopy(array_merge(
[
'$uid',
'email',
'registration',
'name',
],
$oauthKeys
)), ['roles' => Authorization::getRoles()]));
}
);
@ -691,7 +704,7 @@ $utopia->patch('/v1/account/email')
->param('email', '', function () { return new Email(); }, 'Email Address')
->param('password', '', function () { return new Password(); }, 'User Password')
->action(
function ($email, $password) use ($response, $user, $projectDB, $audit) {
function ($email, $password) use ($response, $user, $projectDB, $audit, $oauthKeys) {
if (!Auth::passwordVerify($password, $user->getAttribute('password'))) { // Double check user password
throw new Exception('Invalid credentials', 401);
}
@ -724,7 +737,15 @@ $utopia->patch('/v1/account/email')
->setParam('resource', 'users/'.$user->getUid())
;
$response->json(array('result' => 'success'));
$response->json(array_merge($user->getArrayCopy(array_merge(
[
'$uid',
'email',
'registration',
'name',
],
$oauthKeys
)), ['roles' => Authorization::getRoles()]));
}
);
@ -751,7 +772,19 @@ $utopia->patch('/v1/account/prefs')
->setParam('resource', 'users/'.$user->getUid())
;
$response->json(array('result' => 'success'));
$prefs = $user->getAttribute('prefs', '{}');
if (empty($prefs)) {
$prefs = '[]';
}
try {
$prefs = json_decode($prefs, true);
} catch (\Exception $error) {
throw new Exception('Failed to parse preferences', 500);
}
$response->json($prefs);
}
);
@ -795,39 +828,46 @@ $utopia->delete('/v1/account')
$response
->addCookie(Auth::$cookieName, '', time() - 3600, '/', COOKIE_DOMAIN, ('https' == $request->getServer('REQUEST_SCHEME', 'https')), true, COOKIE_SAMESITE)
->json(array('result' => 'success'));
->noContent()
;
}
);
$utopia->delete('/v1/account/sessions/current')
->desc('Delete Current Account Session')
->label('webhook', 'account.sessions.delete')
$utopia->delete('/v1/account/sessions')
->desc('Delete All Account Sessions')
->label('scope', 'account')
->label('webhook', 'account.sessions.delete')
->label('sdk.namespace', 'account')
->label('sdk.method', 'deleteAccountCurrentSession')
->label('sdk.description', '/docs/references/account/delete-session-current.md')
->label('sdk.method', 'deleteAccountSessions')
->label('sdk.description', '/docs/references/account/delete-sessions.md')
->label('abuse-limit', 100)
->action(
function () use ($response, $request, $user, $projectDB, $audit, $webhook) {
$token = Auth::tokenVerify($user->getAttribute('tokens'), Auth::TOKEN_TYPE_LOGIN, Auth::$secret);
$tokens = $user->getAttribute('tokens', []);
if (!$projectDB->deleteDocument($token)) {
throw new Exception('Failed to remove token from DB', 500);
foreach ($tokens as $token) { /* @var $token Document */
if (!$projectDB->deleteDocument($token->getUid())) {
throw new Exception('Failed to remove token from DB', 500);
}
$audit
->setParam('event', 'account.sessions.delete')
->setParam('resource', '/user/'.$user->getUid())
;
$webhook
->setParam('payload', [
'name' => $user->getAttribute('name', ''),
'email' => $user->getAttribute('email', ''),
])
;
if ($token->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too
$response->addCookie(Auth::$cookieName, '', time() - 3600, '/', COOKIE_DOMAIN, ('https' == $request->getServer('REQUEST_SCHEME', 'https')), true, COOKIE_SAMESITE);
}
}
$webhook
->setParam('payload', [
'name' => $user->getAttribute('name', ''),
'email' => $user->getAttribute('email', ''),
])
;
$audit->setParam('event', 'account.sessions.delete');
$response
->addCookie(Auth::$cookieName, '', time() - 3600, '/', COOKIE_DOMAIN, ('https' == $request->getServer('REQUEST_SCHEME', 'https')), true, COOKIE_SAMESITE)
->json(array('result' => 'success'))
;
$response->noContent();
}
);
@ -868,45 +908,39 @@ $utopia->delete('/v1/account/sessions/:id')
}
}
$response->json(array('result' => 'success'));
$response->noContent();
}
);
$utopia->delete('/v1/account/sessions')
->desc('Delete All Account Sessions')
->label('scope', 'account')
$utopia->delete('/v1/account/sessions/current')
->desc('Delete Current Account Session')
->label('webhook', 'account.sessions.delete')
->label('scope', 'account')
->label('sdk.namespace', 'account')
->label('sdk.method', 'deleteAccountSessions')
->label('sdk.description', '/docs/references/account/delete-sessions.md')
->label('sdk.method', 'deleteAccountCurrentSession')
->label('sdk.description', '/docs/references/account/delete-session-current.md')
->label('abuse-limit', 100)
->action(
function () use ($response, $request, $user, $projectDB, $audit, $webhook) {
$tokens = $user->getAttribute('tokens', []);
$token = Auth::tokenVerify($user->getAttribute('tokens'), Auth::TOKEN_TYPE_LOGIN, Auth::$secret);
foreach ($tokens as $token) { /* @var $token Document */
if (!$projectDB->deleteDocument($token->getUid())) {
throw new Exception('Failed to remove token from DB', 500);
}
$audit
->setParam('event', 'account.sessions.delete')
->setParam('resource', '/user/'.$user->getUid())
;
$webhook
->setParam('payload', [
'name' => $user->getAttribute('name', ''),
'email' => $user->getAttribute('email', ''),
])
;
if ($token->getAttribute('secret') == Auth::hash(Auth::$secret)) { // If current session delete the cookies too
$response->addCookie(Auth::$cookieName, '', time() - 3600, '/', COOKIE_DOMAIN, ('https' == $request->getServer('REQUEST_SCHEME', 'https')), true, COOKIE_SAMESITE);
}
if (!$projectDB->deleteDocument($token)) {
throw new Exception('Failed to remove token from DB', 500);
}
$response->json(array('result' => 'success'));
$webhook
->setParam('payload', [
'name' => $user->getAttribute('name', ''),
'email' => $user->getAttribute('email', ''),
])
;
$audit->setParam('event', 'account.sessions.delete');
$response
->addCookie(Auth::$cookieName, '', time() - 3600, '/', COOKIE_DOMAIN, ('https' == $request->getServer('REQUEST_SCHEME', 'https')), true, COOKIE_SAMESITE)
->noContent()
;
}
);
@ -936,8 +970,7 @@ $utopia->post('/v1/account/recovery')
}
$secret = Auth::tokenGenerator();
$profile->setAttribute('tokens', new Document([
$recovery = new Document([
'$collection' => Database::SYSTEM_COLLECTION_TOKENS,
'$permissions' => ['read' => ['user:'.$profile->getUid()], 'write' => ['user:'.$profile->getUid()]],
'type' => Auth::TOKEN_TYPE_RECOVERY,
@ -945,10 +978,18 @@ $utopia->post('/v1/account/recovery')
'expire' => time() + Auth::TOKEN_EXPIRATION_RECOVERY,
'userAgent' => $request->getServer('HTTP_USER_AGENT', 'UNKNOWN'),
'ip' => $request->getIP(),
]), Document::SET_TYPE_APPEND);
]);
Authorization::setRole('user:'.$profile->getUid());
$recovery = $projectDB->createDocument($recovery->getArrayCopy());
if (false === $recovery) {
throw new Exception('Failed saving recovery to DB', 500);
}
$profile->setAttribute('tokens', $recovery, Document::SET_TYPE_APPEND);
$profile = $projectDB->updateDocument($profile->getArrayCopy());
if (false === $profile) {
@ -978,7 +1019,7 @@ $utopia->post('/v1/account/recovery')
try {
$mail->send();
} catch (\Exception $error) {
//throw new Exception('Problem sending mail: ' . $error->getMessage(), 500);
throw new Exception('Error sending mail: ' . $error->getMessage(), 500);
}
$audit
@ -986,7 +1027,10 @@ $utopia->post('/v1/account/recovery')
->setParam('event', 'account.recovery.create')
;
$response->json(array('result' => 'success'));
$response
->setStatusCode(Response::STATUS_CODE_CREATED)
->json($recovery->getArrayCopy(['$uid', 'type', 'expire']))
;
}
);
@ -998,7 +1042,7 @@ $utopia->put('/v1/account/recovery')
->label('sdk.description', '/docs/references/account/update-recovery.md')
->label('abuse-limit', 10)
->label('abuse-key', 'url:{url},userId:{param-userId}')
->param('userId', '', function () { return new UID(); }, 'User account email address.')
->param('userId', '', function () { return new UID(); }, 'User account UID address.')
->param('token', '', function () { return new Text(256); }, 'Valid reset token.')
->param('password-a', '', function () { return new Password(); }, 'New password.')
->param('password-b', '', function () {return new Password(); }, 'New password again.')
@ -1021,10 +1065,10 @@ $utopia->put('/v1/account/recovery')
throw new Exception('User not found', 404); // TODO maybe hide this
}
$token = Auth::tokenVerify($profile->getAttribute('tokens', []), Auth::TOKEN_TYPE_RECOVERY, $token);
$recovery = Auth::tokenVerify($profile->getAttribute('tokens', []), Auth::TOKEN_TYPE_RECOVERY, $token);
if (!$token) {
throw new Exception('Recovery token is not valid', 401);
if (!$recovery) {
throw new Exception('Invalid recovery token', 401);
}
Authorization::setRole('user:'.$profile->getUid());
@ -1039,8 +1083,12 @@ $utopia->put('/v1/account/recovery')
throw new Exception('Failed saving user to DB', 500);
}
if (!$projectDB->deleteDocument($token)) {
throw new Exception('Failed to remove token from DB', 500);
/**
* We act like we're updating and validating
* the recovery token but actually we don't need it anymore.
*/
if (!$projectDB->deleteDocument($recovery)) {
throw new Exception('Failed to remove recovery from DB', 500);
}
$audit
@ -1048,6 +1096,8 @@ $utopia->put('/v1/account/recovery')
->setParam('event', 'account.recovery.update')
;
$response->json(array('result' => 'success'));
$recovery = $profile->search('$uid', $recovery, $profile->getAttribute('tokens', []));
$response->json($recovery->getArrayCopy(['$uid', 'type', 'expire']));
}
);

View file

@ -378,7 +378,7 @@ $utopia->post('/v1/teams/:teamId/memberships')
try {
$mail->send();
} catch (\Exception $error) {
//throw new Exception('Problem sending mail: ' . $error->getMessage(), 500);
throw new Exception('Error sending mail: ' . $error->getMessage(), 500);
}
$audit
@ -457,7 +457,7 @@ $utopia->post('/v1/teams/:teamId/memberships/:inviteId/resend')
try {
$mail->send();
} catch (\Exception $error) {
//throw new Exception('Problem sending mail: ' . $error->getMessage(), 500);
throw new Exception('Error sending mail: ' . $error->getMessage(), 500);
}
$audit

View file

@ -111,8 +111,8 @@ $register->set('smtp', function () use ($request) {
$mail->isSMTP();
$username = $request->getServer('_APP_SMTP_USERNAME', '');
$password = $request->getServer('_APP_SMTP_PASSWORD', '');
$username = $request->getServer('_APP_SMTP_USERNAME', null);
$password = $request->getServer('_APP_SMTP_PASSWORD', null);
$mail->XMailer = 'Appwrite Mailer';
$mail->Host = $request->getServer('_APP_SMTP_HOST', 'smtp');
@ -120,7 +120,8 @@ $register->set('smtp', function () use ($request) {
$mail->SMTPAuth = (!empty($username) && !empty($password));
$mail->Username = $username;
$mail->Password = $password;
$mail->SMTPSecure = $request->getServer('_APP_SMTP_SECURE', '');
$mail->SMTPSecure = $request->getServer('_APP_SMTP_SECURE', false);
$mail->SMTPAutoTLS = false;
$mail->setFrom('team@appwrite.io', APP_NAME.' Team');
$mail->addReplyTo('team@appwrite.io', APP_NAME.' Team');

View file

@ -17,6 +17,7 @@ services:
- ./phpunit.xml:/usr/share/nginx/html/phpunit.xml
- ./tests:/usr/share/nginx/html/tests
- ./app:/usr/share/nginx/html/app
- ./vendor:/usr/share/nginx/html/vendor
- ./docs:/usr/share/nginx/html/docs
- ./public:/usr/share/nginx/html/public
- ./src:/usr/share/nginx/html/src
@ -31,6 +32,7 @@ services:
- clamav
- influxdb
- telegraf
- maildev
environment:
- _APP_ENV=development
- _APP_OPTIONS_ABUSE=disabled
@ -46,6 +48,8 @@ services:
- _APP_INFLUXDB_PORT=8086
- _APP_STATSD_HOST=telegraf
- _APP_STATSD_PORT=8125
- _APP_SMTP_HOST=maildev
- _APP_SMTP_PORT=25
mariadb:
image: appwrite/mariadb:1.0.2 # fix issues when upgrading using: mysql_upgrade -u root -p
@ -100,18 +104,25 @@ services:
networks:
- appwrite
# resque:
# image: registry.gitlab.com/appwrite/appwrite/resque-web:v1.0.2
# restart: unless-stopped
# networks:
# - appwrite
# ports:
# - "5678:5678"
# environment:
# - RESQUE_WEB_HOST=redis
# - RESQUE_WEB_PORT=6379
# - RESQUE_WEB_HTTP_BASIC_AUTH_USER=user
# - RESQUE_WEB_HTTP_BASIC_AUTH_PASSWORD=password
resque:
image: registry.gitlab.com/appwrite/appwrite/resque-web:v1.0.2
restart: unless-stopped
networks:
- appwrite
ports:
- "5678:5678"
environment:
- RESQUE_WEB_HOST=redis
- RESQUE_WEB_PORT=6379
- RESQUE_WEB_HTTP_BASIC_AUTH_USER=user
- RESQUE_WEB_HTTP_BASIC_AUTH_PASSWORD=password
maildev:
ports:
- '1080:80'
networks:
- appwrite
image: djfarrelly/maildev
networks:
appwrite:

920
tests/e2e/AccountBase.php Normal file
View file

@ -0,0 +1,920 @@
<?php
namespace Tests\E2E;
use Tests\E2E\Client;
trait AccountBase
{
public function testCreateAccount():array
{
$email = uniqid().'user@localhost.test';
$password = 'passwrod';
$name = 'User Name';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_POST, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email,
'password' => $password,
'name' => $name,
]);
$uid = $response['body']['$uid'];
$this->assertEquals($response['headers']['status-code'], 201);
$this->assertNotEmpty($response['body']);
$this->assertNotEmpty($response['body']['$uid']);
$this->assertIsNumeric($response['body']['registration']);
$this->assertEquals($response['body']['email'], $email);
$this->assertEquals($response['body']['name'], $name);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_POST, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email,
'password' => $password,
'name' => $name,
]);
$this->assertEquals($response['headers']['status-code'], 409);
return [
'uid' => $uid,
'email' => $email,
'password' => $password,
'name' => $name,
];
}
/**
* @depends testCreateAccount
*/
public function testCreateAccountSession($data):array
{
$email = (isset($data['email'])) ? $data['email'] : '';
$password = (isset($data['password'])) ? $data['password'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_POST, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email,
'password' => $password,
]);
$sessionUid = $response['body']['$uid'];
$session = $this->client->parseCookie($response['headers']['set-cookie'])['a_session_console'];
$this->assertEquals($response['headers']['status-code'], 201);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_POST, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email.'x',
'password' => $password,
]);
$this->assertEquals($response['headers']['status-code'], 401);
$response = $this->client->call(Client::METHOD_POST, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email,
'password' => $password.'x',
]);
$this->assertEquals($response['headers']['status-code'], 401);
$response = $this->client->call(Client::METHOD_POST, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => '',
'password' => '',
]);
$this->assertEquals($response['headers']['status-code'], 400);
return array_merge($data, [
'sessionUid' => $sessionUid,
'session' => $session,
]);
}
/**
* @depends testCreateAccountSession
*/
public function testGetAccount($data):array
{
$email = (isset($data['email'])) ? $data['email'] : '';
$name = (isset($data['name'])) ? $data['name'] : '';
$session = (isset($data['session'])) ? $data['session'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_GET, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 200);
$this->assertNotEmpty($response['body']);
$this->assertNotEmpty($response['body']['$uid']);
$this->assertIsNumeric($response['body']['registration']);
$this->assertEquals($response['body']['email'], $email);
$this->assertEquals($response['body']['name'], $name);
$this->assertContains('*', $response['body']['roles']);
$this->assertContains('user:'.$response['body']['$uid'], $response['body']['roles']);
$this->assertContains('role:1', $response['body']['roles']);
$this->assertCount(3, $response['body']['roles']);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_GET, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
$response = $this->client->call(Client::METHOD_GET, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session.'xx',
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
return $data;
}
/**
* @depends testCreateAccountSession
*/
public function testGetAccountPrefs($data):array
{
$session = (isset($data['session'])) ? $data['session'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_GET, '/account/prefs', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 200);
$this->assertIsArray($response['body']);
$this->assertEmpty($response['body']);
$this->assertCount(0, $response['body']);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_GET, '/account/prefs', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
return $data;
}
/**
* @depends testCreateAccountSession
*/
public function testGetAccountSessions($data):array
{
$session = (isset($data['session'])) ? $data['session'] : '';
$sessionUid = (isset($data['sessionUid'])) ? $data['sessionUid'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_GET, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 200);
$this->assertIsArray($response['body']);
$this->assertNotEmpty($response['body']);
$this->assertCount(1, $response['body']);
$this->assertEquals($sessionUid, $response['body'][0]['$uid']);
$this->assertIsArray($response['body'][0]['OS']);
$this->assertEquals('Windows', $response['body'][0]['OS']['name']);
$this->assertEquals('WIN', $response['body'][0]['OS']['short_name']);
$this->assertEquals('10', $response['body'][0]['OS']['version']);
$this->assertEquals('x64', $response['body'][0]['OS']['platform']);
$this->assertIsArray($response['body'][0]['client']);
$this->assertEquals('browser', $response['body'][0]['client']['type']);
$this->assertEquals('Chrome', $response['body'][0]['client']['name']);
$this->assertEquals('CH', $response['body'][0]['client']['short_name']); // FIXME (v1) key name should be camelcase
$this->assertEquals('70.0', $response['body'][0]['client']['version']);
$this->assertEquals('Blink', $response['body'][0]['client']['engine']);
$this->assertEquals(0, $response['body'][0]['device']);
$this->assertEquals('', $response['body'][0]['brand']);
$this->assertEquals('', $response['body'][0]['model']);
$this->assertEquals($response['body'][0]['ip'], filter_var($response['body'][0]['ip'], FILTER_VALIDATE_IP));
$this->assertIsArray($response['body'][0]['geo']);
$this->assertEquals('--', $response['body'][0]['geo']['isoCode']);
$this->assertEquals('Unknown', $response['body'][0]['geo']['country']);
$this->assertEquals(true, $response['body'][0]['current']);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_GET, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
return $data;
}
/**
* @depends testCreateAccountSession
*/
public function testGetAccountLogs($data):array
{
sleep(5);
$session = (isset($data['session'])) ? $data['session'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_GET, '/account/logs', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 200);
$this->assertIsArray($response['body']);
$this->assertNotEmpty($response['body']);
$this->assertCount(2, $response['body']);
$this->assertEquals('account.create', $response['body'][0]['event']);
$this->assertEquals($response['body'][0]['ip'], filter_var($response['body'][0]['ip'], FILTER_VALIDATE_IP));
$this->assertIsNumeric($response['body'][0]['time']);
$this->assertIsArray($response['body'][0]['OS']);
$this->assertEquals('Windows', $response['body'][0]['OS']['name']);
$this->assertEquals('WIN', $response['body'][0]['OS']['short_name']);
$this->assertEquals('10', $response['body'][0]['OS']['version']);
$this->assertEquals('x64', $response['body'][0]['OS']['platform']);
$this->assertIsArray($response['body'][0]['client']);
$this->assertEquals('browser', $response['body'][0]['client']['type']);
$this->assertEquals('Chrome', $response['body'][0]['client']['name']);
$this->assertEquals('CH', $response['body'][0]['client']['short_name']); // FIXME (v1) key name should be camelcase
$this->assertEquals('70.0', $response['body'][0]['client']['version']);
$this->assertEquals('Blink', $response['body'][0]['client']['engine']);
$this->assertEquals(0, $response['body'][0]['device']);
$this->assertEquals('', $response['body'][0]['brand']);
$this->assertEquals('', $response['body'][0]['model']);
$this->assertEquals($response['body'][0]['ip'], filter_var($response['body'][0]['ip'], FILTER_VALIDATE_IP));
$this->assertIsArray($response['body'][0]['geo']);
$this->assertEquals('--', $response['body'][0]['geo']['isoCode']);
$this->assertEquals('Unknown', $response['body'][0]['geo']['country']);
$this->assertEquals('account.sessions.create', $response['body'][1]['event']);
$this->assertEquals($response['body'][1]['ip'], filter_var($response['body'][0]['ip'], FILTER_VALIDATE_IP));
$this->assertIsNumeric($response['body'][1]['time']);
$this->assertIsArray($response['body'][1]['OS']);
$this->assertEquals('Windows', $response['body'][1]['OS']['name']);
$this->assertEquals('WIN', $response['body'][1]['OS']['short_name']);
$this->assertEquals('10', $response['body'][1]['OS']['version']);
$this->assertEquals('x64', $response['body'][1]['OS']['platform']);
$this->assertIsArray($response['body'][1]['client']);
$this->assertEquals('browser', $response['body'][1]['client']['type']);
$this->assertEquals('Chrome', $response['body'][1]['client']['name']);
$this->assertEquals('CH', $response['body'][1]['client']['short_name']); // FIXME (v1) key name should be camelcase
$this->assertEquals('70.0', $response['body'][1]['client']['version']);
$this->assertEquals('Blink', $response['body'][1]['client']['engine']);
$this->assertEquals(0, $response['body'][1]['device']);
$this->assertEquals('', $response['body'][1]['brand']);
$this->assertEquals('', $response['body'][1]['model']);
$this->assertEquals($response['body'][1]['ip'], filter_var($response['body'][0]['ip'], FILTER_VALIDATE_IP));
$this->assertIsArray($response['body'][1]['geo']);
$this->assertEquals('--', $response['body'][1]['geo']['isoCode']);
$this->assertEquals('Unknown', $response['body'][1]['geo']['country']);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_GET, '/account/logs', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
return $data;
}
//TODO Add tests for OAuth session creation
/**
* @depends testCreateAccountSession
*/
public function testUpdateAccountName($data):array
{
$email = (isset($data['email'])) ? $data['email'] : '';
$session = (isset($data['session'])) ? $data['session'] : '';
$newName = 'New Name';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_PATCH, '/account/name', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
], [
'name' => $newName
]);
$this->assertEquals($response['headers']['status-code'], 200);
$this->assertIsArray($response['body']);
$this->assertNotEmpty($response['body']);
$this->assertNotEmpty($response['body']);
$this->assertNotEmpty($response['body']['$uid']);
$this->assertIsNumeric($response['body']['registration']);
$this->assertEquals($response['body']['email'], $email);
$this->assertEquals($response['body']['name'], $newName);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_PATCH, '/account/name', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
$response = $this->client->call(Client::METHOD_PATCH, '/account/name', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
], [
]);
$this->assertEquals($response['headers']['status-code'], 400);
$response = $this->client->call(Client::METHOD_PATCH, '/account/name', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
], [
'name' => 'ocSRq1d3QphHivJyUmYY7WMnrxyjdk5YvVwcDqx2zS0coxESN8RmsQwLWw5Whnf0WbVohuFWTRAaoKgCOO0Y0M7LwgFnZmi8881Y7'
]);
$this->assertEquals($response['headers']['status-code'], 400);
$data['name'] = $newName;
return $data;
}
/**
* @depends testUpdateAccountName
*/
public function testUpdateAccountPassword($data):array
{
$email = (isset($data['email'])) ? $data['email'] : '';
$password = (isset($data['password'])) ? $data['password'] : '';
$session = (isset($data['session'])) ? $data['session'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_PATCH, '/account/password', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
], [
'password' => 'new-password',
'old-password' => $password,
]);
$this->assertEquals($response['headers']['status-code'], 200);
$this->assertIsArray($response['body']);
$this->assertNotEmpty($response['body']);
$this->assertNotEmpty($response['body']);
$this->assertNotEmpty($response['body']['$uid']);
$this->assertIsNumeric($response['body']['registration']);
$this->assertEquals($response['body']['email'], $email);
$this->assertEquals($response['body']['name'], 'New Name');
$response = $this->client->call(Client::METHOD_POST, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email,
'password' => 'new-password',
]);
$this->assertEquals($response['headers']['status-code'], 201);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_PATCH, '/account/password', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
$response = $this->client->call(Client::METHOD_PATCH, '/account/password', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
], [
]);
$this->assertEquals($response['headers']['status-code'], 400);
$data['password'] = 'new-password';
return $data;
}
/**
* @depends testUpdateAccountPassword
*/
public function testUpdateAccountEmail($data):array
{
$newEmail = uniqid().'new@localhost.test';
$session = (isset($data['session'])) ? $data['session'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_PATCH, '/account/email', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
], [
'email' => $newEmail,
'password' => 'new-password',
]);
$this->assertEquals($response['headers']['status-code'], 200);
$this->assertIsArray($response['body']);
$this->assertNotEmpty($response['body']);
$this->assertNotEmpty($response['body']);
$this->assertNotEmpty($response['body']['$uid']);
$this->assertIsNumeric($response['body']['registration']);
$this->assertEquals($response['body']['email'], $newEmail);
$this->assertEquals($response['body']['name'], 'New Name');
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_PATCH, '/account/email', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
$response = $this->client->call(Client::METHOD_PATCH, '/account/email', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
], [
]);
$this->assertEquals($response['headers']['status-code'], 400);
$data['email'] = $newEmail;
return $data;
}
/**
* @depends testUpdateAccountEmail
*/
public function testUpdateAccountPrefs($data):array
{
$newEmail = uniqid().'new@localhost.test';
$session = (isset($data['session'])) ? $data['session'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_PATCH, '/account/prefs', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
], [
'prefs' => [
'key1' => 'value1',
'key2' => 'value2',
]
]);
$this->assertEquals($response['headers']['status-code'], 200);
$this->assertIsArray($response['body']);
$this->assertNotEmpty($response['body']);
$this->assertNotEmpty($response['body']);
$this->assertEquals('value1', $response['body']['key1']);
$this->assertEquals('value2', $response['body']['key2']);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_PATCH, '/account/prefs', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
return $data;
}
/**
* @depends testUpdateAccountPrefs
*/
public function testDeleteAccountSession($data):array
{
$email = (isset($data['email'])) ? $data['email'] : '';
$password = (isset($data['password'])) ? $data['password'] : '';
$session = (isset($data['session'])) ? $data['session'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_POST, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email,
'password' => $password,
]);
$sessionNewUid = $response['body']['$uid'];
$sessionNew = $this->client->parseCookie($response['headers']['set-cookie'])['a_session_console'];
$this->assertEquals($response['headers']['status-code'], 201);
$response = $this->client->call(Client::METHOD_GET, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $sessionNew,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 200);
$response = $this->client->call(Client::METHOD_DELETE, '/account/sessions/'.$sessionNewUid, [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 204);
$response = $this->client->call(Client::METHOD_GET, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 200);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_GET, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $sessionNew,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
return $data;
}
/**
* @depends testUpdateAccountPrefs
*/
public function testDeleteAccountSessionCurrent($data):array
{
$email = (isset($data['email'])) ? $data['email'] : '';
$password = (isset($data['password'])) ? $data['password'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_POST, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email,
'password' => $password,
]);
$sessionNew = $this->client->parseCookie($response['headers']['set-cookie'])['a_session_console'];
$this->assertEquals($response['headers']['status-code'], 201);
$response = $this->client->call(Client::METHOD_GET, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $sessionNew,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 200);
$response = $this->client->call(Client::METHOD_DELETE, '/account/sessions/current', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $sessionNew,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 204);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_GET, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $sessionNew,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
return $data;
}
/**
* @depends testUpdateAccountPrefs
*/
public function testDeleteAccountSessions($data):array
{
$session = (isset($data['session'])) ? $data['session'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_DELETE, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 204);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_GET, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
/**
* Create new fallback session
*/
$email = (isset($data['email'])) ? $data['email'] : '';
$password = (isset($data['password'])) ? $data['password'] : '';
$response = $this->client->call(Client::METHOD_POST, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email,
'password' => $password,
]);
$data['session'] = $this->client->parseCookie($response['headers']['set-cookie'])['a_session_console'];
return $data;
}
/**
* @depends testDeleteAccountSession
*/
public function testCreateAccountRecovery($data):array
{
$email = (isset($data['email'])) ? $data['email'] : '';
$name = (isset($data['name'])) ? $data['name'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_POST, '/account/recovery', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email,
'reset' => 'http://localhost/recovery',
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty(3, $response['body']['$uid']);
$this->assertEquals(3, $response['body']['type']);
$this->assertIsNumeric($response['body']['expire']);
$lastEmail = $this->getLastEmail();
$this->assertEquals($email, $lastEmail['to'][0]['address']);
$this->assertEquals($name, $lastEmail['to'][0]['name']);
$this->assertEquals('Password Reset', $lastEmail['subject']);
$recovery = substr($lastEmail['text'], strpos($lastEmail['text'], '&token=', 0) + 7, 256);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_POST, '/account/recovery', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email,
'reset' => 'localhost/recovery',
]);
$this->assertEquals(400, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_POST, '/account/recovery', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email,
'reset' => 'http://remotehost/recovery',
]);
$this->assertEquals(400, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_POST, '/account/recovery', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => 'not-found@localhost.test',
'reset' => 'http://localhost/recovery',
]);
$this->assertEquals(404, $response['headers']['status-code']);
$data['recovery'] = $recovery;
return $data;
}
/**
* @depends testCreateAccountRecovery
*/
public function testUpdateAccountRecovery($data):array
{
$uid = (isset($data['uid'])) ? $data['uid'] : '';
$recovery = (isset($data['recovery'])) ? $data['recovery'] : '';
$newPassowrd = 'test-recovery';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_PUT, '/account/recovery', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'userId' => $uid,
'token' => $recovery,
'password-a' => $newPassowrd,
'password-b' => $newPassowrd,
]);
$this->assertEquals(200, $response['headers']['status-code']);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_PUT, '/account/recovery', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'userId' => 'ewewe',
'token' => $recovery,
'password-a' => $newPassowrd,
'password-b' => $newPassowrd,
]);
$this->assertEquals(404, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_PUT, '/account/recovery', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'userId' => $uid,
'token' => 'sdasdasdasd',
'password-a' => $newPassowrd,
'password-b' => $newPassowrd,
]);
$this->assertEquals(401, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_PUT, '/account/recovery', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'userId' => $uid,
'token' => $recovery,
'password-a' => $newPassowrd.'x',
'password-b' => $newPassowrd,
]);
$this->assertEquals(400, $response['headers']['status-code']);
return $data;
}
}

View file

@ -0,0 +1,14 @@
<?php
namespace Tests\E2E;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\ProjectConsole;
use Tests\E2E\Scopes\SideClient;
class AccountConsoleClientTest extends Scope
{
use AccountBase;
use ProjectConsole;
use SideClient;
}

View file

@ -0,0 +1,14 @@
<?php
namespace Tests\E2E;
use Tests\E2E\Scopes\Scope;
use Tests\E2E\Scopes\ProjectCustom;
use Tests\E2E\Scopes\SideClient;
class AccountCustomClientTest extends Scope
{
use AccountBase;
use ProjectCustom;
use SideClient;
}

View file

@ -0,0 +1,9 @@
<?php
namespace Tests\E2E;
use Tests\E2E\Scopes\Scope;
class AccountServerClientTest extends Scope
{
}

View file

@ -184,7 +184,7 @@ class Client
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, php_uname('s') . '-' . php_uname('r') . ':php-' . phpversion());
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36');
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($curl, $header) use (&$responseHeaders) {
$len = strlen($header);
@ -215,7 +215,14 @@ class Client
switch (substr($responseType, 0, strpos($responseType, ';'))) {
case 'application/json':
$responseBody = json_decode($responseBody, true);
$json = json_decode($responseBody, true);
if($json === null) {
throw new Exception('Failed to parse response: '.$responseBody);
}
$responseBody = $json;
$json = null;
break;
}

View file

@ -0,0 +1,15 @@
<?php
namespace Tests\E2E\Scopes;
trait ProjectConsole
{
public function getProject(): array
{
return [
'$uid' => 'console',
'name' => 'Appwrite',
'apiKey' => '',
];
}
}

View file

@ -0,0 +1,119 @@
<?php
namespace Tests\E2E\Scopes;
use Tests\E2E\Client;
trait ProjectCustom
{
/**
* @var string
*/
protected $rootEmail = '';
/**
* @var string
*/
protected $rootPassword = '';
/**
* @var array
*/
protected $project = [];
/**
* @return array
*/
public function getProject(): array
{
if(!empty($this->project)) {
return $this->project;
}
$root = $this->client->call(Client::METHOD_POST, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $this->rootEmail,
'password' => $this->rootEmail,
'name' => 'Demo User',
]);
$this->assertEquals(201, $root['headers']['status-code']);
$session = $this->client->parseCookie($root['headers']['set-cookie'])['a_session_console'];
$team = $this->client->call(Client::METHOD_POST, '/teams', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
], [
'name' => 'Demo Project Team',
]);
$this->assertEquals(201, $team['headers']['status-code']);
$this->assertEquals('Demo Project Team', $team['body']['name']);
$this->assertNotEmpty($team['body']['$uid']);
$project = $this->client->call(Client::METHOD_POST, '/projects', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
], [
'name' => 'Demo Project',
'teamId' => $team['body']['$uid'],
'description' => 'Demo Project Description',
'logo' => '',
'url' => 'https://appwrite.io',
'legalName' => '',
'legalCountry' => '',
'legalState' => '',
'legalCity' => '',
'legalAddress' => '',
'legalTaxId' => '',
]);
$this->assertEquals(201, $project['headers']['status-code']);
$this->assertNotEmpty($project['body']);
$key = $this->client->call(Client::METHOD_POST, '/projects/' . $project['body']['$uid'] . '/keys', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
], [
'name' => 'Demo Project Key',
'scopes' => [
'account',
'',
'',
],
]);
$this->assertEquals(201, $project['headers']['status-code']);
$this->assertNotEmpty($key['body']);
$this->assertNotEmpty($key['body']['secret']);
// return [
// 'email' => $this->demoEmail,
// 'password' => $this->demoPassword,
// 'session' => $session,
// 'projectUid' => $project['body']['$uid'],
// 'projectAPIKeySecret' => $key['body']['secret'],
// 'projectSession' => $this->client->parseCookie($user['headers']['set-cookie'])['a_session_' . $project['body']['$uid']],
// ];
$this->project = [
'$uid' => $project['body']['$uid'],
'name' => $project['body']['name'],
'apiKey' => $key['body']['secret'],
];
var_dump('init project');
return $this->project;
}
}

View file

@ -0,0 +1,55 @@
<?php
namespace Tests\E2E\Scopes;
use Tests\E2E\Client;
use PHPUnit\Framework\TestCase;
abstract class Scope extends TestCase
{
/**
* @var Client
*/
protected $client = null;
/**
* @var string
*/
protected $endpoint = 'http://localhost/v1';
protected function setUp(): void
{
$this->client = new Client();
$this->client
->setEndpoint($this->endpoint)
;
}
protected function tearDown(): void
{
$this->client = null;
}
protected function getLastEmail():array
{
sleep(3);
$emails = json_decode(file_get_contents('http://maildev/email'), true);
if($emails && is_array($emails)) {
return end($emails);
}
return [];
}
/**
* @return array
*/
abstract public function getHeaders():array;
/**
* @return array
*/
abstract public function getProject():array;
}

View file

@ -0,0 +1,11 @@
<?php
namespace Tests\E2E\Scopes;
trait SideClient
{
public function getHeaders():array
{
return [];
}
}

View file

@ -0,0 +1,19 @@
<?php
namespace Tests\E2E\Scopes;
trait SideServer
{
/**
* @var array
*/
protected $key = [];
public function getHeaders():array
{
return [
'x-appwrite-key' => $this->getProject()
];
}
}

930
tests/old/AccountTest.php Normal file
View file

@ -0,0 +1,930 @@
<?php
namespace Tests\E2E;
use Tests\E2E\Client;
trait TraitDemo {
function demo2() { var_dump(9876); $this->demo(); }
}
class AccountTest extends Base
{
use TraitDemo;
public function demo() {
var_dump(4321);
}
public function testCreateAccount():array
{
$email = uniqid().'user@localhost.test';
$password = 'passwrod';
$name = 'User Name';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_POST, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email,
'password' => $password,
'name' => $name,
]);
$uid = $response['body']['$uid'];
$this->assertEquals($response['headers']['status-code'], 201);
$this->assertNotEmpty($response['body']);
$this->assertNotEmpty($response['body']['$uid']);
$this->assertIsNumeric($response['body']['registration']);
$this->assertEquals($response['body']['email'], $email);
$this->assertEquals($response['body']['name'], $name);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_POST, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email,
'password' => $password,
'name' => $name,
]);
$this->assertEquals($response['headers']['status-code'], 409);
return [
'uid' => $uid,
'email' => $email,
'password' => $password,
'name' => $name,
];
}
/**
* @depends testCreateAccount
*/
public function testCreateAccountSession($data):array
{
$email = (isset($data['email'])) ? $data['email'] : '';
$password = (isset($data['password'])) ? $data['password'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_POST, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email,
'password' => $password,
]);
$sessionUid = $response['body']['$uid'];
$session = $this->client->parseCookie($response['headers']['set-cookie'])['a_session_console'];
$this->assertEquals($response['headers']['status-code'], 201);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_POST, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email.'x',
'password' => $password,
]);
$this->assertEquals($response['headers']['status-code'], 401);
$response = $this->client->call(Client::METHOD_POST, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email,
'password' => $password.'x',
]);
$this->assertEquals($response['headers']['status-code'], 401);
$response = $this->client->call(Client::METHOD_POST, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => '',
'password' => '',
]);
$this->assertEquals($response['headers']['status-code'], 400);
return array_merge($data, [
'sessionUid' => $sessionUid,
'session' => $session,
]);
}
/**
* @depends testCreateAccountSession
*/
public function testGetAccount($data):array
{
$email = (isset($data['email'])) ? $data['email'] : '';
$name = (isset($data['name'])) ? $data['name'] : '';
$session = (isset($data['session'])) ? $data['session'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_GET, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 200);
$this->assertNotEmpty($response['body']);
$this->assertNotEmpty($response['body']['$uid']);
$this->assertIsNumeric($response['body']['registration']);
$this->assertEquals($response['body']['email'], $email);
$this->assertEquals($response['body']['name'], $name);
$this->assertContains('*', $response['body']['roles']);
$this->assertContains('user:'.$response['body']['$uid'], $response['body']['roles']);
$this->assertContains('role:1', $response['body']['roles']);
$this->assertCount(3, $response['body']['roles']);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_GET, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
$response = $this->client->call(Client::METHOD_GET, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session.'xx',
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
return $data;
}
/**
* @depends testCreateAccountSession
*/
public function testGetAccountPrefs($data):array
{
$session = (isset($data['session'])) ? $data['session'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_GET, '/account/prefs', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 200);
$this->assertIsArray($response['body']);
$this->assertEmpty($response['body']);
$this->assertCount(0, $response['body']);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_GET, '/account/prefs', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
return $data;
}
/**
* @depends testCreateAccountSession
*/
public function testGetAccountSessions($data):array
{
$session = (isset($data['session'])) ? $data['session'] : '';
$sessionUid = (isset($data['sessionUid'])) ? $data['sessionUid'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_GET, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 200);
$this->assertIsArray($response['body']);
$this->assertNotEmpty($response['body']);
$this->assertCount(1, $response['body']);
$this->assertEquals($sessionUid, $response['body'][0]['$uid']);
$this->assertIsArray($response['body'][0]['OS']);
$this->assertEquals('Windows', $response['body'][0]['OS']['name']);
$this->assertEquals('WIN', $response['body'][0]['OS']['short_name']);
$this->assertEquals('10', $response['body'][0]['OS']['version']);
$this->assertEquals('x64', $response['body'][0]['OS']['platform']);
$this->assertIsArray($response['body'][0]['client']);
$this->assertEquals('browser', $response['body'][0]['client']['type']);
$this->assertEquals('Chrome', $response['body'][0]['client']['name']);
$this->assertEquals('CH', $response['body'][0]['client']['short_name']); // FIXME (v1) key name should be camelcase
$this->assertEquals('70.0', $response['body'][0]['client']['version']);
$this->assertEquals('Blink', $response['body'][0]['client']['engine']);
$this->assertEquals(0, $response['body'][0]['device']);
$this->assertEquals('', $response['body'][0]['brand']);
$this->assertEquals('', $response['body'][0]['model']);
$this->assertEquals($response['body'][0]['ip'], filter_var($response['body'][0]['ip'], FILTER_VALIDATE_IP));
$this->assertIsArray($response['body'][0]['geo']);
$this->assertEquals('--', $response['body'][0]['geo']['isoCode']);
$this->assertEquals('Unknown', $response['body'][0]['geo']['country']);
$this->assertEquals(true, $response['body'][0]['current']);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_GET, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
return $data;
}
/**
* @depends testCreateAccountSession
*/
public function testGetAccountLogs($data):array
{
sleep(5);
$session = (isset($data['session'])) ? $data['session'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_GET, '/account/logs', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 200);
$this->assertIsArray($response['body']);
$this->assertNotEmpty($response['body']);
$this->assertCount(2, $response['body']);
$this->assertEquals('account.create', $response['body'][0]['event']);
$this->assertEquals($response['body'][0]['ip'], filter_var($response['body'][0]['ip'], FILTER_VALIDATE_IP));
$this->assertIsNumeric($response['body'][0]['time']);
$this->assertIsArray($response['body'][0]['OS']);
$this->assertEquals('Windows', $response['body'][0]['OS']['name']);
$this->assertEquals('WIN', $response['body'][0]['OS']['short_name']);
$this->assertEquals('10', $response['body'][0]['OS']['version']);
$this->assertEquals('x64', $response['body'][0]['OS']['platform']);
$this->assertIsArray($response['body'][0]['client']);
$this->assertEquals('browser', $response['body'][0]['client']['type']);
$this->assertEquals('Chrome', $response['body'][0]['client']['name']);
$this->assertEquals('CH', $response['body'][0]['client']['short_name']); // FIXME (v1) key name should be camelcase
$this->assertEquals('70.0', $response['body'][0]['client']['version']);
$this->assertEquals('Blink', $response['body'][0]['client']['engine']);
$this->assertEquals(0, $response['body'][0]['device']);
$this->assertEquals('', $response['body'][0]['brand']);
$this->assertEquals('', $response['body'][0]['model']);
$this->assertEquals($response['body'][0]['ip'], filter_var($response['body'][0]['ip'], FILTER_VALIDATE_IP));
$this->assertIsArray($response['body'][0]['geo']);
$this->assertEquals('--', $response['body'][0]['geo']['isoCode']);
$this->assertEquals('Unknown', $response['body'][0]['geo']['country']);
$this->assertEquals('account.sessions.create', $response['body'][1]['event']);
$this->assertEquals($response['body'][1]['ip'], filter_var($response['body'][0]['ip'], FILTER_VALIDATE_IP));
$this->assertIsNumeric($response['body'][1]['time']);
$this->assertIsArray($response['body'][1]['OS']);
$this->assertEquals('Windows', $response['body'][1]['OS']['name']);
$this->assertEquals('WIN', $response['body'][1]['OS']['short_name']);
$this->assertEquals('10', $response['body'][1]['OS']['version']);
$this->assertEquals('x64', $response['body'][1]['OS']['platform']);
$this->assertIsArray($response['body'][1]['client']);
$this->assertEquals('browser', $response['body'][1]['client']['type']);
$this->assertEquals('Chrome', $response['body'][1]['client']['name']);
$this->assertEquals('CH', $response['body'][1]['client']['short_name']); // FIXME (v1) key name should be camelcase
$this->assertEquals('70.0', $response['body'][1]['client']['version']);
$this->assertEquals('Blink', $response['body'][1]['client']['engine']);
$this->assertEquals(0, $response['body'][1]['device']);
$this->assertEquals('', $response['body'][1]['brand']);
$this->assertEquals('', $response['body'][1]['model']);
$this->assertEquals($response['body'][1]['ip'], filter_var($response['body'][0]['ip'], FILTER_VALIDATE_IP));
$this->assertIsArray($response['body'][1]['geo']);
$this->assertEquals('--', $response['body'][1]['geo']['isoCode']);
$this->assertEquals('Unknown', $response['body'][1]['geo']['country']);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_GET, '/account/logs', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
return $data;
}
//TODO Add tests for OAuth session creation
/**
* @depends testCreateAccountSession
*/
public function testUpdateAccountName($data):array
{
$email = (isset($data['email'])) ? $data['email'] : '';
$session = (isset($data['session'])) ? $data['session'] : '';
$newName = 'New Name';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_PATCH, '/account/name', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
], [
'name' => $newName
]);
$this->assertEquals($response['headers']['status-code'], 200);
$this->assertIsArray($response['body']);
$this->assertNotEmpty($response['body']);
$this->assertNotEmpty($response['body']);
$this->assertNotEmpty($response['body']['$uid']);
$this->assertIsNumeric($response['body']['registration']);
$this->assertEquals($response['body']['email'], $email);
$this->assertEquals($response['body']['name'], $newName);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_PATCH, '/account/name', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
$response = $this->client->call(Client::METHOD_PATCH, '/account/name', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
], [
]);
$this->assertEquals($response['headers']['status-code'], 400);
$response = $this->client->call(Client::METHOD_PATCH, '/account/name', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
], [
'name' => 'ocSRq1d3QphHivJyUmYY7WMnrxyjdk5YvVwcDqx2zS0coxESN8RmsQwLWw5Whnf0WbVohuFWTRAaoKgCOO0Y0M7LwgFnZmi8881Y7'
]);
$this->assertEquals($response['headers']['status-code'], 400);
$data['name'] = $newName;
return $data;
}
/**
* @depends testUpdateAccountName
*/
public function testUpdateAccountPassword($data):array
{
$email = (isset($data['email'])) ? $data['email'] : '';
$password = (isset($data['password'])) ? $data['password'] : '';
$session = (isset($data['session'])) ? $data['session'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_PATCH, '/account/password', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
], [
'password' => 'new-password',
'old-password' => $password,
]);
$this->assertEquals($response['headers']['status-code'], 200);
$this->assertIsArray($response['body']);
$this->assertNotEmpty($response['body']);
$this->assertNotEmpty($response['body']);
$this->assertNotEmpty($response['body']['$uid']);
$this->assertIsNumeric($response['body']['registration']);
$this->assertEquals($response['body']['email'], $email);
$this->assertEquals($response['body']['name'], 'New Name');
$response = $this->client->call(Client::METHOD_POST, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email,
'password' => 'new-password',
]);
$this->assertEquals($response['headers']['status-code'], 201);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_PATCH, '/account/password', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
$response = $this->client->call(Client::METHOD_PATCH, '/account/password', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
], [
]);
$this->assertEquals($response['headers']['status-code'], 400);
$data['password'] = 'new-password';
return $data;
}
/**
* @depends testUpdateAccountPassword
*/
public function testUpdateAccountEmail($data):array
{
$newEmail = uniqid().'new@localhost.test';
$session = (isset($data['session'])) ? $data['session'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_PATCH, '/account/email', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
], [
'email' => $newEmail,
'password' => 'new-password',
]);
$this->assertEquals($response['headers']['status-code'], 200);
$this->assertIsArray($response['body']);
$this->assertNotEmpty($response['body']);
$this->assertNotEmpty($response['body']);
$this->assertNotEmpty($response['body']['$uid']);
$this->assertIsNumeric($response['body']['registration']);
$this->assertEquals($response['body']['email'], $newEmail);
$this->assertEquals($response['body']['name'], 'New Name');
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_PATCH, '/account/email', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
$response = $this->client->call(Client::METHOD_PATCH, '/account/email', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
], [
]);
$this->assertEquals($response['headers']['status-code'], 400);
$data['email'] = $newEmail;
return $data;
}
/**
* @depends testUpdateAccountEmail
*/
public function testUpdateAccountPrefs($data):array
{
$newEmail = uniqid().'new@localhost.test';
$session = (isset($data['session'])) ? $data['session'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_PATCH, '/account/prefs', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
], [
'prefs' => [
'key1' => 'value1',
'key2' => 'value2',
]
]);
$this->assertEquals($response['headers']['status-code'], 200);
$this->assertIsArray($response['body']);
$this->assertNotEmpty($response['body']);
$this->assertNotEmpty($response['body']);
$this->assertEquals('value1', $response['body']['key1']);
$this->assertEquals('value2', $response['body']['key2']);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_PATCH, '/account/prefs', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
return $data;
}
/**
* @depends testUpdateAccountPrefs
*/
public function testDeleteAccountSession($data):array
{
$email = (isset($data['email'])) ? $data['email'] : '';
$password = (isset($data['password'])) ? $data['password'] : '';
$session = (isset($data['session'])) ? $data['session'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_POST, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email,
'password' => $password,
]);
$sessionNewUid = $response['body']['$uid'];
$sessionNew = $this->client->parseCookie($response['headers']['set-cookie'])['a_session_console'];
$this->assertEquals($response['headers']['status-code'], 201);
$response = $this->client->call(Client::METHOD_GET, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $sessionNew,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 200);
$response = $this->client->call(Client::METHOD_DELETE, '/account/sessions/'.$sessionNewUid, [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 204);
$response = $this->client->call(Client::METHOD_GET, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 200);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_GET, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $sessionNew,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
return $data;
}
/**
* @depends testUpdateAccountPrefs
*/
public function testDeleteAccountSessionCurrent($data):array
{
$email = (isset($data['email'])) ? $data['email'] : '';
$password = (isset($data['password'])) ? $data['password'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_POST, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email,
'password' => $password,
]);
$sessionNew = $this->client->parseCookie($response['headers']['set-cookie'])['a_session_console'];
$this->assertEquals($response['headers']['status-code'], 201);
$response = $this->client->call(Client::METHOD_GET, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $sessionNew,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 200);
$response = $this->client->call(Client::METHOD_DELETE, '/account/sessions/current', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $sessionNew,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 204);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_GET, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $sessionNew,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
return $data;
}
/**
* @depends testUpdateAccountPrefs
*/
public function testDeleteAccountSessions($data):array
{
$session = (isset($data['session'])) ? $data['session'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_DELETE, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 204);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_GET, '/account', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'cookie' => 'a_session_console=' . $session,
'x-appwrite-project' => 'console',
]);
$this->assertEquals($response['headers']['status-code'], 401);
/**
* Create new fallback session
*/
$email = (isset($data['email'])) ? $data['email'] : '';
$password = (isset($data['password'])) ? $data['password'] : '';
$response = $this->client->call(Client::METHOD_POST, '/account/sessions', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email,
'password' => $password,
]);
$data['session'] = $this->client->parseCookie($response['headers']['set-cookie'])['a_session_console'];
return $data;
}
/**
* @depends testDeleteAccountSession
*/
public function testCreateAccountRecovery($data):array
{
$email = (isset($data['email'])) ? $data['email'] : '';
$name = (isset($data['name'])) ? $data['name'] : '';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_POST, '/account/recovery', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email,
'reset' => 'http://localhost/recovery',
]);
$this->assertEquals(201, $response['headers']['status-code']);
$this->assertNotEmpty(3, $response['body']['$uid']);
$this->assertEquals(3, $response['body']['type']);
$this->assertIsNumeric($response['body']['expire']);
$lastEmail = $this->getLastEmail();
$this->assertEquals($email, $lastEmail['to'][0]['address']);
$this->assertEquals($name, $lastEmail['to'][0]['name']);
$this->assertEquals('Password Reset', $lastEmail['subject']);
$recovery = substr($lastEmail['text'], strpos($lastEmail['text'], '&token=', 0) + 7, 256);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_POST, '/account/recovery', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email,
'reset' => 'localhost/recovery',
]);
$this->assertEquals(400, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_POST, '/account/recovery', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => $email,
'reset' => 'http://remotehost/recovery',
]);
$this->assertEquals(400, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_POST, '/account/recovery', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'email' => 'not-found@localhost.test',
'reset' => 'http://localhost/recovery',
]);
$this->assertEquals(404, $response['headers']['status-code']);
$data['recovery'] = $recovery;
return $data;
}
/**
* @depends testCreateAccountRecovery
*/
public function testUpdateAccountRecovery($data):array
{
$uid = (isset($data['uid'])) ? $data['uid'] : '';
$recovery = (isset($data['recovery'])) ? $data['recovery'] : '';
$newPassowrd = 'test-recovery';
/**
* Test for SUCCESS
*/
$response = $this->client->call(Client::METHOD_PUT, '/account/recovery', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'userId' => $uid,
'token' => $recovery,
'password-a' => $newPassowrd,
'password-b' => $newPassowrd,
]);
$this->assertEquals(200, $response['headers']['status-code']);
/**
* Test for FAILURE
*/
$response = $this->client->call(Client::METHOD_PUT, '/account/recovery', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'userId' => 'ewewe',
'token' => $recovery,
'password-a' => $newPassowrd,
'password-b' => $newPassowrd,
]);
$this->assertEquals(404, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_PUT, '/account/recovery', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'userId' => $uid,
'token' => 'sdasdasdasd',
'password-a' => $newPassowrd,
'password-b' => $newPassowrd,
]);
$this->assertEquals(401, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_PUT, '/account/recovery', [
'origin' => 'http://localhost',
'content-type' => 'application/json',
'x-appwrite-project' => 'console',
], [
'userId' => $uid,
'token' => $recovery,
'password-a' => $newPassowrd.'x',
'password-b' => $newPassowrd,
]);
$this->assertEquals(400, $response['headers']['status-code']);
return $data;
}
}

41
tests/old/Base.php Normal file
View file

@ -0,0 +1,41 @@
<?php
namespace Tests\E2E;
use Tests\E2E\Client;
use PHPUnit\Framework\TestCase;
class Base extends TestCase
{
/**
* @var Client
*/
protected $client = null;
protected $endpoint = 'http://localhost/v1';
protected function setUp(): void
{
$this->client = new Client();
$this->client
->setEndpoint($this->endpoint)
;
}
protected function tearDown(): void
{
$this->client = null;
}
protected function getLastEmail():array
{
sleep(3);
$emails = json_decode(file_get_contents('http://localhost:1080/email'), true);
if($emails && is_array($emails)) {
return end($emails);
}
return [];
}
}