forked from alphagov/e-petitions
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Replace developer strategy with SAML
- Loading branch information
Showing
25 changed files
with
514 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,45 @@ | ||
class Admin::OmniauthCallbacksController < Devise::OmniauthCallbacksController | ||
skip_before_action :require_admin | ||
skip_before_action :verify_authenticity_token, only: %i[developer] | ||
skip_before_action :verify_authenticity_token, only: %i[saml] | ||
|
||
def developer | ||
@user = AdminUser.find_by(email: omniauth_hash["uid"]) | ||
rescue_from ActiveRecord::RecordNotFound do | ||
redirect_to admin_login_url, alert: :login_failed | ||
end | ||
|
||
def saml | ||
@user = AdminUser.find_or_create_from!(provider, auth_data) | ||
|
||
if @user.present? | ||
sign_in_and_redirect @user, event: :authentication | ||
set_flash_message(:notice, :signed_in) if is_navigational_format? | ||
sign_in @user, event: :authentication | ||
|
||
set_flash_message(:notice, :signed_in) | ||
set_refresh_header | ||
|
||
render "admin/admin/index" | ||
else | ||
redirect_to admin_login_url, alert: :invalid_login | ||
end | ||
end | ||
|
||
def failure | ||
redirect_to admin_login_url, alert: :login_failed | ||
end | ||
|
||
private | ||
|
||
def after_omniauth_failure_path_for(scope) | ||
admin_login_url | ||
end | ||
|
||
def omniauth_hash | ||
def auth_data | ||
request.env["omniauth.auth"] | ||
end | ||
|
||
def provider | ||
IdentityProvider.find_by!(name: auth_data.provider) | ||
end | ||
|
||
def set_refresh_header | ||
headers['Refresh'] = "0; url=#{admin_root_url}" | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
class IdentityProvider | ||
class ProviderNotFound < ArgumentError; end | ||
|
||
class << self | ||
delegate :each, to: :providers | ||
|
||
def providers | ||
@providers ||= load_providers | ||
end | ||
|
||
def names | ||
providers.map(&:name) | ||
end | ||
|
||
def find_by(domain:) | ||
providers.detect { |provider| provider.domains.include?(domain) } | ||
end | ||
|
||
def find_by!(name:) | ||
providers.detect { |provider| provider.name.to_s == name } || raise_provider_not_found(name) | ||
end | ||
|
||
private | ||
|
||
def load_providers | ||
Rails.application.config_for(:sso).map { |options| IdentityProvider.new(options) } | ||
end | ||
|
||
def raise_provider_not_found(name) | ||
raise ProviderNotFound, "Couldn't find the provider '#{name}'" | ||
end | ||
end | ||
|
||
attr_reader :name, :attribute_statements | ||
attr_reader :assertion_consumer_service_url, :sp_entity_id | ||
attr_reader :idp_sso_service_url, :idp_cert, :domains | ||
attr_reader :sysadmins, :moderators, :reviewers | ||
|
||
def initialize(options) | ||
@name = options.fetch(:name).to_sym | ||
@attribute_statements = options.fetch(:attributes, default_attributes) | ||
@assertion_consumer_service_url = "#{Site.moderate_url}/admin/auth/#{name}/callback" | ||
@sp_entity_id = "#{Site.moderate_url}/admin/auth/#{name}" | ||
@idp_sso_service_url = options.fetch(:idp_sso_service_url) | ||
@idp_cert = options.fetch(:idp_cert, "") | ||
@domains = options.fetch(:domains) | ||
@sysadmins = options.fetch(:sysadmins, []) | ||
@moderators = options.fetch(:moderators, []) | ||
@reviewers = options.fetch(:reviewers, []) | ||
|
||
unless klass_defined? | ||
strategies.const_set(klass, new_klass) | ||
end | ||
end | ||
|
||
def to_param | ||
name.to_s | ||
end | ||
|
||
def config | ||
{ | ||
attribute_statements: attribute_statements, | ||
assertion_consumer_service_url: assertion_consumer_service_url, | ||
sp_entity_id: sp_entity_id, | ||
idp_sso_service_url: idp_sso_service_url, | ||
idp_cert: idp_cert | ||
} | ||
end | ||
|
||
private | ||
|
||
def default_attributes | ||
{ | ||
email: ["email"], | ||
first_name: ["first_name"], | ||
last_name: ["last_name"], | ||
groups: ["groups"] | ||
} | ||
end | ||
|
||
def strategies | ||
OmniAuth::Strategies | ||
end | ||
|
||
def parent_klass | ||
OmniAuth::Strategies::SAML | ||
end | ||
|
||
def new_klass | ||
Class.new(parent_klass) | ||
end | ||
|
||
def klass | ||
@klass ||= name.to_s.camelize.to_sym | ||
end | ||
|
||
def klass_defined? | ||
strategies.const_defined?(klass, false) | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,13 @@ | ||
<h1>Sign in</h1> | ||
<div class="grid-row"> | ||
<div class="column-half"> | ||
<%= form_tag(admin_auth_developer_path, method: :post) do %> | ||
<button type="submit" class="button">Login with developer strategy</button> | ||
<%= form_for(@user, as: :user, url: admin_login_path, authenticity_token: form_authenticity_token) do |form| %> | ||
<div class="form-group"> | ||
<%= form.label :email, "Email", class: "form-label" %> | ||
<%= form.text_field :email, class: "form-control", type: "email", autofocus: "autofocus" %> | ||
</div> | ||
|
||
<%= form.submit "Sign in", class: "button" %> | ||
<% end %> | ||
</div> | ||
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,10 @@ | ||
OmniAuth.configure do |config| | ||
config.logger = Rails.logger | ||
Rails.application.config.middleware.use OmniAuth::Builder do | ||
configure do |config| | ||
config.path_prefix = '/admin/auth' | ||
config.logger = Rails.logger | ||
end | ||
|
||
IdentityProvider.each do |idp| | ||
provider idp.name, idp.config | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
development: [] | ||
|
||
test: | ||
- name: "example" | ||
idp_sso_service_url: "http://localhost:3000/sso" | ||
domains: | ||
- "example.com" | ||
sysadmins: | ||
- "sysadmins" | ||
moderators: | ||
- "moderators" | ||
reviewers: | ||
- "reviewers" |
Oops, something went wrong.