diff --git a/Gemfile b/Gemfile index 06508087..5e5823f6 100644 --- a/Gemfile +++ b/Gemfile @@ -33,6 +33,7 @@ gem 'hiera-eyaml' gem 'net-ldap', require: "net/ldap" gem 'breadcrumbs_on_rails' gem 'cancancan' +gem 'ruby-saml' # To use retry middleware with Faraday v2.0+ gem 'faraday-retry' diff --git a/Gemfile.lock b/Gemfile.lock index ba845ee7..d01c29d7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -332,6 +332,9 @@ GEM rubocop-rake (0.6.0) rubocop (~> 1.0) ruby-progressbar (1.11.0) + ruby-saml (1.15.0) + nokogiri (>= 1.13.10) + rexml ruby2_keywords (0.0.5) rubyzip (2.3.2) sassc (2.4.0) @@ -435,6 +438,7 @@ DEPENDENCIES rubocop rubocop-rails rubocop-rake + ruby-saml selenium-webdriver simplecov sprockets-rails diff --git a/app/controllers/saml_sessions_controller.rb b/app/controllers/saml_sessions_controller.rb new file mode 100644 index 00000000..fb0f97fb --- /dev/null +++ b/app/controllers/saml_sessions_controller.rb @@ -0,0 +1,41 @@ +class SamlSessionsController < ApplicationController + skip_before_action :authentication_required + skip_forgery_protection only: :create + + def new + saml_request = OneLogin::RubySaml::Authrequest.new + redirect_to saml_request.create(saml_settings), allow_other_host: true + end + + def create + saml_response = OneLogin::RubySaml::Response.new(params[:SAMLResponse]) + saml_response.settings = saml_settings + + if saml_response.is_valid? + user = find_or_create_user(saml_response) + session[:user_id] = user.id + if user.admin? + redirect_to users_path, notice: "Logged in!" + else + redirect_to root_url, notice: "Logged in!" + end + else + redirect_to new_session_path, alert: "Could not sign you in via SSO" + end + end + + private + + def find_or_create_user(saml_response) + User.find_or_create_by!(email: saml_response.nameid) do |user| + user.first_name = "SAML" + user.last_name = "User" + end + end + + def saml_settings + settings = Saml.new.settings + settings.assertion_consumer_service_url = saml_session_url + settings + end +end diff --git a/app/models/saml.rb b/app/models/saml.rb new file mode 100644 index 00000000..ac0a7beb --- /dev/null +++ b/app/models/saml.rb @@ -0,0 +1,14 @@ +class Saml + def self.configured? + Rails.configuration.hdm[:saml].present? + end + + def initialize + @hdm_settings = Rails.configuration.hdm[:saml] + @hdm_settings[:name_identifier_format] ||= "urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress" + end + + def settings + OneLogin::RubySaml::Settings.new(@hdm_settings) + end +end diff --git a/app/views/ldap_sessions/new.html.erb b/app/views/ldap_sessions/new.html.erb index 65acb536..4c7df0f1 100644 --- a/app/views/ldap_sessions/new.html.erb +++ b/app/views/ldap_sessions/new.html.erb @@ -1,13 +1,6 @@