diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/assets/javascripts/notes/components/note_header.vue | 2 | ||||
-rw-r--r-- | app/controllers/concerns/import/github_oauth.rb | 100 | ||||
-rw-r--r-- | app/controllers/import/github_controller.rb | 76 | ||||
-rw-r--r-- | app/controllers/import/github_groups_controller.rb | 57 | ||||
-rw-r--r-- | app/models/user.rb | 2 | ||||
-rw-r--r-- | app/serializers/import/github_org_entity.rb | 8 | ||||
-rw-r--r-- | app/serializers/import/github_org_serializer.rb | 7 |
7 files changed, 176 insertions, 76 deletions
diff --git a/app/assets/javascripts/notes/components/note_header.vue b/app/assets/javascripts/notes/components/note_header.vue index c1824dc883c..f3530344181 100644 --- a/app/assets/javascripts/notes/components/note_header.vue +++ b/app/assets/javascripts/notes/components/note_header.vue @@ -201,7 +201,7 @@ export default { data-testid="internalNoteIndicator" variant="warning" size="sm" - class="gl-mb-3 gl-ml-2" + class="gl-ml-2" :title="internalNoteTooltip" > {{ __('Internal note') }} diff --git a/app/controllers/concerns/import/github_oauth.rb b/app/controllers/concerns/import/github_oauth.rb new file mode 100644 index 00000000000..d53022aabf2 --- /dev/null +++ b/app/controllers/concerns/import/github_oauth.rb @@ -0,0 +1,100 @@ +# frozen_string_literal: true + +module Import + module GithubOauth + extend ActiveSupport::Concern + + OAuthConfigMissingError = Class.new(StandardError) + + included do + rescue_from OAuthConfigMissingError, with: :missing_oauth_config + end + + private + + def provider_auth + return if session[access_token_key].present? + + go_to_provider_for_permissions unless ci_cd_only? + end + + def ci_cd_only? + %w[1 true].include?(params[:ci_cd_only]) + end + + def go_to_provider_for_permissions + redirect_to authorize_url + end + + def oauth_client + raise OAuthConfigMissingError unless oauth_config + + oauth_client_from_config + end + + def oauth_client_from_config + @oauth_client_from_config ||= ::OAuth2::Client.new( + oauth_config.app_id, + oauth_config.app_secret, + oauth_options.merge(ssl: { verify: oauth_config['verify_ssl'] }) + ) + end + + def oauth_config + @oauth_config ||= Gitlab::Auth::OAuth::Provider.config_for('github') + end + + def oauth_options + return unless oauth_config + + oauth_config.dig('args', 'client_options').deep_symbolize_keys + end + + def authorize_url + state = SecureRandom.base64(64) + session[auth_state_key] = state + if Feature.enabled?(:remove_legacy_github_client) + oauth_client.auth_code.authorize_url( + redirect_uri: callback_import_url, + scope: 'repo, user, user:email', + state: state + ) + else + client.authorize_url(callback_import_url, state) + end + end + + def get_token(code) + if Feature.enabled?(:remove_legacy_github_client) + oauth_client.auth_code.get_token(code).token + else + client.get_token(code) + end + end + + def missing_oauth_config + session[access_token_key] = nil + + message = _('Missing OAuth configuration for GitHub.') + + respond_to do |format| + format.json do + render json: { errors: message }, status: :unauthorized + end + + format.any do + redirect_to new_import_url, + alert: message + end + end + end + + def callback_import_url + public_send("users_import_#{provider_name}_callback_url", extra_import_params.merge({ namespace_id: params[:namespace_id] })) # rubocop:disable GitlabSecurity/PublicSend + end + + def extra_import_params + {} + end + end +end diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb index 517191b2573..ab81fdfddb2 100644 --- a/app/controllers/import/github_controller.rb +++ b/app/controllers/import/github_controller.rb @@ -5,14 +5,12 @@ class Import::GithubController < Import::BaseController include ImportHelper include ActionView::Helpers::SanitizeHelper + include Import::GithubOauth before_action :verify_import_enabled before_action :provider_auth, only: [:status, :realtime_changes, :create] before_action :expire_etag_cache, only: [:status, :create] - OAuthConfigMissingError = Class.new(StandardError) - - rescue_from OAuthConfigMissingError, with: :missing_oauth_config rescue_from Octokit::Unauthorized, with: :provider_unauthorized rescue_from Octokit::TooManyRequests, with: :provider_rate_limit rescue_from Gitlab::GithubImport::RateLimitError, with: :rate_limit_threshold_exceeded @@ -154,58 +152,10 @@ class Import::GithubController < Import::BaseController @filter = @filter&.tr(' ', '')&.tr(':', '') end - def oauth_client - raise OAuthConfigMissingError unless oauth_config - - @oauth_client ||= ::OAuth2::Client.new( - oauth_config.app_id, - oauth_config.app_secret, - oauth_options.merge(ssl: { verify: oauth_config['verify_ssl'] }) - ) - end - - def oauth_config - @oauth_config ||= Gitlab::Auth::OAuth::Provider.config_for('github') - end - - def oauth_options - if oauth_config - oauth_config.dig('args', 'client_options').deep_symbolize_keys - else - OmniAuth::Strategies::GitHub.default_options[:client_options].symbolize_keys - end - end - - def authorize_url - state = SecureRandom.base64(64) - session[auth_state_key] = state - if Feature.enabled?(:remove_legacy_github_client) - oauth_client.auth_code.authorize_url( - redirect_uri: callback_import_url, - scope: 'repo, user, user:email', - state: state - ) - else - client.authorize_url(callback_import_url, state) - end - end - - def get_token(code) - if Feature.enabled?(:remove_legacy_github_client) - oauth_client.auth_code.get_token(code).token - else - client.get_token(code) - end - end - def verify_import_enabled render_404 unless import_enabled? end - def go_to_provider_for_permissions - redirect_to authorize_url - end - def import_enabled? __send__("#{provider_name}_import_enabled?") # rubocop:disable GitlabSecurity/PublicSend end @@ -222,10 +172,6 @@ class Import::GithubController < Import::BaseController public_send("status_import_#{provider_name}_url", extra_import_params.merge({ namespace_id: params[:namespace_id].presence })) # rubocop:disable GitlabSecurity/PublicSend end - def callback_import_url - public_send("users_import_#{provider_name}_callback_url", extra_import_params.merge({ namespace_id: params[:namespace_id] })) # rubocop:disable GitlabSecurity/PublicSend - end - def provider_unauthorized session[access_token_key] = nil redirect_to new_import_url, @@ -239,12 +185,6 @@ class Import::GithubController < Import::BaseController alert: _("GitHub API rate limit exceeded. Try again after %{reset_time}") % { reset_time: reset_time } end - def missing_oauth_config - session[access_token_key] = nil - redirect_to new_import_url, - alert: _('Missing OAuth configuration for GitHub.') - end - def auth_state_key :"#{provider_name}_auth_state_key" end @@ -263,24 +203,10 @@ class Import::GithubController < Import::BaseController end # rubocop: enable CodeReuse/ActiveRecord - def provider_auth - if !ci_cd_only? && session[access_token_key].blank? - go_to_provider_for_permissions - end - end - - def ci_cd_only? - %w[1 true].include?(params[:ci_cd_only]) - end - def client_options { wait_for_rate_limit_reset: false } end - def extra_import_params - {} - end - def rate_limit_threshold_exceeded head :too_many_requests end diff --git a/app/controllers/import/github_groups_controller.rb b/app/controllers/import/github_groups_controller.rb new file mode 100644 index 00000000000..6c0773bcfb3 --- /dev/null +++ b/app/controllers/import/github_groups_controller.rb @@ -0,0 +1,57 @@ +# frozen_string_literal: true + +module Import + class GithubGroupsController < ApplicationController + include Import::GithubOauth + + before_action :provider_auth, only: [:status] + feature_category :importers + + PAGE_LENGTH = 25 + + def status + respond_to do |format| + format.json do + render json: { provider_groups: serialized_provider_groups } + end + end + end + + private + + def serialized_provider_groups + Import::GithubOrgSerializer.new.represent(importable_orgs) + end + + def importable_orgs + client_orgs.to_a + end + + def client_orgs + @client_orgs ||= client.octokit.organizations(nil, pagination_options) + end + + def client + @client ||= Gitlab::GithubImport::Client.new(session[access_token_key]) + end + + def pagination_options + { + page: [1, params[:page].to_i].max, + per_page: PAGE_LENGTH + } + end + + def auth_state_key + :"#{provider_name}_auth_state_key" + end + + def access_token_key + :"#{provider_name}_access_token" + end + + def provider_name + :github + end + end +end diff --git a/app/models/user.rb b/app/models/user.rb index 488b3a9cb5b..4bc2d8f76aa 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -198,6 +198,8 @@ class User < ApplicationRecord has_many :snippets, dependent: :destroy, foreign_key: :author_id # rubocop:disable Cop/ActiveRecordDependent has_many :notes, dependent: :destroy, foreign_key: :author_id # rubocop:disable Cop/ActiveRecordDependent has_many :issues, dependent: :destroy, foreign_key: :author_id # rubocop:disable Cop/ActiveRecordDependent + has_many :legacy_assigned_merge_requests, class_name: 'MergeRequest', dependent: :nullify, foreign_key: :assignee_id # rubocop:disable Cop/ActiveRecordDependent + has_many :updated_merge_requests, class_name: 'MergeRequest', dependent: :nullify, foreign_key: :updated_by_id # rubocop:disable Cop/ActiveRecordDependent has_many :updated_issues, class_name: 'Issue', dependent: :nullify, foreign_key: :updated_by_id # rubocop:disable Cop/ActiveRecordDependent has_many :closed_issues, class_name: 'Issue', dependent: :nullify, foreign_key: :closed_by_id # rubocop:disable Cop/ActiveRecordDependent has_many :merge_requests, dependent: :destroy, foreign_key: :author_id # rubocop:disable Cop/ActiveRecordDependent diff --git a/app/serializers/import/github_org_entity.rb b/app/serializers/import/github_org_entity.rb new file mode 100644 index 00000000000..a250a9b60f5 --- /dev/null +++ b/app/serializers/import/github_org_entity.rb @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +module Import + class GithubOrgEntity < Grape::Entity + expose :login, as: :name + expose :description + end +end diff --git a/app/serializers/import/github_org_serializer.rb b/app/serializers/import/github_org_serializer.rb new file mode 100644 index 00000000000..69a598e4b24 --- /dev/null +++ b/app/serializers/import/github_org_serializer.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +module Import + class GithubOrgSerializer < BaseSerializer + entity Import::GithubOrgEntity + end +end |