Skip to content

Commit

Permalink
New : API key authentication
Browse files Browse the repository at this point in the history
One key is stored by user when login API method is called. Each API request must have api_key parameter
  • Loading branch information
jfefe committed May 2, 2015
1 parent 8027759 commit fa49436
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 27 deletions.
41 changes: 32 additions & 9 deletions htdocs/api/class/api.class.php
Expand Up @@ -18,6 +18,7 @@
use Luracast\Restler\Restler;
use Luracast\Restler\RestException;

require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';

/**
* Class for API
Expand Down Expand Up @@ -84,20 +85,25 @@ protected function cleanObjectDatas($object){
*/
class DolibarrApiInit extends DolibarrApi {



function __construct() {

global $db;
$this->db = $db;
}

/**
* Log user with login and password
* Login
*
* Log user with username and password
* @todo : to finish!
*
* @param string $login
* @param string $password
* @param int $entity
* @throws RestException
* @param string $login Username
* @param string $password User password
* @param int $entity User entity
* @throws RestException
*/
public function login($login, $password, $entity = '') {
public function login($login, $password, $entity = 0) {

// Authentication mode
if (empty($dolibarr_main_authentication))
Expand All @@ -114,10 +120,27 @@ public function login($login, $password, $entity = '') {
{
throw new RestException(403, 'Access denied');
}


// Generate token for user
$token = dol_hash($login.uniqid().$conf->global->MAIN_API_KEY,1);

// We store API token into database
$sql = "UPDATE ".MAIN_DB_PREFIX."user";
$sql.= " SET api_key = '".$this->db->escape($token)."'";
$sql.= " WHERE login = '".$this->db->escape($login)."'";

dol_syslog(get_class($this)."::login", LOG_DEBUG); // No log
$result = $this->db->query($sql);
if (!$result)
{
throw new RestException(500, 'Error when updating user :'.$this->db->error_msg);
}

//return token
return array(
'success' => array(
'code' => 200,
'token' => $token,
'message' => 'Welcome ' . $login
)
);
Expand All @@ -127,7 +150,7 @@ public function login($login, $password, $entity = '') {
* @access protected
* @class DolibarrApiAccess {@requires admin}
*/
public function status() {
function status() {
require_once DOL_DOCUMENT_ROOT . '/core/lib/functions.lib.php';
return array(
'success' => array(
Expand Down
58 changes: 41 additions & 17 deletions htdocs/api/class/api_access.class.php
Expand Up @@ -14,57 +14,81 @@
class DolibarrApiAccess implements iAuthenticate
{
const REALM = 'Restricted Dolibarr API';
const TEST_KEY = 'changeme';

/**
*
* @var string $role user / external / admin
* @var string $requires
* @var string $requires role required by API method user / external / admin
*/
public static $requires = 'user';

/**
* @var string $role user role
*/
public static $role = 'user';

/**
* Check access
*
* @return boolean
*/
public function __isAllowed()
{
global $db;

//@todo hardcoded api_key=>role for brevity
//
$roles = array('123' => 'user', '456' => 'external', '789' => 'admin');
$stored_key = '';

$userClass = Defaults::$userIdentifierClass;

// for dev @todo : remove this!
static::$role = 'user';

if( isset($_GET['test_key'])) {
if( ! $_GET['test_key'] == DolibarrApiAccess::TEST_KEY) {
$userClass::setCacheIdentifier($_GET['test_key']);
return false;
}
}
elseif (isset($_GET['api_key'])) {
if (isset($_GET['api_key'])) {
// @todo : check from database
if (!array_key_exists($_GET['api_key'], $roles)) {
$sql = "SELECT u.login, u.datec, u.api_key, ";
$sql.= " u.tms as date_modification, u.entity";
$sql.= " FROM ".MAIN_DB_PREFIX."user as u";
$sql.= " WHERE u.api_key = '".$db->escape($_GET['api_key'])."'";

$result=$db->query($sql);

if ($result)
{
if ($db->num_rows($result))
{
$obj = $db->fetch_object($result);
$login = $obj->login;
$stored_key = $obj->api_key;
}
}

if ( $stored_key != $_GET['api_key']) {
$userClass::setCacheIdentifier($_GET['api_key']);
return false;
}
static::$role = $roles[$_GET['api_key']];

$fuser = new User($db);
$result = $fuser->fetch('',$login);

if($fuser->societe_id)
static::$role = 'external';

if($fuser->admin)
static::$role = 'admin';
}
else
{
return false;
}



$userClass::setCacheIdentifier(static::$role);
Resources::$accessControlFunction = 'DolibarrApiAccess::verifyAccess';
return static::$requires == static::$role || static::$role == 'admin';
}

public function __getWWWAuthenticateString()
{
return 'Query name="api_key"';
return '';
}

/**
Expand Down
2 changes: 1 addition & 1 deletion htdocs/public/api/explorer/index.html
Expand Up @@ -46,7 +46,7 @@
discoveryUrl:"../resources.json",
apiKey:"",
dom_id:"swagger-ui-container",
supportHeaderParams: false,
supportHeaderParams: true,
supportedSubmitMethods: ['get', 'post', 'put', 'patch', 'delete'],
onComplete: function(swaggerApi, swaggerUi){
if(console) {
Expand Down
1 change: 1 addition & 0 deletions htdocs/societe/class/api_thirdparty.class.php
Expand Up @@ -23,6 +23,7 @@
* API class for thirdparty object
*
* @smart-auto-routing false
* @access protected
*
*/
class ThirdpartyApi extends DolibarrApi {
Expand Down

0 comments on commit fa49436

Please sign in to comment.