From c28c132242d3b1bae0d625169a894f1ddcb1bda2 Mon Sep 17 00:00:00 2001
From: Manuel VACELET <manuel.vacelet@enalean.com>
Date: Mon, 25 Oct 2021 17:21:58 +0200
Subject: [PATCH] Detect admin with JiraServer

Change-Id: Ib9e61fdeeba91a583cd10f8de2e7b1f1f6c84c71
---
 .../UserRole/UserRolesChecker.php             | 56 ++++++++++++++++---
 1 file changed, 49 insertions(+), 7 deletions(-)

diff --git a/plugins/tracker/include/Tracker/Creation/JiraImporter/UserRole/UserRolesChecker.php b/plugins/tracker/include/Tracker/Creation/JiraImporter/UserRole/UserRolesChecker.php
index 87e46c2487..82d311b232 100644
--- a/plugins/tracker/include/Tracker/Creation/JiraImporter/UserRole/UserRolesChecker.php
+++ b/plugins/tracker/include/Tracker/Creation/JiraImporter/UserRole/UserRolesChecker.php
@@ -29,9 +29,14 @@ use Tuleap\Tracker\Creation\JiraImporter\JiraClient;
 
 class UserRolesChecker
 {
-    private const NAME_KEY                 = 'name';
-    private const ADMINISTRATORS_ROLE_NAME = 'Administrators';
-    private const ADMINISTRATOR_ROLE_NAME  = 'Administrator';
+    private const JIRA_CLOUD_NAME_KEY                 = 'name';
+    private const JIRA_CLOUD_ADMINISTRATORS_ROLE_NAME = 'Administrators';
+    private const JIRA_CLOUD_ADMINISTRATOR_ROLE_NAME  = 'Administrator';
+    private const JIRA_SERVER_PERMISSIONS_KEY         = 'permissions';
+    private const JIRA_SERVER_PERMISSION_NAMES        = [
+        'PROJECT_ADMIN',
+        'ADMINISTER_PROJECTS',
+    ];
 
     /**
      * @throws UserRolesResponseNotWellFormedException
@@ -46,6 +51,17 @@ class UserRolesChecker
     ): void {
         $logger->debug("Check if user is administrator in Jira Project");
 
+        match ($jira_client->isJiraCloud()) {
+            true => $this->checkUserIsAdminJiraCloud($jira_client, $logger, $jira_project),
+            false => $this->checkUserIsAdminJiraServer($jira_client, $logger, $jira_project),
+        };
+    }
+
+    private function checkUserIsAdminJiraCloud(
+        JiraClient $jira_client,
+        LoggerInterface $logger,
+        string $jira_project,
+    ): void {
         $user_role_url = ClientWrapper::JIRA_CORE_BASE_URL . "/project/" . urlencode($jira_project) . "/roledetails?currentMember=true";
         $logger->debug("  GET " . $user_role_url);
 
@@ -56,19 +72,45 @@ class UserRolesChecker
 
         assert(is_array($user_roles_data));
         foreach ($user_roles_data as $user_role) {
-            if (! isset($user_role[self::NAME_KEY])) {
-                throw new UserRolesResponseNotWellFormedException("User roles key `" . self::NAME_KEY . "` not found");
+            if (! isset($user_role[self::JIRA_CLOUD_NAME_KEY])) {
+                throw new UserRolesResponseNotWellFormedException("User roles key `" . self::JIRA_CLOUD_NAME_KEY . "` not found");
             }
 
             if (
-                $user_role[self::NAME_KEY] === self::ADMINISTRATORS_ROLE_NAME ||
-                $user_role[self::NAME_KEY] === self::ADMINISTRATOR_ROLE_NAME
+                $user_role[self::JIRA_CLOUD_NAME_KEY] === self::JIRA_CLOUD_ADMINISTRATORS_ROLE_NAME ||
+                $user_role[self::JIRA_CLOUD_NAME_KEY] === self::JIRA_CLOUD_ADMINISTRATOR_ROLE_NAME
             ) {
                 $logger->info("User is project administrator.");
                 return;
             }
         }
+        throw new UserIsNotProjectAdminException("User is not project administrator.");
+    }
+
+
+    private function checkUserIsAdminJiraServer(
+        JiraClient $jira_client,
+        LoggerInterface $logger,
+        string $jira_project,
+    ): void {
+        $user_role_url = ClientWrapper::JIRA_CORE_BASE_URL . "/mypermissions?projectId=" . urlencode($jira_project);
+        $logger->debug("  GET " . $user_role_url);
+
+        $user_permissions = $jira_client->getUrl($user_role_url);
+        if ($user_permissions === null) {
+            throw new UserRolesResponseNotWellFormedException("JiraServer user permission data is null");
+        }
 
+        assert(is_array($user_permissions));
+        if (! isset($user_permissions[self::JIRA_SERVER_PERMISSIONS_KEY])) {
+            throw new UserRolesResponseNotWellFormedException("JiraServer user permissions key `" . self::JIRA_SERVER_PERMISSIONS_KEY . "` not found");
+        }
+        foreach ($user_permissions[self::JIRA_SERVER_PERMISSIONS_KEY] as $permission_key => $permission_object) {
+            if (in_array($permission_key, self::JIRA_SERVER_PERMISSION_NAMES, true)) {
+                $logger->info("User is project administrator.");
+                return;
+            }
+        }
         throw new UserIsNotProjectAdminException("User is not project administrator.");
     }
 }
-- 
2.33.0

