Merge branch 'oauth2' into 'dev'

Fixes to OAuth2 connect-with-openid.  Add zothash Claim.  Add zotwebbie Claim.

See merge request hubzilla/core!1254
This commit is contained in:
Mario 2018-08-12 14:03:36 +02:00
commit 26f51ece90
5 changed files with 81 additions and 12 deletions

View File

@ -4,7 +4,7 @@ namespace Zotlabs\Identity;
class OAuth2Server extends \OAuth2\Server {
public function __construct(OAuth2Storage $storage, $config = []) {
public function __construct(OAuth2Storage $storage, $config = null) {
if(! is_array($config)) {
$config = [
@ -19,7 +19,8 @@ class OAuth2Server extends \OAuth2\Server {
$this->addGrantType(new \OAuth2\GrantType\ClientCredentials($storage));
// Add the "Authorization Code" grant type (this is where the oauth magic happens)
$this->addGrantType(new \OAuth2\GrantType\AuthorizationCode($storage));
// Need to use OpenID\GrantType to return id_token (see:https://github.com/bshaffer/oauth2-server-php/issues/443)
$this->addGrantType(new \OAuth2\OpenID\GrantType\AuthorizationCode($storage));
$keyStorage = new \OAuth2\Storage\Memory( [
'keys' => [

View File

@ -50,20 +50,67 @@ class OAuth2Storage extends \OAuth2\Storage\Pdo {
public function getUser($username)
{
$x = channelx_by_nick($username);
$x = channelx_by_n($username);
if(! $x) {
return false;
}
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'
] );
}
public function scopeExists($scope) {
// Report that the scope is valid even if it's not.
// We will only return a very small subset no matter what.
// @TODO: Truly validate the scope
// see vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ScopeInterface.php and
// vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/Pdo.php
// for more info.
return true;
}
public function getDefaultScope($client_id=null) {
// Do not REQUIRE a scope
// see vendor/bshaffer/oauth2-server-php/src/OAuth2/Storage/ScopeInterface.php and
// for more info.
return null;
}
public function getUserClaims ($user_id, $claims) {
// Populate the CLAIMS requested (if any).
// @TODO: create a more reasonable/comprehensive list.
// @TODO: present claims on the AUTHORIZATION screen
$userClaims = Array();
$claims = explode (' ', trim($claims));
$validclaims = Array ("name","preferred_username","zothash");
$claimsmap = Array (
"zotwebbie" => 'webbie',
"zothash" => 'zothash',
"name" => 'name',
"preferred_username" => "username"
);
$userinfo = $this->getUser($user_id);
foreach ($validclaims as $validclaim) {
if (in_array($validclaim,$claims)) {
$claimkey = $claimsmap[$validclaim];
$userClaims[$validclaim] = $userinfo[$claimkey];
} else {
$userClaims[$validclaim] = $validclaim;
}
}
$userClaims["sub"]=$user_id;
return $userClaims;
}
/**
* plaintext passwords are bad! Override this for your application
*
@ -78,4 +125,4 @@ class OAuth2Storage extends \OAuth2\Storage\Pdo {
return true;
}
}
}

View File

@ -60,12 +60,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"];
// If the client is not registered, add to the database
if (!$client = $storage->getClientDetails($client_id)) {
$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
$user_id = local_channel();
$storage->setClientDetails($client_id, $client_secret, $redirect_uri, 'authorization_code', null, $user_id);
$storage->setClientDetails($client_id, $client_secret, $redirect_uri, 'authorization_code', urldecode($_REQUEST["scope"]), $user_id);
}
if (!$client = $storage->getClientDetails($client_id)) {
@ -83,7 +87,7 @@ class Authorize extends \Zotlabs\Web\Controller {
// print the authorization code if the user has authorized your client
$is_authorized = ($_POST['authorize'] === 'allow');
$s->handleAuthorizeRequest($request, $response, $is_authorized, local_channel());
$s->handleAuthorizeRequest($request, $response, $is_authorized, $user_id);
if ($is_authorized) {
$code = substr($response->getHttpHeader('Location'), strpos($response->getHttpHeader('Location'), 'code=') + 5, 40);
logger('Authorization Code: ' . $code);

View File

@ -27,11 +27,11 @@ class Token extends \Zotlabs\Web\Controller {
$_SERVER['PHP_AUTH_PW'] = $password;
}
}
$s = new \Zotlabs\Identity\OAuth2Server(new OAuth2Storage(\DBA::$dba->db));
$storage = new OAuth2Storage(\DBA::$dba->db);
$s = new \Zotlabs\Identity\OAuth2Server($storage);
$request = \OAuth2\Request::createFromGlobals();
$s->handleTokenRequest($request)->send();
$response = $s->handleTokenRequest($request);
$response->send();
killme();
}

View File

@ -0,0 +1,17 @@
<?php
namespace Zotlabs\Module;
use Zotlabs\Identity\OAuth2Storage;
class Userinfo extends \Zotlabs\Web\Controller {
function init() {
$s = new \Zotlabs\Identity\OAuth2Server(new OAuth2Storage(\DBA::$dba->db));
$request = \OAuth2\Request::createFromGlobals();
$s->handleUserInfoRequest($request)->send();
killme();
}
}