1
0
Fork 0
mirror of synced 2024-06-03 03:14:50 +12:00

Fixed domain validation

This commit is contained in:
Eldad Fux 2020-07-03 00:48:02 +03:00
parent d6e85bc39e
commit 934ae8beac
8 changed files with 64 additions and 51 deletions

View file

@ -15,7 +15,6 @@ use Appwrite\Database\Document;
use Appwrite\Database\Validator\Authorization; use Appwrite\Database\Validator\Authorization;
use Appwrite\Network\Validator\Origin; use Appwrite\Network\Validator\Origin;
Config::setParam('domain', 'localhost');
Config::setParam('domainVerification', false); Config::setParam('domainVerification', false);
Config::setParam('cookieDomain', 'localhost'); Config::setParam('cookieDomain', 'localhost');
Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE); Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE);
@ -33,8 +32,8 @@ Config::setParam('cookieSamesite', Response::COOKIE_SAMESITE_NONE);
App::init(function ($utopia, $request, $response, $console, $project, $user, $locale, $webhooks, $audits, $usage, $clients) { App::init(function ($utopia, $request, $response, $console, $project, $user, $locale, $webhooks, $audits, $usage, $clients) {
Authorization::$roles = ['*']; Authorization::$roles = ['*'];
/** @var Utopia\Request $request */ /** @var Appwrite\Utopia\Request $request */
/** @var Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Document $console */ /** @var Appwrite\Database\Document $console */
/** @var Appwrite\Database\Document $project */ /** @var Appwrite\Database\Document $project */
/** @var Appwrite\Database\Document $user */ /** @var Appwrite\Database\Document $user */
@ -66,19 +65,19 @@ App::init(function ($utopia, $request, $response, $console, $project, $user, $lo
'hostname' => $request->getHostname(), 'hostname' => $request->getHostname(),
], Document::SET_TYPE_APPEND); ], Document::SET_TYPE_APPEND);
$referrer = $request->getServer('HTTP_REFERER', ''); $referrer = $request->getReferer();
$origin = \parse_url($request->getServer('HTTP_ORIGIN', $referrer), PHP_URL_HOST); $origin = \parse_url($request->getOrigin($referrer), PHP_URL_HOST);
$protocol = \parse_url($request->getServer('HTTP_ORIGIN', $referrer), PHP_URL_SCHEME); $protocol = \parse_url($request->getOrigin($referrer), PHP_URL_SCHEME);
$port = \parse_url($request->getServer('HTTP_ORIGIN', $referrer), PHP_URL_PORT); $port = \parse_url($request->getOrigin($referrer), PHP_URL_PORT);
$refDomain = $protocol.'://'.((\in_array($origin, $clients)) $refDomain = $protocol.'://'.((\in_array($origin, $clients))
? $origin : 'localhost') . (!empty($port) ? ':'.$port : ''); ? $origin : 'localhost') . (!empty($port) ? ':'.$port : '');
$selfDomain = new Domain(Config::getParam('hostname')); $selfDomain = new Domain($request->getHostname());
$endDomain = new Domain($origin); $endDomain = new Domain($origin);
Config::setParam('domain', $request->getServer('HTTP_HOST', '')); // var_dump('referer', $referrer);
// var_dump('origin', $origin);
// var_dump('port', $request->getPort()); // var_dump('port', $request->getPort());
// var_dump('hostname', $request->getHostname()); // var_dump('hostname', $request->getHostname());
// var_dump('protocol', $request->getProtocol()); // var_dump('protocol', $request->getProtocol());
@ -87,18 +86,21 @@ App::init(function ($utopia, $request, $response, $console, $project, $user, $lo
// var_dump('-----------------'); // var_dump('-----------------');
// var_dump($request->debug()); // var_dump($request->debug());
var_dump($selfDomain->getRegisterable());
var_dump($endDomain->getRegisterable());
Config::setParam('domainVerification', Config::setParam('domainVerification',
($selfDomain->getRegisterable() === $endDomain->getRegisterable()) && ($selfDomain->getRegisterable() === $endDomain->getRegisterable()) &&
$endDomain->getRegisterable() !== ''); $endDomain->getRegisterable() !== '');
Config::setParam('cookieDomain', ( Config::setParam('cookieDomain', (
$request->getServer('HTTP_HOST', null) === 'localhost' || $request->getHostname() === 'localhost' ||
$request->getServer('HTTP_HOST', null) === 'localhost:'.$request->getPort() || $request->getHostname() === 'localhost:'.$request->getPort() ||
(\filter_var($request->getHostname(), FILTER_VALIDATE_IP) !== false) (\filter_var($request->getHostname(), FILTER_VALIDATE_IP) !== false)
) )
? null ? null
: '.'.$request->getHostname() : '.'.$request->getHostname()
); );
/* /*
* Security Headers * Security Headers
* *
@ -107,7 +109,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $user, $lo
*/ */
if (App::getEnv('_APP_OPTIONS_FORCE_HTTPS', 'disabled') === 'enabled') { // Force HTTPS if (App::getEnv('_APP_OPTIONS_FORCE_HTTPS', 'disabled') === 'enabled') { // Force HTTPS
if($request->getProtocol() !== 'https') { if($request->getProtocol() !== 'https') {
return $response->redirect('https://' . Config::getParam('domain').$request->getServer('REQUEST_URI')); return $response->redirect('https://'.$request->getHostname().$request->getServer('REQUEST_URI'));
} }
$response->addHeader('Strict-Transport-Security', 'max-age='.(60 * 60 * 24 * 126)); // 126 days $response->addHeader('Strict-Transport-Security', 'max-age='.(60 * 60 * 24 * 126)); // 126 days
@ -179,7 +181,7 @@ App::init(function ($utopia, $request, $response, $console, $project, $user, $lo
$user = new Document([ $user = new Document([
'$id' => 0, '$id' => 0,
'status' => Auth::USER_STATUS_ACTIVATED, 'status' => Auth::USER_STATUS_ACTIVATED,
'email' => 'app.'.$project->getId().'@service.'.Config::getParam('domain'), 'email' => 'app.'.$project->getId().'@service.'.$request->getHostname(),
'password' => '', 'password' => '',
'name' => $project->getAttribute('name', 'Untitled'), 'name' => $project->getAttribute('name', 'Untitled'),
]); ]);

View file

@ -160,8 +160,8 @@ App::post('/v1/account/sessions')
->param('email', '', function () { return new Email(); }, 'User email.') ->param('email', '', function () { return new Email(); }, 'User email.')
->param('password', '', function () { return new Password(); }, 'User password. Must be between 6 to 32 chars.') ->param('password', '', function () { return new Password(); }, 'User password. Must be between 6 to 32 chars.')
->action(function ($email, $password, $request, $response, $projectDB, $webhook, $audit) { ->action(function ($email, $password, $request, $response, $projectDB, $webhook, $audit) {
/** @var Utopia\Request $request */ /** @var Appwrite\Utopia\Request $request */
/** @var Utopia\Response $response */ /** @var Appwrite\Utopia\Response $response */
/** @var Appwrite\Database\Database $projectDB */ /** @var Appwrite\Database\Database $projectDB */
/** @var Appwrite\Event\Event $webhook */ /** @var Appwrite\Event\Event $webhook */
/** @var Appwrite\Event\Event $audit */ /** @var Appwrite\Event\Event $audit */
@ -230,15 +230,15 @@ App::post('/v1/account/sessions')
$response $response
->addHeader('X-Fallback-Cookies', \json_encode([Auth::$cookieName => Auth::encodeSession($profile->getId(), $secret)])) ->addHeader('X-Fallback-Cookies', \json_encode([Auth::$cookieName => Auth::encodeSession($profile->getId(), $secret)]))
; ;
$response->dynamic($session, Response::MODEL_SESSION);
} }
$response $response
->addCookie(Auth::$cookieName.'_legacy', Auth::encodeSession($profile->getId(), $secret), $expiry, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, null) ->addCookie(Auth::$cookieName.'_legacy', Auth::encodeSession($profile->getId(), $secret), $expiry, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, null)
->addCookie(Auth::$cookieName, Auth::encodeSession($profile->getId(), $secret), $expiry, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, Config::getParam('cookieSamesite')) ->addCookie(Auth::$cookieName, Auth::encodeSession($profile->getId(), $secret), $expiry, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, Config::getParam('cookieSamesite'))
->setStatusCode(Response::STATUS_CODE_CREATED) ->setStatusCode(Response::STATUS_CODE_CREATED)
->json($session->getArrayCopy(['$id', 'type', 'expire'])) ;
$response->dynamic($session, Response::MODEL_SESSION);
; ;
}, ['request', 'response', 'projectDB', 'webhook', 'audit']); }, ['request', 'response', 'projectDB', 'webhook', 'audit']);
@ -309,7 +309,7 @@ App::get('/v1/account/sessions/oauth2/callback/:provider/:projectId')
/** @var Utopia\Request $request */ /** @var Utopia\Request $request */
/** @var Utopia\Response $response */ /** @var Utopia\Response $response */
$domain = Config::getParam('domain'); $domain = $request->getHostname();
$protocol = $request->getProtocol(); $protocol = $request->getProtocol();
$response $response
@ -334,7 +334,7 @@ App::post('/v1/account/sessions/oauth2/callback/:provider/:projectId')
/** @var Utopia\Request $request */ /** @var Utopia\Request $request */
/** @var Utopia\Response $response */ /** @var Utopia\Response $response */
$domain = Config::getParam('domain'); $domain = $request->getHostname();
$protocol = $request->getProtocol(); $protocol = $request->getProtocol();
$response $response

View file

@ -567,29 +567,18 @@ App::patch('/v1/teams/:teamId/memberships/:inviteId/status')
$response $response
->addHeader('X-Fallback-Cookies', \json_encode([Auth::$cookieName => Auth::encodeSession($user->getId(), $secret)])) ->addHeader('X-Fallback-Cookies', \json_encode([Auth::$cookieName => Auth::encodeSession($user->getId(), $secret)]))
; ;
$response->dynamic(new Document(\array_merge($membership->getArrayCopy(), [
'email' => $user->getAttribute('email'),
'name' => $user->getAttribute('name'),
])), Response::MODEL_MEMBERSHIP);
} }
$response $response
->addCookie(Auth::$cookieName.'_legacy', Auth::encodeSession($user->getId(), $secret), $expiry, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, null) ->addCookie(Auth::$cookieName.'_legacy', Auth::encodeSession($user->getId(), $secret), $expiry, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, null)
->addCookie(Auth::$cookieName, Auth::encodeSession($user->getId(), $secret), $expiry, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, Config::getParam('cookieSamesite')) ->addCookie(Auth::$cookieName, Auth::encodeSession($user->getId(), $secret), $expiry, '/', Config::getParam('cookieDomain'), ('https' == $protocol), true, Config::getParam('cookieSamesite'))
->json(\array_merge($membership->getArrayCopy([
'$id',
'userId',
'teamId',
'roles',
'invited',
'joined',
'confirm',
]), [
'email' => $user->getAttribute('email'),
'name' => $user->getAttribute('name'),
]))
; ;
$response->dynamic(new Document(\array_merge($membership->getArrayCopy(), [
'email' => $user->getAttribute('email'),
'name' => $user->getAttribute('name'),
])), Response::MODEL_MEMBERSHIP);
}, ['request', 'response', 'user', 'projectDB', 'audit']); }, ['request', 'response', 'user', 'projectDB', 'audit']);
App::delete('/v1/teams/:teamId/memberships/:inviteId') App::delete('/v1/teams/:teamId/memberships/:inviteId')

View file

@ -1,8 +1,6 @@
<?php <?php
use Utopia\App; use Utopia\App;
use Utopia\View;
use Utopia\Config\Config;
App::init(function ($utopia, $request, $response, $layout) { App::init(function ($utopia, $request, $response, $layout) {
/** @var Utopia\App $utopia */ /** @var Utopia\App $utopia */
@ -18,7 +16,7 @@ App::init(function ($utopia, $request, $response, $layout) {
$layout $layout
->setParam('title', APP_NAME) ->setParam('title', APP_NAME)
->setParam('protocol', $request->getProtocol()) ->setParam('protocol', $request->getProtocol())
->setParam('domain', Config::getParam('domain')) ->setParam('domain', $request->getHostname())
->setParam('home', App::getEnv('_APP_HOME')) ->setParam('home', App::getEnv('_APP_HOME'))
->setParam('setup', App::getEnv('_APP_SETUP')) ->setParam('setup', App::getEnv('_APP_SETUP'))
->setParam('class', 'unknown') ->setParam('class', 'unknown')

View file

@ -322,7 +322,7 @@ App::get('/open-api-2.json')
'url' => 'https://raw.githubusercontent.com/appwrite/appwrite/master/LICENSE', 'url' => 'https://raw.githubusercontent.com/appwrite/appwrite/master/LICENSE',
], ],
], ],
'host' => \parse_url(App::getEnv('_APP_HOME', Config::getParam('domain')), PHP_URL_HOST), 'host' => \parse_url(App::getEnv('_APP_HOME', $request->getHostname()), PHP_URL_HOST),
'basePath' => '/v1', 'basePath' => '/v1',
'schemes' => ['https'], 'schemes' => ['https'],
'consumes' => ['application/json', 'multipart/form-data'], 'consumes' => ['application/json', 'multipart/form-data'],
@ -369,7 +369,7 @@ App::get('/open-api-2.json')
], ],
'externalDocs' => [ 'externalDocs' => [
'description' => 'Full API docs, specs and tutorials', 'description' => 'Full API docs, specs and tutorials',
'url' => $request->getProtocol().'://'.Config::getParam('domain').'/docs', 'url' => $request->getProtocol().'://'.$request->getHostname().'/docs',
], ],
]; ];

View file

@ -120,7 +120,7 @@ class Request extends UtopiaRequest
public function debug() public function debug()
{ {
return $this->swoole->server; return $this->swoole->header;
} }
/** /**
@ -184,11 +184,35 @@ class Request extends UtopiaRequest
* *
* @return string * @return string
*/ */
public function getMethod():string public function getMethod(): string
{ {
return $this->getServer('request_method', 'UNKNOWN'); return $this->getServer('request_method', 'UNKNOWN');
} }
/**
* Get Referer
*
* Return HTTP referer header
*
* @return string
*/
public function getReferer(string $default = ''): string
{
return $this->getHeader('referer', '');
}
/**
* Get Origin
*
* Return HTTP origin header
*
* @return string
*/
public function getOrigin(string $default = ''): string
{
return $this->getHeader('origin', $default);
}
/** /**
* Get files * Get files
* *

View file

@ -92,7 +92,7 @@ abstract class Scope extends TestCase
'password' => $password, 'password' => $password,
]); ]);
$session = $this->client->parseCookie($session['headers']['set-cookie'])['a_session_console']; $session = $this->client->parseCookie((string)$session['headers']['set-cookie'])['a_session_console'];
self::$root = [ self::$root = [
'$id' => $root['body']['$id'], '$id' => $root['body']['$id'],
@ -143,7 +143,7 @@ abstract class Scope extends TestCase
'password' => $password, 'password' => $password,
]); ]);
$session = $this->client->parseCookie($session['headers']['set-cookie'])['a_session_'.$this->getProject()['$id']]; $session = $this->client->parseCookie((string)$session['headers']['set-cookie'])['a_session_'.$this->getProject()['$id']];
self::$user[$this->getProject()['$id']] = [ self::$user[$this->getProject()['$id']] = [
'$id' => $user['body']['$id'], '$id' => $user['body']['$id'],

View file

@ -83,7 +83,7 @@ trait AccountBase
$this->assertEquals($response['headers']['status-code'], 201); $this->assertEquals($response['headers']['status-code'], 201);
$sessionId = $response['body']['$id']; $sessionId = $response['body']['$id'];
$session = $this->client->parseCookie($response['headers']['set-cookie'])['a_session_'.$this->getProject()['$id']]; $session = $this->client->parseCookie((string)$response['headers']['set-cookie'])['a_session_'.$this->getProject()['$id']];
/** /**
* Test for FAILURE * Test for FAILURE
@ -774,7 +774,7 @@ trait AccountBase
]); ]);
$sessionNewId = $response['body']['$id']; $sessionNewId = $response['body']['$id'];
$sessionNew = $this->client->parseCookie($response['headers']['set-cookie'])['a_session_'.$this->getProject()['$id']]; $sessionNew = $this->client->parseCookie((string)$response['headers']['set-cookie'])['a_session_'.$this->getProject()['$id']];
$this->assertEquals($response['headers']['status-code'], 201); $this->assertEquals($response['headers']['status-code'], 201);
@ -840,7 +840,7 @@ trait AccountBase
'password' => $password, 'password' => $password,
]); ]);
$sessionNew = $this->client->parseCookie($response['headers']['set-cookie'])['a_session_'.$this->getProject()['$id']]; $sessionNew = $this->client->parseCookie((string)$response['headers']['set-cookie'])['a_session_'.$this->getProject()['$id']];
$this->assertEquals($response['headers']['status-code'], 201); $this->assertEquals($response['headers']['status-code'], 201);
@ -922,7 +922,7 @@ trait AccountBase
'password' => $password, 'password' => $password,
]); ]);
$data['session'] = $this->client->parseCookie($response['headers']['set-cookie'])['a_session_'.$this->getProject()['$id']]; $data['session'] = $this->client->parseCookie((string)$response['headers']['set-cookie'])['a_session_'.$this->getProject()['$id']];
return $data; return $data;
} }