lib/grape_token_auth/omniauth/omniauth_resource.rb
# frozen_string_literal: true
module GrapeTokenAuth
class OmniAuthResource
extend Forwardable
attr_reader :resource
def_delegators :token, :expiry, :client_id
def_delegator :resource, :uid
def initialize(resource, auth_hash, omniauth_params)
@resource = resource
@auth_hash = auth_hash
@omniauth_params = omniauth_params
end
def persist_oauth_attributes!
set_crazy_password
sync_token_to_resource
sync_attributes_to_resource
# skip_confirmable_email
resource.save!
end
def self.fetch_or_create(resource_class, auth_hash, oauth_params)
resource = resource_class.where(
uid: auth_hash['uid'],
provider: auth_hash['provider']).first_or_initialize
new(resource, auth_hash, oauth_params)
end
def token
@token ||= Token.new
end
def token_value
token.to_s
end
def attributes
{ 'auth_token' => token_value,
'client_id' => token.client_id,
'expiry' => token.expiry }.merge(resource.serializable_hash)
end
private
attr_reader :auth_hash, :omniauth_params
def set_crazy_password
# set crazy password for new oauth users. this is only used to prevent
# access via email sign-in.
return if resource.id
p = SecureRandom.urlsafe_base64(nil, false)
resource.password = p
resource.password_confirmation = p
end
def sync_attributes_to_resource
# sync user info with provider, update/generate auth token
assign_provider_attrs
# assign any additional (whitelisted) attributes
assign_extra_attributes
end
def assign_provider_attrs
info_hash = auth_hash['info']
attrs = %i(nickname name image email).each_with_object({}) do |k, hsh|
hsh[k] = info_hash.fetch(k, '')
end
resource.assign_attributes(attrs)
end
def assign_extra_attributes
extra_params = whitelisted_params
resource.assign_attributes(extra_params) if extra_params
end
def whitelisted_params
whitelist = GrapeTokenAuth.configuration.param_white_list
return unless whitelist
scoped_list = whitelist[scope] || whitelist[scope.to_s]
return unless scoped_list
scoped_list.each_with_object({}) do |key, permitted|
value = Utility.find_with_indifference(omniauth_params, key)
permitted[key] = value if value
end
end
def scope
klass = resource.class
@scope ||= GrapeTokenAuth.configuration.mappings
.find { |k,v| v == klass }.try(:[], 0)
end
def sync_token_to_resource
resource.tokens[token.client_id] = token.to_h
end
end
end