aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/welcome_controller.rb102
1 files changed, 67 insertions, 35 deletions
diff --git a/app/controllers/welcome_controller.rb b/app/controllers/welcome_controller.rb
index 0ca7af4..5e80d26 100644
--- a/app/controllers/welcome_controller.rb
+++ b/app/controllers/welcome_controller.rb
@@ -6,60 +6,42 @@ class WelcomeController < ApplicationController
# GET /authenticate(/:token)
# Discourse SSO Authentication
def authenticate
- # Ensure nobody tries silly things with our session
- if params[:token].present? && !params[:token].match?(/[a-z0-9]{32}/)
- raise(ArgumentError, "Token invalid")
- end
+ validate_token_format!
# Try an ongoing SSO or create a new one
@sso = SSO::FromDiscourse.new(token: params[:token], nonce: session[params[:token]])
- # Remove any current session
- Rails.logger.info("Removing current session (#{session[:current_user]})")
- session.destroy
- @current_user = nil
- if params[:token].nil? # Send to authenticate
+ clear_current_session
+
+ # Start SSO roundtrip if we're not passed a token
+ if params[:token].nil?
# Record this token and nonce in the session
session[@sso.token] = @sso.nonce
- # Send to authorization
+ # Send to SSO authenticator
redirect_to @sso.request_uri and return
end
- # Validate authentication
+ # Validate authentication params from SSO
begin
@sso.parse(params)
rescue ArgumentError => e
- return 403, e.message
+ Rails.logger.debug("SSO request failed: #{e.message}")
+ return :forbidden
end
+ # Resolve SSO and finish authentication
case @sso.status
- when :unauthorized
- Rails.logger.info("Authentication failed!")
- return 403
when :ok
Rails.logger.info("Authentication succeeded!")
- @current_user = User.find_by(external_id: @sso.user_info[:external_id]) ||
- begin
- Rails.logger.info('new user...')
- u = User.create(
- external_id: @sso.user_info[:external_id],
- avatar_url: @sso.user_info[:avatar_url],
- email: @sso.user_info[:email],
- name: @sso.user_info[:name],
- username: @sso.user_info[:username])
- Rails.logger.info('created user %s' % u.inspect)
- u
- rescue Exception => e
- raise
- end
- # Update user agents
- if @current_user.present?
- AgencyWatcherJob.perform_later(@current_user, @sso.user_info[:groups].split(','))
- end
- # Save User ID in session
- session[:current_user] = @current_user[:external_id]
+ find_or_create_current_user
+ perform_background_jobs
+ update_current_session
+ when :unauthorized
+ Rails.logger.info("Authentication failed!")
end
+ return :forbidden unless @current_user.present?
+ # TODO add some memory of previously called URL and return there
redirect_to '/my/dashboard'
end
@@ -73,4 +55,54 @@ class WelcomeController < ApplicationController
session.destroy
render :index
end
+
+ private
+
+ # Ensure nobody tries silly things with our session
+ def validate_token_format!
+ if params[:token].present? && !params[:token].match?(/[a-z0-9]{32}/)
+ raise(ArgumentError, "Token invalid")
+ end
+ end
+
+ # Remove any current session
+ def clear_current_session
+ Rails.logger.info("Removing current session (#{session[:current_user]})")
+ session.destroy
+ @current_user = nil
+ end
+
+ # Set @current_user to existing or new User record from SSO user info
+ def find_or_create_current_user
+ @current_user = User.find_by(external_id: @sso.user_info[:external_id]) ||
+ begin
+ Rails.logger.info('new user...')
+ u = User.create(
+ external_id: @sso.user_info[:external_id],
+ avatar_url: @sso.user_info[:avatar_url],
+ email: @sso.user_info[:email],
+ name: @sso.user_info[:name],
+ username: @sso.user_info[:username])
+ Rails.logger.info('created user %s' % u.inspect)
+ u
+ rescue Exception => e
+ Rails.logger.warning("#{e.type}: #{e.message}")
+ end
+ end
+
+ # Update user agents
+ def perform_background_jobs
+ if @current_user.present?
+ AgencyWatcherJob.perform_later(@current_user, @sso.user_info[:groups].split(','))
+ end
+ end
+
+ # Save User ID and current agent in session
+ def update_current_session
+ if @current_user.present?
+ session[:current_user] = @current_user[:external_id]
+ # TODO: make this a bit smarter
+ session[:current_agent] = @current_user&.agents&.pluck(:name)&.last
+ end
+ end
end