Skip to content

Commit

Permalink
Extract EncryptedUser functionality for use in other controllers
Browse files Browse the repository at this point in the history
  • Loading branch information
jcoyne committed Nov 14, 2014
1 parent d204d82 commit a4f89a3
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 63 deletions.
1 change: 1 addition & 0 deletions lib/blacklight.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module Blacklight
autoload :Controller, 'blacklight/controller'
autoload :Base, 'blacklight/base'
autoload :Catalog, 'blacklight/catalog'
autoload :EncryptedUser, 'blacklight/encrypted_user'
autoload :Bookmarks, 'blacklight/bookmarks'
autoload :DocumentPresenter, 'blacklight/document_presenter'

Expand Down
79 changes: 16 additions & 63 deletions lib/blacklight/bookmarks.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- encoding : utf-8 -*-
# note that while this is mostly restful routing, the #update and #destroy actions
# take the Solr document ID as the :id, NOT the id of the actual Bookmark action.
# take the Solr document ID as the :id, NOT the id of the actual Bookmark action.
module Blacklight::Bookmarks
extend ActiveSupport::Concern

Expand All @@ -9,15 +9,11 @@ module Blacklight::Bookmarks
# Give Bookmarks access to the CatalogController configuration
include Blacklight::Configurable
include Blacklight::SolrHelper
include Blacklight::EncryptedUser

copy_blacklight_config_from(CatalogController)

rescue_from Blacklight::Exceptions::ExpiredSessionToken do
head :unauthorized
end

before_filter :verify_user
helper_method :encrypt_user_id

self.document_actions = document_actions.reject { |k,v| k == :sms }
end
Expand All @@ -31,7 +27,7 @@ def action_documents
def action_success_redirect_path
bookmarks_path
end

# Blacklight uses #search_action_url to figure out the right URL for
# the global search box
def search_action_url *args
Expand All @@ -41,7 +37,7 @@ def search_action_url *args
def index
@bookmarks = token_or_current_or_guest_user.bookmarks
bookmark_ids = @bookmarks.collect { |b| b.document_id.to_s }

@response, @document_list = get_solr_response_for_document_ids(bookmark_ids)

respond_to do |format|
Expand All @@ -62,14 +58,14 @@ def update
create
end

# For adding a single bookmark, suggest use PUT/#update to
# For adding a single bookmark, suggest use PUT/#update to
# /bookmarks/$docuemnt_id instead.
# But this method, accessed via POST to /bookmarks, can be used for
# creating multiple bookmarks at once, by posting with keys
# such as bookmarks[n][document_id], bookmarks[n][title].
# such as bookmarks[n][document_id], bookmarks[n][title].
# It can also be used for creating a single bookmark by including keys
# bookmark[title] and bookmark[document_id], but in that case #update
# is simpler.
# is simpler.
def create
if params[:bookmarks]
@bookmarks = params[:bookmarks]
Expand All @@ -80,7 +76,7 @@ def create
current_or_guest_user.save! unless current_or_guest_user.persisted?

success = @bookmarks.all? do |bookmark|
current_or_guest_user.bookmarks.where(bookmark).exists? || current_or_guest_user.bookmarks.create(bookmark)
current_or_guest_user.bookmarks.where(bookmark).exists? || current_or_guest_user.bookmarks.create(bookmark)
end

if request.xhr?
Expand All @@ -95,9 +91,9 @@ def create
redirect_to :back
end
end

# Beware, :id is the Solr document_id, not the actual Bookmark id.
# idempotent, as DELETE is supposed to be.
# idempotent, as DELETE is supposed to be.
def destroy
bookmark = current_or_guest_user.bookmarks.where(document_id: params[:id], document_type: blacklight_config.solr_document_model).first

Expand All @@ -108,23 +104,23 @@ def destroy
flash[:notice] = I18n.t('blacklight.bookmarks.remove.success')
else
flash[:error] = I18n.t('blacklight.bookmarks.remove.failure')
end
end
redirect_to :back
else
# ajaxy request needs no redirect and should not have flash set
success ? render(json: { bookmarks: { count: current_or_guest_user.bookmarks.count }}) : render(:text => "", :status => "500")
end
end
end

def clear
def clear
if current_or_guest_user.bookmarks.clear
flash[:notice] = I18n.t('blacklight.bookmarks.clear.success')
flash[:notice] = I18n.t('blacklight.bookmarks.clear.success')
else
flash[:error] = I18n.t('blacklight.bookmarks.clear.failure')
flash[:error] = I18n.t('blacklight.bookmarks.clear.failure')
end
redirect_to :action => "index"
end

protected
def verify_user
unless current_or_guest_user or (action == "index" and token_or_current_or_guest_user)
Expand All @@ -135,47 +131,4 @@ def verify_user
def start_new_search_session?
action_name == "index"
end

# Used for #export action, with encrypted user_id.
def decrypt_user_id(encrypted_user_id)
user_id, timestamp = message_encryptor.decrypt_and_verify(encrypted_user_id)

if timestamp < 1.hour.ago
raise Blacklight::Exceptions::ExpiredSessionToken.new
end

user_id
end

# Used for #export action with encrypted user_id, available
# as a helper method for views.
def encrypt_user_id(user_id)
message_encryptor.encrypt_and_sign([user_id, Time.now])
end

##
# This method provides Rails 3 compatibility to our message encryptor.
# When we drop support for Rails 3, we can just use the AS::KeyGenerator
# directly instead of this helper.
def bookmarks_export_secret_token salt
OpenSSL::PKCS5.pbkdf2_hmac_sha1(Blacklight.secret_key, salt, 1000, 64)
end

def message_encryptor
derived_secret = bookmarks_export_secret_token("bookmarks session key")
ActiveSupport::MessageEncryptor.new(derived_secret)
end

def token_or_current_or_guest_user
token_user || current_or_guest_user
end

def token_user
@token_user ||= if params[:encrypted_user_id]
user_id = decrypt_user_id params[:encrypted_user_id]
User.find(user_id)
else
nil
end
end
end
59 changes: 59 additions & 0 deletions lib/blacklight/encrypted_user.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
module Blacklight::EncryptedUser
extend ActiveSupport::Concern

included do
helper_method :encrypt_user_id

rescue_from Blacklight::Exceptions::ExpiredSessionToken do
head :unauthorized
end

end

protected

def token_or_current_or_guest_user
token_user || current_or_guest_user
end

def token_user
@token_user ||= if params[:encrypted_user_id]
user_id = decrypt_user_id params[:encrypted_user_id]
User.find(user_id)
else
nil
end
end

# Used for #export action, with encrypted user_id.
def decrypt_user_id(encrypted_user_id)
user_id, timestamp = message_encryptor.decrypt_and_verify(encrypted_user_id)

if timestamp < 1.hour.ago
raise Blacklight::Exceptions::ExpiredSessionToken.new
end

user_id
end

# Used for #export action with encrypted user_id, available
# as a helper method for views.
def encrypt_user_id(user_id)
message_encryptor.encrypt_and_sign([user_id, Time.now])
end

##
# This method provides Rails 3 compatibility to our message encryptor.
# When we drop support for Rails 3, we can just use the AS::KeyGenerator
# directly instead of this helper.
def bookmarks_export_secret_token salt
OpenSSL::PKCS5.pbkdf2_hmac_sha1(Blacklight.secret_key, salt, 1000, 64)
end

def message_encryptor
derived_secret = bookmarks_export_secret_token("bookmarks session key")
ActiveSupport::MessageEncryptor.new(derived_secret)
end


end

0 comments on commit a4f89a3

Please sign in to comment.