main
rb 67 lines 2.6 KB
Raw
1 # frozen_string_literal: true
2
3 module Oauth
4 # Shared "Continue with <provider>" flow — delegates to smbCloud Auth, which
5 # brokers the provider's OAuth dance (smbCloud is our Auth0-style
6 # auth-as-a-service). smbCloud signs the user in / creates the account from
7 # the provider profile, then redirects back to #callback with an
8 # `access_token` we exchange for a local session — the same upsert path as
9 # SessionsController#create.
10 #
11 # Subclasses supply the provider specifics:
12 # provider_label — human name used in flash/log messages ("GitHub")
13 # provider_key — lowercase key stored on User#oauth_provider ("github")
14 # authorize_url — the smbCloud authorize URL carrying our callback
15 class ProviderController < ApplicationController
16 before_action :redirect_if_signed_in
17
18 # GET /auth/<provider>
19 def start
20 redirect_to authorize_url, allow_other_host: true
21 end
22
23 # GET /auth/<provider>/callback
24 def callback
25 if params[:error].present?
26 Rails.logger.warn("#{provider_label} sign-in error: #{params[:error]}")
27 return redirect_to signin_path, alert: "#{provider_label} sign-in was cancelled or failed. Please try again."
28 end
29
30 access_token = params[:access_token].to_s
31 if access_token.blank?
32 return redirect_to signin_path, alert: "#{provider_label} sign-in failed. Please try again."
33 end
34
35 profile = SmbcloudAuthService.me(access_token: access_token)
36 user = User.find_or_create_from_smbcloud(
37 profile,
38 access_token: access_token,
39 oauth_provider: provider_key
40 )
41
42 reset_session
43 session[:user_id] = user.id
44
45 return_to = session.delete(:return_to)
46 redirect_to(return_to || root_path, notice: "Welcome, #{user.display_name_or_username}!")
47
48 rescue SmbcloudAuthService::AuthenticationError => e
49 Rails.logger.warn("#{provider_label} sign-in auth error: #{e.message}")
50 redirect_to signin_path, alert: "#{provider_label} sign-in failed. Please try again."
51
52 rescue KeyError => e
53 Rails.logger.error("smbCloud configuration error during #{provider_label} sign-in: #{e.message}")
54 redirect_to signin_path, alert: "Authentication service is not configured. Please contact support."
55
56 rescue => e
57 Rails.logger.error("Unexpected #{provider_label} sign-in error: #{e.message}\n#{e.backtrace.first(5).join("\n")}")
58 redirect_to signin_path, alert: "An unexpected error occurred. Please try again."
59 end
60
61 private
62
63 def redirect_if_signed_in
64 redirect_to root_path, notice: "You are already signed in." if signed_in?
65 end
66 end
67 end