Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,15 @@ The present file will list all changes made to the project; according to the
## [11.0.2] unreleased

### Added
- `uuid`, `user_tech`, `group_tech`, `date`, `date_creation`, `date_mod`, `planned_begin`, `planned_end`, `timeline_position`, `source_item_id`, and `source_of_item_id` properties for the applicable Ticket, Change and Problem Task schemas in the High-Level API v2.1.
- `date`, `timeline_position`, `source_item_id`, and `source_of_item_id` properties for the Followup schema in the High-Level API v2.1.
- `approver`, `approval_followup`, `date_creation`, `date_mod`, and `date_approval` properties for the Solution schema in the High-Level API v2.1.
- `timeline_position` property for the TicketValidation, ChangeValidation and Document_Item schemas in the High-Level API v2.1.
- `date_solve`, `date_close`, and `global_validation` properties for the applicable Ticket, Change and Problem schemas in the High-Level API v2.1.

### Changed
- Added High-Level API version 2.1. Make sure you are pinning your requests to a specific version (Ex: `/api.php/v2.0`) if needed to exclude endpoints/properties added in later versions. See version pinning in the getting started documentation `/api.php/getting-started`.
- High-Level API responses for not found routes now correctly return a body including the standard error properties (status, title, detail). This is not controlled by the API version.

### Deprecated

Expand Down
7 changes: 4 additions & 3 deletions src/Glpi/Api/HL/Controller/CoreController.php
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@ public function showDocumentation(Request $request): Response
$swagger_content .= Html::script('/lib/swagger-ui.js');
$swagger_content .= Html::css('/lib/swagger-ui.css');
$favicon = Html::getPrefixedUrl('/pics/favicon.ico');
$doc_json_path = $CFG_GLPI['root_doc'] . '/api.php/doc.json';
$api_version = $this->getAPIVersion($request);
$doc_json_path = $CFG_GLPI['root_doc'] . '/api.php/v' . $api_version . '/doc.json';
$swagger_content .= <<<HTML
<link rel="shortcut icon" type="images/x-icon" href="$favicon" />
</head>
Expand Down Expand Up @@ -285,7 +286,7 @@ private function getAllowedMethodsForMatchedRoute(Request $request): array
)]
public function defaultRoute(Request $request): Response
{
return new JSONResponse(null, 404);
return self::getNotFoundErrorResponse();
}

#[Route(path: '/{req}', methods: ['OPTIONS'], requirements: ['req' => '.*'], priority: -1, security_level: Route::SECURITY_NONE)]
Expand All @@ -299,7 +300,7 @@ public function defaultOptionsRoute(Request $request): Response
$authenticated = Session::getLoginUserID() !== false;
$allowed_methods = $authenticated ? $this->getAllowedMethodsForMatchedRoute($request) : ['GET', 'POST', 'PATCH', 'PUT', "DELETE"];
if (count($allowed_methods) === 0) {
return new JSONResponse(null, 404);
return self::getNotFoundErrorResponse();
}
$response_headers = [];
if ($authenticated) {
Expand Down
183 changes: 183 additions & 0 deletions src/Glpi/Api/HL/Controller/ITILController.php
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ public static function getRawKnownSchemas(): array
],
'name' => ['type' => Doc\Schema::TYPE_STRING],
'content' => ['type' => Doc\Schema::TYPE_STRING],
'user_recipient' => self::getDropdownTypeSchema(class: User::class, field: 'users_id_recipient', full_schema: 'User') + ['x-version-introduced' => '2.1.0'],
'user_editor' => self::getDropdownTypeSchema(class: User::class, field: 'users_id_lastupdater', full_schema: 'User') + ['x-version-introduced' => '2.1.0'],
'is_deleted' => ['type' => Doc\Schema::TYPE_BOOLEAN],
'category' => self::getDropdownTypeSchema(class: ITILCategory::class, full_schema: 'ITILCategory'),
'location' => self::getDropdownTypeSchema(class: Location::class, full_schema: 'Location'),
Expand All @@ -203,6 +205,18 @@ public static function getRawKnownSchemas(): array
'date_creation' => ['type' => Doc\Schema::TYPE_STRING, 'format' => Doc\Schema::FORMAT_STRING_DATE_TIME],
'date_mod' => ['type' => Doc\Schema::TYPE_STRING, 'format' => Doc\Schema::FORMAT_STRING_DATE_TIME],
'date' => ['type' => Doc\Schema::TYPE_STRING, 'format' => Doc\Schema::FORMAT_STRING_DATE_TIME],
'date_solve' => [
'x-version-introduced' => '2.1.0',
'type' => Doc\Schema::TYPE_STRING,
'format' => Doc\Schema::FORMAT_STRING_DATE_TIME,
'x-field' => 'solvedate',
],
'date_close' => [
'x-version-introduced' => '2.1.0',
'type' => Doc\Schema::TYPE_STRING,
'format' => Doc\Schema::FORMAT_STRING_DATE_TIME,
'x-field' => 'closedate',
],
],
];

Expand Down Expand Up @@ -375,6 +389,25 @@ public static function getRawKnownSchemas(): array
];
$schemas[$itil_type]['properties']['request_type'] = self::getDropdownTypeSchema(class: RequestType::class, full_schema: 'RequestType');
}
if ($itil_type === Ticket::class || $itil_type === Change::class) {
$schemas[$itil_type]['properties']['global_validation'] = [
'x-version-introduced' => '2.1.0',
'type' => Doc\Schema::TYPE_INTEGER,
'enum' => [
CommonITILValidation::NONE,
CommonITILValidation::WAITING,
CommonITILValidation::ACCEPTED,
CommonITILValidation::REFUSED,
],
'description' => <<<EOT
The global status of the validation.
- 1: None
- 2: Waiting
- 3: Accepted
- 4: Refused
EOT,
];
}
$schemas[$itil_type]['x-itemtype'] = $itil_type;
$status_description = '';
foreach ($itil_type::getAllStatusArray() as $status => $status_name) {
Expand Down Expand Up @@ -421,6 +454,24 @@ public static function getRawKnownSchemas(): array
];
}

$timeline_position_enum = [
CommonITILObject::NO_TIMELINE,
CommonITILObject::TIMELINE_NOTSET,
CommonITILObject::TIMELINE_LEFT,
CommonITILObject::TIMELINE_MIDLEFT,
CommonITILObject::TIMELINE_MIDRIGHT,
CommonITILObject::TIMELINE_RIGHT,
];
$timeline_position_description = <<<EOT
The position in the timeline.
- 0: No timeline
- 1: Not set
- 2: Left
- 3: Mid left
- 4: Mid right
- 5: Right
EOT;

$base_task_schema = [
'type' => Doc\Schema::TYPE_OBJECT,
'x-rights-conditions' => [ // Object-level extra permissions
Expand All @@ -444,11 +495,46 @@ public static function getRawKnownSchemas(): array
'format' => Doc\Schema::FORMAT_INTEGER_INT64,
'readOnly' => true,
],
'uuid' => [
'x-version-introduced' => '2.1.0',
'type' => Doc\Schema::TYPE_STRING,
'format' => Doc\Schema::PATTERN_UUIDV4,
'readOnly' => true,
],
'content' => ['type' => Doc\Schema::TYPE_STRING],
'is_private' => ['type' => Doc\Schema::TYPE_BOOLEAN],
'user' => self::getDropdownTypeSchema(class: User::class, full_schema: 'User'),
'user_editor' => self::getDropdownTypeSchema(class: User::class, field: 'users_id_editor', full_schema: 'User'),
'user_tech' => self::getDropdownTypeSchema(class: User::class, field: 'users_id_tech', full_schema: 'User') + ['x-version-introduced' => '2.1.0'],
'group_tech' => self::getDropdownTypeSchema(class: Group::class, field: 'groups_id_tech', full_schema: 'Group') + ['x-version-introduced' => '2.1.0'],
'date' => [
'x-version-introduced' => '2.1.0',
'type' => Doc\Schema::TYPE_STRING,
'format' => Doc\Schema::FORMAT_STRING_DATE_TIME,
],
'date_creation' => [
'x-version-introduced' => '2.1.0',
'type' => Doc\Schema::TYPE_STRING,
'format' => Doc\Schema::FORMAT_STRING_DATE_TIME,
],
'date_mod' => [
'x-version-introduced' => '2.1.0',
'type' => Doc\Schema::TYPE_STRING,
'format' => Doc\Schema::FORMAT_STRING_DATE_TIME,
],
'duration' => ['type' => Doc\Schema::TYPE_INTEGER, 'x-field' => 'actiontime'],
'planned_begin' => [
'x-version-introduced' => '2.1.0',
'type' => Doc\Schema::TYPE_STRING,
'format' => Doc\Schema::FORMAT_STRING_DATE_TIME,
'x-field' => 'begin',
],
'planned_end' => [
'x-version-introduced' => '2.1.0',
'type' => Doc\Schema::TYPE_STRING,
'format' => Doc\Schema::FORMAT_STRING_DATE_TIME,
'x-field' => 'end',
],
'state' => [
'type' => Doc\Schema::TYPE_INTEGER,
'enum' => [
Expand All @@ -464,13 +550,31 @@ public static function getRawKnownSchemas(): array
EOT,
],
'category' => self::getDropdownTypeSchema(class: TaskCategory::class, full_schema: 'TaskCategory'),
'timeline_position' => [
'x-version-introduced' => '2.1.0',
'type' => Doc\Schema::TYPE_NUMBER,
'enum' => $timeline_position_enum,
'description' => $timeline_position_description,
],
],
];

$schemas['TicketTask'] = $base_task_schema;
$schemas['TicketTask']['x-version-introduced'] = '2.0';
$schemas['TicketTask']['x-itemtype'] = TicketTask::class;
$schemas['TicketTask']['properties'][Ticket::getForeignKeyField()] = ['type' => Doc\Schema::TYPE_INTEGER, 'format' => Doc\Schema::FORMAT_INTEGER_INT64];
$schemas['TicketTask']['properties']['source_item_id'] = [
'x-version-introduced' => '2.1.0',
'type' => Doc\Schema::TYPE_INTEGER,
'format' => Doc\Schema::FORMAT_INTEGER_INT64,
'x-field' => 'sourceitems_id',
];
$schemas['TicketTask']['properties']['source_of_item_id'] = [
'x-version-introduced' => '2.1.0',
'type' => Doc\Schema::TYPE_INTEGER,
'format' => Doc\Schema::FORMAT_INTEGER_INT64,
'x-field' => 'sourceof_items_id',
];

$schemas['ChangeTask'] = $base_task_schema;
$schemas['ChangeTask']['x-version-introduced'] = '2.0';
Expand Down Expand Up @@ -559,8 +663,31 @@ public static function getRawKnownSchemas(): array
'user' => self::getDropdownTypeSchema(class: User::class, full_schema: 'User'),
'user_editor' => self::getDropdownTypeSchema(class: User::class, field: 'users_id_editor', full_schema: 'User'),
'request_type' => self::getDropdownTypeSchema(RequestType::class, full_schema: 'RequestType'),
'date' => [
'x-version-introduced' => '2.1.0',
'type' => Doc\Schema::TYPE_STRING,
'format' => Doc\Schema::FORMAT_STRING_DATE_TIME,
],
'date_creation' => ['type' => Doc\Schema::TYPE_STRING, 'format' => Doc\Schema::FORMAT_STRING_DATE_TIME],
'date_mod' => ['type' => Doc\Schema::TYPE_STRING, 'format' => Doc\Schema::FORMAT_STRING_DATE_TIME],
'timeline_position' => [
'x-version-introduced' => '2.1.0',
'type' => Doc\Schema::TYPE_NUMBER,
'enum' => $timeline_position_enum,
'description' => $timeline_position_description,
],
'source_item_id' => [
'x-version-introduced' => '2.1.0',
'type' => Doc\Schema::TYPE_INTEGER,
'format' => Doc\Schema::FORMAT_INTEGER_INT64,
'x-field' => 'sourceitems_id',
],
'source_of_item_id' => [
'x-version-introduced' => '2.1.0',
'type' => Doc\Schema::TYPE_INTEGER,
'format' => Doc\Schema::FORMAT_INTEGER_INT64,
'x-field' => 'sourceof_items_id',
],
],
];

Expand All @@ -579,6 +706,56 @@ public static function getRawKnownSchemas(): array
'content' => ['type' => Doc\Schema::TYPE_STRING],
'user' => self::getDropdownTypeSchema(class: User::class, full_schema: 'User'),
'user_editor' => self::getDropdownTypeSchema(class: User::class, field: 'users_id_editor', full_schema: 'User'),
'approver' => self::getDropdownTypeSchema(class: User::class, field: 'users_id_approval', full_schema: 'User') + ['x-version-introduced' => '2.1.0'],
'status' => [
'type' => Doc\Schema::TYPE_INTEGER,
'enum' => [
CommonITILValidation::NONE,
CommonITILValidation::WAITING,
CommonITILValidation::ACCEPTED,
CommonITILValidation::REFUSED,
],
'description' => <<<EOT
The status of the solution.
- 1: None
- 2: Waiting
- 3: Accepted
- 4: Refused
EOT,
],
'approval_followup' => [
'x-version-introduced' => '2.1.0',
'type' => Doc\Schema::TYPE_OBJECT,
'x-field' => ITILFollowup::getForeignKeyField(),
'x-itemtype' => ITILFollowup::class,
'x-join' => [
'table' => ITILFollowup::getTable(),
'fkey' => ITILFollowup::getForeignKeyField(),
'field' => 'id',
],
'properties' => [
'id' => [
'type' => Doc\Schema::TYPE_INTEGER,
'format' => Doc\Schema::FORMAT_INTEGER_INT64,
'readOnly' => true,
],
],
],
'date_creation' => [
'x-version-introduced' => '2.1.0',
'type' => Doc\Schema::TYPE_STRING,
'format' => Doc\Schema::FORMAT_STRING_DATE_TIME,
],
'date_mod' => [
'x-version-introduced' => '2.1.0',
'type' => Doc\Schema::TYPE_STRING,
'format' => Doc\Schema::FORMAT_STRING_DATE_TIME,
],
'date_approval' => [
'x-version-introduced' => '2.1.0',
'type' => Doc\Schema::TYPE_STRING,
'format' => Doc\Schema::FORMAT_STRING_DATE_TIME,
],
],
];

Expand Down Expand Up @@ -625,6 +802,12 @@ public static function getRawKnownSchemas(): array
],
'submission_date' => ['type' => Doc\Schema::TYPE_STRING, 'format' => Doc\Schema::FORMAT_STRING_DATE_TIME],
'approval_date' => ['type' => Doc\Schema::TYPE_STRING, 'format' => Doc\Schema::FORMAT_STRING_DATE_TIME, 'x-field' => 'validation_date'],
'timeline_position' => [
'x-version-introduced' => '2.1.0',
'type' => Doc\Schema::TYPE_NUMBER,
'enum' => $timeline_position_enum,
'description' => $timeline_position_description,
],
],
];

Expand Down
22 changes: 22 additions & 0 deletions src/Glpi/Api/HL/Controller/ManagementController.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
use BusinessCriticity;
use Cluster;
use CommonDBTM;
use CommonITILObject;
use Contact;
use Contract;
use Database;
Expand Down Expand Up @@ -366,6 +367,27 @@ protected static function getRawKnownSchemas(): array
'x-mapped-from' => 'documents_id',
'x-mapper' => static fn($v) => $CFG_GLPI["root_doc"] . "/front/document.send.php?docid=" . $v,
],
'timeline_position' => [
'x-version-introduced' => '2.1.0',
'type' => Doc\Schema::TYPE_NUMBER,
'enum' => [
CommonITILObject::NO_TIMELINE,
CommonITILObject::TIMELINE_NOTSET,
CommonITILObject::TIMELINE_LEFT,
CommonITILObject::TIMELINE_MIDLEFT,
CommonITILObject::TIMELINE_MIDRIGHT,
CommonITILObject::TIMELINE_RIGHT,
],
'description' => <<<EOT
The position in the timeline.
- 0: No timeline
- 1: Not set
- 2: Left
- 3: Mid left
- 4: Mid right
- 5: Right
EOT,
],
],
];

Expand Down
2 changes: 2 additions & 0 deletions src/Glpi/Api/HL/Doc/Schema.php
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,8 @@ public static function filterSchemaByAPIVersion(array $schema, string $api_versi
'removed' => $schema['x-version-removed'] ?? null,
];

$api_version = Router::normalizeAPIVersion($api_version);

// Check if the schema itself is applicable to the requested version
// If the requested version is before the introduction of the schema, or after the removal of the schema, it is not applicable
// Deprecation has no effect here
Expand Down
Loading