refinery / refinerycms-authentication-devise

Devise based authentication extension for Refinery CMS
MIT License
17 stars 61 forks source link

Unable to authenticate custom admin pages and controllers using refinerycms-authentication-devise #28

Open ITDevMohsin opened 8 years ago

ITDevMohsin commented 8 years ago

Hi,

I have installed refinery cms and need to add custom controller, currently I have added all my controllers and they are working fine as well.

Basically, its admin controller that is other than refinery controllers whom I wants to authenticate if user is not logged in.

so, if no user is logged into the site, it will redirect it to refinery/login page.

I have admin controller whose code is like:

require 'refinery/core/nil_user'

class AdminController < ApplicationController # Refinery::Admin::CoreController
  include RefineryAuthenticationPatch

  include ::Refinery::ApplicationController
  helper Refinery::Core::Engine.helpers

  include Refinery::Admin::BaseController
  include Refinery::Authentication::Devise
end

My gem file:

gem 'refinerycms'
gem 'refinerycms-authentication-devise', '~> 1.0.4'
gem 'refinerycms-wymeditor', '~> 1.0', '>= 1.0.6'

Some page code:

<%= form_for([:admin, @current_object]) do |f| %>
    <div class='field'>
      <%= f.label :title %>
      <%= f.text_field :title, :class => 'larger widest' %>
    </div>
<% end %>

And my link is something like: http://localhost:3000/admin/teachers/new. These links are of in great number so I wants to authenticate all of them. So, if user try to access these pages by putting URL in browser, so it will redirect user to login page.

Simply, what I need to do is if some one directly access http://localhost:3000/admin/teachers/new page, he should redirected to refinery/login page.

For all other controllers or pages the behavior is working fine but I want to fix it for these custom pages now.

I have tried loads of codes and things regarding device or refinery authentications but all in vain.

Here is my reference question on google group as well:

https://groups.google.com/forum/#!topic/refinery-cms/yQ_OWIKxLdY

ITDevMohsin commented 8 years ago

@bricesanchez Any update Sir? I need your help to get through this please. Thanks.!

bricesanchez commented 8 years ago

@parndt could you help us?

parndt commented 8 years ago
# in your controller
before_action :authenticate_refinery_user!
parndt commented 8 years ago

https://github.com/refinery/refinerycms/blob/master/core/lib/refinery/admin/base_controller.rb#L12-L14

ITDevMohsin commented 8 years ago

@parndt @bricesanchez

I added:

class AdminController < ApplicationController
  before_action :authenticate_refinery_user!
end

Now, I am having these issues:

NoMethodError in Admin::TeachersController#new
undefined method `authenticate_refinery_user!' for #<Admin::TeachersController:0x00000005d92bc8>

and full trace is:

Extracted source (around line #432):
        case filter
        when Symbol
          lambda { |target, _, &blk| target.send filter, &blk } // ERROR IN THIS LINE NOW - line # 432
        when String
          l = eval "lambda { |value| #{filter} }"
          lambda { |target, value| target.instance_exec(value, &l) }
parndt commented 8 years ago

You need to include the BaseController module inside your controller to use its functionality.

ITDevMohsin commented 8 years ago

@parndt

My code now look like this:

require 'refinery/core/nil_user'

class AdminController < ApplicationController # Refinery::Admin::CoreController  #ApplicationController #Refinery::AdminController
  include RefineryAuthenticationPatch

  include ::Refinery::ApplicationController
  helper Refinery::Core::Engine.helpers

  include Refinery::Admin::BaseController
  include Refinery::Authentication::Devise
  before_action :authenticate_refinery_user!
end

And it says:

Showing /home/projectschool/app/views/refinery/admin/_menu.html.erb where line #3 raised:

undefined method `active_plugins' for nil:NilClass

full trace is:

<nav id="menu">
  <%= render partial: "refinery/admin/menu_item",
             collection: current_refinery_user.active_plugins.in_menu -%> // ERROR IS HERE
  <%= render 'admin/nav_links' %>
</nav>

if i comment include RefineryAuthenticationPatch line it does not authenticate nor it shows any error and does not perform any action and redirects me to /new page without asking logins.

If I try with below code in application controller:

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  protect_from_forgery with: :exception
  before_action :authenticate_refinery_user!
end

it returns me the errors below.

undefined method `authenticate_refinery_user!' for #<Refinery::Authentication::Devise::SessionsController:0x007f24ba347a98>
parndt commented 8 years ago

If I try with below code in application controller:

class ApplicationController < ActionController::Base

Prevent CSRF attacks by raising an exception.

For APIs, you may want to use :null_session instead.

protect_from_forgery with: :exception before_action :authenticate_refinery_user! end it returns me the errors below.

undefined method `authenticate_refinery_user!' for #Refinery::Authentication::Devise::SessionsController:0x007f24ba347a98

ActionController::Base doesn't include Refinery::Admin::BaseController so that method won't be available.

evenreven commented 5 years ago

I've been trying to update the refinerycms-dynamicfields extension for my Refinery 4.0.3/Rails 5.1 app, and I'm running into what seems like this issue. I've tried to put before_action :authenticate_refinery_user! in the admin controller, and in a fit of desperation I tried to add the line include Refinery::Admin::BaseController as well. Here's the fork: https://github.com/evenreven/refinerycms-dynamicfields (not very interesting; I've more or less just updated the gemspec so far).

Sadly, I'm not competent to really delve into this issue. Do you have any pointers, @parndt ?

This issue seems related as well: https://stackoverflow.com/questions/36921220/refinerycms-admin-tried-to-access-refinery-admin-accommodations-but-was-reje

This is what I'm getting:

Started GET "/refinery/dynamicfields" for 192.168.121.109 at 2019-09-06 22:28:22 +0200
Cannot render console from 192.168.121.109! Allowed networks: 127.0.0.1, ::1, 127.0.0.0/127.255.255.255
   (0.6ms)  SELECT "schema_migrations"."version" FROM "schema_migrations" ORDER BY "schema_migrations"."version" ASC
  Refinery::Redirections::Redirection Load (0.7ms)  SELECT  "refinery_redirections_redirections".* FROM "refinery_redirections_redirections" WHERE "refinery_redirections_redirections"."from_url" = $1 ORDER BY "refinery_redirections_redirections"."id" ASC LIMIT $2  [["from_url", "/refinery/dynamicfields"], ["LIMIT", 1]]
[Redirections] Redirection not found for: "/refinery/dynamicfields"
  CACHE Refinery::Redirections::Redirection Load (0.0ms)  SELECT  "refinery_redirections_redirections".* FROM "refinery_redirections_redirections" WHERE "refinery_redirections_redirections"."from_url" = $1 ORDER BY "refinery_redirections_redirections"."id" ASC LIMIT $2  [["from_url", "/refinery/dynamicfields"], ["LIMIT", 1]]
[Redirections] Redirection not found for: "/refinery/dynamicfields"
Processing by Refinery::AdminController#error_404 as HTML
  Parameters: {"path"=>"dynamicfields", "locale"=>"nb"}
  Refinery::Authentication::Devise::User Load (0.7ms)  SELECT  "refinery_authentication_devise_users".* FROM "refinery_authentication_devise_users" WHERE "refinery_authentication_devise_users"."id" = $1 ORDER BY "refinery_authentication_devise_users"."id" ASC LIMIT $2  [["id", 3], ["LIMIT", 1]]
  Refinery::Authentication::Devise::Role Load (0.5ms)  SELECT "refinery_authentication_devise_roles".* FROM "refinery_authentication_devise_roles" INNER JOIN "refinery_authentication_devise_roles_users" ON "refinery_authentication_devise_roles"."id" = "refinery_authentication_devise_roles_users"."role_id" WHERE "refinery_authentication_devise_roles_users"."user_id" = $1  [["user_id", 3]]
'even' tried to access 'refinery/admin' but was rejected.
  Refinery::Page Load (1.0ms)  SELECT  "refinery_pages"."id", "refinery_pages"."parent_id", "refinery_pages"."path", "refinery_pages"."show_in_menu", "refinery_pages"."link_url", "refinery_pages"."menu_match", "refinery_pages"."deletable", "refinery_pages"."draft", "refinery_pages"."skip_to_first_child", "refinery_pages"."lft", "refinery_pages"."rgt", "refinery_pages"."depth", "refinery_pages"."view_template", "refinery_pages"."layout_template", "refinery_pages"."created_at", "refinery_pages"."updated_at", "refinery_pages"."teaser", "refinery_pages"."event_tags", "refinery_pages"."children_count" FROM "refinery_pages" WHERE "refinery_pages"."menu_match" = $1 ORDER BY "refinery_pages"."id" ASC LIMIT $2  [["menu_match", "^/404$"], ["LIMIT", 1]]
  Refinery::PagePart Load (0.6ms)  SELECT "refinery_page_parts"."id", "refinery_page_parts"."refinery_page_id", "refinery_page_parts"."title", "refinery_page_parts"."old_body", "refinery_page_parts"."position", "refinery_page_parts"."created_at", "refinery_page_parts"."updated_at", "refinery_page_parts"."slug" FROM "refinery_page_parts" WHERE "refinery_page_parts"."refinery_page_id" = 2 ORDER BY position ASC
  Refinery::PagePart::Translation Load (0.6ms)  SELECT "refinery_page_part_translations".* FROM "refinery_page_part_translations" WHERE "refinery_page_part_translations"."refinery_page_part_id" IN (3, 127)
  Rendering refinery/pages/show.html.erb within layouts/refinery/admin
  Refinery::Page::Translation Load (0.6ms)  SELECT "refinery_page_translations".* FROM "refinery_page_translations" WHERE "refinery_page_translations"."refinery_page_id" = $1  [["refinery_page_id", 2]]
  Rendered /home.rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/bundler/gems/refinerycms-5d59e69a430e/core/app/views/refinery/_content_page.html.erb (10.2ms)
  Refinery::ImagePage Load (0.7ms)  SELECT "refinery_image_pages"."image_id", "refinery_image_pages"."page_id", "refinery_image_pages"."position", "refinery_image_pages"."id", "refinery_image_pages"."page_type", "refinery_image_pages"."top_image" FROM "refinery_image_pages" WHERE "refinery_image_pages"."page_id" = $1 AND "refinery_image_pages"."page_type" = $2 AND "refinery_image_pages"."top_image" = $3 ORDER BY position ASC  [["page_id", 2], ["page_type", "Refinery::Page"], ["top_image", "f"]]
  Rendered refinery/pages/show.html.erb within layouts/refinery/admin (104.5ms)
  Rendered /home.rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/bundler/gems/refinerycms-5d59e69a430e/core/app/views/refinery/_html_tag.html.erb (0.5ms)
  Rendered /home.rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/bundler/gems/refinerycms-5d59e69a430e/core/app/views/refinery/admin/_javascripts.html.erb (1023.5ms)
  Rendered /home.rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/bundler/gems/refinerycms-5d59e69a430e/core/app/views/refinery/admin/_head.html.erb (7515.9ms)
  Rendered /home.rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/bundler/gems/refinerycms-5d59e69a430e/core/app/views/refinery/_site_bar.html.erb (10.8ms)
  Rendered collection of /home.rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/bundler/gems/refinerycms-5d59e69a430e/core/app/views/refinery/admin/_menu_item.html.erb [8 times] (2.4ms)
  Rendered /home.rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/bundler/gems/refinerycms-5d59e69a430e/core/app/views/refinery/admin/_menu.html.erb (58.4ms)
  Rendered /home.rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/bundler/gems/refinerycms-5d59e69a430e/core/app/views/refinery/_no_script.html.erb (0.6ms)
  Rendered /home.rbenv/versions/2.4.7/lib/ruby/gems/2.4.0/bundler/gems/refinerycms-5d59e69a430e/core/app/views/refinery/_message.html.erb (0.5ms)
Filter chain halted as :restrict_controller rendered or redirected
Completed 404 Not Found in 8197ms (Views: 8050.3ms | ActiveRecord: 26.3ms)

cache: [GET /refinery/dynamicfields] miss
cache: [GET /refinery/dynamicfields] miss
parndt commented 5 years ago

it seems like it's failing at the engine permissions level: https://github.com/refinery/refinerycms/blob/e49a6bebefe34bedcca932887f1446f084a23c33/core/lib/refinery/admin/base_controller.rb#L55-L60

https://github.com/refinery/refinerycms/blob/e49a6bebefe34bedcca932887f1446f084a23c33/core/lib/refinery/admin/base_controller.rb#L64-L66

https://github.com/refinery/refinerycms-authentication-devise/blob/125ec0a3249931c68b7812abd1ed44410b5cb02b/lib/refinery/authentication/devise/authorisation_adapter.rb#L18-L31

so we can see in the last link that for this particular message, it's because your user doesn't appear to have access to your plugin, which is inside the controlled by this line https://github.com/refinery/refinerycms-authentication-devise/blob/125ec0a3249931c68b7812abd1ed44410b5cb02b/lib/refinery/authentication/devise/authorisation_adapter.rb#L23 and this line https://github.com/refinery/refinerycms-authentication-devise/blob/125ec0a3249931c68b7812abd1ed44410b5cb02b/lib/refinery/authentication/devise/authorisation_adapter.rb#L25-L27

parndt commented 5 years ago

Are there any special installation steps for the plugin @evenreven ? I can try this later on if I get a chance!

parndt commented 5 years ago

However... it seems like you just need to set a menu_match property that is a regular expression that matches the URL you're accessing. Here's the one for pages: https://github.com/refinery/refinerycms/blob/6e60d27edc85c60f80baf302e40be69074872e82/pages/lib/refinery/pages/engine.rb#L15

plugin.menu_match = %r{refinery/page(_part|s_dialog)?s(/preview)?$}
evenreven commented 5 years ago

Thanks for the quick response!

The installation is done with a generator. The steps are in the readme of the forked repo I linked to above. I just had to edit the migration with my Rails version (in my case put [5.1] in there) before running db:migrate. I haven't actually done anything with the engine/generator, and it was written for Refinery 3.0, so it's not surprising that it needs some more work.

I will take a look at your suggestion in a few hours when I'm back at the computer.

evenreven commented 5 years ago

Oh, I think I see now! I'll try to put the relevant regex in the engine.rb instead. Does this mean that my other changes were pointless?

A general comment: the dynamic fields extension seems really useful. I've needed some pages and view templates to have extra fields, but I've held back because I don't want extra fields on every page, and additional page parts are rarely the right approach for us. (Also, different page/content types have their own challenges with routing etc., for me regular pages using different view templates is most often the best approach.)

evenreven commented 5 years ago

Thanks for the pointer. I tried this and even though I still get a 404 and nothing changed when I click the tab inside Refinery, these lines are now gone from the rails s output:

'even' tried to access 'refinery/admin' but was rejected.
[snip]
Filter chain halted as :restrict_controller rendered or redirected

So something happened, but it still 404s.

EDIT: Oh, and to answer an obvious question you might have, I've given my user permissions (inside the user tab) to use the Dynamicfields component. :) EDIT2: I can't rule out that weirdnesses of my application are causing this, my project has a lot of moving parts and quite a few forked gems. I haven't tried with a properly clean environment, but I can setup a clean Rails 5.1/Refinery 4.0.3 without any baggage to rule out config issues in a few days.

anitagraham commented 5 years ago

Good to see someone is using that extension. I have been thinking of trying it too, but didn't know how well it would work with Refinery 4.

evenreven commented 5 years ago

Well, to say I'm using it is pushing it, considering my fork doesn't work yet. ;)

Any pointers beyond what @parndt suggested would be great! (BTW, I noticed in old pull requests that @bricesanchez did some work on the Refinery 3-compatible version.)

anitagraham commented 5 years ago

I tend to have the same problem every now and then, and I find it hard to remember what the fix is. iirc, the problem is with the refinery/admin part of the path.

I will have a look back over some recent commits. I would also look at the routes and make sure that the route matches.

Here is a fragment of one that is working

 before_inclusion do
        Refinery::Plugin.register do |plugin|
          plugin.name = "refinery_music"
          plugin.url = proc { Refinery::Core::Engine.routes.url_helpers.music_admin_albums_path }
          plugin.pathname = root
          plugin.menu_match = %r{refinery/music/.*?$}
        end
      end
# routes.rb
namespace :music, path: '' do
    namespace :admin, path: Refinery::Core.backend_route do
      scope path: Refinery::Music.page_url do
        root to: 'albums#index'
        resources 'albums'
        resources 'tracks'
      end
  end
end

good luck.

evenreven commented 5 years ago

Haven't looked at routes at all. Good tip, thanks!

evenreven commented 5 years ago

Couldn't get that to work either, sadly. Giving up for now (unless some competent dev has the time to look at it).

radek2r commented 5 years ago

@evenreven please look here https://github.com/jfalameda/refinerycms-dynamicfields/pull/13

You can try to bundle project with my fork (https://github.com/radek2r/refinerycms-dynamicfields) and check if it resolves your problem

evenreven commented 5 years ago

Thanks! One step closer. Now I can see the add field GUI without getting a 404. But I still can't find the newly added field anywhere in the page editing window. There's some HTML with display:none; there, so something is happening, but nothing I can bring out and use. Have you tried it yourself? Could be a config issue too.

parndt commented 4 years ago

Shall I leave this issue open?