sso_controller.rb 2.43 KB
Newer Older
1 2
# frozen_string_literal: true

James Edwards-Jones's avatar
James Edwards-Jones committed
3 4 5 6 7 8
class Groups::SsoController < Groups::ApplicationController
  skip_before_action :group
  before_action :unauthenticated_group
  before_action :check_group_saml_configured
  before_action :check_group_saml_available!
  before_action :require_configured_provider
9
  before_action :require_enabled_provider, except: [:unlink]
10 11
  before_action :authenticate_user!, only: [:unlink]
  before_action :check_user_can_sign_in_with_provider, only: [:saml]
James Edwards-Jones's avatar
James Edwards-Jones committed
12 13 14 15 16 17 18
  before_action :redirect_if_group_moved

  layout 'devise'

  def saml
    @group_path = params[:group_id]
    @group_name = @unauthenticated_group.full_name
19 20
    @group_saml_identity = linked_identity
    @idp_url = @unauthenticated_group.saml_provider.sso_url
James Edwards-Jones's avatar
James Edwards-Jones committed
21 22
  end

23 24 25 26 27 28 29 30
  def unlink
    return route_not_found unless linked_identity

    GroupSaml::Identity::DestroyService.new(linked_identity).execute

    redirect_to profile_account_path
  end

James Edwards-Jones's avatar
James Edwards-Jones committed
31 32
  private

33 34 35 36
  def linked_identity
    @linked_identity ||= GroupSamlIdentityFinder.new(user: current_user).find_linked(group: @unauthenticated_group)
  end

James Edwards-Jones's avatar
James Edwards-Jones committed
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
  def check_group_saml_available!
    route_not_found unless @unauthenticated_group.feature_available?(:group_saml)
  end

  def check_group_saml_configured
    route_not_found unless Gitlab::Auth::GroupSaml::Config.enabled?
  end

  def unauthenticated_group
    @unauthenticated_group = Group.find_by_full_path(params[:group_id], follow_redirects: true)

    route_not_found unless @unauthenticated_group
  end

  def require_configured_provider
    return if @unauthenticated_group.saml_provider

54 55 56 57 58 59 60 61 62 63
    redirect_settings_or_not_found
  end

  def require_enabled_provider
    return if @unauthenticated_group.saml_provider&.enabled?

    redirect_settings_or_not_found
  end

  def redirect_settings_or_not_found
James Edwards-Jones's avatar
James Edwards-Jones committed
64 65 66 67 68 69 70 71 72 73
    if can?(current_user, :admin_group_saml, @unauthenticated_group)
      flash[:notice] = 'SAML sign on has not been configured for this group'

      redirect_to [@unauthenticated_group, :saml_providers]
    else
      route_not_found
    end
  end

  def check_user_can_sign_in_with_provider
74 75 76 77 78 79
    actor = saml_discovery_token_actor || current_user
    route_not_found unless can?(actor, :sign_in_with_saml_provider, @unauthenticated_group.saml_provider)
  end

  def saml_discovery_token_actor
    Gitlab::Auth::GroupSaml::TokenActor.new(params[:token]) if params[:token]
James Edwards-Jones's avatar
James Edwards-Jones committed
80 81 82 83 84 85
  end

  def redirect_if_group_moved
    ensure_canonical_path(@unauthenticated_group, params[:group_id])
  end
end