1# frozen_string_literal: true
2
3module Clusters
4  module Aws
5    class AuthorizeRoleService
6      attr_reader :user
7
8      Response = Struct.new(:status, :body)
9
10      ERRORS = [
11        ActiveRecord::RecordInvalid,
12        ActiveRecord::RecordNotFound,
13        Clusters::Aws::FetchCredentialsService::MissingRoleError,
14        ::Aws::Errors::MissingCredentialsError,
15        ::Aws::STS::Errors::ServiceError
16      ].freeze
17
18      def initialize(user, params:)
19        @user = user
20        @role_arn = params[:role_arn]
21        @region = params[:region]
22      end
23
24      def execute
25        ensure_role_exists!
26        update_role_arn!
27
28        Response.new(:ok, credentials)
29      rescue *ERRORS => e
30        Gitlab::ErrorTracking.track_exception(e)
31
32        Response.new(:unprocessable_entity, response_details(e))
33      end
34
35      private
36
37      attr_reader :role, :role_arn, :region
38
39      def ensure_role_exists!
40        @role = ::Aws::Role.find_by_user_id!(user.id)
41      end
42
43      def update_role_arn!
44        role.update!(role_arn: role_arn, region: region)
45      end
46
47      def credentials
48        Clusters::Aws::FetchCredentialsService.new(role).execute
49      end
50
51      def response_details(exception)
52        message =
53          case exception
54          when ::Aws::STS::Errors::AccessDenied
55            _("Access denied: %{error}") % { error: exception.message }
56          when ::Aws::STS::Errors::ServiceError
57            _("AWS service error: %{error}") % { error: exception.message }
58          when ActiveRecord::RecordNotFound
59            _("Error: Unable to find AWS role for current user")
60          when ActiveRecord::RecordInvalid
61            exception.message
62          when Clusters::Aws::FetchCredentialsService::MissingRoleError
63            _("Error: No AWS provision role found for user")
64          when ::Aws::Errors::MissingCredentialsError
65            _("Error: No AWS credentials were supplied")
66          else
67            _('An error occurred while authorizing your role')
68          end
69
70        { message: message }.compact
71      end
72    end
73  end
74end
75