Skip to content

Commit

Permalink
Adding alma as a login option
Browse files Browse the repository at this point in the history
Still need a message for the user when there are no optons
  • Loading branch information
carolyncole committed Apr 7, 2022
1 parent 492aa4e commit 73fc156
Show file tree
Hide file tree
Showing 33 changed files with 2,345 additions and 190 deletions.
2 changes: 1 addition & 1 deletion .rubocop_todo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ Metrics/BlockNesting:
# Offense count: 9
# Configuration parameters: CountComments.
Metrics/ClassLength:
Max: 303
Max: 308

# Offense count: 23
# Configuration parameters: IgnoredMethods.
Expand Down
2 changes: 1 addition & 1 deletion app/assets/stylesheets/components/user.scss
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ address .name, address .street {
}
}

.card-barcode {
.card-barcode, .card-alma {
margin: 0 10px 20px;

.card-header p {
Expand Down
7 changes: 4 additions & 3 deletions app/controllers/account_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,11 @@ def verify_user

def cas_user
if current_user
set_patron
if @patron && @patron[:barcode] && current_user.cas_provider?
redirect_to borrow_direct_url(@patron[:barcode])
if current_user.cas_provider?
set_patron
redirect_to borrow_direct_url(@patron[:barcode]) if @patron && @patron[:barcode]
else
@illiad_transactions = []
flash[:error] = I18n.t('blacklight.account.borrow_direct_ineligible')
redirect_to root_url
end
Expand Down
15 changes: 12 additions & 3 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,19 @@ class ApplicationController < ActionController::Base
protect_from_forgery with: :exception

def after_sign_in_path_for(_resource)
if params[:origin]
referrer = params[:url] || request.referer
origin = params[:origin]
if origin.blank? && referrer.present? && referrer.include?("origin")
referrer_params = Rack::Utils.parse_query URI.parse(referrer).query
origin = referrer_params["origin"]
end

if referrer.present? && !referrer.include?("sign_in")
referrer
elsif origin.present?
request.flash.delete('alert')
request.flash.keep('notice')
params[:origin].chomp('/email')
origin.chomp('/email')
elsif !request.env['omniauth.origin'].nil? &&
/request|borrow-direct|email|bookmarks|search_history|redirect-to-alma/.match(request.env['omniauth.origin'])
request.env['omniauth.origin']
Expand All @@ -27,7 +36,7 @@ def after_sign_in_path_for(_resource)
end

def after_sign_out_path_for(resource)
if resource == 'barcode'
if resource == 'barcode' || resource == "alma"
root_url
else
Rails.configuration.x.after_sign_out_url
Expand Down
18 changes: 18 additions & 0 deletions app/controllers/users/omniauth_callbacks_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,19 @@ def barcode
redirect_to user_barcode_omniauth_authorize_path(origin: omniauth_origin)
end

def alma
if Alma::User.authenticate(user_id: alma_params[:username], password: alma_params[:password])
@user ||= User.from_alma(access_token_in_request_params)
@user.save
sign_in_and_redirect @user, event: :authentication # this will throw if @user not activated
set_flash_message(:notice, :success, kind: 'with alma account') if is_navigational_format?
else
set_flash_message(:error, :failure,
reason: 'username or password did not match an alma account')
redirect_to user_barcode_omniauth_authorize_path(origin: omniauth_origin)
end
end

private

def barcode_user
Expand All @@ -55,6 +68,7 @@ def last_name_match?(username, last_name)
end

def netid_patron?(patron)
return false if patron['expire_date'].nil?
!patron['netid'].nil? && Date.parse(patron['expire_date']) > Time.zone.today
end

Expand All @@ -77,5 +91,9 @@ def barcode_token_in_request_params
access_token.uid = access_token.uid.gsub(/\s/, '') unless access_token.nil? || access_token.uid.blank?
access_token
end

def alma_params
params.permit(:username, :password)
end
end
end
33 changes: 27 additions & 6 deletions app/models/requests/patron.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ module Requests
class Patron
attr_reader :user, :session, :patron, :errors

delegate :guest?, :provider, :barcode_provider?, to: :user
delegate :guest?, :provider, :barcode_provider?, :cas_provider?, :alma_provider?, to: :user

def initialize(user:, session: {}, patron: nil)
@user = user
Expand Down Expand Up @@ -170,11 +170,11 @@ def api_request_patron(id:)
def current_patron(uid)
return unless uid

api_response = api_request_patron(id: uid)
return if api_response.nil?

patron_resource = JSON.parse(api_response.body)
patron_resource.with_indifferent_access
if alma_provider?
build_alma_patron(uid: uid)
else
build_cas_patron(uid: uid)
end
end

def build_access_patron(email:, user_name:)
Expand All @@ -194,5 +194,26 @@ def access_patron(email, user_name)
def access_patron?
barcode == "ACCESS"
end

def build_alma_patron(uid:)
alma_user = Alma::User.find(uid)
barcodes = alma_user["user_identifier"].select { |id| id["id_type"]["value"] == "BARCODE" }
{
last_name: alma_user.preferred_last_name,
active_email: alma_user.preferred_email,
barcode: barcodes.first&.fetch("value") || "ALMA",
barcode_status: 1,
netid: "ALMA",
university_id: uid
}
end

def build_cas_patron(uid:)
api_response = api_request_patron(id: uid)
return if api_response.nil?

patron_resource = JSON.parse(api_response.body)
patron_resource.with_indifferent_access
end
end
end
6 changes: 6 additions & 0 deletions app/models/requests/request.rb
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,12 @@ def scsb_location
doc['location_code_s'].first
end

def off_site?
return false if location['library'].nil? || location['library']['code'].nil?
library_code = location[:library][:code]
library_code == 'recap' || library_code == 'marquand' || library_code == 'annex'
end

private

### builds a list of possible requestable items
Expand Down
2 changes: 1 addition & 1 deletion app/models/requests/request_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class RequestDecorator
delegate :patron,
:ctx, :system_id, :language, :mfhd, :source, :holdings, :default_pick_ups,
:serial?, :borrow_direct_eligible?, :any_loanable_copies?, :requestable?, :all_items_online?,
:thesis?, :numismatics?, :single_aeon_requestable?, :eligible_for_library_services?,
:thesis?, :numismatics?, :single_aeon_requestable?, :eligible_for_library_services?, :off_site?,
:user_name, :email, # passed to request as login options on the request form
to: :request
delegate :content_tag, :hidden_field_tag, :concat, to: :view_context
Expand Down
15 changes: 9 additions & 6 deletions app/models/requests/requestable_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,11 @@ class RequestableDecorator

alias bib_id system_id

attr_reader :requestable, :view_context
def initialize(requestable, view_context)
attr_reader :requestable, :view_context, :for_fill_in
def initialize(requestable, view_context, for_fill_in: false)
@requestable = requestable
@view_context = view_context
@for_fill_in = for_fill_in
end

## If the item doesn't have any item level data use the holding mfhd ID as a unique key
Expand All @@ -26,15 +27,17 @@ def preferred_request_id
end

def digitize?
eligible_for_library_services? && (item_data? || !circulates?) && (on_shelf_edd? || recap_edd? || marquand_edd?) && !request_status?
return false unless patron.cas_provider? # only allow digitization for cas users
eligible_for_library_services? && (item_data? || !circulates? || for_fill_in) && (on_shelf_edd? || recap_edd? || marquand_edd?) && !request_status?
end

def fill_in_digitize?
return false unless patron.cas_provider? # only allow fill in digitization for cas users
!item_data? || digitize?
end

def pick_up?
return false if etas? || !eligible_to_pickup?
return false if etas? || !eligible_to_pickup? || (!patron.cas_provider? && !off_site?)
item_data? && (on_shelf? || recap? || annex?) && circulates? && !holding_library_in_library_only? && !scsb_in_library_use? && !request_status?
end

Expand All @@ -60,7 +63,7 @@ def help_me?
end

def will_submit_via_form?
return false unless eligible_for_library_services?
return false if !eligible_for_library_services? || (!patron.cas_provider? && !off_site?)
digitize? || pick_up? || scsb_in_library_use? || (ill_eligible? && patron.covid_trained?) || on_order? || in_process? || traceable? || off_site? || help_me?
end

Expand Down Expand Up @@ -101,7 +104,7 @@ def off_site_location
def create_fill_in_requestable
fill_in_req = Requestable.new(bib: bib, holding: holding, item: nil, location: location, patron: patron)
fill_in_req.services = services
RequestableDecorator.new(fill_in_req, view_context)
RequestableDecorator.new(fill_in_req, view_context, for_fill_in: true)
end

def libcal_url
Expand Down
9 changes: 5 additions & 4 deletions app/models/requests/router.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ class Router
attr_accessor :requestable
attr_reader :user, :any_loanable

delegate :cas_provider?, :barcode_provider?, to: :user
delegate :cas_provider?, :barcode_provider?, :alma_provider?, to: :user

def initialize(requestable:, user:, any_loanable: false)
@requestable = requestable
Expand Down Expand Up @@ -99,10 +99,11 @@ def calculate_recap_services
end

def calculate_unavailable_services
return [] unless cas_provider?
services = []
services << 'bd' if !requestable.enumerated? && cas_provider? && !any_loanable? && requestable.bib['isbn_s'].present?
services << 'bd' if !requestable.enumerated? && !any_loanable? && requestable.bib['isbn_s'].present?
# for mongraphs - title level check OR for serials - copy level check
services << 'ill' if (cas_provider? && !any_loanable?) || (cas_provider? && requestable.enumerated?)
services << 'ill' if !any_loanable? || requestable.enumerated?
services
end

Expand All @@ -129,7 +130,7 @@ def access_user?
end

def auth_user?
cas_provider? || barcode_provider?
cas_provider? || barcode_provider? || alma_provider?
end
end
end
18 changes: 18 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ def barcode_provider?
provider == 'barcode'
end

# Determines whether or not this is a user which is identifiable by alma
# @return [TrueClass, FalseClass]
def alma_provider?
provider == 'alma'
end

# Determines whether or not this is a user which is identifiable by cas
# @return [TrueClass, FalseClass]
def cas_provider?
Expand Down Expand Up @@ -60,6 +66,18 @@ def self.from_barcode(access_token)
end
end

# Retrieves a user authenticated using a alma account
# @param access_token [] access token containing the barcode accessed using #uid
# @return [User,nil]
def self.from_alma(access_token)
User.where(provider: access_token.provider, uid: access_token.uid).first_or_initialize do |user|
user.uid = access_token.uid
user.username = access_token.uid
user.guest = false
user.provider = access_token.provider
end
end

# Alternative to the implementation used in devise-guests, due to memory use
# problems when running that task
# https://github.com/cbeer/devise-guests/blob/7ab8c55d7a2b677ce61cc83486d6e3723d8795b2/lib/railties/devise_guests.rake
Expand Down
52 changes: 2 additions & 50 deletions app/views/devise/sessions/new.html.erb
Original file line number Diff line number Diff line change
@@ -1,51 +1,3 @@
<div class="col px-0">
<div class='card border-0'>
<div class='card-body text-center'>
<%= link_to t('blacklight.login.netid_login_msg'), user_cas_omniauth_authorize_path, :class => 'btn btn-primary' %>
<hr>
<p class="or-divider">
or
</p>
<p><a role="button" data-toggle="collapse" href="#collapseBarcode" aria-expanded="false" aria-controls="collapseBarcode" class="btn btn-outline-secondary">
<%= t('blacklight.login.barcode_login_msg') %>
</a></p>
</div>
</div>

<div class='card card-barcode collapse' id="collapseBarcode">
<div class='card-body'>
<%= simple_form_for(@user, url: user_barcode_omniauth_callback_path, class: 'form-horizontal', data: { toggle: 'validator' }) do |f| %>
<div class='field form-group col-md-12 row'>
<%= f.label 'Last name', class: 'control-label col-md-2 col-form-label' %>
<div class='col-md-5 <%= 'has-error' if flash[:last_name] %>'>
<%= text_field_tag 'last_name', '', class: 'form-control', autocomplete: 'off' %>
<% if flash[:last_name] %>
<span id="inputError2Status" class="sr-only">(error)</span>
<span class="error">Last name can't be blank</span>
<% end %>
</div>
</div>

<div class='field form-group col-md-12 row'>
<%= f.label 'Barcode', class: 'control-label col-md-2 col-form-label' %>
<div class='col-md-5 <%= 'has-error' if flash[:barcode] %>'>
<%= text_field_tag 'barcode', '22101', class: 'form-control', autocomplete: 'off' %>
<% if flash[:barcode] %>
<span id="inputError2Status" class="sr-only">(error)</span>
<span class="error">Barcode must be a 14-digit number</span>
<% end %>
</div>
</div>

<div class='login_actions form-group row'>
<div class='offset-md-2 col-md-10'>
<%= f.submit 'Log in', class: 'btn btn-outline-dark' %>
</div>
</div>
<% end %>
<div class='offset-md-2 col-md-8'>
<p><%=t('blacklight.login.barcode_help').html_safe%></p>
</div>
</div>
</div>
</div>
<%= render 'shared/login' %>
</div>
3 changes: 0 additions & 3 deletions app/views/requests/request/_cas_user_no_barcode.html.erb

This file was deleted.

3 changes: 0 additions & 3 deletions app/views/requests/request/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
<% end %>
<% elsif !@user.guest && @patron.blank? %>
<%= render partial: 'auth_user_lookup_fail' %>
<!-- Temporary change to allow students not on campus digitization, but not pick-up options -->
<%# elsif !@user.guest && @patron['barcode'].blank? %>
<%# = render partial: 'cas_user_no_barcode' %>
<% elsif @user.barcode_provider? %>
<%= render partial: 'no_access' %>
<% else %>
Expand Down
10 changes: 7 additions & 3 deletions app/views/requests/request/_request_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,12 @@
<span class="error error-items">
</span>
</div>
<%= render partial: "requestable_list_form", locals: { requestable_list: @request.requestable, mfhd: @request.mfhd, holdings: @request.holdings, default_pick_ups: @request.default_pick_ups } %>
<% if !@request.all_items_online? && @request.any_will_submit_via_form? %>
<%= f.submit submit_message(@request.requestable), class: "btn btn-primary submit--request", disabled: submit_button_disabled(@request.requestable), data: { disable_with: "Submitting Request" } %>
<% if @current_user.alma_provider? && !@request.off_site? %>
<h2>You may view this item at <%= @request.location_label %> </h2>
<% else %>
<%= render partial: "requestable_list_form", locals: { requestable_list: @request.requestable, mfhd: @request.mfhd, holdings: @request.holdings, default_pick_ups: @request.default_pick_ups } %>
<% if !@request.all_items_online? && @request.any_will_submit_via_form? %>
<%= f.submit submit_message(@request.requestable), class: "btn btn-primary submit--request", disabled: submit_button_disabled(@request.requestable), data: { disable_with: "Submitting Request" } %>
<% end %>
<% end %>
<% end %>
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
<% unless @patron.university_id.blank? %>
<div>
<%= radio_button_tag "requestable[][delivery_mode_#{requestable.preferred_request_id}]", "edd", selected, data: { target: "#fields-eed__#{requestable.preferred_request_id}" }, 'aria-controls' => "fields-eed__#{requestable.preferred_request_id}", class: 'control-label' %>
<%= label_tag "requestable[][delivery_mode_#{requestable.preferred_request_id}_edd]", "Electronic Delivery", class: 'control-label', id: "requestable__type_recap_edd_#{requestable.preferred_request_id}" %>
Expand All @@ -15,4 +14,3 @@
<%= hidden_field_tag "requestable[][library_code]", requestable.off_site_location %>
<%= hidden_field_tag "requestable[][type]", type %>
</div>
<% end %>
Loading

0 comments on commit 73fc156

Please sign in to comment.