osTicket: custom client auth backend plugin

Trabla: osTicket: custom client auth backend plugin


osTicket Support Ticket System logo





In this tutorial we will create custom client auth backend plugin ( only for clients/users not admin and managers )
Explanation schema:

osTicket custom client auth backend plugin

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