From c1ce2ad39f7134284352c8ef17adef180d514e1e Mon Sep 17 00:00:00 2001 From: Curtis Conard Date: Thu, 22 Dec 2022 06:08:05 -0500 Subject: [PATCH 1/6] HL API integration --- hook.php | 49 +++++++++++++ inc/apicontroller.class.php | 141 ++++++++++++++++++++++++++++++++++++ setup.php | 7 +- 3 files changed, 196 insertions(+), 1 deletion(-) create mode 100644 inc/apicontroller.class.php diff --git a/hook.php b/hook.php index ec9c091..6e30016 100644 --- a/hook.php +++ b/hook.php @@ -28,6 +28,8 @@ * ------------------------------------------------------------------------- */ +use Glpi\Api\HL\Doc as Doc; + // Plugin hook after *Uninstall* function plugin_uninstall_after_tag($item) { $tagitem = new PluginTagTagItem(); @@ -276,3 +278,50 @@ function plugin_tag_getRuleActions($params = []) return $actions; } + +function plugin_tag_redefine_api_schemas(array $data): array { + foreach ($data['schemas'] as &$schema) { + if (!isset($schema['x-itemtype'])) { + continue; + } + if (PluginTagTag::canItemtype($schema['x-itemtype'])) { + $schema['properties']['tags'] = [ + 'type' => Doc\Schema::TYPE_ARRAY, + 'description' => 'Tags', + 'items' => [ + 'type' => Doc\Schema::TYPE_OBJECT, + 'x-join' => [ + // This is the join with the desired data + 'table' => PluginTagTag::getTable(), + 'fkey' => 'plugin_tag_tags_id', + 'field' => 'id', + 'ref_join' => [ + // This is the linking join between the main item and the data needed + 'table' => PluginTagTagItem::getTable(), + 'fkey' => 'id', + 'field' => 'items_id', + 'condition' => [ + 'itemtype' => $schema['x-itemtype'] + ], + ] + ], + 'properties' => [ + 'id' => [ + 'type' => Doc\Schema::TYPE_INTEGER, + 'description' => 'ID', + ], + 'name' => [ + 'type' => Doc\Schema::TYPE_STRING, + 'description' => 'Name', + ], + 'comment' => [ + 'type' => Doc\Schema::TYPE_STRING, + 'description' => 'Comment', + ], + ] + ] + ]; + } + } + return $data; +} diff --git a/inc/apicontroller.class.php b/inc/apicontroller.class.php new file mode 100644 index 0000000..dc1a03e --- /dev/null +++ b/inc/apicontroller.class.php @@ -0,0 +1,141 @@ +. + * ------------------------------------------------------------------------- + * @copyright Copyright (C) 2014-2022 by Teclib'. + * @license GPLv2 https://www.gnu.org/licenses/gpl-2.0.html + * @link https://github.com/pluginsGLPI/tag + * ------------------------------------------------------------------------- + */ + +use Glpi\Api\HL\Controller\AbstractController; +use Glpi\Api\HL\Doc as Doc; +use Glpi\Api\HL\Route; +use Glpi\Http\Request; +use Glpi\Http\Response; + +#[Route(path: '/Tag', priority: 1, tags: ['Tag'])] +final class PluginTagApicontroller extends AbstractController +{ + protected static function getRawKnownSchemas(): array + { + return [ + 'Tag' => [ + 'type' => Doc\Schema::TYPE_OBJECT, + 'x-itemtype' => PluginTagTag::class, + 'properties' => [ + 'id' => [ + 'type' => Doc\Schema::TYPE_INTEGER, + 'format' => Doc\Schema::FORMAT_INTEGER_INT64, + 'x-readonly' => true, + ], + 'name' => ['type' => Doc\Schema::TYPE_STRING], + 'comment' => ['type' => Doc\Schema::TYPE_STRING], + ] + ] + ]; + } + + #[Route(path: '/', methods: ['GET'])] + #[Doc\Route( + description: 'List or search tags' + )] + public function getTags(Request $request): Response + { + return $this->searchBySchema($this->getKnownSchema('Tag'), $request->getParameters()); + } + + #[Route(path: '/{id}', methods: ['GET'], requirements: ['id' => '\d+'])] + #[Doc\Route( + description: 'Get a tag by ID', + parameters: [ + [ + 'name' => 'id', + 'description' => 'The ID of the tag', + 'location' => Doc\Parameter::LOCATION_PATH, + 'schema' => ['type' => Doc\Schema::TYPE_INTEGER] + ] + ] + )] + public function getTag(Request $request, int $id): Response + { + return $this->getOneBySchema($this->getKnownSchema('Tag'), $request->getAttributes(), $request->getParameters(), $id); + } + + #[Route(path: '/', methods: ['POST'])] + #[Doc\Route(description: 'Create a new tag', parameters: [ + [ + 'name' => '_', + 'location' => Doc\Parameter::LOCATION_BODY, + 'type' => Doc\Schema::TYPE_OBJECT, + 'schema' => 'Tag', + ] + ])] + public function createTag(Request $request): Response + { + return $this->createBySchema($this->getKnownSchema('Tag'), $request->getParameters(), 'getTag'); + } + + #[Route(path: '/{id}', methods: ['PATCH'], requirements: ['id' => '\d+'])] + #[Doc\Route( + description: 'Update a tag by ID', + parameters: [ + [ + 'name' => 'id', + 'description' => 'The ID of the tag', + 'location' => Doc\Parameter::LOCATION_PATH, + 'schema' => ['type' => Doc\Schema::TYPE_INTEGER] + ], + [ + 'name' => '_', + 'location' => Doc\Parameter::LOCATION_BODY, + 'type' => Doc\Schema::TYPE_OBJECT, + 'schema' => 'Tag', + ] + ], + responses: [ + ['schema' => 'Tag'] + ] + )] + public function updateTag(Request $request, int $id): Response + { + return $this->updateBySchema($this->getKnownSchema('Tag'), $request->getAttributes(), $request->getParameters(), $id); + } + + #[Route(path: '/{id}', methods: ['DELETE'], requirements: ['id' => '\d+'])] + #[Doc\Route( + description: 'Delete a tag by ID', + parameters: [ + [ + 'name' => 'id', + 'description' => 'The ID of the tag', + 'location' => Doc\Parameter::LOCATION_PATH, + 'schema' => ['type' => Doc\Schema::TYPE_INTEGER] + ] + ] + )] + public function deleteTag(Request $request, int $id): Response + { + return $this->deleteBySchema($this->getKnownSchema('Tag'), $request->getAttributes(), $request->getParameters(), $id); + } +} diff --git a/setup.php b/setup.php index 21bf9d1..79479a8 100644 --- a/setup.php +++ b/setup.php @@ -35,7 +35,7 @@ // Minimal GLPI version, inclusive define("PLUGIN_TAG_MIN_GLPI", "10.0.0"); // Maximum GLPI version, exclusive -define("PLUGIN_TAG_MAX_GLPI", "10.0.99"); +define("PLUGIN_TAG_MAX_GLPI", "10.1.99"); /** * Init hooks of the plugin. @@ -135,6 +135,11 @@ function plugin_init_tag() { $PLUGIN_HOOKS['add_javascript']['tag'][] = 'js/entity.js'; } + $PLUGIN_HOOKS[Hooks::REDEFINE_API_SCHEMAS]['tag'] = 'plugin_tag_redefine_api_schemas'; + $PLUGIN_HOOKS[Hooks::API_CONTROLLERS]['tag'] = [ + PluginTagApicontroller::class + ]; + Plugin::registerClass('PluginTagProfile', ['addtabon' => ['Profile']]); Plugin::registerClass('PluginTagConfig', ['addtabon' => 'Config']); From 3df5bc44fbf3f2ae694ff652d747963294559eef Mon Sep 17 00:00:00 2001 From: Curtis Conard Date: Wed, 28 Jun 2023 11:04:40 -0400 Subject: [PATCH 2/6] add comments --- hook.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/hook.php b/hook.php index 6e30016..d5d311b 100644 --- a/hook.php +++ b/hook.php @@ -298,8 +298,9 @@ function plugin_tag_redefine_api_schemas(array $data): array { 'ref_join' => [ // This is the linking join between the main item and the data needed 'table' => PluginTagTagItem::getTable(), - 'fkey' => 'id', - 'field' => 'items_id', + 'fkey' => 'id', // ID field on the main join table + 'field' => 'items_id', // items_id field on the linking join table + // Join params becomes tags_ref.items_id=_.id 'condition' => [ 'itemtype' => $schema['x-itemtype'] ], From 86980cb66d4f013fd7a292fb6837e8d75029ad3d Mon Sep 17 00:00:00 2001 From: Curtis Conard Date: Wed, 28 Jun 2023 11:04:55 -0400 Subject: [PATCH 3/6] use new API search engine --- inc/apicontroller.class.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/inc/apicontroller.class.php b/inc/apicontroller.class.php index dc1a03e..b36ae78 100644 --- a/inc/apicontroller.class.php +++ b/inc/apicontroller.class.php @@ -62,7 +62,7 @@ protected static function getRawKnownSchemas(): array )] public function getTags(Request $request): Response { - return $this->searchBySchema($this->getKnownSchema('Tag'), $request->getParameters()); + return \Glpi\Api\HL\Search::searchBySchema($this->getKnownSchema('Tag'), $request->getParameters()); } #[Route(path: '/{id}', methods: ['GET'], requirements: ['id' => '\d+'])] @@ -79,7 +79,7 @@ public function getTags(Request $request): Response )] public function getTag(Request $request, int $id): Response { - return $this->getOneBySchema($this->getKnownSchema('Tag'), $request->getAttributes(), $request->getParameters(), $id); + return \Glpi\Api\HL\Search::getOneBySchema($this->getKnownSchema('Tag'), $request->getAttributes(), $request->getParameters(), $id); } #[Route(path: '/', methods: ['POST'])] @@ -93,7 +93,7 @@ public function getTag(Request $request, int $id): Response ])] public function createTag(Request $request): Response { - return $this->createBySchema($this->getKnownSchema('Tag'), $request->getParameters(), 'getTag'); + return \Glpi\Api\HL\Search::createBySchema($this->getKnownSchema('Tag'), $request->getParameters(), 'getTag'); } #[Route(path: '/{id}', methods: ['PATCH'], requirements: ['id' => '\d+'])] @@ -119,7 +119,7 @@ public function createTag(Request $request): Response )] public function updateTag(Request $request, int $id): Response { - return $this->updateBySchema($this->getKnownSchema('Tag'), $request->getAttributes(), $request->getParameters(), $id); + return \Glpi\Api\HL\Search::updateBySchema($this->getKnownSchema('Tag'), $request->getAttributes(), $request->getParameters(), $id); } #[Route(path: '/{id}', methods: ['DELETE'], requirements: ['id' => '\d+'])] @@ -136,6 +136,6 @@ public function updateTag(Request $request, int $id): Response )] public function deleteTag(Request $request, int $id): Response { - return $this->deleteBySchema($this->getKnownSchema('Tag'), $request->getAttributes(), $request->getParameters(), $id); + return \Glpi\Api\HL\Search::deleteBySchema($this->getKnownSchema('Tag'), $request->getAttributes(), $request->getParameters(), $id); } } From 75e305e3533e40e7f47c825c4964225c77d1d608 Mon Sep 17 00:00:00 2001 From: Curtis Conard Date: Wed, 28 Jun 2023 20:30:03 -0400 Subject: [PATCH 4/6] check rights --- hook.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/hook.php b/hook.php index d5d311b..df80344 100644 --- a/hook.php +++ b/hook.php @@ -280,6 +280,9 @@ function plugin_tag_getRuleActions($params = []) } function plugin_tag_redefine_api_schemas(array $data): array { + if (!Session::haveRight('plugin_tag_tag', READ)) { + return $data; + } foreach ($data['schemas'] as &$schema) { if (!isset($schema['x-itemtype'])) { continue; From cd79f100b6bbdfd83d9d72162bc10b3c72f650ef Mon Sep 17 00:00:00 2001 From: Curtis Conard Date: Sun, 15 Oct 2023 23:00:03 -0400 Subject: [PATCH 5/6] permission check won't work here --- hook.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/hook.php b/hook.php index df80344..d5d311b 100644 --- a/hook.php +++ b/hook.php @@ -280,9 +280,6 @@ function plugin_tag_getRuleActions($params = []) } function plugin_tag_redefine_api_schemas(array $data): array { - if (!Session::haveRight('plugin_tag_tag', READ)) { - return $data; - } foreach ($data['schemas'] as &$schema) { if (!isset($schema['x-itemtype'])) { continue; From 769f2ef79f95725261580eb002e3e2b9c2c34bc2 Mon Sep 17 00:00:00 2001 From: Curtis Conard Date: Sun, 15 Oct 2023 23:00:18 -0400 Subject: [PATCH 6/6] rename prop --- hook.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hook.php b/hook.php index d5d311b..5e3715b 100644 --- a/hook.php +++ b/hook.php @@ -295,7 +295,7 @@ function plugin_tag_redefine_api_schemas(array $data): array { 'table' => PluginTagTag::getTable(), 'fkey' => 'plugin_tag_tags_id', 'field' => 'id', - 'ref_join' => [ + 'ref-join' => [ // This is the linking join between the main item and the data needed 'table' => PluginTagTagItem::getTable(), 'fkey' => 'id', // ID field on the main join table