2017-05-04 05:37:06 +00:00
< ? php
namespace Zotlabs\Module ;
2018-02-17 00:49:01 +00:00
use Zotlabs\Identity\OAuth2Storage ;
2017-05-04 05:37:06 +00:00
2018-02-17 00:49:01 +00:00
class Authorize extends \Zotlabs\Web\Controller {
2017-05-04 05:37:06 +00:00
2018-02-22 20:10:05 +00:00
function get () {
if ( ! local_channel ()) {
return login ();
} else {
2018-02-24 11:48:30 +00:00
// 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 (
2018-04-04 04:08:40 +00:00
'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' ]) : '' ),
2018-02-24 11:48:30 +00:00
);
2018-02-22 20:10:05 +00:00
$o .= replace_macros ( get_markup_template ( 'oauth_authorize.tpl' ), array (
2018-04-04 04:08:40 +00:00
'$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> ' ),
2018-02-22 20:10:05 +00:00
'$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' ] : '' ),
2018-02-24 11:48:30 +00:00
'$state' => ( x ( $_REQUEST , 'state' ) ? $_REQUEST [ 'state' ] : '' ),
2018-02-22 20:10:05 +00:00
));
return $o ;
}
}
function post () {
2018-04-04 04:08:40 +00:00
if ( ! local_channel ()) {
return ;
2018-02-22 20:10:05 +00:00
}
$storage = new OAuth2Storage ( \DBA :: $dba -> db );
$s = new \Zotlabs\Identity\OAuth2Server ( $storage );
2018-02-24 11:48:30 +00:00
// TODO: The automatic client registration protocol below should adhere more
// closely to "OAuth 2.0 Dynamic Client Registration Protocol" defined
// at https://tools.ietf.org/html/rfc7591
2018-02-22 20:10:05 +00:00
// If no client_id was provided, generate a new one.
if ( x ( $_POST , 'client_id' )) {
$client_id = $_POST [ 'client_id' ];
} else {
$client_id = $_POST [ 'client_id' ] = random_string ( 16 );
}
// If no redirect_uri was provided, generate a fake one.
if ( x ( $_POST , 'redirect_uri' )) {
$redirect_uri = $_POST [ 'redirect_uri' ];
} else {
2018-02-26 23:16:43 +00:00
$redirect_uri = $_POST [ 'redirect_uri' ] = 'https://fake.example.com/oauth' ;
2018-02-22 20:10:05 +00:00
}
2017-05-04 05:37:06 +00:00
2018-02-25 13:36:40 +00:00
$request = \OAuth2\Request :: createFromGlobals ();
$response = new \OAuth2\Response ();
2018-08-10 02:35:12 +00:00
// 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 " ];
2018-02-22 20:10:05 +00:00
// If the client is not registered, add to the database
2018-02-26 23:16:43 +00:00
if ( ! $client = $storage -> getClientDetails ( $client_id )) {
2018-08-10 02:35:12 +00:00
// 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 );
2018-02-24 11:48:30 +00:00
// Client apps are registered per channel
2018-08-10 02:35:12 +00:00
$storage -> setClientDetails ( $client_id , $client_secret , $redirect_uri , 'authorization_code' , urldecode ( $_REQUEST [ " scope " ]), $user_id );
2018-02-26 23:16:43 +00:00
}
if ( ! $client = $storage -> getClientDetails ( $client_id )) {
// There was an error registering the client.
$response -> send ();
killme ();
2018-02-22 20:10:05 +00:00
}
2018-02-26 23:16:43 +00:00
$response -> setParameter ( 'client_secret' , $client [ 'client_secret' ]);
2017-05-04 05:37:06 +00:00
2018-02-16 02:47:56 +00:00
// validate the authorize request
2018-02-22 20:10:05 +00:00
if ( ! $s -> validateAuthorizeRequest ( $request , $response )) {
2018-02-17 00:49:01 +00:00
$response -> send ();
killme ();
2018-02-16 02:47:56 +00:00
}
2017-05-04 05:37:06 +00:00
2018-02-17 00:49:01 +00:00
// print the authorization code if the user has authorized your client
2018-02-22 20:10:05 +00:00
$is_authorized = ( $_POST [ 'authorize' ] === 'allow' );
2018-08-10 02:35:12 +00:00
$s -> handleAuthorizeRequest ( $request , $response , $is_authorized , $user_id );
2018-02-17 00:49:01 +00:00
if ( $is_authorized ) {
2018-02-22 20:10:05 +00:00
$code = substr ( $response -> getHttpHeader ( 'Location' ), strpos ( $response -> getHttpHeader ( 'Location' ), 'code=' ) + 5 , 40 );
2018-04-04 04:08:40 +00:00
logger ( 'Authorization Code: ' . $code );
2018-02-17 00:49:01 +00:00
}
2017-05-04 05:37:06 +00:00
2018-02-17 00:49:01 +00:00
$response -> send ();
killme ();
2017-05-04 05:37:06 +00:00
}
2018-02-17 00:49:01 +00:00
}