Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conflicting Controllers with Devise & Devise Token Auth causing unwanted actions to be called #302

Closed
arinhouck opened this issue Aug 12, 2017 · 8 comments

Comments

@arinhouck
Copy link
Contributor

When I added Fae to an existing project that had Devise + Devise Token Auth for JSON API. Upon my request to my Customer Devise model (mounted by devise_auth_token). All before_actions from Fae's controller are being called.

Any thoughts? Something to do with extending ApplicationController?

Started POST "/api/v1/customers/sign_in" for 127.0.0.1 at 2017-08-11 22:49:53 -0700
Processing by Overrides::SessionsController#create as JSON
  Parameters: {"customer"=>{"email"=>"[email protected]", "password"=>"[FILTERED]"}, "session"=>{"customer"=>{"email"=>"[email protected]", "password"=>"[FILTERED]"}}}
Can't verify CSRF token authenticity.
  Fae::User Load (0.8ms)  SELECT "fae_users".* FROM "fae_users" INNER JOIN "public"."fae_roles" ON "public"."fae_roles"."id" = "fae_users"."role_id" WHERE "fae_users"."active" = $1 AND "fae_roles"."name" = $2 ORDER BY "fae_users"."first_name" ASC, "fae_users"."last_name" ASC  [["active", "t"], ["name", "super admin"]]
Redirected to http://lvh.me:3000/admin/first_user

Ruby 2.3.1
Rails 5.0.5
Fae 1.5.1
Devise Auth Token 0.1.42
Devise 4.3.0

@jamesmk
Copy link
Member

jamesmk commented Aug 12, 2017

@arinhouck It'll be hard to see what's going on without more context. Is your project OS or could you recreate and share the issue in another project?

thanks

@arinhouck
Copy link
Contributor Author

arinhouck commented Aug 12, 2017

@jamesmk I can label the project as public temporarily as it doesn't have any business logic built in yet. I just setup the basic structure with public facing API for Customers using Devise Auth Token. Then used Apartment to build a multi-tenant database wrapping the Fae objects. So each tenant has there own Fae Admin Portal when a Business record is created.

However Apartment in this equation should not affect the outcome.
https://github.com/arinhouck/stuff2du

@arinhouck
Copy link
Contributor Author

It wouldn't let me attach .json so I had to zip the file. Here is the request I am trying to make through Postman.

Stuff2du Local.postman_collection.json.zip

@arinhouck
Copy link
Contributor Author

arinhouck commented Aug 12, 2017

I think it just clicked what I needed to do after sleeping on it and reading this repetitively. I fixed the issue by configuring devise.rb to inherit its parent controller as ActionController::Base instead of default ApplicationController.

  config.parent_controller = 'ActionController::Base'

However will I see any side-effects to this is the real question? Fae seems to be working and my devise token auth no longer calls Fae::ApplicationController actions.

EDIT: Restarted and now Fae does not work for Devise views so this is not a solution.

@arinhouck
Copy link
Contributor Author

arinhouck commented Aug 12, 2017

Now my current issue is the Devise views that are overriding through Fae are overriding my default Devise views.

Go to http://lvh.me:3000/customers/sign_in and it uses the following /fae-rails-1.5.1/app/views/devise/sessions/new.html.slim where line #2 raised:

So if I set config.scoped_views = true for devise and generate customer devise views. I can get around fae acting as the default devise views.

Now my issue is similar to heartcombo/devise#1984 and ankane/blazer#73, where somehow resource_path cannot be found in this context. However if I use customer_session_path instead of session_path(resource_name) the issue can be resolved.

With those paths resolved, I now have issues with devise_token_auth views needing to be fixed in same manner.

However, now my devise layout is being overwritten by fae.
lib/ruby/gems/2.3.0/gems/fae-rails-1.5.1/app/views/layouts/devise.html.slim where line #4 raised:

UPDATE (alternative option to fix layout issue but has other side effects)

So if I set config.parent_controller = 'ApplicationController' devise works as expected, but now Fae devise views are not configured (views are broken for /admin sign up, etc). So is there a way to configure Fae for it's respective devise configuration with its inherited properties without sacrificing the ability to have another type of user with a different layout, model, etc in Devise and Devise Token Auth which has its own set of configurations.

READING FURTHER
https://groups.google.com/forum/#!topic/plataformatec-devise/1ZPdAPpjGAY
Trying to see if there is a way to separate this logic per devise scope. It seems the solution is to override every controller and put the respective concerns there instead of at the root controller of devise.

--

My temporary solution that solved both cases:

class ApplicationDeviseController < Fae::ApplicationController
  
  skip_before_action :check_disabled_environment, if: -> { custom_devise_controller? }
  skip_before_action :first_user_redirect, if: -> { custom_devise_controller? }
  skip_before_action :authenticate_user!, if: -> { custom_devise_controller? }
  skip_before_action :build_nav, if: -> { custom_devise_controller? }
  skip_before_action :set_option, if: -> { custom_devise_controller?(['api']) }
  skip_before_action :detect_cancellation, if: -> { custom_devise_controller? }
  skip_before_action :set_change_user, if: -> { custom_devise_controller? }
  skip_before_action :set_locale, if: -> { custom_devise_controller? }

  protect_from_forgery prepend: true, if: Proc.new { |c| c.request.format.json? }
  
  helper_method :custom_devise_controller?

  private

  def custom_devise_controller?(values = ['api', 'customers'])
   values.include?(request.path[1..-1].split('/')[0])
  end
end

I changed generated my views for customers to use custom copies of fae's devise look and feel. Changed all paths to support customer_*.

config.scoped_views = true

Use the above controller

config.parent_controller = 'ApplicationDeviseController'

Change layout to support scoped_views as it was harcoded to be /devise

.login-helper == render "#{custom_devise_controller? ? devise_mapping.scoped_path : 'devise'}/shared/links" unless params[:controller] == 'fae/setup'

@jamesmk
Copy link
Member

jamesmk commented Aug 14, 2017

@arinhouck Sounds like you've been on quite a journey, glad to see you're making progress.

I was afraid that your original issues wasn't going to be the only one to come up in this setup. I don't know off hand what it would take to make this edge case any easier to integration, but I'm open to suggestions or better yet, a PR. I'd consider this type of support a feature request.

If you managed to get this working with your custom setup, a brief doc in our tutorials section would be amazing!

thanks

@arinhouck
Copy link
Contributor Author

@jamesmk

Yeah, this issue exists in many different gems involved with Devise as there can only be one base controller of Devise. You can read more about the issue here. Put together a quick write up on #307

@jamesmk
Copy link
Member

jamesmk commented Aug 15, 2017

Thanks again for the tutorial @arinhouck. I'm closing this one out.

@jamesmk jamesmk closed this as completed Aug 15, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants