mirror of
https://github.com/opensupports/opensupports.git
synced 2025-07-31 01:35:15 +02:00
Merge pull request #687 from ivandiazwm/create-ticket-api-key
Create ticket api key
This commit is contained in:
commit
56b50596cb
@ -153,7 +153,7 @@ class AdminPanelAdvancedSettings extends React.Component {
|
|||||||
ModalContainer.closeModal();
|
ModalContainer.closeModal();
|
||||||
API.call({
|
API.call({
|
||||||
path: '/system/add-api-key',
|
path: '/system/add-api-key',
|
||||||
data: {name}
|
data: {name, type: 'REGISTRATION'}
|
||||||
}).then(this.getAllKeys.bind(this));
|
}).then(this.getAllKeys.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,7 +177,7 @@ class AdminPanelAdvancedSettings extends React.Component {
|
|||||||
|
|
||||||
onRetrieveSuccess(result) {
|
onRetrieveSuccess(result) {
|
||||||
this.setState({
|
this.setState({
|
||||||
APIKeys: result.data,
|
APIKeys: result.data.filter(key => key['type'] === 'REGISTRATION'),
|
||||||
selectedAPIKey: -1
|
selectedAPIKey: -1
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -14,10 +14,12 @@ use Respect\Validation\Validator as DataValidator;
|
|||||||
* @apiPermission staff3
|
* @apiPermission staff3
|
||||||
*
|
*
|
||||||
* @apiParam {String} name Name of the new APIKey.
|
* @apiParam {String} name Name of the new APIKey.
|
||||||
|
* @apiParam {String} type Type of APIKey: "REGISTRATION" or "TICKET_CREATE"
|
||||||
*
|
*
|
||||||
* @apiUse NO_PERMISSION
|
* @apiUse NO_PERMISSION
|
||||||
* @apiUse INVALID_NAME
|
* @apiUse INVALID_NAME
|
||||||
* @apiUse NAME_ALREADY_USED
|
* @apiUse NAME_ALREADY_USED
|
||||||
|
* @apiUse INVALID_API_KEY_TYPE
|
||||||
*
|
*
|
||||||
* @apiSuccess {String} data Token of the APIKey.
|
* @apiSuccess {String} data Token of the APIKey.
|
||||||
*
|
*
|
||||||
@ -34,6 +36,10 @@ class AddAPIKeyController extends Controller {
|
|||||||
'name' => [
|
'name' => [
|
||||||
'validation' => DataValidator::length(2, 55)->alnum(),
|
'validation' => DataValidator::length(2, 55)->alnum(),
|
||||||
'error' => ERRORS::INVALID_NAME
|
'error' => ERRORS::INVALID_NAME
|
||||||
|
],
|
||||||
|
'type' => [
|
||||||
|
'validation' => DataValidator::in(APIKey::TYPES),
|
||||||
|
'error' => ERRORS::INVALID_API_KEY_TYPE
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
];
|
];
|
||||||
@ -43,6 +49,7 @@ class AddAPIKeyController extends Controller {
|
|||||||
$apiInstance = new APIKey();
|
$apiInstance = new APIKey();
|
||||||
|
|
||||||
$name = Controller::request('name');
|
$name = Controller::request('name');
|
||||||
|
$type = Controller::request('type');
|
||||||
|
|
||||||
$keyInstance = APIKey::getDataStore($name, 'name');
|
$keyInstance = APIKey::getDataStore($name, 'name');
|
||||||
|
|
||||||
@ -51,7 +58,8 @@ class AddAPIKeyController extends Controller {
|
|||||||
|
|
||||||
$apiInstance->setProperties([
|
$apiInstance->setProperties([
|
||||||
'name' => $name,
|
'name' => $name,
|
||||||
'token' => $token
|
'token' => $token,
|
||||||
|
'type' => $type,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$apiInstance->store();
|
$apiInstance->store();
|
||||||
|
@ -75,7 +75,7 @@ class CreateController extends Controller {
|
|||||||
if(!Controller::isUserSystemEnabled() && !Controller::isStaffLogged()) {
|
if(!Controller::isUserSystemEnabled() && !Controller::isStaffLogged()) {
|
||||||
$validations['permission'] = 'any';
|
$validations['permission'] = 'any';
|
||||||
$validations['requestData']['captcha'] = [
|
$validations['requestData']['captcha'] = [
|
||||||
'validation' => DataValidator::captcha(),
|
'validation' => DataValidator::captcha(APIKey::TICKET_CREATE),
|
||||||
'error' => ERRORS::INVALID_CAPTCHA
|
'error' => ERRORS::INVALID_CAPTCHA
|
||||||
];
|
];
|
||||||
$validations['requestData']['email'] = [
|
$validations['requestData']['email'] = [
|
||||||
|
@ -72,7 +72,7 @@ class SignUpController extends Controller {
|
|||||||
|
|
||||||
if(!$this->csvImported) {
|
if(!$this->csvImported) {
|
||||||
$validations['requestData']['captcha'] = [
|
$validations['requestData']['captcha'] = [
|
||||||
'validation' => DataValidator::captcha(),
|
'validation' => DataValidator::captcha(APIKey::REGISTRATION),
|
||||||
'error' => ERRORS::INVALID_CAPTCHA
|
'error' => ERRORS::INVALID_CAPTCHA
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
@ -103,6 +103,10 @@ class SignUpController extends Controller {
|
|||||||
throw new RequestException(ERRORS::NO_PERMISSION);
|
throw new RequestException(ERRORS::NO_PERMISSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(!$apiKey->isNull() && $apiKey->type !== APIKey::REGISTRATION) {
|
||||||
|
throw new RequestException(ERRORS::INVALID_API_KEY_TYPE);
|
||||||
|
}
|
||||||
|
|
||||||
$userId = $this->createNewUserAndRetrieveId();
|
$userId = $this->createNewUserAndRetrieveId();
|
||||||
|
|
||||||
if(MailSender::getInstance()->isConnected()) {
|
if(MailSender::getInstance()->isConnected()) {
|
||||||
|
@ -251,6 +251,10 @@
|
|||||||
* @apiDefine INVALID_COLOR
|
* @apiDefine INVALID_COLOR
|
||||||
* @apiError {String} INVALID_COLOR The color should be in hexadecimal, preceded by a '#'
|
* @apiError {String} INVALID_COLOR The color should be in hexadecimal, preceded by a '#'
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* @apiDefine INVALID_API_KEY_TYPE
|
||||||
|
* @apiError {String} INVALID_API_KEY_TYPE Api key type is not one of the availables
|
||||||
|
*/
|
||||||
|
|
||||||
class ERRORS {
|
class ERRORS {
|
||||||
const INVALID_CREDENTIALS = 'INVALID_CREDENTIALS';
|
const INVALID_CREDENTIALS = 'INVALID_CREDENTIALS';
|
||||||
@ -326,4 +330,5 @@ class ERRORS {
|
|||||||
const INVALID_CUSTOM_FIELD_OPTION = 'INVALID_CUSTOM_FIELD_OPTION';
|
const INVALID_CUSTOM_FIELD_OPTION = 'INVALID_CUSTOM_FIELD_OPTION';
|
||||||
const UNAVAILABLE_STATS = 'UNAVAILABLE_STATS';
|
const UNAVAILABLE_STATS = 'UNAVAILABLE_STATS';
|
||||||
const INVALID_COLOR = 'INVALID_COLOR';
|
const INVALID_COLOR = 'INVALID_COLOR';
|
||||||
|
const INVALID_API_KEY_TYPE = 'INVALID_API_KEY_TYPE';
|
||||||
}
|
}
|
||||||
|
@ -5,12 +5,22 @@ namespace CustomValidations;
|
|||||||
use Respect\Validation\Rules\AbstractRule;
|
use Respect\Validation\Rules\AbstractRule;
|
||||||
|
|
||||||
class Captcha extends AbstractRule {
|
class Captcha extends AbstractRule {
|
||||||
|
private $dataStoreName;
|
||||||
|
|
||||||
|
public function __construct($apiKeyType = '') {
|
||||||
|
if (in_array($apiKeyType, \APIKey::TYPES)) {
|
||||||
|
$this->apiKeyType = $apiKeyType;
|
||||||
|
} else if($apiKeyType) {
|
||||||
|
throw new \Exception(\ERRORS::INVALID_API_KEY_TYPE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public function validate($reCaptchaResponse) {
|
public function validate($reCaptchaResponse) {
|
||||||
$reCaptchaPrivateKey = \Setting::getSetting('recaptcha-private')->getValue();
|
$reCaptchaPrivateKey = \Setting::getSetting('recaptcha-private')->getValue();
|
||||||
$apiKey = \APIKey::getDataStore(\Controller::request('apiKey'), 'token');
|
$apiKey = \APIKey::getDataStore(\Controller::request('apiKey'), 'token');
|
||||||
|
|
||||||
if (!$reCaptchaPrivateKey || !$apiKey->isNull()) return true;
|
if (!$reCaptchaPrivateKey) return true;
|
||||||
|
if (!$apiKey->isNull() && $apiKey->type === $apiKeyType) return true;
|
||||||
|
|
||||||
$reCaptcha = new \ReCaptcha\ReCaptcha($reCaptchaPrivateKey);
|
$reCaptcha = new \ReCaptcha\ReCaptcha($reCaptchaPrivateKey);
|
||||||
$reCaptchaValidation = $reCaptcha->verify($reCaptchaResponse, $_SERVER['REMOTE_ADDR']);
|
$reCaptchaValidation = $reCaptcha->verify($reCaptchaResponse, $_SERVER['REMOTE_ADDR']);
|
||||||
|
@ -9,18 +9,29 @@
|
|||||||
|
|
||||||
class APIKey extends DataStore {
|
class APIKey extends DataStore {
|
||||||
const TABLE = 'apikey';
|
const TABLE = 'apikey';
|
||||||
|
const REGISTRATION = 'REGISTRATION';
|
||||||
|
const TICKET_CREATE = 'TICKET_CREATE';
|
||||||
|
const TYPES = [APIKey::REGISTRATION, APIKey::TICKET_CREATE];
|
||||||
|
|
||||||
public static function getProps() {
|
public static function getProps() {
|
||||||
return [
|
return [
|
||||||
'name',
|
'name',
|
||||||
'token'
|
'token',
|
||||||
|
'type'
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDefaultProps() {
|
||||||
|
return [
|
||||||
|
'type' => APIKey::REGISTRATION
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public function toArray() {
|
public function toArray() {
|
||||||
return [
|
return [
|
||||||
'name' => $this->name,
|
'name' => $this->name,
|
||||||
'token' => $this->token
|
'token' => $this->token,
|
||||||
|
'type' => $this->type
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,6 +2,10 @@
|
|||||||
include_once 'tests/__mocks__/NullDataStoreMock.php';
|
include_once 'tests/__mocks__/NullDataStoreMock.php';
|
||||||
|
|
||||||
class APIKey extends \Mock {
|
class APIKey extends \Mock {
|
||||||
|
const REGISTRATION = 'REGISTRATION';
|
||||||
|
const TICKET_CREATE = 'TICKET_CREATE';
|
||||||
|
const TYPES = [APIKey::REGISTRATION, APIKey::TICKET_CREATE];
|
||||||
|
|
||||||
public static $functionList = array();
|
public static $functionList = array();
|
||||||
|
|
||||||
public static function initStubs() {
|
public static function initStubs() {
|
||||||
|
@ -56,11 +56,11 @@ require './system/edit-department.rb'
|
|||||||
require './system/delete-department.rb'
|
require './system/delete-department.rb'
|
||||||
require './staff/last-events.rb'
|
require './staff/last-events.rb'
|
||||||
# require './system/mail-templates.rb'
|
# require './system/mail-templates.rb'
|
||||||
require './system/disable-registration.rb'
|
|
||||||
require './system/enable-registration.rb'
|
|
||||||
require './system/add-api-key.rb'
|
require './system/add-api-key.rb'
|
||||||
require './system/delete-api-key.rb'
|
require './system/delete-api-key.rb'
|
||||||
require './system/get-api-keys.rb'
|
require './system/get-api-keys.rb'
|
||||||
|
require './system/disable-registration.rb'
|
||||||
|
require './system/enable-registration.rb'
|
||||||
require './system/file-upload-download.rb'
|
require './system/file-upload-download.rb'
|
||||||
require './system/csv-import.rb'
|
require './system/csv-import.rb'
|
||||||
require './ticket/create-tag.rb'
|
require './ticket/create-tag.rb'
|
||||||
|
@ -97,11 +97,12 @@ class Scripts
|
|||||||
result['data']
|
result['data']
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.createAPIKey(name)
|
def self.createAPIKey(name, type)
|
||||||
request('/system/add-api-key', {
|
request('/system/add-api-key', {
|
||||||
csrf_userid: $csrf_userid,
|
csrf_userid: $csrf_userid,
|
||||||
csrf_token: $csrf_token,
|
csrf_token: $csrf_token,
|
||||||
name: name
|
name: name,
|
||||||
|
type: type
|
||||||
})
|
})
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -6,7 +6,8 @@ describe'system/add-api-key' do
|
|||||||
result= request('/system/add-api-key', {
|
result= request('/system/add-api-key', {
|
||||||
csrf_userid: $csrf_userid,
|
csrf_userid: $csrf_userid,
|
||||||
csrf_token: $csrf_token,
|
csrf_token: $csrf_token,
|
||||||
name: 'new API'
|
name: 'new API',
|
||||||
|
type: 'REGISTRATION'
|
||||||
})
|
})
|
||||||
|
|
||||||
(result['status']).should.equal('success')
|
(result['status']).should.equal('success')
|
||||||
@ -15,16 +16,29 @@ describe'system/add-api-key' do
|
|||||||
|
|
||||||
(row['name']).should.equal('new API')
|
(row['name']).should.equal('new API')
|
||||||
(result['data']).should.equal(row['token'])
|
(result['data']).should.equal(row['token'])
|
||||||
|
|
||||||
end
|
end
|
||||||
it 'should not add API key' do
|
|
||||||
|
it 'should not add API key if name already used' do
|
||||||
result= request('/system/add-api-key', {
|
result= request('/system/add-api-key', {
|
||||||
csrf_userid: $csrf_userid,
|
csrf_userid: $csrf_userid,
|
||||||
csrf_token: $csrf_token,
|
csrf_token: $csrf_token,
|
||||||
name: 'new API'
|
name: 'new API',
|
||||||
|
type: 'REGISTRATION'
|
||||||
})
|
})
|
||||||
|
|
||||||
(result['status']).should.equal('fail')
|
(result['status']).should.equal('fail')
|
||||||
(result['message']).should.equal('NAME_ALREADY_USED')
|
(result['message']).should.equal('NAME_ALREADY_USED')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'should not add API key if invalid type is used' do
|
||||||
|
result= request('/system/add-api-key', {
|
||||||
|
csrf_userid: $csrf_userid,
|
||||||
|
csrf_token: $csrf_token,
|
||||||
|
name: 'new API2',
|
||||||
|
type: 'REGISTRATON'
|
||||||
|
})
|
||||||
|
|
||||||
|
(result['status']).should.equal('fail')
|
||||||
|
(result['message']).should.equal('INVALID_API_KEY_TYPE')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
describe'/system/disable-registration' do
|
describe'/system/disable-registration' do
|
||||||
request('/user/logout')
|
request('/user/logout')
|
||||||
Scripts.login($staff[:email], $staff[:password], true)
|
Scripts.login($staff[:email], $staff[:password], true)
|
||||||
|
api_key = Scripts.createAPIKey('registrationKey', 'REGISTRATION')['data']
|
||||||
|
|
||||||
it 'should not disable registration if password is not correct' do
|
it 'should not disable registration if password is not correct' do
|
||||||
result= request('/system/disable-registration', {
|
result= request('/system/disable-registration', {
|
||||||
@ -17,7 +18,7 @@ describe'/system/disable-registration' do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'should disable registration' do
|
it 'should disable registration' do
|
||||||
result= request('/system/disable-registration', {
|
result = request('/system/disable-registration', {
|
||||||
csrf_userid: $csrf_userid,
|
csrf_userid: $csrf_userid,
|
||||||
csrf_token: $csrf_token,
|
csrf_token: $csrf_token,
|
||||||
password: $staff[:password]
|
password: $staff[:password]
|
||||||
@ -31,13 +32,23 @@ describe'/system/disable-registration' do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'should not create user in database if registration is false' do
|
it 'should not create user in database if registration is false' do
|
||||||
response = request('/user/signup', {
|
result = request('/user/signup', {
|
||||||
:name => 'ponzio',
|
:name => 'ponzio',
|
||||||
:email => 'jc@ponziolandia.com',
|
:email => 'jc@ponziolandia.com',
|
||||||
:password => 'tequila'
|
:password => 'tequila'
|
||||||
})
|
})
|
||||||
|
|
||||||
(response['status']).should.equal('fail')
|
(result['status']).should.equal('fail')
|
||||||
|
(result['message']).should.equal('NO_PERMISSION')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should create user if using api key' do
|
||||||
|
result = request('/user/signup', {
|
||||||
|
:name => 'ponzio',
|
||||||
|
:email => 'jc@ponziolandia.com',
|
||||||
|
:password => 'tequila',
|
||||||
|
:apiKey => api_key
|
||||||
|
})
|
||||||
|
(result['status']).should.equal('success')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -17,7 +17,7 @@ describe'system/disable-user-system' do
|
|||||||
row = $database.getRow('user', 1, 'id')
|
row = $database.getRow('user', 1, 'id')
|
||||||
(row).should.equal(nil)
|
(row).should.equal(nil)
|
||||||
|
|
||||||
numberOftickets= $database.query("SELECT * FROM ticket WHERE author_id IS NULL AND author_email IS NOT NULL AND author_name IS NOT NULL")
|
numberOftickets = $database.query("SELECT * FROM ticket WHERE author_id IS NULL AND author_email IS NOT NULL AND author_name IS NOT NULL")
|
||||||
|
|
||||||
(numberOftickets.num_rows).should.equal(51)
|
(numberOftickets.num_rows).should.equal(51)
|
||||||
|
|
||||||
@ -148,6 +148,21 @@ describe'system/disable-user-system' do
|
|||||||
(ticket['author_staff_id']).should.equal('1')
|
(ticket['author_staff_id']).should.equal('1')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'should be able to create a ticket using api' do
|
||||||
|
api_key = Scripts.createAPIKey('ticketCreateKey', 'TICKET_CREATE')['data']
|
||||||
|
request('/user/logout')
|
||||||
|
result = request('/ticket/create', {
|
||||||
|
email: 'fromapi@testemail.com',
|
||||||
|
name: 'Random user',
|
||||||
|
title: 'created by api',
|
||||||
|
content: 'this ticket was created using anapi key while user system is disabled',
|
||||||
|
departmentId: 1,
|
||||||
|
language: 'en',
|
||||||
|
apiKey: api_key
|
||||||
|
})
|
||||||
|
(result['status']).should.equal('success')
|
||||||
|
end
|
||||||
|
|
||||||
it 'should not disable the user system if it is already disabled 'do
|
it 'should not disable the user system if it is already disabled 'do
|
||||||
request('/user/logout')
|
request('/user/logout')
|
||||||
Scripts.login($staff[:email], $staff[:password], true)
|
Scripts.login($staff[:email], $staff[:password], true)
|
||||||
@ -205,7 +220,7 @@ describe'system/disable-user-system' do
|
|||||||
|
|
||||||
numberOftickets= $database.query("SELECT * FROM ticket WHERE author_email IS NULL AND author_name IS NULL AND author_id IS NOT NULL" )
|
numberOftickets= $database.query("SELECT * FROM ticket WHERE author_email IS NULL AND author_name IS NULL AND author_id IS NOT NULL" )
|
||||||
|
|
||||||
(numberOftickets.num_rows).should.equal(53)
|
(numberOftickets.num_rows).should.equal(54)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should not enable the user system' do
|
it 'should not enable the user system' do
|
||||||
|
@ -3,11 +3,11 @@ describe'system/get-api-keys' do
|
|||||||
Scripts.login($staff[:email], $staff[:password], true)
|
Scripts.login($staff[:email], $staff[:password], true)
|
||||||
|
|
||||||
it 'should get all API keys' do
|
it 'should get all API keys' do
|
||||||
Scripts.createAPIKey('namekey1')
|
Scripts.createAPIKey('namekey1', 'REGISTRATION')
|
||||||
Scripts.createAPIKey('namekey2')
|
Scripts.createAPIKey('namekey2', 'REGISTRATION')
|
||||||
Scripts.createAPIKey('namekey3')
|
Scripts.createAPIKey('namekey3', 'REGISTRATION')
|
||||||
Scripts.createAPIKey('namekey4')
|
Scripts.createAPIKey('namekey4', 'REGISTRATION')
|
||||||
Scripts.createAPIKey('namekey5')
|
Scripts.createAPIKey('namekey5', 'REGISTRATION')
|
||||||
|
|
||||||
result = request('/system/get-api-keys', {
|
result = request('/system/get-api-keys', {
|
||||||
csrf_userid: $csrf_userid,
|
csrf_userid: $csrf_userid,
|
||||||
@ -22,5 +22,4 @@ describe'system/get-api-keys' do
|
|||||||
(result['data'][4]['name']).should.equal('namekey5')
|
(result['data'][4]['name']).should.equal('namekey5')
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user