Skip to content

Commit 719add7

Browse files
author
goldsmithb
committed
update omniauth-cul to 0.3.0
1 parent 9a443e2 commit 719add7

File tree

10 files changed

+48
-73
lines changed

10 files changed

+48
-73
lines changed

Gemfile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ gem 'grape-swagger', '~> 2.0.0'
2929
gem 'mustermann', '~> 2.0'
3030
gem 'om', '3.1.1'
3131
gem 'omniauth', '>= 2.1'
32-
gem 'omniauth-cul'
33-
gem 'omniauth-rails_csrf_protection', '~> 1.0'
32+
gem 'omniauth-cul', '~> 0.3.0'
3433

3534
gem 'http'
3635
gem 'jbuilder', '~> 2.13.0'

Gemfile.lock

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -387,12 +387,9 @@ GEM
387387
hashie (>= 3.4.6)
388388
rack (>= 2.2.3)
389389
rack-protection
390-
omniauth-cul (0.2.0)
390+
omniauth-cul (0.3.0)
391391
devise (>= 4.9)
392392
omniauth (>= 2.0)
393-
omniauth-rails_csrf_protection (1.0.2)
394-
actionpack (>= 4.2)
395-
omniauth (~> 2.0)
396393
orm_adapter (0.5.0)
397394
ostruct (0.6.3)
398395
parallel (1.27.0)
@@ -753,8 +750,7 @@ DEPENDENCIES
753750
okcomputer
754751
om (= 3.1.1)
755752
omniauth (>= 2.1)
756-
omniauth-cul
757-
omniauth-rails_csrf_protection (~> 1.0)
753+
omniauth-cul (~> 0.3.0)
758754
premailer (~> 1.27.0)
759755
premailer-rails
760756
puma (~> 5.2)

app/controllers/users/omniauth_callbacks_controller.rb

Lines changed: 29 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,43 @@
33
require 'omniauth/cul'
44

55
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
6-
# Adding the line below so that if the auth endpoint POSTs to our cas endpoint, it won't
7-
# be rejected by authenticity token verification.
86
# See https://github.com/omniauth/omniauth/wiki/FAQ#rails-session-is-clobbered-after-callback-on-developer-strategy
9-
skip_before_action :verify_authenticity_token, only: :cas
7+
# The CAS login redirect to the columbia_cas callback endpoint AND the developer form submission to the
8+
# developer_uid callback do not send authenticity tokens, so we'll skip token verification for these actions.
9+
skip_before_action :verify_authenticity_token, only: [:columbia_cas, :developer_uid]
1010

11-
def app_cas_callback_endpoint
12-
"#{request.base_url}/users/auth/cas/callback"
13-
end
11+
# POST /users/auth/developer_uid/callback
12+
def developer_uid
13+
return unless Rails.env.development? # Only allow this action to run in the development environment
1414

15-
# In local development, use devise's controller action. In deployed env, use CAS server
16-
def passthru
17-
if Rails.env.development?
18-
super
19-
else
20-
redirect_to Omniauth::Cul::Cas3.passthru_redirect_url(app_cas_callback_endpoint), allow_other_host: true
21-
end
22-
end
15+
uid = params[:uid]
16+
user = User.find_by(uid: uid)
2317

24-
def developer
25-
current_user ||= User.find_or_create_by(
26-
uid: request.env['omniauth.auth'][:uid], provider: :developer
27-
)
18+
unless user
19+
flash[:alert] = "Login attempt failed. User #{uid} does not have an account."
20+
redirect_to root_path
21+
return
22+
end
2823

29-
sign_in_and_redirect current_user, event: :authentication
24+
flash[:success] = 'You have succesfully logged in.'
25+
sign_in_and_redirect user, event: :authentication # this will throw if user is not activated
3026
end
3127

32-
def cas
33-
user_id, _affils = Omniauth::Cul::Cas3.validation_callback(request.params['ticket'], app_cas_callback_endpoint)
28+
# POST /users/auth/columbia_cas/callback
29+
def columbia_cas # rubocop:disable Metrics/AbcSize
30+
callback_url = user_columbia_cas_omniauth_callback_url # The columbia_cas callback route in this application
31+
uid, _affils = Omniauth::Cul::ColumbiaCas.validation_callback(request.params['ticket'], callback_url)
3432

35-
user = User.find_by(uid: user_id) || User.create!(
36-
uid: user_id,
37-
email: "#{user_id}@columbia.edu"
38-
)
33+
user = User.find_by(uid: uid) || User.create(uid: uid, email: "#{uid}@columbia.edu")
34+
flash[:success] = 'You have succesfully logged in.'
3935
sign_in_and_redirect user, event: :authentication
36+
rescue Omniauth::Cul::Exceptions::Error => e
37+
# If an unexpected CAS ticket validation occurs, log the error message and ask the user to try
38+
# logging in again. Do not display the exception object's original message to the user because it may
39+
# contain information that only a developer should see.
40+
error_message = 'CAS login validation failed. Please try again.'
41+
Rails.logger.debug(error_message + " #{e.class.name}: #{e.message}")
42+
flash[:alert] = error_message
43+
redirect_to root_path
4044
end
4145
end

app/controllers/users/sessions_controller.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ class Users::SessionsController < Devise::SessionsController
77
# that sends a POST req to our omniauth endpoint (this is the secure way and
88
# POST is not possible with redirect_to)
99
# inspiration: https://stackoverflow.com/questions/985596/redirect-to-using-post-in-rails
10-
def new
11-
render 'users/sessions/new'
10+
def new # rubocop:disable Lint/UselessMethodDefinition
11+
super
1212
end
1313

1414
# This is needed if not using database authenticable (see https://github.com/heartcombo/devise/wiki/OmniAuth:-Overview#using-omniauth-without-other-authentications)

app/models/user.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class User < ApplicationRecord
1111
before_save :set_personal_info_via_ldap
1212

1313
# Configure devise for our User model
14-
devise :rememberable, :trackable, :omniauthable, omniauth_providers: [Rails.env.development? ? :developer : :cas]
14+
devise :rememberable, :trackable, :omniauthable, omniauth_providers: Devise.omniauth_configs.keys
1515

1616
ADMIN = 'admin'.freeze
1717
ROLES = [ADMIN].freeze

app/views/users/sessions/new.html.erb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
Our Sessions Controller is scoped to users (not user), hence the directory
55
structure. %>
66

7-
<%= form_with url: (Rails.env.development? ? user_developer_omniauth_authorize_path : user_cas_omniauth_authorize_path),
7+
<%= form_with url: (Rails.env.development? ? user_developer_uid_omniauth_authorize_path : user_columbia_cas_omniauth_authorize_path),
88
method: :post, data: { turbo: false }, id: 'signInForm' do |f| %>
99
<p>Redirecting you to be authenticated...</p>
1010
<%= f.submit 'Sign In', style: 'display: none;', id: 'signInRedirect' %>

config/initializers/devise.rb

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -250,11 +250,8 @@
250250
# config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
251251
# config.omniauth :developer, { fields: [:uid], uid_field: :uid } # TODO : These options...
252252

253-
if Rails.env.development?
254-
config.omniauth :developer, fields: [:uid], uid_field: :uid
255-
else
256-
config.omniauth :cas, strategy_class: Omniauth::Cul::Strategies::Cas3Strategy
257-
end
253+
config.omniauth :columbia_cas, { label: 'Columbia SSO (CAS)' }
254+
config.omniauth :developer_uid, { label: 'Developer UID' } if Rails.env.development?
258255

259256
# ==> Warden configuration
260257
# If you want to use other strategies, that are not supported by Devise, or

config/initializers/omniauth.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# frozen_string_literal: true
2+
3+
# From omniauth-cul v0.3.0 Readme
4+
# Mitigate CVE-2015-9284
5+
OmniAuth.config.request_validation_phase = OmniAuth::AuthenticityTokenProtection.new(key: :_csrf_token)

config/routes.rb

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,32 +4,13 @@
44
# temporarily removing range slider
55
# concern :range_searchable, BlacklightRangeLimit::Routes::RangeSearchable.new
66

7-
# When we are doing local development, we use omniauth's built-in developer strategy with devise's built-in omniauth
8-
# engine. By not skipping :omniauth_callbacks in development, devise creates the routes /users/auth/developer and
9-
# /users/auth/developer/callback and configures them to use devise's omniauth_callbacks_controller actions.
10-
# In deployed environments, we use CUL's cas server (with the omniauth-cul gem) to authenticate users, with our
11-
# custom defined routes and custom omniauth_callbacks_controller.
12-
# If we had not skipped the creation of these routes by devise, we would be able to authenticate users with our CAS
13-
# server, but Academic Commons would be vulnerable to CVE-2015-9284, because the devise routes allow clients to make
14-
# a GET request to users/auth/cas (instead of requiring a POST request).
15-
# We are trying to find a more elegant way to do this (and the documentation for omniauth implies that with v2, GET
16-
# requests should not be allowed, even if we have not gotten it to work), but this is a secure workaround for now.
17-
skip_omniauth_callbacks = Rails.env.development? ? [] : [:omniauth_callbacks]
18-
devise_for :users,
19-
controllers: { sessions: 'users/sessions', omniauth_callbacks: 'users/omniauth_callbacks' },
20-
skip: skip_omniauth_callbacks
21-
7+
# Create the sign in and sign out routes (simply redirects to our auth endpoint), needed for redirecting on
8+
# cancancan access denied error
229
devise_scope :user do
23-
# Create the sign in and sign out routes (simply redirects to our auth endpoint), needed for redirecting on
24-
# cancancan access denied error
2510
delete 'sign_out', to: 'users/sessions#destroy', as: :destroy_user_session
2611
get 'sign_in', to: 'users/sessions#new', as: :new_user_session
27-
# Create the routes for omniauth auth and callback routes (unless doing local development) (see comment above)
28-
unless Rails.env.development?
29-
post 'users/auth/cas', to: 'users/omniauth_callbacks#passthru', as: :user_cas_omniauth_authorize
30-
get 'users/auth/cas/callback', to: 'users/omniauth_callbacks#cas', as: :user_cas_omniauth_callback
31-
end
3212
end
13+
devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' }
3314

3415
root to: "catalog#home"
3516

spec/controllers/users/omniauth_callbacks_controller_spec.rb

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,19 @@
55
RSpec.describe Users::OmniauthCallbacksController, type: :controller do
66
include_context 'mock ldap request' # provides uni, cul_ldap, and cul_ldap entry as well as mocks LDAP methods
77

8-
# let(:uid) { 'abc123' }
98
let(:auth_hash) do
109
OmniAuth::AuthHash.new({ 'uid' => uni, 'extra' => {} })
1110
end
1211

13-
# let(:cul_ldap_entry) do
14-
# instance_double('Cul::LDAP::Entry', uni: 'abc123', email: 'abc123@columbia.edu', last_name: 'Doe', first_name: 'Jane')
15-
# end
16-
1712
before :each do
1813
request.env['devise.mapping'] = Devise.mappings[:user]
19-
allow(Omniauth::Cul::Cas3).to receive(:validation_callback).and_return([uni, nil])
20-
# allow_any_instance_of(Cul::LDAP).to receive(:initialize).and_return(cul_ldap)
21-
# allow_any_instance_of(Cul::LDAP).to receive(:find_by_uni).with(uid).and_return(cul_ldap_entry)
14+
allow(Omniauth::Cul::ColumbiaCas).to receive(:validation_callback).and_return([uni, nil])
2215
end
2316

2417
# GET :cas
2518
describe '#cas' do
2619
before :each do
27-
get :cas
20+
get :columbia_cas
2821
end
2922

3023
it 'creates new user' do

0 commit comments

Comments
 (0)