Trabla: osTicket: custom client auth backend plugin
In this tutorial we will create custom client auth backend plugin ( only for clients/users not admin and managers )
Explanation schema:
So our custom client auth backend plugin should:
1. Get user entered login / pass
2. Send auth confirm request to your app entry point
3. Get response - if it OK and user not exists create new user in osTicket
and sign in into osTicket. if already exist - sign in into osTicket.
Else show error message - wrong credentials.
So user will be auto-registered when first sign in if your app confirm authentification.
Solving:
1. Create folder and name it - auth-my
( You can replace 'my' with your name, auth- is mandatory)
2. Create three text files and name them ( this is mandatory files for plugin ):
.../auth-my/plugin.php
.../auth-my/authentication.php
.../auth-my/config.php
3. Open file config.php , paste following code and save it ( this is osTicket Admin settings ):
<?php
require_once(INCLUDE_DIR.'/class.plugin.php');
require_once(INCLUDE_DIR.'/class.forms.php');
class MyConfig extends PluginConfig { //replace My with your name
// Provide compatibility function for versions of osTicket prior to
// translation support (v1.9.4)
function translate() {
if (!method_exists('Plugin', 'translate')) {
return array(
function($x) { return $x; },
function($x, $y, $n) { return $n != 1 ? $y : $x; },
);
}
return Plugin::translate('auth-my');
}
function getOptions() {
list($__, $_N) = self::translate();
return array(
'my' => new SectionBreakField(array(
'label' => 'MY AUTH',
'hint' => $__('This section should be all that is required for MY Auth'),
)),
'auth-url' => new TextboxField(array(
'id' => 'url',
'label' => $__('MY Auth Url'),
'configuration' => array('size'=>70, 'length'=>120),
'hint' => $__('MY Url. Should return json e.g. {"fullname":"John Deer","email":"test1@mail.com"} if auth success. Login and pass will be added to url Example: https://api.myapp.com/login.php?login=test1&password=123'),
)),
);
}
}
?>
4. Open file plugin.php , paste following code and save it:
<?php
set_include_path(get_include_path().PATH_SEPARATOR.dirname(__file__).'/include');
return array(
//Based on https://github.com/osTicket/core-plugins/blob/develop/auth-ldap
'id' => 'auth:my', # notrans
'version' => '0.0.1',
'name' => /* trans */ 'MY Authentication and Lookup',
'author' => 'Samurai Kit',
'description' => /* trans */ 'Provides a configurable authentication backend
which works against MY application',
'plugin' => 'authentication.php:MyAuthPlugin',
);
?>
5. Open file authentication.php , paste following code and save it:
<?php
require_once(INCLUDE_DIR.'class.osticket.php');
require_once(INCLUDE_DIR.'class.auth.php');
//==========================================
class ClientMyAuthentication extends UserAuthenticationBackend {
static $name = "My Client Auth";
static $id = "my.client";
function __construct($config) {
$this->config = $config;
}
function getName() {
$config = $this->config;
list($__, $_N) = $config::translate();
return $__(static::$name);
}
function authenticate($username, $password=false, $errors=array()) {
global $ost,$cfg;
// Do some encryption here if you need
$encrypted_username = $username;
$encrypted_password = $password;
$url = $this->config->get('auth-url') . "?login={$encrypted_username}&password={$encrypted_password}" ;
$request = @file_get_contents($url);
if($request === FALSE ){ //if FALSE means app response 404 Not Found
return;
}
// Reponse should be json e.g. {"fullname":"John Deer", "email":"jdeer@mail.com"}
// This data is needed for auto registration
$request = (array)json_decode($request);
$info = array(
'username' => $username,
'name' => $request['fullname'],
'email' => $request['email']
);
$acct = false;
foreach (array($username, $info['username'], $info['email']) as $name) {
if ($name && ($acct = ClientAccount::lookupByUsername($name)))
break;
}
//Account not exist - creating new account
if (!$acct){
$defaults = array(
'timezone_id' => $cfg->getDefaultTimezoneId(),
'dst' => $cfg->observeDaylightSaving(),
'username' => $username,
'backend' => self::$id,
'passwd' => Passwd::hash($password),
);
//Creating user from My App data
$U = User::fromVars($info);
//Creating Client account
$acct = ClientAccount::createForUser($U, $defaults);
$acct->confirm();
$bk = $this;
$cl = new ClientSession(new EndUser($U));
$bk->login($cl, $bk);
return $cl;
}
if (($client = new ClientSession(new EndUser($acct->getUser())))
&& !$client->getId())
return;
return $client;
}
function supportsPasswordChange() {
return false;
}
function supportsPasswordReset() {
return false;
}
function supportsInteractiveAuthentication(){
return true;
}
}
//==========================================
require_once(INCLUDE_DIR.'class.plugin.php');
require_once('config.php');
class MyAuthPlugin extends Plugin {
var $config_class = 'MyConfig';
function bootstrap() {
$config = $this->getConfig();
//Only Client Auth, not for Staff
UserAuthenticationBackend::register(new ClientMyAuthentication($config));
}
}
//==========================================
Thats all !!! Now we need deploy plugin into osTicket
6. Copy folder ../auth-my to ../include/plugins folder in your web-server
e.g.
/var/www/osticket/.../include/plugins
7. Login into osTicket as Administrator - go to plugin page and enable new plugin.
Set in config url to your app login method.
This is example of dummy MY api login script ( for testing ):
File name : login.php
<?php
/**
* Dummy My api script
* Url:
* https://localhost/myapi/login.php?login=samuraikit1&password=123
*/
$users = array(
'samuraikit1#123' => array(
'fullname' => 'Kit Samurai1',
'email' => 'samurai1@mail.com',
),
'samuraikit2#123' => array(
'fullname' => 'Kit Samurai2',
'email' => 'samurai2@mail.com',
),
'samuraikit3#123' => array(
'fullname' => 'Kit Samurai3',
'email' => 'samurai3@mail.com',
),
);
/**
*
*/
function response($status, $message){
http_response_code($status);
echo $message;
}
/**
* Login immitation :)
* @param string $login
* @param string $password
*/
$login = function( $login, $password ) use ($users) {
if(!is_null($login) && !is_null($password)){
$key = htmlentities($login) . '#' . htmlentities($password);
if(array_key_exists($key, $users)){
response(200,json_encode($users[$key]));
die;
}else{
response(404,"Wrong Login or password");
die;
}
}else{
response(404,"Login or Password is empty");
die;
}
};
if(isset($_GET['login']) && isset($_GET['password'])){
$login($_GET['login'],$_GET['password'] );
}else{
response(404,"Login or Password is empty");
die;
}
?>
No comments:
Post a Comment