diff --git a/Gemfile b/Gemfile index 1c84a426ad..87cbb14fac 100644 --- a/Gemfile +++ b/Gemfile @@ -79,6 +79,8 @@ gem 'equivalent-xml' gem 'net-ldap' + gem 'omniauth-cas' + group :assets, :production do gem 'coffee-rails' gem 'uglifier', '>= 1.0.3' diff --git a/app/controllers/users/providers_controller.rb b/app/controllers/users/providers_controller.rb new file mode 100644 index 0000000000..5db49d8b0f --- /dev/null +++ b/app/controllers/users/providers_controller.rb @@ -0,0 +1,80 @@ +# Copyright 2011-2015, The Trustees of Indiana University and Northwestern +# University. Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# --- END LICENSE_HEADER BLOCK --- + +class Users::ProvidersController < ApplicationController + + def login + logger.info "in omniauth callback after logging in" + + #4/25/16 current implemented provider is "CAS" + params[:provider] ? provider = params[:provider] : provider = "" + user_info = getExtraFromLDAP(request.env["omniauth.auth"].uid) + user_info["mail"] ? email = user_info["mail"][0] : email = "" + user_info["uid"] ? username = user_info["uid"][0] : username = "" + logger.info "provider: #{provider}" + logger.info "email: #{email}" + logger.info "username: #{username}" + + if provider.present? == false || email.present? == false || username.present? == false + logger.error "missing key info - provider, email, username" + flash[:error] = "Error retrieving user information" + redirect_to root_path and return + end + #service = Service.find_by_provider_uid(provider,uid) + user = User.where(provider: provider,username: username) + if user.empty? == false + logger.info "signing in as user #{user.inspect}" + if user[0].email != email + logger.info "email from ldap #{email} doesn't match email in this app #{user[0].email}, update." + user[0].email = email + user[0].save! + end + flash[:notice] = "Signed in successfully via #{provider.upcase} as #{username} with email #{email}." + sign_in_and_redirect(user[0]) and return + else + logger.info "no user found, creating #{provider.upcase} user #{username} email #{email}" + user = User.new(:username => username, :provider => provider, :email => email) + user.save! + flash[:notice] = "Sign in via #{provider.upcase} has been added to your account #{username} with email #{email}." + sign_in_and_redirect(user) and return + end + logger.error "Something went wrong on login." + flash[:error] = "Something went wrong on login. Contact administrator" + redirect_to root_path and return + end + + def logout + logger.info "logging out of cas" + sign_out(current_user) + redirect_to 'https://secure.its.yale.edu/cas/logout' + end + + protected + + def getExtraFromLDAP(netid) + begin + require 'net/ldap' + ldap = Net::LDAP.new( :host =>"directory.yale.edu" , :port =>"389" ) + f = Net::LDAP::Filter.eq('uid', netid) + b = 'ou=People,o=yale.edu' + p = ldap.search(:base => b, :filter => f, :return_result => true).first + rescue Exception => e + return + end + return p + end + + private + +end diff --git a/app/views/_user_util_links.html.erb b/app/views/_user_util_links.html.erb index 4ea6074637..b159b55d48 100644 --- a/app/views/_user_util_links.html.erb +++ b/app/views/_user_util_links.html.erb @@ -37,7 +37,7 @@ Unless required by applicable law or agreed to in writing, software distributed
  • <%= link_to_if user_signed_in?, 'Sign out', destroy_user_session_path do %> <%# Fallback if the test above fails %> - <%= link_to 'Sign in', new_user_session_path %> + <%= link_to 'Sign in', "users/auth/cas" %> <% end %> diff --git a/app/views/modules/_user_management.html.erb b/app/views/modules/_user_management.html.erb index ee10e57d68..283ae46b7b 100644 --- a/app/views/modules/_user_management.html.erb +++ b/app/views/modules/_user_management.html.erb @@ -15,7 +15,7 @@ Unless required by applicable law or agreed to in writing, software distributed %> <%# The containers for the links need to be defined by the calling partial %> <% if user_signed_in? %> - <%= user_key %> <%= link_to t('auth.sign_out'), destroy_user_session_path %> + <%= user_key %> <%= " #{current_user.email}" %><%= link_to t('auth.sign_out'), destroy_user_session_path %> <% else %> - <%= link_to t('auth.sign_in'), new_user_session_path %> + <%= link_to t('auth.sign_in'), "users/auth/cas" %> <% end %> diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb new file mode 100644 index 0000000000..06c4433eed --- /dev/null +++ b/config/initializers/omniauth.rb @@ -0,0 +1,8 @@ +Rails.application.config.middleware.use OmniAuth::Builder do + provider :cas, + host: 'secure.its.yale.edu', + login_url: '/cas/login', + service_validate_url: '/cas/serviceValidate', + disable_ssl_verification: true, + logout_url: '/cas/logout' +end diff --git a/config/routes.rb b/config/routes.rb index 38e8e6ccf0..49269f9366 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -20,11 +20,18 @@ root :to => "catalog#index" - devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }, format: false + #devise_for :users, :controllers => { :omniauth_callbacks => "users/omniauth_callbacks" }, format: false + #devise_scope :user do + # match '/users/sign_in', :to => "users/sessions#new", :as => :new_user_session, via: [:get] + # match '/users/sign_out', :to => "users/sessions#destroy", :as => :destroy_user_session, via: [:get] + #end + + devise_for :users devise_scope :user do - match '/users/sign_in', :to => "users/sessions#new", :as => :new_user_session, via: [:get] - match '/users/sign_out', :to => "users/sessions#destroy", :as => :destroy_user_session, via: [:get] + match 'users/auth/:provider/callback', :to => "users/providers#login", via: [:get] + match '/users/sign_out', :to => "users/providers#logout", :as => :destroy_user_session, via: [:get] end + match "/authorize", to: 'derivatives#authorize', via: [:get, :post] match "/authorize/:path", to: 'derivatives#authorize', via: [:get, :post] match "/autocomplete", to: 'object#autocomplete', via: [:get] diff --git a/db/schema.rb b/db/schema.rb index da1831013e..77645d3b09 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20150625121750) do +ActiveRecord::Schema.define(version: 20150824155143) do create_table "bookmarks", force: true do |t| t.integer "user_id", null: false @@ -82,8 +82,8 @@ add_index "searches", ["user_id"], name: "index_searches_on_user_id" create_table "sessions", force: true do |t| - t.string "session_id", null: false - t.text "data" + t.string "session_id", null: false + t.text "data", limit: 16777215 t.datetime "created_at" t.datetime "updated_at" end diff --git a/spec/controllers/users/providers_controller_spec.rb b/spec/controllers/users/providers_controller_spec.rb new file mode 100644 index 0000000000..e8ffe70d84 --- /dev/null +++ b/spec/controllers/users/providers_controller_spec.rb @@ -0,0 +1,37 @@ +# Copyright 2011-2015, The Trustees of Indiana University and Northwestern +# University. Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software distributed +# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR +# CONDITIONS OF ANY KIND, either express or implied. See the License for the +# specific language governing permissions and limitations under the License. +# --- END LICENSE_HEADER BLOCK --- + +require 'spec_helper' + +describe Users::ProvidersController do + describe "#login" do + describe "as an authenticated user" do + it "should flash error if provider is missing" do + end + it "should flash error if email missing" do + end + it "should flash error if username missing" do + end + it "should login new user with new provider and username, with email" do + end + it "should login existing user if provider and username exist and same email" do + end + it "should login existing user if provider and username exist and change email if email changed" do + end + it "currently 4-25-16 should have only have one provider that is cas" do + end + end + end + +end