Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
2883ec5
thinkwell/yolk#78 : integrate resource db lookup into authenticate_cr…
dominiksteiner May 6, 2020
2f39ea2
thinkwell/yolk#78 : check UserToken in token_authenticatable
dominiksteiner May 6, 2020
bdca434
thinkwell/yolk#78 : fix log message
dominiksteiner May 6, 2020
776bf1c
thinkwell/yolk#78 : update password only if not pwd exist or invalid …
dominiksteiner May 7, 2020
ed1e910
thinkwell/yolk#78 : improve log messages
dominiksteiner May 7, 2020
0ad9078
thinkwell/yolk#78 : only sync_from_crowd when update_crowd_records = …
dominiksteiner May 7, 2020
d61b75a
thinkwell/yolk#78 : try to find resource by username in DB first
dominiksteiner May 7, 2020
b5ef818
thinkwell/yolk#78 : create user token in DB after validating and fetc…
dominiksteiner May 8, 2020
2bd0b0a
thinkwell/yolk#78 : lookup resource by email or username
dominiksteiner May 12, 2020
02e4dd5
thinkwell/yolk#81 : rename config.disabled to config.noop
dominiksteiner May 13, 2020
7930e4e
thinkwell/yolk#78 : use resource.upsert_user_token to update or inser…
dominiksteiner May 23, 2020
783abfc
thinkwell/yolk#78 : get token from user_token response
dominiksteiner May 26, 2020
ac1d9b5
thinkwell/yolk#78 : use DeviseCrowd::Logger for logging
dominiksteiner May 26, 2020
594ca02
thinkwell/yolk#78 : get token from crowd before upserting
dominiksteiner May 27, 2020
4c93a78
thinkwell/yolk#78 : use crowd first in credentials_authenticatable
dominiksteiner May 28, 2020
d2f0d80
thinkwell/yolk#82 : use prepend CrowdUsernameKeyWithDefault instead o…
dominiksteiner Jun 5, 2020
022e249
thinkwell/yolk#82 : use with_indifferent_access for authentication_hash
dominiksteiner Jun 8, 2020
5fba445
thinkwell/yolk#82 : use seconds gor crowd_auth_every.ago
dominiksteiner Jun 8, 2020
49f3cae
thinkwell/yolk#78 : merge vs do-yolk-heroku-upgrade
dominiksteiner Jul 6, 2020
b246cbc
thinkwell/yolk#78 : merge vs do-yolk-heroku-upgrade
dominiksteiner Jul 6, 2020
c112fab
thinkwell/yolk#78 : fix File.exists? to File.exist?
dominiksteiner Feb 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion lib/devise_crowd/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ module Devise
mattr_accessor :crowd_service_url
@@crowd_service_url = "http://localhost:8095/crowd"

mattr_accessor :crowd_noop
@@crowd_noop = false

mattr_accessor :crowd_app_name
@@crowd_app_name = "crowd"

Expand All @@ -22,7 +25,7 @@ module Devise
# The name of the crowd username parameter/field. If nil (default), the
# first authentication_keys key will be used (e.g. email).
mattr_accessor :crowd_username_key
@@crowd_username_key = nil
@@crowd_username_key = "crowd_username"

mattr_accessor :crowd_logger
@@crowd_logger = true
Expand All @@ -33,6 +36,12 @@ module Devise
mattr_accessor :crowd_auto_register
@@crowd_auto_register = true

mattr_accessor :cookie_domain
@@cookie_domain = nil

mattr_accessor :cookie_secure
@@cookie_secure = nil

mattr_accessor :add_crowd_records
@@add_crowd_records = false

Expand Down
13 changes: 11 additions & 2 deletions lib/devise_crowd/cookie.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
module DeviseCrowd

def self.get_cookie_info(record_class, crowd_client)
if record_class.cookie_domain
{domain: record_class.cookie_domain, secure: record_class.cookie_secure}
else
Rails.logger.debug "DEVISE CROWD : set_cookie : get_cookie_info"
DeviseCrowd.crowd_fetch { crowd_client.get_cookie_info }
end
end

def self.set_cookie(token, warden, record_class, crowd_client=nil)
crowd_client ||= record_class.crowd_client
cookie_info = DeviseCrowd.crowd_fetch { crowd_client.get_cookie_info }
cookie_info = self.get_cookie_info(record_class, crowd_client)
if cookie_info
warden.cookies[record_class.crowd_token_key] = {
:domain => cookie_info[:domain],
Expand All @@ -14,7 +23,7 @@ def self.set_cookie(token, warden, record_class, crowd_client=nil)

def self.destroy_cookie(warden, record_class, crowd_client=nil)
crowd_client ||= record_class.crowd_client
cookie_info = DeviseCrowd.crowd_fetch { crowd_client.get_cookie_info }
cookie_info = self.get_cookie_info(record_class, crowd_client)
if cookie_info
warden.cookies.delete(record_class.crowd_token_key, :domain => cookie_info[:domain])
end
Expand Down
26 changes: 15 additions & 11 deletions lib/devise_crowd/models/common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ def has_crowd_record?
end

def needs_crowd_auth?(last_auth)
last_auth && last_auth <= self.class.crowd_auth_every.ago
last_auth && last_auth <= self.class.crowd_auth_every.seconds.ago
end

def next_crowd_auth(last_auth)
Expand All @@ -55,6 +55,7 @@ def crowd_record
if @crowd_record.nil?
@crowd_record = false
username = self.send(:"#{self.class.crowd_username_key}")
Rails.logger.debug "DEVISE CROWD model : crowd_record : find_user_by_name #{username}"
record = DeviseCrowd.crowd_fetch {crowd_client.find_user_by_name(username)} if username
@crowd_record = record if record
end
Expand Down Expand Up @@ -149,16 +150,28 @@ def do_sync_to_crowd
private :do_sync_to_crowd


module CrowdUsernameKeyWithDefault
def default
key = super
unless key
key = (authentication_keys.is_a?(Hash) ? authentication_keys.keys : authentication_keys).first
end
key
end
end

module ClassMethods
Devise::Models.config(self, :crowd_enabled, :crowd_service_url, :crowd_app_name, :crowd_app_password, :crowd_token_key, :crowd_username_key, :crowd_auth_every, :crowd_allow_forgery_protection, :crowd_auto_register, :add_crowd_records, :update_crowd_records)
prepend CrowdUsernameKeyWithDefault

Devise::Models.config(self, :crowd_enabled, :crowd_noop, :crowd_service_url, :crowd_app_name, :crowd_app_password, :crowd_token_key, :crowd_username_key, :crowd_auth_every, :crowd_allow_forgery_protection, :crowd_auto_register, :add_crowd_records, :update_crowd_records, :cookie_domain, :cookie_secure)

def crowd_client
SimpleCrowd::Client.new({
:service_url => self.crowd_service_url,
:app_name => self.crowd_app_name,
:app_password => self.crowd_app_password,
:cache_store => Rails.cache,
:noop => self.crowd_noop
})
end

Expand All @@ -170,15 +183,6 @@ def crowd_enabled?(strategy=nil)
end
end

def crowd_username_key_with_default
key = crowd_username_key_without_default
unless key
key = (authentication_keys.is_a?(Hash) ? authentication_keys.keys : authentication_keys).first
end
key
end
alias_method_chain :crowd_username_key, :default

def find_for_crowd_username(username)
find_for_authentication({self.crowd_username_key => username})
end
Expand Down
19 changes: 17 additions & 2 deletions lib/devise_crowd/strategies/common.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,12 @@ def crowd_username=(username)
end

def crowd_record
@crowd_record ||= @crowd_username && DeviseCrowd.crowd_fetch { crowd_client.find_user_by_name(@crowd_username) }
if !@crowd_record && @crowd_username
Rails.logger.debug "DEVISE CROWD : crowd_record : find_user_by_name #{@crowd_username}"
@crowd_record = DeviseCrowd.crowd_fetch { crowd_client.find_user_by_name(@crowd_username) }
end

@crowd_record
end

def crowd_record=(record)
Expand All @@ -24,7 +29,13 @@ def crowd_record=(record)
private

def validate_crowd_username!
# lookup resource on DB first
if crowd_username
resource = resource_class.find_by_username_or_email(crowd_username)
end

# if resource not found lookup on CROWD
if crowd_username && !resource
resource = resource_class.find_for_crowd_username(crowd_username)
resource = create_from_crowd if !resource && crowd_auto_register?
end
Expand All @@ -36,7 +47,7 @@ def validate_crowd_username!
fail(:crowd_unverified_request)
else
DeviseCrowd::Logger.send("authenticated via #{authenticatable_name}!")
sync_from_crowd(resource) if sync_from_crowd?
sync_from_crowd(resource) if sync_from_crowd? and update_crowd_records?
cache_authentication if store?
yield(resource) if block_given?
success!(resource)
Expand Down Expand Up @@ -68,6 +79,10 @@ def crowd_auto_register?
!!resource_class.crowd_auto_register
end

def update_crowd_records?
!!resource_class.update_crowd_records
end

def crowd_client
@crowd_client ||= resource_class.crowd_client
end
Expand Down
45 changes: 42 additions & 3 deletions lib/devise_crowd/strategies/credentials_authenticatable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,51 @@ def valid_params?
end

def authenticate_crowd_credentials
username = authentication_hash[resource_class.crowd_username_key]
token = DeviseCrowd.crowd_fetch { crowd_client.authenticate_user(username, password) } if username
crowd_username = authentication_hash.with_indifferent_access[resource_class.crowd_username_key]
email = params[@scope][:username] || params[@scope][:email] || crowd_username

# authentication against crowd
DeviseCrowd::Logger.send "DEVISE CREDS AUTH : #{crowd_username} : in CROWD ..."
token = DeviseCrowd.crowd_fetch { crowd_client.authenticate_user(crowd_username, password) }

if token
resource = resource_class.find_by_username_or_email(email)
# if user does not exist create and update from crowd user
unless resource
resource = resource_class.new
crowd_user = DeviseCrowd.crowd_fetch { crowd_client.find_user_by_name(crowd_username) }
resource.update_from_crowd_user crowd_user
DeviseCrowd::Logger.send "DEVISE CREDS AUTH : #{resource.email} : created user from CROWD #{crowd_user.inspect}"
end

DeviseCrowd::Logger.send "DEVISE CREDS AUTH : #{resource.email} : upsert user token in DB : #{token}"
resource.upsert_user_token token

# if successful update password hash in DB via devise
DeviseCrowd::Logger.send "DEVISE CREDS AUTH : #{resource.email} : update password in DB"
resource.password = password
resource.save!
end

if email && !token
# authenticate against DB password
resource = resource || resource_class.find_by_username_or_email(email)
unless resource
DeviseCrowd::Logger.send "DEVISE CREDS AUTH : #{email} : no User found in DB"
else
if resource.valid_password?(password)
token = resource.user_token && resource.user_token.token
token = resource.upsert_user_token(token).token
crowd_username = email
else
DeviseCrowd::Logger.send "DEVISE CREDS AUTH : #{email} : password in DB does not match"
end
end
end

if token
self.crowd_token = token
self.crowd_username = username
self.crowd_username = crowd_username
else
self.crowd_token = self.crowd_username = nil
end
Expand Down
41 changes: 35 additions & 6 deletions lib/devise_crowd/strategies/token_authenticatable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,43 @@ def crowd_token_param
def authenticate_crowd_token
self.crowd_record = nil
if has_crowd_token?
if DeviseCrowd.crowd_fetch { crowd_client.is_valid_user_token?(crowd_token) }
crowd_session = DeviseCrowd.session(warden, scope)
if crowd_session['crowd.last_token'] == crowd_token && crowd_session['crowd.last_username']
self.crowd_username = crowd_session['crowd.last_username']
# try to first authenticate against DB token if exists
resource = resource_class.find_by_token(crowd_token)
if resource
resource.upsert_user_token(crowd_token)
self.crowd_username = resource.send(resource_class.crowd_username_key)
end

unless self.crowd_username
if DeviseCrowd.crowd_fetch { crowd_client.is_valid_user_token?(crowd_token) }
DeviseCrowd::Logger.send "DEVISE TOKEN AUTH : #{crowd_token} : is valid in CROWD"
crowd_session = DeviseCrowd.session(warden, scope)
if crowd_session['crowd.last_token'] == crowd_token && crowd_session['crowd.last_username']
self.crowd_username = crowd_session['crowd.last_username']
else
self.crowd_record = DeviseCrowd.crowd_fetch { crowd_client.find_user_by_token(crowd_token) }
if self.crowd_record
DeviseCrowd::Logger.send "DEVISE TOKEN AUTH : #{crowd_token} : found user by token in CROWD : #{self.crowd_username}"
resource = resource_class.find_by_username(self.crowd_username)
# if user does not exist create and update from crowd user
unless resource
resource = resource_class.new
resource.update_from_crowd_user self.crowd_record
resource.save!
DeviseCrowd::Logger.send "DEVISE TOKEN AUTH : #{self.crowd_username} : created user #{resource.id} from CROWD"
end

# if successful update user token in DB
DeviseCrowd::Logger.send "DEVISE TOKEN AUTH : #{self.crowd_username} : update user token in DB"
resource.upsert_user_token(crowd_token)
else
DeviseCrowd::Logger.send "DEVISE TOKEN AUTH : #{crowd_token} : no user found by token in CROWD"
end
end
DeviseCrowd::Logger.send("cannot find user for token key") unless self.crowd_username
else
self.crowd_record = DeviseCrowd.crowd_fetch { crowd_client.find_user_by_token(crowd_token) }
DeviseCrowd::Logger.send "DEVISE TOKEN AUTH : #{crowd_token} : NOT valid in CROWD"
end
DeviseCrowd::Logger.send("cannot find user for token key") unless self.crowd_username
end
end
end
Expand Down
2 changes: 1 addition & 1 deletion spec/rails_app/config/boot.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)

require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])