diff options
-rw-r--r-- | Zotlabs/Identity/OAuth2Storage.php | 35 | ||||
-rw-r--r-- | Zotlabs/Module/Authorize.php | 58 | ||||
-rw-r--r-- | Zotlabs/Module/Oauthinfo.php | 6 | ||||
-rw-r--r-- | Zotlabs/Module/Well_known.php | 1 | ||||
-rw-r--r-- | Zotlabs/Module/Wfinger.php | 5 | ||||
-rw-r--r-- | Zotlabs/Update/_1218.php | 31 | ||||
-rwxr-xr-x | boot.php | 2 | ||||
-rw-r--r-- | include/api_auth.php | 37 | ||||
-rw-r--r-- | include/hubloc.php | 2 | ||||
-rw-r--r-- | install/schema_mysql.sql | 6 | ||||
-rw-r--r-- | install/schema_postgres.sql | 5 | ||||
-rw-r--r-- | library/certs/lets-encrypt-x3-cross-signed.pem | 28 |
12 files changed, 149 insertions, 67 deletions
diff --git a/Zotlabs/Identity/OAuth2Storage.php b/Zotlabs/Identity/OAuth2Storage.php index a50b21a70..bbf61cf2b 100644 --- a/Zotlabs/Identity/OAuth2Storage.php +++ b/Zotlabs/Identity/OAuth2Storage.php @@ -55,15 +55,22 @@ class OAuth2Storage extends \OAuth2\Storage\Pdo { return false; } + $a = q("select * from account where account_id = %d", + intval($x['channel_account_id']) + ); + + $n = explode(' ', $x['channel_name']); + return( [ - 'webbie' => $x['channel_address'].'@'.\App::get_hostname(), - 'zothash' => $x['channel_hash'], - 'username' => $x['channel_address'], - 'user_id' => $x['channel_id'], - 'name' => $x['channel_name'], - 'firstName' => $x['channel_name'], - 'lastName' => '', - 'password' => 'NotARealPassword' + 'webfinger' => channel_reddress($x), + 'portable_id' => $x['channel_hash'], + 'email' => $a['account_email'], + 'username' => $x['channel_address'], + 'user_id' => $x['channel_id'], + 'name' => $x['channel_name'], + 'firstName' => ((count($n) > 1) ? $n[1] : $n[0]), + 'lastName' => ((count($n) > 2) ? $n[count($n) - 1] : ''), + 'picture' => $x['xchan_photo_l'] ] ); } @@ -91,12 +98,16 @@ class OAuth2Storage extends \OAuth2\Storage\Pdo { $userClaims = Array(); $claims = explode (' ', trim($claims)); - $validclaims = Array ("name","preferred_username","zothash"); + $validclaims = Array ("name","preferred_username","webfinger","portable_id","email","picture","firstName","lastName"); $claimsmap = Array ( - "zotwebbie" => 'webbie', - "zothash" => 'zothash', + "webfinger" => 'webfinger', + "portable_id" => 'portable_id', "name" => 'name', - "preferred_username" => "username" + "email" => 'email', + "preferred_username" => 'username', + "picture" => 'picture', + "given_name" => 'firstName', + "family_name" => 'lastName' ); $userinfo = $this->getUser($user_id); foreach ($validclaims as $validclaim) { diff --git a/Zotlabs/Module/Authorize.php b/Zotlabs/Module/Authorize.php index e042848d8..c6709f602 100644 --- a/Zotlabs/Module/Authorize.php +++ b/Zotlabs/Module/Authorize.php @@ -7,27 +7,34 @@ use Zotlabs\Identity\OAuth2Storage; class Authorize extends \Zotlabs\Web\Controller { function get() { - if (!local_channel()) { + if (! local_channel()) { return login(); - } else { - // TODO: Fully implement the dynamic client registration protocol: - // OpenID Connect Dynamic Client Registration 1.0 Client Metadata - // http://openid.net/specs/openid-connect-registration-1_0.html - $app = array( - 'name' => (x($_REQUEST, 'client_name') ? urldecode($_REQUEST['client_name']) : t('Unknown App')), - 'icon' => (x($_REQUEST, 'logo_uri') ? urldecode($_REQUEST['logo_uri']) : z_root() . '/images/icons/plugin.png'), - 'url' => (x($_REQUEST, 'client_uri') ? urldecode($_REQUEST['client_uri']) : ''), - ); - $o .= replace_macros(get_markup_template('oauth_authorize.tpl'), array( - '$title' => t('Authorize'), - '$authorize' => sprintf( t('Do you authorize the app %s to access your channel data?'), '<a style="float: none;" href="' . $app['url'] . '">' . $app['name'] . '</a> '), - '$app' => $app, - '$yes' => t('Allow'), - '$no' => t('Deny'), - '$client_id' => (x($_REQUEST, 'client_id') ? $_REQUEST['client_id'] : ''), + } + else { + + $name = $_REQUEST['client_name']; + if(! $name) { + $name = (($_REQUEST['client_id']) ?: t('Unknown App')); + } + + $app = [ + 'name' => $name, + 'icon' => (x($_REQUEST, 'logo_uri') ? $_REQUEST['logo_uri'] : z_root() . '/images/icons/plugin.png'), + 'url' => (x($_REQUEST, 'client_uri') ? $_REQUEST['client_uri'] : ''), + ]; + + $link = (($app['url']) ? '<a style="float: none;" href="' . $app['url'] . '">' . $app['name'] . '</a> ' : $app['name']); + + $o .= replace_macros(get_markup_template('oauth_authorize.tpl'), [ + '$title' => t('Authorize'), + '$authorize' => sprintf( t('Do you authorize the app %s to access your channel data?'), $link ), + '$app' => $app, + '$yes' => t('Allow'), + '$no' => t('Deny'), + '$client_id' => (x($_REQUEST, 'client_id') ? $_REQUEST['client_id'] : ''), '$redirect_uri' => (x($_REQUEST, 'redirect_uri') ? $_REQUEST['redirect_uri'] : ''), - '$state' => (x($_REQUEST, 'state') ? $_REQUEST['state'] : ''), - )); + '$state' => (x($_REQUEST, 'state') ? $_REQUEST['state'] : ''), + ]); return $o; } } @@ -60,17 +67,16 @@ class Authorize extends \Zotlabs\Web\Controller { $request = \OAuth2\Request::createFromGlobals(); $response = new \OAuth2\Response(); - // Note, "sub" field must match type and content. $user_id is used to populate - make sure it's a string. - $channel = channelx_by_n(local_channel()); - $user_id = $channel["channel_id"]; + // Note, "sub" field must match type and content. $user_id is used to populate - make sure it's a string. + $channel = channelx_by_n(local_channel()); + $user_id = $channel['channel_id']; // If the client is not registered, add to the database if (!$client = $storage->getClientDetails($client_id)) { - // Until "Dynamic Client Registration" is pursued - allow new clients to assign their own secret in the REQUEST - $client_secret = (isset($_REQUEST["client_secret"])) ? $_REQUEST["client_secret"] : random_string(16); + // Until "Dynamic Client Registration" is pursued - allow new clients to assign their own secret in the REQUEST + $client_secret = (isset($_REQUEST['client_secret'])) ? $_REQUEST['client_secret'] : random_string(16); // Client apps are registered per channel - $storage->setClientDetails($client_id, $client_secret, $redirect_uri, 'authorization_code', urldecode($_REQUEST["scope"]), $user_id); - + $storage->setClientDetails($client_id, $client_secret, $redirect_uri, 'authorization_code', $_REQUEST['scope'], $user_id); } if (!$client = $storage->getClientDetails($client_id)) { // There was an error registering the client. diff --git a/Zotlabs/Module/Oauthinfo.php b/Zotlabs/Module/Oauthinfo.php index 2d10913c4..f380cec97 100644 --- a/Zotlabs/Module/Oauthinfo.php +++ b/Zotlabs/Module/Oauthinfo.php @@ -5,19 +5,17 @@ namespace Zotlabs\Module; class Oauthinfo extends \Zotlabs\Web\Controller { - function init() { $ret = [ 'issuer' => z_root(), 'authorization_endpoint' => z_root() . '/authorize', 'token_endpoint' => z_root() . '/token', + 'userinfo_endpoint' => z_root() . '/userinfo', + 'scopes_supported' => [ 'openid', 'profile', 'email' ], 'response_types_supported' => [ 'code', 'token', 'id_token', 'code id_token', 'token id_token' ] ]; - json_return_and_die($ret); } - - }
\ No newline at end of file diff --git a/Zotlabs/Module/Well_known.php b/Zotlabs/Module/Well_known.php index 442994b54..09e743788 100644 --- a/Zotlabs/Module/Well_known.php +++ b/Zotlabs/Module/Well_known.php @@ -52,6 +52,7 @@ class Well_known extends \Zotlabs\Web\Controller { break; case 'oauth-authorization-server': + case 'openid-configuration': \App::$argc -= 1; array_shift(\App::$argv); \App::$argv[0] = 'oauthinfo'; diff --git a/Zotlabs/Module/Wfinger.php b/Zotlabs/Module/Wfinger.php index 88cb3e879..1866bce40 100644 --- a/Zotlabs/Module/Wfinger.php +++ b/Zotlabs/Module/Wfinger.php @@ -172,6 +172,11 @@ class Wfinger extends \Zotlabs\Web\Controller { 'href' => z_root() . '/hcard/' . $r[0]['channel_address'] ], + [ + 'rel' => 'http://openid.net/specs/connect/1.0/issuer', + 'href' => z_root() + ], + [ 'rel' => 'http://webfinger.net/rel/profile-page', diff --git a/Zotlabs/Update/_1218.php b/Zotlabs/Update/_1218.php new file mode 100644 index 000000000..67d8b49a5 --- /dev/null +++ b/Zotlabs/Update/_1218.php @@ -0,0 +1,31 @@ +<?php + +namespace Zotlabs\Update; + +class _1218 { + + function run() { + + if(ACTIVE_DBTYPE == DBTYPE_POSTGRES) { + $r1 = q("ALTER TABLE hubloc add hubloc_id_url text NOT NULL"); + $r2 = q("create index \"hubloc_id_url\" on hubloc (\"hubloc_id_url\")"); + $r3 = q("ALTER TABLE hubloc add hubloc_site_id text NOT NULL"); + $r4 = q("create index \"hubloc_site_id\" on hubloc (\"hubloc_site_id\")"); + + $r = $r1 && $r2 && $r3 && $r4; + } + + if(ACTIVE_DBTYPE == DBTYPE_MYSQL) { + $r1 = q("ALTER TABLE hubloc add hubloc_id_url varchar(191) NOT NULL, ADD INDEX hubloc_id_url (hubloc_id_url)"); + $r2 = q("ALTER TABLE hubloc add hubloc_site_id varchar(191) NOT NULL, ADD INDEX hubloc_site_id (hubloc_site_id)"); + + $r = $r1 && $r2; + } + + if($r) + return UPDATE_SUCCESS; + return UPDATE_FAILED; + + } + +} @@ -54,7 +54,7 @@ define ( 'STD_VERSION', '3.7.1' ); define ( 'ZOT_REVISION', '6.0a' ); -define ( 'DB_UPDATE_VERSION', 1217 ); +define ( 'DB_UPDATE_VERSION', 1218 ); define ( 'PROJECT_BASE', __DIR__ ); diff --git a/include/api_auth.php b/include/api_auth.php index e2f7ab155..23ab9c946 100644 --- a/include/api_auth.php +++ b/include/api_auth.php @@ -12,7 +12,13 @@ function api_login(&$a){ require_once('include/oauth.php'); + + if(array_key_exists('REDIRECT_REMOTE_USER',$_SERVER) && (! array_key_exists('HTTP_AUTHORIZATION',$_SERVER))) { + $_SERVER['HTTP_AUTHORIZATION'] = $_SERVER['REDIRECT_REMOTE_USER']; + } + // login with oauth + try { // OAuth 2.0 $storage = new \Zotlabs\Identity\OAuth2Storage(\DBA::$dba->db); @@ -66,32 +72,27 @@ function api_login(&$a){ logger($e->getMessage()); } - // workarounds for HTTP-auth in CGI mode - foreach([ 'REDIRECT_REMOTE_USER', 'HTTP_AUTHORIZATION' ] as $head) { + if(array_key_exists('HTTP_AUTHORIZATION',$_SERVER)) { /* Basic authentication */ - if(array_key_exists($head,$_SERVER) && substr(trim($_SERVER[$head]),0,5) === 'Basic') { - $userpass = @base64_decode(substr(trim($_SERVER[$head]),6)) ; + if (substr(trim($_SERVER['HTTP_AUTHORIZATION']),0,5) === 'Basic') { + $userpass = @base64_decode(substr(trim($_SERVER['HTTP_AUTHORIZATION']),6)) ; if(strlen($userpass)) { list($name, $password) = explode(':', $userpass); $_SERVER['PHP_AUTH_USER'] = $name; $_SERVER['PHP_AUTH_PW'] = $password; } - break; } - /* Signature authentication */ + /* OpenWebAuth */ - if(array_key_exists($head,$_SERVER) && substr(trim($_SERVER[$head]),0,9) === 'Signature') { + if(substr(trim($_SERVER['HTTP_AUTHORIZATION']),0,9) === 'Signature') { - if($head !== 'HTTP_AUTHORIZATION') { - $_SERVER['HTTP_AUTHORIZATION'] = $_SERVER[$head]; - continue; - } + $record = null; - $sigblock = \Zotlabs\Web\HTTPSig::parse_sigheader($_SERVER[$head]); + $sigblock = \Zotlabs\Web\HTTPSig::parse_sigheader($_SERVER['HTTP_AUTHORIZATION']); if($sigblock) { $keyId = str_replace('acct:','',$sigblock['keyId']); if($keyId) { @@ -108,16 +109,7 @@ function api_login(&$a){ $record = [ 'channel' => $c, 'account' => $a[0] ]; $channel_login = $c['channel_id']; } - else { - continue; - } } - else { - continue; - } - } - else { - continue; } if($record) { @@ -125,7 +117,6 @@ function api_login(&$a){ if(! ($verified && $verified['header_signed'] && $verified['header_valid'])) { $record = null; } - break; } } } @@ -137,7 +128,7 @@ function api_login(&$a){ // process normal login request - if(isset($_SERVER['PHP_AUTH_USER'])) { + if(isset($_SERVER['PHP_AUTH_USER']) && (! $record)) { $channel_login = 0; $record = account_verify_password($_SERVER['PHP_AUTH_USER'],$_SERVER['PHP_AUTH_PW']); if($record && $record['channel']) { diff --git a/include/hubloc.php b/include/hubloc.php index 33d5dcbb2..d1170a62c 100644 --- a/include/hubloc.php +++ b/include/hubloc.php @@ -24,6 +24,8 @@ function hubloc_store_lowlevel($arr) { 'hubloc_status' => ((array_key_exists('hubloc_status',$arr)) ? $arr['hubloc_status'] : 0), 'hubloc_url' => ((array_key_exists('hubloc_url',$arr)) ? $arr['hubloc_url'] : ''), 'hubloc_url_sig' => ((array_key_exists('hubloc_url_sig',$arr)) ? $arr['hubloc_url_sig'] : ''), + 'hubloc_id_url' => ((array_key_exists('hubloc_id_url',$arr)) ? $arr['hubloc_id_url'] : ''), + 'hubloc_site_id' => ((array_key_exists('hubloc_site_id',$arr)) ? $arr['hubloc_site_id'] : ''), 'hubloc_host' => ((array_key_exists('hubloc_host',$arr)) ? $arr['hubloc_host'] : ''), 'hubloc_callback' => ((array_key_exists('hubloc_callback',$arr)) ? $arr['hubloc_callback'] : ''), 'hubloc_connect' => ((array_key_exists('hubloc_connect',$arr)) ? $arr['hubloc_connect'] : ''), diff --git a/install/schema_mysql.sql b/install/schema_mysql.sql index b556b15cd..7fd2cfea8 100644 --- a/install/schema_mysql.sql +++ b/install/schema_mysql.sql @@ -501,10 +501,12 @@ CREATE TABLE IF NOT EXISTS `hook` ( KEY `hook_version` (`hook_version`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + CREATE TABLE IF NOT EXISTS `hubloc` ( `hubloc_id` int(10) unsigned NOT NULL AUTO_INCREMENT, `hubloc_guid` char(191) NOT NULL DEFAULT '', `hubloc_guid_sig` text NOT NULL, + `hubloc_id_url` char(191) NOT NULL DEFAULT '0', `hubloc_hash` char(191) NOT NULL DEFAULT '', `hubloc_addr` char(191) NOT NULL DEFAULT '', `hubloc_network` char(32) NOT NULL DEFAULT '', @@ -512,6 +514,7 @@ CREATE TABLE IF NOT EXISTS `hubloc` ( `hubloc_status` int(10) unsigned NOT NULL DEFAULT 0 , `hubloc_url` char(191) NOT NULL DEFAULT '', `hubloc_url_sig` text NOT NULL, + `hubloc_site_id` char(191) NOT NULL DEFAULT '', `hubloc_host` char(191) NOT NULL DEFAULT '', `hubloc_callback` char(191) NOT NULL DEFAULT '', `hubloc_connect` char(191) NOT NULL DEFAULT '', @@ -524,7 +527,9 @@ CREATE TABLE IF NOT EXISTS `hubloc` ( `hubloc_deleted` tinyint(1) NOT NULL DEFAULT 0 , PRIMARY KEY (`hubloc_id`), KEY `hubloc_url` (`hubloc_url`), + KEY `hubloc_site_id` (`hubloc_site_id`), KEY `hubloc_guid` (`hubloc_guid`), + KEY `hubloc_id_url` (`hubloc_id_url`), KEY `hubloc_hash` (`hubloc_hash`), KEY `hubloc_flags` (`hubloc_flags`), KEY `hubloc_connect` (`hubloc_connect`), @@ -540,7 +545,6 @@ CREATE TABLE IF NOT EXISTS `hubloc` ( KEY `hubloc_error` (`hubloc_error`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; - CREATE TABLE IF NOT EXISTS `iconfig` ( `id` int(11) NOT NULL AUTO_INCREMENT, `iid` int(11) NOT NULL DEFAULT 0 , diff --git a/install/schema_postgres.sql b/install/schema_postgres.sql index 8db0eb8be..68c65c830 100644 --- a/install/schema_postgres.sql +++ b/install/schema_postgres.sql @@ -474,10 +474,12 @@ create index "hook_idx" on hook ("hook"); create index "hook_version_idx" on hook ("hook_version"); create index "hook_priority_idx" on hook ("priority"); + CREATE TABLE "hubloc" ( "hubloc_id" serial NOT NULL, "hubloc_guid" text NOT NULL DEFAULT '', "hubloc_guid_sig" text NOT NULL DEFAULT '', + "hubloc_id_url" text NOT NULL DEFAULT '', "hubloc_hash" text NOT NULL, "hubloc_addr" text NOT NULL DEFAULT '', "hubloc_network" text NOT NULL DEFAULT '', @@ -485,6 +487,7 @@ CREATE TABLE "hubloc" ( "hubloc_status" bigint NOT NULL DEFAULT '0', "hubloc_url" text NOT NULL DEFAULT '', "hubloc_url_sig" text NOT NULL DEFAULT '', + "hubloc_site_id" text NOT NULL DEFAULT '', "hubloc_host" text NOT NULL DEFAULT '', "hubloc_callback" text NOT NULL DEFAULT '', "hubloc_connect" text NOT NULL DEFAULT '', @@ -498,7 +501,9 @@ CREATE TABLE "hubloc" ( PRIMARY KEY ("hubloc_id") ); create index "hubloc_url" on hubloc ("hubloc_url"); +create index "hubloc_site_id" on hubloc ("hubloc_site_id"); create index "hubloc_guid" on hubloc ("hubloc_guid"); +create index "hubloc_id_url" on hubloc ("hubloc_id_url"); create index "hubloc_flags" on hubloc ("hubloc_flags"); create index "hubloc_connect" on hubloc ("hubloc_connect"); create index "hubloc_host" on hubloc ("hubloc_host"); diff --git a/library/certs/lets-encrypt-x3-cross-signed.pem b/library/certs/lets-encrypt-x3-cross-signed.pem index 0002462ce..6e5176f1e 100644 --- a/library/certs/lets-encrypt-x3-cross-signed.pem +++ b/library/certs/lets-encrypt-x3-cross-signed.pem @@ -25,3 +25,31 @@ X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6 KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg== -----END CERTIFICATE----- + +-----BEGIN CERTIFICATE----- +MIIEkjCCA3qgAwIBAgIQCgFBQgAAAVOFc2oLheynCDANBgkqhkiG9w0BAQsFADA/ +MSQwIgYDVQQKExtEaWdpdGFsIFNpZ25hdHVyZSBUcnVzdCBDby4xFzAVBgNVBAMT +DkRTVCBSb290IENBIFgzMB4XDTE2MDMxNzE2NDA0NloXDTIxMDMxNzE2NDA0Nlow +SjELMAkGA1UEBhMCVVMxFjAUBgNVBAoTDUxldCdzIEVuY3J5cHQxIzAhBgNVBAMT +GkxldCdzIEVuY3J5cHQgQXV0aG9yaXR5IFgzMIIBIjANBgkqhkiG9w0BAQEFAAOC +AQ8AMIIBCgKCAQEAnNMM8FrlLke3cl03g7NoYzDq1zUmGSXhvb418XCSL7e4S0EF +q6meNQhY7LEqxGiHC6PjdeTm86dicbp5gWAf15Gan/PQeGdxyGkOlZHP/uaZ6WA8 +SMx+yk13EiSdRxta67nsHjcAHJyse6cF6s5K671B5TaYucv9bTyWaN8jKkKQDIZ0 +Z8h/pZq4UmEUEz9l6YKHy9v6Dlb2honzhT+Xhq+w3Brvaw2VFn3EK6BlspkENnWA +a6xK8xuQSXgvopZPKiAlKQTGdMDQMc2PMTiVFrqoM7hD8bEfwzB/onkxEz0tNvjj +/PIzark5McWvxI0NHWQWM6r6hCm21AvA2H3DkwIDAQABo4IBfTCCAXkwEgYDVR0T +AQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMCAYYwfwYIKwYBBQUHAQEEczBxMDIG +CCsGAQUFBzABhiZodHRwOi8vaXNyZy50cnVzdGlkLm9jc3AuaWRlbnRydXN0LmNv +bTA7BggrBgEFBQcwAoYvaHR0cDovL2FwcHMuaWRlbnRydXN0LmNvbS9yb290cy9k +c3Ryb290Y2F4My5wN2MwHwYDVR0jBBgwFoAUxKexpHsscfrb4UuQdf/EFWCFiRAw +VAYDVR0gBE0wSzAIBgZngQwBAgEwPwYLKwYBBAGC3xMBAQEwMDAuBggrBgEFBQcC +ARYiaHR0cDovL2Nwcy5yb290LXgxLmxldHNlbmNyeXB0Lm9yZzA8BgNVHR8ENTAz +MDGgL6AthitodHRwOi8vY3JsLmlkZW50cnVzdC5jb20vRFNUUk9PVENBWDNDUkwu +Y3JsMB0GA1UdDgQWBBSoSmpjBH3duubRObemRWXv86jsoTANBgkqhkiG9w0BAQsF +AAOCAQEA3TPXEfNjWDjdGBX7CVW+dla5cEilaUcne8IkCJLxWh9KEik3JHRRHGJo +uM2VcGfl96S8TihRzZvoroed6ti6WqEBmtzw3Wodatg+VyOeph4EYpr/1wXKtx8/ +wApIvJSwtmVi4MFU5aMqrSDE6ea73Mj2tcMyo5jMd6jmeWUHK8so/joWUoHOUgwu +X4Po1QYz+3dszkDqMp4fklxBwXRsW10KXzPMTZ+sOPAveyxindmjkW8lGy+QsRlG +PfZ+G6Z6h7mjem0Y+iWlkYcV4PIWL1iwBi8saCbGS5jN2p8M+X+Q7UNKEkROb3N6 +KOqkqm57TH2H3eDJAkSnh6/DNFu0Qg== +-----END CERTIFICATE----- |