Class: LcpRuby::Auth::SessionsController
- Inherits:
-
Devise::SessionsController
- Object
- Devise::SessionsController
- LcpRuby::Auth::SessionsController
- Includes:
- BaseController
- Defined in:
- app/controllers/lcp_ruby/auth/sessions_controller.rb
Instance Method Summary collapse
- #create ⇒ Object
-
#destroy ⇒ Object
Devise destroy + optional RP-initiated OIDC logout.
- #new ⇒ Object
Instance Method Details
#create ⇒ Object
27 28 29 30 31 32 33 34 |
# File 'app/controllers/lcp_ruby/auth/sessions_controller.rb', line 27 def create unless LcpRuby::Authentication::ProviderRegistry.password_sign_in_allowed? flash[:alert] = I18n.t("lcp_ruby.auth.password_disabled", default: "Password sign-in is disabled.") redirect_to(new_user_session_path) and return end super end |
#destroy ⇒ Object
Devise destroy + optional RP-initiated OIDC logout. When the signed-in user came in via an OIDC provider configured with logout.mode: rp_initiated, redirect after local sign-out to the IdP’s end_session_endpoint with id_token_hint and post_logout_redirect_uri, so the user is also signed out of the IdP for this RP.
The RP-initiated branch must run BEFORE ‘super` because Devise’s destroy ends in ‘respond_to_on_destroy`, which calls `redirect_to after_sign_out_path_for(…)` and sets `response_body`. A second `redirect_to` after super would raise AbstractController::DoubleRenderError.
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'app/controllers/lcp_ruby/auth/sessions_controller.rb', line 46 def destroy # Read the user directly from Warden's session store. This is the correct # API for "what user is in this session right now" — we don't need to run # full authentication strategies (timeoutable, lockable, …) just to figure # out where to redirect. Using `current_user` here would also be fragile: # host apps can override `ApplicationController#current_user`, and in # test rigs (spec/dummy) that override may shadow Devise's helper entirely. oidc_user = request.env["warden"]&.user(:user) provider_name = oidc_user && oidc_user.respond_to?(:provider) ? oidc_user.provider.presence : nil provider = provider_name && LcpRuby::Authentication::ProviderRegistry.find_by(provider_name) id_token = session[:oidc_id_token] if provider&.oidc? && provider.logout[:mode] == :rp_initiated end_session_url = build_end_session_url(provider, id_token) if end_session_url Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name) flash[:notice] = I18n.t("lcp_ruby.auth.signed_out", default: "You have been signed out.") redirect_to(end_session_url, allow_other_host: true) and return end # end_session_endpoint missing or discovery unavailable — fall through # to local-only sign-out so the user isn't trapped half-signed-in. Rails.logger.info( "[lcp_ruby] OIDC end_session_endpoint unavailable for provider=#{provider.name}; " \ "completing local sign-out only." ) end super flash[:notice] ||= I18n.t("lcp_ruby.auth.signed_out", default: "You have been signed out.") end |
#new ⇒ Object
16 17 18 19 20 21 22 23 24 25 |
# File 'app/controllers/lcp_ruby/auth/sessions_controller.rb', line 16 def new registry = LcpRuby::Authentication::ProviderRegistry @providers = registry.all @oidc_providers = registry.oidc_providers @show_password_form = registry.password_sign_in_allowed? @auto_redirect = @oidc_providers.size == 1 && !@show_password_form && registry.default_auto_redirect? super end |