1
0
Fork 0
mirror of synced 2024-06-16 17:54:53 +12:00

Added URL parsing lib

This commit is contained in:
Eldad Fux 2020-04-08 16:38:36 +03:00
parent 7becafdd1e
commit 586341b323
4 changed files with 181 additions and 42 deletions

View file

@ -29,6 +29,9 @@ use GeoIp2\Database\Reader;
include_once __DIR__ . '/../shared/api.php';
$oauthDefaultSuccess = Config::getParam('protocol').'://'.Config::getParam('domain').'/auth/oauth2/success';
$oauthDefaultFailure = Config::getParam('protocol').'://'.Config::getParam('domain').'/auth/oauth2/failure';
$oauth2Keys = [];
$utopia->init(function() use (&$oauth2Keys) {
@ -247,8 +250,8 @@ $utopia->get('/v1/account/sessions/oauth2/:provider')
->label('abuse-limit', 50)
->label('abuse-key', 'ip:{ip}')
->param('provider', '', function () { return new WhiteList(array_keys(Config::getParam('providers'))); }, 'OAuth2 Provider. Currently, supported providers are: ' . implode(', ', array_keys(array_filter(Config::getParam('providers'), function($node) {return (!$node['mock']);}))).'.')
->param('success', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect back to your app after a successful login attempt.')
->param('failure', '', function () use ($clients) { return new Host($clients); }, 'URL to redirect back to your app after a failed login attempt.')
->param('success', $oauthDefaultSuccess, function () use ($clients) { return new Host($clients); }, 'URL to redirect back to your app after a successful login attempt.', true)
->param('failure', $oauthDefaultFailure, function () use ($clients) { return new Host($clients); }, 'URL to redirect back to your app after a failed login attempt.', true)
->action(
function ($provider, $success, $failure) use ($response, $request, $project) {
$protocol = Config::getParam('protocol');
@ -316,7 +319,7 @@ $utopia->get('/v1/account/sessions/oauth2/:provider/redirect')
->param('code', '', function () { return new Text(1024); }, 'OAuth2 code.')
->param('state', '', function () { return new Text(2048); }, 'OAuth2 state params.', true)
->action(
function ($provider, $code, $state) use ($response, $request, $user, $projectDB, $project, $audit) {
function ($provider, $code, $state) use ($response, $request, $user, $projectDB, $project, $audit, $oauthDefaultSuccess) {
$protocol = Config::getParam('protocol');
$callback = $protocol.'://'.$request->getServer('HTTP_HOST').'/v1/account/sessions/oauth2/callback/'.$provider.'/'.$project->getId();
$defaultState = ['success' => $project->getAttribute('url', ''), 'failure' => ''];
@ -476,6 +479,10 @@ $utopia->get('/v1/account/sessions/oauth2/:provider/redirect')
;
}
if($state['success'] === $oauthDefaultSuccess) { // Add keys for non-web platforms
$state['success'] = $state['success'].'/?end=true';
}
$response
->addHeader('Cache-Control', 'no-store, no-cache, must-revalidate, max-age=0')
->addHeader('Pragma', 'no-cache')

View file

@ -10,6 +10,7 @@ use Utopia\Validator\URL;
use Utopia\Cache\Cache;
use Utopia\Cache\Adapter\Filesystem;
use Appwrite\Resize\Resize;
use Appwrite\URL\URL as URLParse;
use BaconQrCode\Renderer\ImageRenderer;
use BaconQrCode\Renderer\Image\ImagickImageBackEnd;
use BaconQrCode\Renderer\RendererStyle\RendererStyle;
@ -265,7 +266,7 @@ $utopia->get('/v1/avatars/favicon')
$href = $link->getAttribute('href');
$rel = $link->getAttribute('rel');
$sizes = $link->getAttribute('sizes');
$absolute = unparse_url(array_merge(parse_url($url), parse_url($href)));
$absolute = URLParse::unparse(array_merge(parse_url($url), parse_url($href)));
switch (strtolower($rel)) {
case 'icon':
@ -381,41 +382,4 @@ $utopia->get('/v1/avatars/qr')
->send('', $writer->writeString($text))
;
}
);
function unparse_url($parsed_url, $ommit = array())
{
if (isset($parsed_url['path']) && mb_substr($parsed_url['path'], 0, 1) !== '/') {
$parsed_url['path'] = '/'.$parsed_url['path'];
}
$p = array();
$p['scheme'] = isset($parsed_url['scheme']) ? $parsed_url['scheme'].'://' : '';
$p['host'] = isset($parsed_url['host']) ? $parsed_url['host'] : '';
$p['port'] = isset($parsed_url['port']) ? ':'.$parsed_url['port'] : '';
$p['user'] = isset($parsed_url['user']) ? $parsed_url['user'] : '';
$p['pass'] = isset($parsed_url['pass']) ? ':'.$parsed_url['pass'] : '';
$p['pass'] = ($p['user'] || $p['pass']) ? $p['pass'].'@' : '';
$p['path'] = isset($parsed_url['path']) ? $parsed_url['path'] : '';
$p['query'] = isset($parsed_url['query']) ? '?'.$parsed_url['query'] : '';
$p['fragment'] = isset($parsed_url['fragment']) ? '#'.$parsed_url['fragment'] : '';
if ($ommit) {
foreach ($ommit as $key) {
if (isset($p[ $key ])) {
$p[ $key ] = '';
}
}
}
return $p['scheme'].$p['user'].$p['pass'].$p['host'].$p['port'].$p['path'].$p['query'].$p['fragment'];
}
);

78
src/Appwrite/URL/URL.php Normal file
View file

@ -0,0 +1,78 @@
<?php
namespace Appwrite\URL;
class URL
{
/**
* Parse URL
*
* Take a URL string and split it to array parts
*
* @param $url string
*
* @return array
*/
static public function parse(string $url):array
{
$default = [
'scheme' => '',
'pass' => '',
'user' => '',
'host' => '',
'port' => null,
'path' => '',
'query' => '',
'fragment' => '',
];
return array_merge($default, parse_url($url));
}
/**
* Un-Parse URL
*
* Take URL parts and combine them to a valid string
*
* @param $url array
* @param $ommit array
*
* @return string
*/
static public function unparse(array $url, array $ommit = []):string
{
if (isset($url['path']) && mb_substr($url['path'], 0, 1) !== '/') {
$url['path'] = '/'.$url['path'];
}
$parts = [];
$parts['scheme'] = isset($url['scheme']) ? $url['scheme'].'://' : '';
$parts['host'] = isset($url['host']) ? $url['host'] : '';
$parts['port'] = isset($url['port']) ? ':'.$url['port'] : '';
$parts['user'] = isset($url['user']) ? $url['user'] : '';
$parts['pass'] = isset($url['pass']) ? ':'.$url['pass'] : '';
$parts['pass'] = ($parts['user'] || $parts['pass']) ? $parts['pass'].'@' : '';
$parts['path'] = isset($url['path']) ? $url['path'] : '';
$parts['query'] = isset($url['query']) && !empty($url['query']) ? '?'.$url['query'] : '';
$parts['fragment'] = isset($url['fragment']) ? '#'.$url['fragment'] : '';
if ($ommit) {
foreach ($ommit as $key) {
if (isset($parts[ $key ])) {
$parts[ $key ] = '';
}
}
}
return $parts['scheme'].$parts['user'].$parts['pass'].$parts['host'].$parts['port'].$parts['path'].$parts['query'].$parts['fragment'];
}
}

View file

@ -0,0 +1,90 @@
<?php
namespace Appwrite\Tests;
use Appwrite\URL\URL;
use PHPUnit\Framework\TestCase;
class URLTest extends TestCase
{
public function testParse()
{
$url = URL::parse('https://appwrite.io:8080/path?query=string&param=value');
$this->assertIsArray($url);
$this->assertEquals('https', $url['scheme']);
$this->assertEquals('appwrite.io', $url['host']);
$this->assertEquals('8080', $url['port']);
$this->assertEquals('/path', $url['path']);
$this->assertEquals('query=string&param=value', $url['query']);
$url = URL::parse('https://appwrite.io');
$this->assertIsArray($url);
$this->assertEquals('https', $url['scheme']);
$this->assertEquals('appwrite.io', $url['host']);
$this->assertEquals(null, $url['port']);
$this->assertEquals('', $url['path']);
$this->assertEquals('', $url['query']);
}
public function testUnparse()
{
$url = URL::unparse([
'scheme' => 'https',
'host' => 'appwrite.io',
'port' => 8080,
'path' => '/path',
'query' => 'query=string&param=value',
]);
$this->assertIsString($url);
$this->assertEquals('https://appwrite.io:8080/path?query=string&param=value', $url);
$url = URL::unparse([
'scheme' => 'https',
'host' => 'appwrite.io',
'port' => null,
'path' => '/path',
'query' => 'query=string&param=value',
]);
$this->assertIsString($url);
$this->assertEquals('https://appwrite.io/path?query=string&param=value', $url);
$url = URL::unparse([
'scheme' => 'https',
'host' => 'appwrite.io',
'port' => null,
'path' => '',
'query' => '',
]);
$this->assertIsString($url);
$this->assertEquals('https://appwrite.io/', $url);
$url = URL::unparse([
'scheme' => 'https',
'host' => 'appwrite.io',
'port' => null,
'path' => '',
'fragment' => 'bottom',
]);
$this->assertIsString($url);
$this->assertEquals('https://appwrite.io/#bottom', $url);
$url = URL::unparse([
'scheme' => 'https',
'user' => 'eldad',
'pass' => 'fux',
'host' => 'appwrite.io',
'port' => null,
'path' => '',
'fragment' => 'bottom',
]);
$this->assertIsString($url);
$this->assertEquals('https://eldad:fux@appwrite.io/#bottom', $url);
}
}