diff options
Diffstat (limited to 'app')
5 files changed, 43 insertions, 6 deletions
diff --git a/app/controllers/jira_connect/app_descriptor_controller.rb b/app/controllers/jira_connect/app_descriptor_controller.rb index a0f387631dd..74fac6ff9bb 100644 --- a/app/controllers/jira_connect/app_descriptor_controller.rb +++ b/app/controllers/jira_connect/app_descriptor_controller.rb @@ -47,7 +47,13 @@ class JiraConnect::AppDescriptorController < JiraConnect::ApplicationController postInstallPage: { key: 'gitlab-configuration', name: { value: 'GitLab Configuration' }, - url: relative_to_base_path(jira_connect_subscriptions_path) + url: relative_to_base_path(jira_connect_subscriptions_path), + conditions: [ + { + condition: 'user_is_admin', + invert: false + } + ] } } diff --git a/app/controllers/jira_connect/application_controller.rb b/app/controllers/jira_connect/application_controller.rb index a6529ecb4ce..352e78d6255 100644 --- a/app/controllers/jira_connect/application_controller.rb +++ b/app/controllers/jira_connect/application_controller.rb @@ -38,12 +38,30 @@ class JiraConnect::ApplicationController < ApplicationController end def installation_from_jwt - return unless auth_token - strong_memoize(:installation_from_jwt) do + next unless claims['iss'] + + JiraConnectInstallation.find_by_client_key(claims['iss']) + end + end + + def claims + strong_memoize(:claims) do + next {} unless auth_token + # Decode without verification to get `client_key` in `iss` payload, _ = Atlassian::Jwt.decode(auth_token, nil, false) - JiraConnectInstallation.find_by_client_key(payload['iss']) + payload + end + end + + def jira_user + strong_memoize(:jira_user) do + next unless installation_from_jwt + next unless claims['sub'] + + # This only works for Jira Cloud installations. + installation_from_jwt.client.user_info(claims['sub']) end end diff --git a/app/controllers/jira_connect/subscriptions_controller.rb b/app/controllers/jira_connect/subscriptions_controller.rb index a9c4dbf2b17..903ad395e44 100644 --- a/app/controllers/jira_connect/subscriptions_controller.rb +++ b/app/controllers/jira_connect/subscriptions_controller.rb @@ -44,7 +44,9 @@ class JiraConnect::SubscriptionsController < JiraConnect::ApplicationController def destroy subscription = current_jira_installation.subscriptions.find(params[:id]) - if subscription.destroy + if !jira_user&.site_admin? + render json: { error: 'forbidden' }, status: :forbidden + elsif subscription.destroy render json: { success: true } else render json: { error: subscription.errors.full_messages.join(', ') }, status: :unprocessable_entity @@ -54,7 +56,7 @@ class JiraConnect::SubscriptionsController < JiraConnect::ApplicationController private def create_service - JiraConnectSubscriptions::CreateService.new(current_jira_installation, current_user, namespace_path: params['namespace_path']) + JiraConnectSubscriptions::CreateService.new(current_jira_installation, current_user, namespace_path: params['namespace_path'], jira_user: jira_user) end def allow_rendering_in_iframe diff --git a/app/models/jira_connect_installation.rb b/app/models/jira_connect_installation.rb index 759d44fb29e..e34543534f3 100644 --- a/app/models/jira_connect_installation.rb +++ b/app/models/jira_connect_installation.rb @@ -20,4 +20,8 @@ class JiraConnectInstallation < ApplicationRecord id: JiraConnectSubscription.for_project(project) }) } + + def client + Atlassian::JiraConnect::Client.new(base_url, shared_secret) + end end diff --git a/app/services/jira_connect_subscriptions/create_service.rb b/app/services/jira_connect_subscriptions/create_service.rb index 38e5fe7e690..2f31a3c8d4e 100644 --- a/app/services/jira_connect_subscriptions/create_service.rb +++ b/app/services/jira_connect_subscriptions/create_service.rb @@ -5,8 +5,11 @@ module JiraConnectSubscriptions include Gitlab::Utils::StrongMemoize MERGE_REQUEST_SYNC_BATCH_SIZE = 20 MERGE_REQUEST_SYNC_BATCH_DELAY = 1.minute.freeze + NOT_SITE_ADMIN = 'The Jira user is not a site administrator.' def execute + return error(NOT_SITE_ADMIN, 403) unless can_administer_jira? + unless namespace && can?(current_user, :create_jira_connect_subscription, namespace) return error('Invalid namespace. Please make sure you have sufficient permissions', 401) end @@ -16,6 +19,10 @@ module JiraConnectSubscriptions private + def can_administer_jira? + @params[:jira_user]&.site_admin? + end + def create_subscription subscription = JiraConnectSubscription.new(installation: jira_connect_installation, namespace: namespace) |