Skip to content

Commit

Permalink
Merge pull request #341 from gkopylov/340_restrict_access_to_controll…
Browse files Browse the repository at this point in the history
…ers_methods

#340 Restrict access to controllers methods
  • Loading branch information
booleanbetrayal committed Aug 31, 2015
2 parents bf0d19b + 77e89f1 commit 0348ad2
Show file tree
Hide file tree
Showing 6 changed files with 156 additions and 145 deletions.
Expand Up @@ -2,6 +2,7 @@ module DeviseTokenAuth
class ApplicationController < DeviseController
include DeviseTokenAuth::Concerns::SetUserByToken

protected

def resource_class(m=nil)
if m
Expand Down
Expand Up @@ -7,6 +7,8 @@ module DeviseTokenAuth::Concerns::SetUserByToken
after_action :update_auth_header
end

protected

# keep track of request duration
def set_request_start
@request_started_at = Time.now
Expand Down
267 changes: 133 additions & 134 deletions app/controllers/devise_token_auth/omniauth_callbacks_controller.rb
Expand Up @@ -22,108 +22,6 @@ def redirect_callbacks
redirect_to redirect_route
end

def get_resource_from_auth_hash
# find or create user by provider and provider uid
@resource = resource_class.where({
uid: auth_hash['uid'],
provider: auth_hash['provider']
}).first_or_initialize

if @resource.new_record?
@oauth_registration = true
set_random_password
end

# sync user info with provider, update/generate auth token
assign_provider_attrs(@resource, auth_hash)

# assign any additional (whitelisted) attributes
extra_params = whitelisted_params
@resource.assign_attributes(extra_params) if extra_params

@resource
end

def set_random_password
# set crazy password for new oauth users. this is only used to prevent
# access via email sign-in.
p = SecureRandom.urlsafe_base64(nil, false)
@resource.password = p
@resource.password_confirmation = p
end

def create_token_info
# create token info
@client_id = SecureRandom.urlsafe_base64(nil, false)
@token = SecureRandom.urlsafe_base64(nil, false)
@expiry = (Time.now + DeviseTokenAuth.token_lifespan).to_i
@config = omniauth_params['config_name']
end

def create_auth_params
@auth_params = {
auth_token: @token,
client_id: @client_id,
uid: @resource.uid,
expiry: @expiry,
config: @config
}
@auth_params.merge!(oauth_registration: true) if @oauth_registration
@auth_params
end

def set_token_on_resource
@resource.tokens[@client_id] = {
token: BCrypt::Password.create(@token),
expiry: @expiry
}
end

def render_data(message, data)
@data = data.merge({
message: message
})
render :layout => nil, :template => "devise_token_auth/omniauth_external_window"
end

def render_data_or_redirect(message, data)

# We handle inAppBrowser and newWindow the same, but it is nice
# to support values in case people need custom implementations for each case
# (For example, nbrustein does not allow new users to be created if logging in with
# an inAppBrowser)
#
# See app/views/devise_token_auth/omniauth_external_window.html.erb to understand
# why we can handle these both the same. The view is setup to handle both cases
# at the same time.
if ['inAppBrowser', 'newWindow'].include?(omniauth_window_type)
render_data(message, data)

elsif auth_origin_url # default to same-window implementation, which forwards back to auth_origin_url

# build and redirect to destination url
redirect_to DeviseTokenAuth::Url.generate(auth_origin_url, data)
else

# there SHOULD always be an auth_origin_url, but if someone does something silly
# like coming straight to this url or refreshing the page at the wrong time, there may not be one.
# In that case, just render in plain text the error message if there is one or otherwise
# a generic message.
fallback_render data[:error] || 'An error occurred'
end
end

def fallback_render(text)
render inline: %Q|
<html>
<head></head>
<body>
#{text}
</body>
</html>|
end

def omniauth_success
get_resource_from_auth_hash
create_token_info
Expand All @@ -144,6 +42,37 @@ def omniauth_success
render_data_or_redirect('deliverCredentials', @resource.as_json.merge(@auth_params.as_json))
end

def omniauth_failure
@error = params[:message]
render_data_or_redirect('authFailure', {error: @error})
end

protected

# this will be determined differently depending on the action that calls
# it. redirect_callbacks is called upon returning from successful omniauth
# authentication, and the target params live in an omniauth-specific
# request.env variable. this variable is then persisted thru the redirect
# using our own dta.omniauth.params session var. the omniauth_success
# method will access that session var and then destroy it immediately
# after use. In the failure case, finally, the omniauth params
# are added as query params in our monkey patch to OmniAuth in engine.rb
def omniauth_params
if !defined?(@_omniauth_params)
if request.env['omniauth.params'] && request.env['omniauth.params'].any?
@_omniauth_params = request.env['omniauth.params']
elsif session['dta.omniauth.params'] && session['dta.omniauth.params'].any?
@_omniauth_params ||= session.delete('dta.omniauth.params')
@_omniauth_params
elsif params['omniauth_window_type']
@_omniauth_params = params.slice('omniauth_window_type', 'auth_origin_url', 'resource_class', 'origin')
else
@_omniauth_params = {}
end
end
@_omniauth_params

end

# break out provider attribute assignment for easy method extension
def assign_provider_attrs(user, auth_hash)
Expand All @@ -155,13 +84,6 @@ def assign_provider_attrs(user, auth_hash)
})
end


def omniauth_failure
@error = params[:message]
render_data_or_redirect('authFailure', {error: @error})
end


# derive allowed params from the standard devise parameter sanitizer
def whitelisted_params
whitelist = devise_parameter_sanitizer.for(:sign_up)
Expand Down Expand Up @@ -189,31 +111,6 @@ def resource_name
resource_class
end

# this will be determined differently depending on the action that calls
# it. redirect_callbacks is called upon returning from successful omniauth
# authentication, and the target params live in an omniauth-specific
# request.env variable. this variable is then persisted thru the redirect
# using our own dta.omniauth.params session var. the omniauth_success
# method will access that session var and then destroy it immediately
# after use. In the failure case, finally, the omniauth params
# are added as query params in our monkey patch to OmniAuth in engine.rb
def omniauth_params
if !defined?(@_omniauth_params)
if request.env['omniauth.params'] && request.env['omniauth.params'].any?
@_omniauth_params = request.env['omniauth.params']
elsif session['dta.omniauth.params'] && session['dta.omniauth.params'].any?
@_omniauth_params ||= session.delete('dta.omniauth.params')
@_omniauth_params
elsif params['omniauth_window_type']
@_omniauth_params = params.slice('omniauth_window_type', 'auth_origin_url', 'resource_class', 'origin')
else
@_omniauth_params = {}
end
end
@_omniauth_params

end

def omniauth_window_type
omniauth_params['omniauth_window_type']
end
Expand Down Expand Up @@ -251,5 +148,107 @@ def devise_mapping
end
end

def set_random_password
# set crazy password for new oauth users. this is only used to prevent
# access via email sign-in.
p = SecureRandom.urlsafe_base64(nil, false)
@resource.password = p
@resource.password_confirmation = p
end

def create_token_info
# create token info
@client_id = SecureRandom.urlsafe_base64(nil, false)
@token = SecureRandom.urlsafe_base64(nil, false)
@expiry = (Time.now + DeviseTokenAuth.token_lifespan).to_i
@config = omniauth_params['config_name']
end

def create_auth_params
@auth_params = {
auth_token: @token,
client_id: @client_id,
uid: @resource.uid,
expiry: @expiry,
config: @config
}
@auth_params.merge!(oauth_registration: true) if @oauth_registration
@auth_params
end

def set_token_on_resource
@resource.tokens[@client_id] = {
token: BCrypt::Password.create(@token),
expiry: @expiry
}
end

def render_data(message, data)
@data = data.merge({
message: message
})
render :layout => nil, :template => "devise_token_auth/omniauth_external_window"
end

def render_data_or_redirect(message, data)

# We handle inAppBrowser and newWindow the same, but it is nice
# to support values in case people need custom implementations for each case
# (For example, nbrustein does not allow new users to be created if logging in with
# an inAppBrowser)
#
# See app/views/devise_token_auth/omniauth_external_window.html.erb to understand
# why we can handle these both the same. The view is setup to handle both cases
# at the same time.
if ['inAppBrowser', 'newWindow'].include?(omniauth_window_type)
render_data(message, data)

elsif auth_origin_url # default to same-window implementation, which forwards back to auth_origin_url

# build and redirect to destination url
redirect_to DeviseTokenAuth::Url.generate(auth_origin_url, data)
else

# there SHOULD always be an auth_origin_url, but if someone does something silly
# like coming straight to this url or refreshing the page at the wrong time, there may not be one.
# In that case, just render in plain text the error message if there is one or otherwise
# a generic message.
fallback_render data[:error] || 'An error occurred'
end
end

def fallback_render(text)
render inline: %Q|
<html>
<head></head>
<body>
#{text}
</body>
</html>|
end

def get_resource_from_auth_hash
# find or create user by provider and provider uid
@resource = resource_class.where({
uid: auth_hash['uid'],
provider: auth_hash['provider']
}).first_or_initialize

if @resource.new_record?
@oauth_registration = true
set_random_password
end

# sync user info with provider, update/generate auth token
assign_provider_attrs(@resource, auth_hash)

# assign any additional (whitelisted) attributes
extra_params = whitelisted_params
@resource.assign_attributes(extra_params) if extra_params

@resource
end

end
end
10 changes: 7 additions & 3 deletions app/controllers/devise_token_auth/passwords_controller.rb
Expand Up @@ -165,6 +165,8 @@ def update
end
end

protected

def resource_update_method
if DeviseTokenAuth.check_current_password_before_update != false
"update_with_password"
Expand All @@ -173,13 +175,15 @@ def resource_update_method
end
end

def password_resource_params
params.permit(devise_parameter_sanitizer.for(:account_update))
end
private

def resource_params
params.permit(:email, :password, :password_confirmation, :current_password, :reset_password_token)
end

def password_resource_params
params.permit(devise_parameter_sanitizer.for(:account_update))
end

end
end
13 changes: 9 additions & 4 deletions app/controllers/devise_token_auth/sessions_controller.rb
Expand Up @@ -86,14 +86,12 @@ def destroy
end
end

protected

def valid_params?(key, val)
resource_params[:password] && key && val
end

def resource_params
params.permit(devise_parameter_sanitizer.for(:sign_in))
end

def get_auth_params
auth_key = nil
auth_val = nil
Expand All @@ -117,5 +115,12 @@ def get_auth_params
val: auth_val
}
end

private

def resource_params
params.permit(devise_parameter_sanitizer.for(:sign_in))
end

end
end

0 comments on commit 0348ad2

Please sign in to comment.