diff --git a/app/controllers/devise_token_auth/application_controller.rb b/app/controllers/devise_token_auth/application_controller.rb index 30de620c7..0edc95010 100644 --- a/app/controllers/devise_token_auth/application_controller.rb +++ b/app/controllers/devise_token_auth/application_controller.rb @@ -2,6 +2,7 @@ module DeviseTokenAuth class ApplicationController < DeviseController include DeviseTokenAuth::Concerns::SetUserByToken + protected def resource_class(m=nil) if m diff --git a/app/controllers/devise_token_auth/concerns/set_user_by_token.rb b/app/controllers/devise_token_auth/concerns/set_user_by_token.rb index 93923cd8f..d2289a34e 100644 --- a/app/controllers/devise_token_auth/concerns/set_user_by_token.rb +++ b/app/controllers/devise_token_auth/concerns/set_user_by_token.rb @@ -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 diff --git a/app/controllers/devise_token_auth/omniauth_callbacks_controller.rb b/app/controllers/devise_token_auth/omniauth_callbacks_controller.rb index 4c355c8ae..7ed01e095 100644 --- a/app/controllers/devise_token_auth/omniauth_callbacks_controller.rb +++ b/app/controllers/devise_token_auth/omniauth_callbacks_controller.rb @@ -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| - - - - - #{text} - - | - end - def omniauth_success get_resource_from_auth_hash create_token_info @@ -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 + + # 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 + + protected # break out provider attribute assignment for easy method extension def assign_provider_attrs(user, auth_hash) @@ -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) @@ -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 @@ -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| + + + + + #{text} + + | + 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 diff --git a/app/controllers/devise_token_auth/passwords_controller.rb b/app/controllers/devise_token_auth/passwords_controller.rb index 1e4c25fb4..96452821a 100644 --- a/app/controllers/devise_token_auth/passwords_controller.rb +++ b/app/controllers/devise_token_auth/passwords_controller.rb @@ -165,6 +165,8 @@ def update end end + protected + def resource_update_method if DeviseTokenAuth.check_current_password_before_update != false "update_with_password" @@ -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 diff --git a/app/controllers/devise_token_auth/sessions_controller.rb b/app/controllers/devise_token_auth/sessions_controller.rb index afaa45365..22bca7582 100644 --- a/app/controllers/devise_token_auth/sessions_controller.rb +++ b/app/controllers/devise_token_auth/sessions_controller.rb @@ -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 @@ -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