Merge branch '355-api-security' into '2-6-0'
Improve API Security Closes #355 See merge request !13
This commit is contained in:
commit
514dae4c57
@ -32,7 +32,7 @@ $request_method = $_SERVER['REQUEST_METHOD'];
|
||||
* @apiSuccess {Integer} priority The ID of the priority the ticket is in
|
||||
* @apiSuccess {String} subject The subject of the ticket
|
||||
* @apiSuccess {String} message The original message of the ticket
|
||||
* @apiSuccess {String} dateCreated The date and time the ticket was submitted, in `YYYY-MM-DD hh:mm:ss`
|
||||
* @apiSuccess {Date} dateCreated The date and time the ticket was submitted
|
||||
* @apiSuccess {Integer} articles The knowledgebase article IDs suggested when the user created the ticket
|
||||
* @apiSuccess {String} ip The IP address of the submitter
|
||||
* @apiSuccess {String} language The language the ticket was submitted in
|
||||
@ -41,7 +41,6 @@ $request_method = $_SERVER['REQUEST_METHOD'];
|
||||
* @apiSuccess {String} timeWorked The total time worked on the ticket, in `hh:mm:ss`
|
||||
* @apiSuccess {Boolean} archive `true` if the ticket is tagged<br>`false` otherwise
|
||||
* @apiSuccess {Boolean} locked `true` if the ticket is locked<br>`false` otherwise
|
||||
* @apiSuccess {Binary[]} attachments Array of attachments, in base-64 encoded binary
|
||||
* @apiSuccess {Integer[]} merged Array of merged ticket IDs
|
||||
* @apiSuccess {String} legacyAuditTrail HTML markup of the entire "Audit Trail" section
|
||||
* @apiSuccess {String} custom1-20 Custom fields 1-20's values.
|
||||
@ -52,6 +51,8 @@ $request_method = $_SERVER['REQUEST_METHOD'];
|
||||
* @apiSuccess {String} userAgent The user agent of the user who submitted the ticket
|
||||
* @apiSuccess {Integer} screenResolutionWidth The width of the screen resolution of the user who submitted the ticket
|
||||
* @apiSuccess {Integer} screenResolutionHeight The height of the screen resolution of the user who submitted the ticket
|
||||
* @apiSuccess {Date} dueDate The ticket's due date, if there is one
|
||||
* @apiSuccess {Boolean} overdueEmailSent Set to `true` if an overdue email has been sent.<br>`false` otherwise
|
||||
*
|
||||
* @apiSuccessExample {json} Success-Response:
|
||||
* HTTP/1.1 200 OK
|
||||
@ -102,7 +103,9 @@ $request_method = $_SERVER['REQUEST_METHOD'];
|
||||
* "html": false,
|
||||
* "userAgent": null,
|
||||
* "screenResolutionWidth": null,
|
||||
* "screenResolutionHeight": null
|
||||
* "screenResolutionHeight": null,
|
||||
* "dueDate": "2016-01-01 00:00:00",
|
||||
* "overdueEmailSent": "true"
|
||||
* }
|
||||
*
|
||||
* @apiError (noTokenProvided) 400 No `X-Auth-Token` was provided where it is required
|
||||
@ -110,17 +113,18 @@ $request_method = $_SERVER['REQUEST_METHOD'];
|
||||
*/
|
||||
if ($request_method == 'GET') {
|
||||
$token = get_header('X-Auth-Token');
|
||||
$user = NULL;
|
||||
|
||||
try {
|
||||
get_user_for_token($token, $hesk_settings);
|
||||
$user = get_user_for_token($token, $hesk_settings);
|
||||
} catch (AccessException $e) {
|
||||
return http_response_code($e->getCode());
|
||||
}
|
||||
|
||||
if (isset($_GET['id'])) {
|
||||
$results = get_ticket_for_staff($hesk_settings, $_GET['id']);
|
||||
$results = get_ticket_for_staff($hesk_settings, $user, $_GET['id']);
|
||||
} else {
|
||||
$results = get_ticket_for_staff($hesk_settings);
|
||||
$results = get_ticket_for_staff($hesk_settings, $user);
|
||||
}
|
||||
|
||||
if ($results == NULL) {
|
||||
|
@ -20,7 +20,7 @@ $request_method = $_SERVER['REQUEST_METHOD'];
|
||||
* @apiVersion 0.0.0
|
||||
* @apiName GetUser
|
||||
* @apiGroup User
|
||||
* @apiPermission protected
|
||||
* @apiPermission canManUsers
|
||||
*
|
||||
* @apiParam {Number} [id] The ID of the user. Omit for all users.
|
||||
*
|
||||
@ -30,7 +30,6 @@ $request_method = $_SERVER['REQUEST_METHOD'];
|
||||
* @apiSuccess {String} name The user's name
|
||||
* @apiSuccess {String} email The user's email address
|
||||
* @apiSuccess {String} signature The user's signature, in plaintext
|
||||
* @apiSuccess {Unknown} language ??? (Unknown)
|
||||
* @apiSuccess {String[]} categories Ticket categories the user has access to. If the user is an admin, this list has one element: ""
|
||||
* @apiSuccess {Integer} afterReply Action to perform after replying to a ticket:<br>
|
||||
* `0` - Show the ticket I just replied to<br>
|
||||
@ -55,6 +54,11 @@ $request_method = $_SERVER['REQUEST_METHOD'];
|
||||
* @apiSuccess {String} rating The overall rating of the user, as a floating point decimal
|
||||
* @apiSuccess {Integer} autorefresh The ticket table autorefresh time for the user, in milliseconds
|
||||
* @apiSuccess {Boolean} active `true` if the user is active<br>`false` otherwise
|
||||
* @apiSuccess {Integer} defaultCalendarView The default view displayed on the calendar screen:<br>
|
||||
* `0` - Month<br>
|
||||
* `1` - Week<br>
|
||||
* `2` - Day<br>
|
||||
* @apiSuccess {Boolean} notifyOverdueUnassigned Notify user of overdue tickets assigned to others / not assigned
|
||||
*
|
||||
* @apiSuccessExample {json} Success-Response:
|
||||
* HTTP/1.1 200 OK
|
||||
@ -65,7 +69,6 @@ $request_method = $_SERVER['REQUEST_METHOD'];
|
||||
* "name": "Your name",
|
||||
* "email": "mkoch227@gmail.com",
|
||||
* "signature": "Sincerely,\r\n\r\nYour name\r\nYour website\r\nhttp://www.yourwebsite.com\r\n& < > ^ &",
|
||||
* "language": null,
|
||||
* "categories": [
|
||||
* ""
|
||||
* ],
|
||||
@ -91,21 +94,28 @@ $request_method = $_SERVER['REQUEST_METHOD'];
|
||||
* "ratingPos": 0,
|
||||
* "rating": "0",
|
||||
* "autorefresh": 0,
|
||||
* "active": true
|
||||
* "active": true,
|
||||
* "defaultCalendarView": 0,
|
||||
* "notifyOverdueUnassigned": true
|
||||
* }
|
||||
*
|
||||
* @apiError (noTokenProvided) 400 No `X-Auth-Token` was provided where it is required
|
||||
* @apiError (invalidXAuthToken) 401 The `X-Auth-Token` provided was invalid
|
||||
* @apiError (invalidXAuthToken) 401 The `X-Auth-Token` provided was invalid, or the user does not have the 'can_man_users' permission
|
||||
*/
|
||||
if ($request_method == 'GET') {
|
||||
$token = get_header('X-Auth-Token');
|
||||
$user = NULL;
|
||||
|
||||
try {
|
||||
get_user_for_token($token, $hesk_settings);
|
||||
$user = get_user_for_token($token, $hesk_settings);
|
||||
} catch (AccessException $e) {
|
||||
return http_response_code($e->getCode());
|
||||
}
|
||||
|
||||
if (!$user['isadmin'] && strpos($user['heskprivileges'], 'can_man_users') === false) {
|
||||
return http_response_code(401);
|
||||
}
|
||||
|
||||
if (isset($_GET['id'])) {
|
||||
$results = retrieve_user($hesk_settings, $_GET['id']);
|
||||
} else {
|
||||
|
@ -1,8 +1,12 @@
|
||||
<?php
|
||||
require_once(API_PATH . 'dao/ticket_dao.php');
|
||||
|
||||
function get_ticket_for_staff($hesk_settings, $id = NULL) {
|
||||
$tickets = get_ticket_for_id($hesk_settings, $id);
|
||||
function get_ticket_for_staff($hesk_settings, $user, $id = NULL) {
|
||||
$tickets = get_ticket_for_id($hesk_settings, $user, $id);
|
||||
|
||||
if ($tickets == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ($id === NULL) {
|
||||
$original_tickets = $tickets;
|
||||
@ -10,10 +14,12 @@ function get_ticket_for_staff($hesk_settings, $id = NULL) {
|
||||
foreach ($original_tickets as $ticket) {
|
||||
$ticket = remove_common_properties($ticket);
|
||||
$ticket = convert_to_camel_case($ticket);
|
||||
$ticket = handle_dates($ticket);
|
||||
$tickets[] = $ticket;
|
||||
}
|
||||
} else {
|
||||
$tickets = remove_common_properties($tickets);
|
||||
$tickets = handle_dates($tickets);
|
||||
$tickets = convert_to_camel_case($tickets);
|
||||
}
|
||||
|
||||
@ -36,27 +42,37 @@ function remove_common_properties($ticket) {
|
||||
return $ticket;
|
||||
}
|
||||
|
||||
function handle_dates($ticket) {
|
||||
$ticket['dt'] = hesk_date($ticket['dt'], true);
|
||||
|
||||
return $ticket;
|
||||
}
|
||||
|
||||
function convert_to_camel_case($ticket) {
|
||||
if (isset($ticket['articles'])) {
|
||||
$ticket['suggestedArticles'] = $ticket['articles'];
|
||||
unset($ticket['articles']);
|
||||
$ticket['legacyAuditTrail'] = $ticket['history'];
|
||||
unset($ticket['history']);
|
||||
$ticket['linkedTo'] = $ticket['parent'];
|
||||
unset($ticket['parent']);
|
||||
$ticket['timeWorked'] = $ticket['time_worked'];
|
||||
unset($ticket['time_worked']);
|
||||
$ticket['userAgent'] = $ticket['user_agent'];
|
||||
unset($ticket['user_agent']);
|
||||
$ticket['screenResolutionWidth'] = $ticket['screen_resolution_width'];
|
||||
unset($ticket['screen_resolution_width']);
|
||||
$ticket['screenResolutionHeight'] = $ticket['screen_resolution_height'];
|
||||
unset($ticket['screen_resolution_height']);
|
||||
}
|
||||
$ticket['legacyAuditTrail'] = $ticket['history'];
|
||||
unset($ticket['history']);
|
||||
$ticket['linkedTo'] = $ticket['parent'];
|
||||
unset($ticket['parent']);
|
||||
$ticket['timeWorked'] = $ticket['time_worked'];
|
||||
unset($ticket['time_worked']);
|
||||
$ticket['userAgent'] = $ticket['user_agent'];
|
||||
unset($ticket['user_agent']);
|
||||
$ticket['screenResolutionWidth'] = $ticket['screen_resolution_width'];
|
||||
unset($ticket['screen_resolution_width']);
|
||||
$ticket['screenResolutionHeight'] = $ticket['screen_resolution_height'];
|
||||
unset($ticket['screen_resolution_height']);
|
||||
$ticket['trackingId'] = $ticket['trackid'];
|
||||
unset($ticket['trackid']);
|
||||
$ticket['dateCreated'] = $ticket['dt'];
|
||||
unset($ticket['dt']);
|
||||
$ticket['dueDate'] = $ticket['due_date'];
|
||||
unset($ticket['due_date']);
|
||||
$ticket['overdueEmailSent'] = $ticket['overdue_email_sent'];
|
||||
|
||||
|
||||
return $ticket;
|
||||
}
|
||||
@ -83,6 +99,8 @@ function remove_staff_specific_properties($ticket) {
|
||||
unset($ticket['screen_resolution_width']);
|
||||
unset($ticket['screen_resolution_height']);
|
||||
unset($ticket['parent']);
|
||||
unset($ticket['due_date']);
|
||||
unset($ticket['overdue_email_sent']);
|
||||
|
||||
return $ticket;
|
||||
}
|
@ -68,6 +68,10 @@ function convert_to_camel_case($user) {
|
||||
unset($user['ratingpos']);
|
||||
$user['heskPrivileges'] = $user['heskprivileges'];
|
||||
unset($user['heskprivileges']);
|
||||
$user['defaultCalendarView'] = $user['default_calendar_view'];
|
||||
unset($user['default_calendar_view']);
|
||||
$user['notifyOverdueUnassigned'] = $user['notify_overdue_unassigned'];
|
||||
unset($user['notify_overdue_unassigned']);
|
||||
|
||||
return $user;
|
||||
}
|
@ -5,8 +5,8 @@
|
||||
*
|
||||
*/
|
||||
/**
|
||||
* @apiDefine protected Protected
|
||||
* A protected API can only be utilized by those with a valid `X-Auth-Token`.
|
||||
* @apiDefine protected Protected (Any)
|
||||
* A protected API can only be utilized by any user with a valid `X-Auth-Token`.
|
||||
*/
|
||||
/**
|
||||
* @apiDefine invalidXAuthToken 401 Unauthorized
|
||||
@ -15,4 +15,7 @@
|
||||
/**
|
||||
* @apiDefine noTokenProvided 400 Bad Request
|
||||
* No `X-Auth-Token` was provided.
|
||||
*
|
||||
* @apiDefine canManUsers Protected (Can Manage Users)
|
||||
* A protected API can only be utilized by users with a valid `X-Auth-Token` and have the 'can_man_users' permission (or is an admin)
|
||||
*/
|
@ -1,9 +1,22 @@
|
||||
<?php
|
||||
|
||||
function get_ticket_for_id($hesk_settings, $id = NULL) {
|
||||
$sql = "SELECT * FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` ";
|
||||
function get_ticket_for_id($hesk_settings, $user, $id = NULL) {
|
||||
$sql = "SELECT `tickets`.* FROM `" . hesk_dbEscape($hesk_settings['db_pfix']) . "tickets` AS `tickets` ";
|
||||
$sql .= "INNER JOIN `" . hesk_dbEscape($hesk_settings['db_pfix']) . "users` AS `users` ON `users`.`id` = " . intval($user['id']) . " ";
|
||||
$used_where_clause = false;
|
||||
if ($id != NULL) {
|
||||
$sql .= "WHERE `id` = ".intval($id);
|
||||
$used_where_clause = true;
|
||||
$sql .= "WHERE `tickets`.`id` = " . intval($id);
|
||||
}
|
||||
|
||||
if (!$user['isadmin']) {
|
||||
$clause = $used_where_clause ? ' AND ' : ' WHERE ';
|
||||
$used_where_clause = true;
|
||||
|
||||
$sql .= $clause . ' `category` IN (' . $user['categories'] . ')';
|
||||
$sql .= " AND ((`heskprivileges` LIKE '%can_view_tickets%' AND `owner` = " . intval($user['id']) . ")";
|
||||
$sql .= " OR (`heskprivileges` LIKE '%can_view_unassigned%' AND `owner` = 0)";
|
||||
$sql .= " OR (`heskprivileges` LIKE '%can_view_ass_others%' AND `owner` <> " . intval($user['id']) . "))";
|
||||
}
|
||||
|
||||
$response = hesk_dbQuery($sql);
|
||||
@ -32,6 +45,7 @@ function build_results($response) {
|
||||
$row['screen_resolution_width'] = convert_to_int($row['screen_resolution_width']);
|
||||
$row['owner'] = convert_to_int($row['owner']);
|
||||
$row['parent'] = convert_to_int($row['parent']);
|
||||
$row['overdue_email_sent'] = $row['overdue_email_sent'] == true;
|
||||
|
||||
|
||||
$results[] = $row;
|
||||
|
@ -36,6 +36,8 @@ function get_user($hesk_settings, $id = NULL) {
|
||||
$row['ratingpos'] = intval($row['ratingpos']);
|
||||
$row['autorefresh'] = intval($row['autorefresh']);
|
||||
$row['active'] = get_boolean($row['active']);
|
||||
$row['default_calendar_view'] = intval($row['default_calendar_view']);
|
||||
$row['notify_overdue_unassigned'] = get_boolean($row['notify_overdue_unassigned']);
|
||||
|
||||
|
||||
// TODO: Remove this once GitHub #346 is complete
|
||||
|
@ -78,7 +78,7 @@ $request_method = $_SERVER['REQUEST_METHOD'];
|
||||
* "custom18": "",
|
||||
* "custom19": "",
|
||||
* "custom20": "",
|
||||
* "html": false,
|
||||
* "html": false
|
||||
* }
|
||||
*
|
||||
* @apiError (noTokenProvided) 400 No `X-Auth-Token` was provided where it is required
|
||||
|
@ -4,15 +4,23 @@ define('HESK_PATH', '../../../');
|
||||
define('INTERNAL_API_PATH', '../../');
|
||||
require_once(HESK_PATH . 'hesk_settings.inc.php');
|
||||
require_once(HESK_PATH . 'inc/common.inc.php');
|
||||
require_once(HESK_PATH . 'inc/admin_functions.inc.php');
|
||||
require_once(INTERNAL_API_PATH . 'core/output.php');
|
||||
require_once(INTERNAL_API_PATH . 'dao/api_authentication_dao.php');
|
||||
|
||||
hesk_session_start();
|
||||
hesk_load_internal_api_database_functions();
|
||||
hesk_dbConnect();
|
||||
|
||||
// Routing
|
||||
$request_method = $_SERVER['REQUEST_METHOD'];
|
||||
if ($request_method == 'POST') {
|
||||
|
||||
if (!isset($_SESSION['heskprivileges']) || !hesk_checkPermission('can_man_settings', 0)) {
|
||||
print_error('Access Denied', 'Access Denied!');
|
||||
return http_response_code(401);
|
||||
}
|
||||
|
||||
$user_id = $_POST['userId'];
|
||||
$action = $_POST['action'];
|
||||
|
||||
|
@ -4,12 +4,19 @@ define('HESK_PATH', '../../../');
|
||||
define('INTERNAL_API_PATH', '../../');
|
||||
require_once(HESK_PATH . 'hesk_settings.inc.php');
|
||||
require_once(HESK_PATH . 'inc/common.inc.php');
|
||||
require_once(HESK_PATH . 'inc/admin_functions.inc.php');
|
||||
require_once(INTERNAL_API_PATH . 'core/output.php');
|
||||
require_once(INTERNAL_API_PATH . 'dao/settings_dao.php');
|
||||
|
||||
hesk_session_start();
|
||||
hesk_load_internal_api_database_functions();
|
||||
hesk_dbConnect();
|
||||
|
||||
if (!isset($_SESSION['heskprivileges']) || !hesk_checkPermission('can_man_settings', 0)) {
|
||||
print_error('Access Denied', 'Access Denied!');
|
||||
return http_response_code(401);
|
||||
}
|
||||
|
||||
// Routing
|
||||
$request_method = $_SERVER['REQUEST_METHOD'];
|
||||
if ($request_method == 'POST') {
|
||||
|
@ -24,6 +24,11 @@ if ($request_method === 'GET') {
|
||||
|
||||
return output($events);
|
||||
} elseif ($request_method === 'POST') {
|
||||
if ($request_method !== 'update-ticket' && !hesk_checkPermission('can_man_calendar', 0)) {
|
||||
print_error('Access Denied', 'Access Denied!');
|
||||
return http_response_code(401);
|
||||
}
|
||||
|
||||
$action = hesk_POST('action');
|
||||
|
||||
if ($action === 'create') {
|
||||
|
Loading…
x
Reference in New Issue
Block a user