Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add generic OAuth backend to auth-oauth #194

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions auth-oauth/authentication.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@ function bootstrap() {
UserAuthenticationBackend::register(
new GoogleClientAuthBackend($this->getConfig()));
}

# ----- Generic OAuth2 ---------------------
$generic = $config->get('generic-enabled');
if (in_array($generic, array('all', 'staff'))) {
require_once('generic-oauth2.php');
StaffAuthenticationBackend::register(
new GenericOAuth2StaffAuthBackend($this->getConfig()));
}
if (in_array($generic, array('all', 'client'))) {
require_once('generic-oauth2.php');
UserAuthenticationBackend::register(
new GenericOAuth2AuthBackend($this->getConfig()));
}
}
}

Expand Down
32 changes: 32 additions & 0 deletions auth-oauth/config.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,38 @@ function getOptions() {
'configuration' => array('size'=>60, 'length'=>100),
)),
'g-enabled' => clone $modes,
'generic' => new SectionBreakField(array(
'label' => $__('Generic OAuth2'),
)),
'generic-servicename' => new TextboxField(array(
'label' => $__('Service name'),
'configuration' => array('size'=>60, 'length'=>200),
)),
'generic-client-id' => new TextboxField(array(
'label' => $__('Client ID'),
'configuration' => array('size'=>60, 'length'=>200),
)),
'generic-client-secret' => new TextboxField(array(
'label' => $__('Client Secret'),
'configuration' => array('size'=>60, 'length'=>200),
)),
'generic-authorize-url' => new TextboxField(array(
'label' => $__('Authorize URL'),
'configuration' => array('size'=>60, 'length'=>200),
)),
'generic-token-url' => new TextboxField(array(
'label' => $__('Token URL'),
'configuration' => array('size'=>60, 'length'=>200),
)),
'generic-userinfo-url' => new TextboxField(array(
'label' => $__('User JSON URL'),
'configuration' => array('size'=>60, 'length'=>200),
)),
'generic-scope' => new TextboxField(array(
'label' => $__('Scope'),
'configuration' => array('size'=>60, 'length'=>200),
)),
'generic-enabled' => clone $modes,
);
}
}
154 changes: 154 additions & 0 deletions auth-oauth/generic-oauth2.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
<?php

use ohmy\Auth2;

class GenericOAuth {
var $config;
var $access_token;

function __construct($config) {
$this->config = $config;
}

function triggerAuth() {
$self = $this;
global $ost;
return Auth2::legs(3)
->set('id', $this->config->get('generic-client-id'))
->set('secret', $this->config->get('generic-client-secret'))
->set('redirect', rtrim($ost->getConfig()->getURL(), '/') . '/api/auth/ext')
->set('scope', $this->config->get('generic-scope'))

->authorize($this->config->get('generic-authorize-url'))
->access($this->config->get('generic-token-url'))
->finally(function($data) use ($self) {
$self->access_token = $data['access_token'];
});
}
}

class GenericOAuth2StaffAuthBackend extends ExternalStaffAuthenticationBackend {
static $id = "oauth";
static $name = "OAuth2";

static $sign_in_image_url = "";

var $config;

function __construct($config) {
$this->config = $config;
$this->oauth = new GenericOAuth($config);
}

function getServiceName() {
return $this->config->get('generic-servicename');
}

function signOn() {
// TODO: Check session for auth token
if (isset($_SESSION[':oauth']['profile']['nickname'])) {
if (($staff = StaffSession::lookup($_SESSION[':oauth']['profile']['nickname']))
&& $staff->getId()
) {
$staffobject = $staff;
}
} elseif (isset($_SESSION[':oauth']['profile']['email'])) {
if (($staff = StaffSession::lookup(array('email' => $_SESSION[':oauth']['profile']['email'])))
&& $staff->getId()
) {
$staffobject = $staff;
}
}
if (isset($staffobject)) {
if (!$staffobject instanceof StaffSession) {
// osTicket <= v1.9.7 or so
$staffobject = new StaffSession($user->getId());
}
return $staffobject;
} else {
$_SESSION['_staff']['auth']['msg'] = 'Have your administrator create a local account';
}
}

static function signOut($user) {
parent::signOut($user);
unset($_SESSION[':oauth']);
}


function triggerAuth() {
parent::triggerAuth();
$oauth = $this->oauth->triggerAuth();
$oauth->GET(
$this->config->get('generic-userinfo-url'), [], array('Authorization' => 'Bearer ' . $this->oauth->access_token))
->then(function($response) {
if (!($json = JsonDataParser::decode($response->text)))
return;
$_SESSION[':oauth']['profile'] = $json;
Http::redirect(ROOT_PATH . 'scp');
}
);
}
}

class GenericOAuth2AuthBackend extends ExternalUserAuthenticationBackend {
static $id = "oauth.client";
static $name = "OAuth2";

static $sign_in_image_url = "";

function __construct($config) {
$this->config = $config;
$this->oauth = new GenericOAuth($config);
}

function getServiceName() {
return $this->config->get('generic-servicename');
}

function supportsInteractiveAuthentication() {
return false;
}

function signOn() {
// TODO: Check session for auth token
if (isset($_SESSION[':oauth']['profile']['email'])) {
if (($acct = ClientAccount::lookupByUsername($_SESSION[':oauth']['profile']['email']))
&& $acct->getId()
&& ($client = new ClientSession(new EndUser($acct->getUser()))))
return $client;

elseif (isset($_SESSION[':oauth']['profile'])) {
// TODO: Prepare ClientCreateRequest
$profile = $_SESSION[':oauth']['profile'];
$info = array(
'email' => $profile['email'],
'name' => $profile['displayName'],
);
return new ClientCreateRequest($this, $info['email'], $info);
}
}
}

static function signOut($user) {
parent::signOut($user);
unset($_SESSION[':oauth']);
}

function triggerAuth() {
require_once INCLUDE_DIR . 'class.json.php';
parent::triggerAuth();
$oauth = $this->oauth->triggerAuth();
$oauth->GET(
$this->config->get('generic-userinfo-url'), [], array('Authorization' => 'Bearer ' . $this->oauth->access_token))
->then(function($response) {
if (!($json = JsonDataParser::decode($response->text)))
return;
$_SESSION[':oauth']['profile'] = $json;
Http::redirect(ROOT_PATH . 'login.php');
}
);
}
}


6 changes: 3 additions & 3 deletions auth-oauth/plugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

return array(
'id' => 'auth:oath2', # notrans
'version' => '0.1',
'version' => '0.2',
'name' => /* trans */ 'Oauth2 Authentication and Lookup',
'author' => 'Jared Hancock',
'author' => 'Jared Hancock, Andreas Valder',
'description' => /* trans */ 'Provides a configurable authentication backend
for authenticating staff and clients using an OAUTH2 server
interface.',
'url' => 'http://www.osticket.com/plugins/auth/oauth',
'url' => 'https://github.com/osTicket/osTicket-plugins',
'plugin' => 'authentication.php:OauthAuthPlugin',
'requires' => array(
"ohmy/auth" => array(
Expand Down