Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-11-24 18:14:19 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-11-24 18:14:19 +0300
commitb8d516a6876de74b68a800c5b69af9448b0de140 (patch)
tree3a56c8af8b36d03c20e9de4298f30b08cba0ea5a /app/controllers
parent77b8390171a55d4593e3730551751d8348992f80 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'app/controllers')
-rw-r--r--app/controllers/clusters/clusters_controller.rb8
-rw-r--r--app/controllers/google_api/authorizations_controller.rb35
-rw-r--r--app/controllers/projects/google_cloud/base_controller.rb26
-rw-r--r--app/controllers/projects/google_cloud/service_accounts_controller.rb84
-rw-r--r--app/controllers/projects/google_cloud_controller.rb27
5 files changed, 144 insertions, 36 deletions
diff --git a/app/controllers/clusters/clusters_controller.rb b/app/controllers/clusters/clusters_controller.rb
index 32de9e69c85..15a261f572a 100644
--- a/app/controllers/clusters/clusters_controller.rb
+++ b/app/controllers/clusters/clusters_controller.rb
@@ -280,7 +280,10 @@ class Clusters::ClustersController < Clusters::BaseController
end
def generate_gcp_authorize_url
- state = generate_session_key_redirect(clusterable.new_path(provider: :gcp).to_s)
+ new_path = clusterable.new_path(provider: :gcp).to_s
+ error_path = @project ? project_clusters_path(@project) : new_path
+
+ state = generate_session_key_redirect(new_path, error_path)
@authorize_url = GoogleApi::CloudPlatform::Client.new(
nil, callback_google_api_auth_url,
@@ -339,9 +342,10 @@ class Clusters::ClustersController < Clusters::BaseController
session[GoogleApi::CloudPlatform::Client.session_key_for_expires_at]
end
- def generate_session_key_redirect(uri)
+ def generate_session_key_redirect(uri, error_uri)
GoogleApi::CloudPlatform::Client.new_session_key_for_redirect_uri do |key|
session[key] = uri
+ session[:error_uri] = error_uri
end
end
diff --git a/app/controllers/google_api/authorizations_controller.rb b/app/controllers/google_api/authorizations_controller.rb
index 76a1c43dfa3..b9c5e87c69c 100644
--- a/app/controllers/google_api/authorizations_controller.rb
+++ b/app/controllers/google_api/authorizations_controller.rb
@@ -8,19 +8,36 @@ module GoogleApi
feature_category :kubernetes_management
+ ##
+ # handle the response from google after the user
+ # goes through authentication and authorization process
def callback
- token, expires_at = GoogleApi::CloudPlatform::Client
- .new(nil, callback_google_api_auth_url)
- .get_token(params[:code])
-
- session[GoogleApi::CloudPlatform::Client.session_key_for_token] = token
- session[GoogleApi::CloudPlatform::Client.session_key_for_expires_at] =
- expires_at.to_s
-
+ redirect_uri = redirect_uri_from_session
+ ##
+ # when the user declines authorizations
+ # `error` param is returned
+ if params[:error]
+ flash[:alert] = _('Google Cloud authorizations required')
+ redirect_uri = session[:error_uri]
+ ##
+ # on success, the `code` param is returned
+ elsif params[:code]
+ token, expires_at = GoogleApi::CloudPlatform::Client
+ .new(nil, callback_google_api_auth_url)
+ .get_token(params[:code])
+
+ session[GoogleApi::CloudPlatform::Client.session_key_for_token] = token
+ session[GoogleApi::CloudPlatform::Client.session_key_for_expires_at] = expires_at.to_s
+ redirect_uri = redirect_uri_from_session
+ end
+ ##
+ # or google may just timeout
rescue ::Faraday::TimeoutError, ::Faraday::ConnectionFailed
flash[:alert] = _('Timeout connecting to the Google API. Please try again.')
+ ##
+ # regardless, we redirect the user appropriately
ensure
- redirect_to redirect_uri_from_session
+ redirect_to redirect_uri
end
private
diff --git a/app/controllers/projects/google_cloud/base_controller.rb b/app/controllers/projects/google_cloud/base_controller.rb
new file mode 100644
index 00000000000..2a9e89a445b
--- /dev/null
+++ b/app/controllers/projects/google_cloud/base_controller.rb
@@ -0,0 +1,26 @@
+# frozen_string_literal: true
+
+class Projects::GoogleCloud::BaseController < Projects::ApplicationController
+ feature_category :google_cloud
+
+ before_action :admin_project_google_cloud!
+ before_action :google_oauth2_enabled!
+ before_action :feature_flag_enabled!
+
+ private
+
+ def admin_project_google_cloud!
+ access_denied! unless can?(current_user, :admin_project_google_cloud, project)
+ end
+
+ def google_oauth2_enabled!
+ config = Gitlab::Auth::OAuth::Provider.config_for('google_oauth2')
+ if config.app_id.blank? || config.app_secret.blank?
+ access_denied! 'This GitLab instance not configured for Google Oauth2.'
+ end
+ end
+
+ def feature_flag_enabled!
+ access_denied! unless Feature.enabled?(:incubation_5mp_google_cloud)
+ end
+end
diff --git a/app/controllers/projects/google_cloud/service_accounts_controller.rb b/app/controllers/projects/google_cloud/service_accounts_controller.rb
new file mode 100644
index 00000000000..21b096a6c66
--- /dev/null
+++ b/app/controllers/projects/google_cloud/service_accounts_controller.rb
@@ -0,0 +1,84 @@
+# frozen_string_literal: true
+
+class Projects::GoogleCloud::ServiceAccountsController < Projects::GoogleCloud::BaseController
+ before_action :validate_gcp_token!
+
+ def index
+ @google_cloud_path = project_google_cloud_index_path(project)
+ google_api_client = GoogleApi::CloudPlatform::Client.new(token_in_session, nil)
+ gcp_projects = google_api_client.list_projects
+
+ if gcp_projects.empty?
+ @js_data = {}.to_json
+ render status: :unauthorized, template: 'projects/google_cloud/errors/no_gcp_projects'
+ else
+ @js_data = {
+ gcpProjects: gcp_projects,
+ environments: project.environments,
+ cancelPath: project_google_cloud_index_path(project)
+ }.to_json
+ end
+ rescue Google::Apis::ClientError => error
+ handle_gcp_error(error, project)
+ end
+
+ def create
+ google_api_client = GoogleApi::CloudPlatform::Client.new(token_in_session, nil)
+ service_accounts_service = GoogleCloud::ServiceAccountsService.new(project)
+ gcp_project = params[:gcp_project]
+ environment = params[:environment]
+ generated_name = "GitLab :: #{@project.name} :: #{environment}"
+ generated_desc = "GitLab generated service account for project '#{@project.name}' and environment '#{environment}'"
+
+ service_account = google_api_client.create_service_account(gcp_project, generated_name, generated_desc)
+ service_account_key = google_api_client.create_service_account_key(gcp_project, service_account.unique_id)
+
+ service_accounts_service.add_for_project(
+ environment,
+ service_account.project_id,
+ service_account.to_json,
+ service_account_key.to_json
+ )
+
+ redirect_to project_google_cloud_index_path(project), notice: _('Service account generated successfully')
+ rescue Google::Apis::ClientError, Google::Apis::ServerError, Google::Apis::AuthorizationError => error
+ handle_gcp_error(error, project)
+ end
+
+ private
+
+ def validate_gcp_token!
+ is_token_valid = GoogleApi::CloudPlatform::Client.new(token_in_session, nil)
+ .validate_token(expires_at_in_session)
+
+ return if is_token_valid
+
+ return_url = project_google_cloud_service_accounts_path(project)
+ state = generate_session_key_redirect(request.url, return_url)
+ @authorize_url = GoogleApi::CloudPlatform::Client.new(nil,
+ callback_google_api_auth_url,
+ state: state).authorize_url
+ redirect_to @authorize_url
+ end
+
+ def generate_session_key_redirect(uri, error_uri)
+ GoogleApi::CloudPlatform::Client.new_session_key_for_redirect_uri do |key|
+ session[key] = uri
+ session[:error_uri] = error_uri
+ end
+ end
+
+ def token_in_session
+ session[GoogleApi::CloudPlatform::Client.session_key_for_token]
+ end
+
+ def expires_at_in_session
+ session[GoogleApi::CloudPlatform::Client.session_key_for_expires_at]
+ end
+
+ def handle_gcp_error(error, project)
+ Gitlab::ErrorTracking.track_exception(error, project_id: project.id)
+ @js_data = { error: error.to_s }.to_json
+ render status: :unauthorized, template: 'projects/google_cloud/errors/gcp_error'
+ end
+end
diff --git a/app/controllers/projects/google_cloud_controller.rb b/app/controllers/projects/google_cloud_controller.rb
index 7257ed1ef6f..6cc67391d6c 100644
--- a/app/controllers/projects/google_cloud_controller.rb
+++ b/app/controllers/projects/google_cloud_controller.rb
@@ -1,34 +1,11 @@
# frozen_string_literal: true
-class Projects::GoogleCloudController < Projects::ApplicationController
- feature_category :google_cloud
-
- before_action :admin_project_google_cloud?
- before_action :google_oauth2_enabled?
- before_action :feature_flag_enabled?
-
+class Projects::GoogleCloudController < Projects::GoogleCloud::BaseController
def index
@js_data = {
serviceAccounts: GoogleCloud::ServiceAccountsService.new(project).find_for_project,
- createServiceAccountUrl: '#mocked-url-create-service',
+ createServiceAccountUrl: project_google_cloud_service_accounts_path(project),
emptyIllustrationUrl: ActionController::Base.helpers.image_path('illustrations/pipelines_empty.svg')
}.to_json
end
-
- private
-
- def admin_project_google_cloud?
- access_denied! unless can?(current_user, :admin_project_google_cloud, project)
- end
-
- def google_oauth2_enabled?
- config = Gitlab::Auth::OAuth::Provider.config_for('google_oauth2')
- if config.app_id.blank? || config.app_secret.blank?
- access_denied! 'This GitLab instance not configured for Google Oauth2.'
- end
- end
-
- def feature_flag_enabled?
- access_denied! unless Feature.enabled?(:incubation_5mp_google_cloud)
- end
end