Skip to content

Commit

Permalink
Remove Shibboleth
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex Dolski committed Jan 24, 2024
1 parent a94277b commit 19ed7b4
Show file tree
Hide file tree
Showing 35 changed files with 197 additions and 634 deletions.
1 change: 0 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@ gem "netaddr"
gem "omniauth-identity", git: "https://github.com/medusa-project/omniauth-identity.git"
gem "omniauth-rails_csrf_protection"
gem "omniauth-saml"
gem "omniauth-shibboleth"
# Our database
gem "pg"
# Our application server
Expand Down
3 changes: 0 additions & 3 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -275,8 +275,6 @@ GEM
omniauth-saml (2.1.0)
omniauth (~> 2.0)
ruby-saml (~> 1.12)
omniauth-shibboleth (1.3.0)
omniauth (>= 1.0.0)
parallel (1.23.0)
parser (3.2.2.4)
ast (~> 2.4.1)
Expand Down Expand Up @@ -444,7 +442,6 @@ DEPENDENCIES
omniauth-identity!
omniauth-rails_csrf_protection
omniauth-saml
omniauth-shibboleth
pg
puma
rails (~> 7.1)
Expand Down
10 changes: 3 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -196,10 +196,7 @@ These tasks are run via cron in the demo and production environments:
Authentication is handled by [OmniAuth](https://github.com/omniauth/omniauth).
OmniAuth supports many different providers, but the ones used by this app are:

* [Shibboleth](https://github.com/toyokazu/omniauth-shibboleth): handles SSO
authentication for UIUC only.
* [SAML](https://github.com/omniauth/omniauth-saml): handles SSO authentication
for many CARLI member institutions, as well as CARLI itself.
* [SAML](https://github.com/omniauth/omniauth-saml): handles SSO authentication.
* [Local identity](https://github.com/omniauth/omniauth-identity):
credentials are stored in a `credentials` database table associated with the
`users` table.
Expand All @@ -212,9 +209,8 @@ provider) calls back to `/auth/:provider/callback`, which is handled by

OmniAuth and its providers are configured in `config/initializers/omniauth.rb`.
Providers can be configured globally when they work the same across all
institutions (local identity), or work with only one institution (Shibboleth).
But the SAML provider in particular needs to be customized per-institution, so
that each institution can work with its own identity provider (IdP).
institutions (local identity), but the SAML provider in particular needs to be
customized per-institution.

Users who have associated local credentials can also log in via some other
provider, if configured, but not vice versa.
Expand Down
7 changes: 0 additions & 7 deletions app/assets/javascripts/institutions.js
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,6 @@ const InstitutionView = {
modalBody.html(data);
});
});
$("button.edit-shibboleth-authentication").on("click", function () {
const url = ROOT_URL + "/institutions/" + institutionKey + "/edit-shibboleth-authentication";
$.get(url, function (data) {
const modalBody = $("#edit-shibboleth-authentication-modal .modal-body");
modalBody.html(data);
});
});
});
});

Expand Down
14 changes: 0 additions & 14 deletions app/controllers/institutions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -146,14 +146,6 @@ def edit_settings
locals: { institution: @institution }
end

##
# Responds to `GET /institutions/:key/edit-shibboleth-authentication`
#
def edit_shibboleth_authentication
render partial: "institutions/shibboleth_authentication_form",
locals: { institution: @institution }
end

##
# Used for editing the theme.
#
Expand Down Expand Up @@ -958,12 +950,6 @@ def settings_params
:saml_sp_private_key,
:saml_sp_public_cert,
:saml_idp_sso_binding_urn,
:shibboleth_auth_enabled,
:shibboleth_email_attribute,
:shibboleth_extra_attributes,
:shibboleth_host,
:shibboleth_name_attributes,
:shibboleth_org_dn,
:sso_federation,
# Theme tab
:active_link_color,
Expand Down
13 changes: 0 additions & 13 deletions app/controllers/sessions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,6 @@ def new
session[:login_failure_url] = login_url
end

##
# Redirects to the Shibboleth login flow. Responds to
# `GET/POST /netid-login`.
#
def new_netid
if Rails.env.development? || Rails.env.test?
redirect_to "/auth/developer"
else
target = "https://#{current_institution.fqdn}/auth/shibboleth/callback"
redirect_to "/Shibboleth.sso/Login?target=#{target}"
end
end

##
# Handles callbacks from the auth provider (OmniAuth). Responsible for
# translating an authentication hash into a {User}, assigning the user to
Expand Down
26 changes: 15 additions & 11 deletions app/models/affiliation.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# frozen_string_literal: true

##
# University affiliation associated with {UserGroup} and Shibboleth-
# authenticated users.
# University affiliation associated with {UserGroup} and UIUC users.
#
# # Attributes
#
Expand All @@ -22,27 +21,32 @@ class Affiliation < ApplicationRecord
PHD_STUDENT_KEY = "phd"
UNDERGRADUATE_STUDENT_KEY = "undergrad"

ITRUST_AFFILIATION_ATTRIBUTE = "urn:oid:1.3.6.1.4.1.11483.101.1"
ITRUST_LEVEL_CODE_ATTRIBUTE = "urn:oid:1.3.6.1.4.1.11483.1.42"
ITRUST_PROGRAM_CODE_ATTRIBUTE = "urn:oid:1.3.6.1.4.1.11483.1.40"

##
# @param info [Hash] Shibboleth auth hash.
# @param info [Hash] OmniAuth auth hash.
#
def self.from_shibboleth(info)
def self.from_omniauth(info)
key = nil
info = info.dig("extra", "raw_info")
if info # this will be nil when using the OmniAuth developer strategy
info = info.symbolize_keys
info = info.deep_stringify_keys
# Explanation of this logic:
# https://uofi.app.box.com/notes/801448983786?s=5k6iiozlhp5mui5b4vrbskn3pu968j8r
if info[:iTrustAffiliation].match?(/staff|allied/)
if info[ITRUST_AFFILIATION_ATTRIBUTE].include?("staff") ||
info[ITRUST_AFFILIATION_ATTRIBUTE].include?("allied")
key = FACULTY_STAFF_KEY
elsif info[:iTrustAffiliation].include?("student")
if %w(1G 1V 1M 1L).include?(info[:levelCode])
elsif info[ITRUST_AFFILIATION_ATTRIBUTE].include?("student")
if %w(1G 1V 1M 1L).include?(info[ITRUST_LEVEL_CODE_ATTRIBUTE])
key = GRADUATE_STUDENT_KEY
elsif info[:levelCode] == "1U"
elsif info[ITRUST_LEVEL_CODE_ATTRIBUTE] == "1U"
key = UNDERGRADUATE_STUDENT_KEY
end
if %w(PHD CAS).include?(info[:programCode])
if %w(PHD CAS).include?(info[ITRUST_PROGRAM_CODE_ATTRIBUTE])
key = PHD_STUDENT_KEY
elsif info[:programCode].present?
elsif info[ITRUST_PROGRAM_CODE_ATTRIBUTE].present?
key = MASTERS_STUDENT_KEY
end
end
Expand Down
11 changes: 9 additions & 2 deletions app/models/department.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
# frozen_string_literal: true

##
# University department associated with a {UserGroup} and a
# {#User::AuthType::SHIBBOLETH} user.
# University department associated with a {UserGroup} and a UIUC user.
#
# This table is not normalized--multiple same-named departments may exist,
# associated with different entities, with {name} being used for comparison.
Expand All @@ -16,9 +15,17 @@
#
class Department < ApplicationRecord

ITRUST_DEPARTMENT_CODE_ATTRIBUTE = "urn:oid:1.3.6.1.4.1.11483.1.122"

belongs_to :user, optional: true
belongs_to :user_group, optional: true

normalizes :name, with: -> (value) { value.squish }

def self.from_omniauth(auth)
auth = auth.deep_stringify_keys
name = auth.dig("extra", "raw_info", ITRUST_DEPARTMENT_CODE_ATTRIBUTE)
Department.new(name: name)
end

end
34 changes: 2 additions & 32 deletions app/models/institution.rb
Original file line number Diff line number Diff line change
Expand Up @@ -138,17 +138,6 @@
# * `service_name` Name of the service that the
# institution is running. For example, at
# UIUC, this would be "IDEALS."
# * `shibboleth_auth_enabled` Whether Shibboleth authentication is
# enabled.
# * `shibboleth_email_attribute` Shibboleth email attribute.
# * `shibboleth_extra_attributes` Array of extra attributes to request
# from the Shibboleth IdP. This can also
# be set to a comma-separated string
# which will be transformed into an array
# upon save.
# * `shibboleth_name_attribute` Shibboleth name attribute.
# * `shibboleth_org_dn` Value of an `eduPersonOrgDN` attribute
# from the Shibboleth IdP.
# * `sso_federation` Set to one of the
# {Institution::SSOFederation} constant
# values.
Expand Down Expand Up @@ -248,8 +237,6 @@ def self.label_for(value)
has_many :users
has_many :vocabularies

serialize :shibboleth_extra_attributes, coder: JSON

normalizes :copyright_notice, :google_analytics_measurement_id,
:saml_idp_encryption_cert, :saml_idp_encryption_cert2,
:saml_idp_signing_cert, :saml_idp_signing_cert2,
Expand Down Expand Up @@ -307,8 +294,6 @@ def self.label_for(value)
:add_default_metadata_profile, :add_default_submission_profile,
:add_default_index_pages, :add_default_user_groups

before_save :arrayize_shibboleth_extra_attributes_csv

##
# @param extension [String]
# @return [String]
Expand Down Expand Up @@ -436,7 +421,7 @@ def self.item_counts(include_buried: false)
# @return [Boolean] Whether at least one authentication method is enabled.
#
def auth_enabled?
local_auth_enabled || saml_auth_enabled || shibboleth_auth_enabled
local_auth_enabled || saml_auth_enabled
end

##
Expand Down Expand Up @@ -732,7 +717,7 @@ def scope_url
# @return [Boolean]
#
def sso_enabled?
saml_auth_enabled || shibboleth_auth_enabled
saml_auth_enabled
end

##
Expand Down Expand Up @@ -1146,21 +1131,6 @@ def add_default_user_groups
self.administrator_groups.build(user_group: admins).save!
end

##
# {shibboleth_extra_attributes} is a serialized array. This method allows us
# to set it to a comma-separated string (from e.g. a textarea) and have it
# auto-transformed into an array.
#
def arrayize_shibboleth_extra_attributes_csv
if self.shibboleth_extra_attributes.kind_of?(String) &&
self.shibboleth_extra_attributes&.include?(",") &&
!self.shibboleth_extra_attributes.start_with?("[") &&
!self.shibboleth_extra_attributes.end_with?("]")
self.shibboleth_extra_attributes =
self.shibboleth_extra_attributes.split(",").map(&:strip)
end
end

def disallow_key_changes
if !new_record? && key_changed?
errors.add(:key, "cannot be changed")
Expand Down
20 changes: 9 additions & 11 deletions app/models/login.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,13 @@
class Login < ApplicationRecord

class Provider
# Credentials are stored in the `credentials` table.
LOCAL = 0
# Used only by UIUC.
SHIBBOLETH = 1
LOCAL = 0
# Used by many CARLI member institutions, and CARLI itself.
SAML = 2
SAML = 2

##
# @return [Enumerable<Integer>]
#
def self.all
self.constants.map{ |c| self.const_get(c) }.sort
end
Expand All @@ -35,7 +35,9 @@ def self.label_for(value)
"Local"
when SAML
"SAML"
when SHIBBOLETH
when 1
# SHIBBOLETH (removed, but there are still some old Logins in the
# database associated with this provider)
"Shibboleth"
else
"Unknown"
Expand Down Expand Up @@ -65,16 +67,12 @@ def auth_hash=(auth)
auth[:extra][:raw_info] = auth[:extra][:raw_info].attributes
auth[:extra][:response_object] = nil
end

case auth[:provider]
when "shibboleth", "developer"
self.provider = Provider::SHIBBOLETH
when "saml"
when "saml", "developer"
self.provider = Provider::SAML
when "identity"
self.provider = Provider::LOCAL
end

super(auth)
end

Expand Down
Loading

0 comments on commit 19ed7b4

Please sign in to comment.