{"action":"created","issue":{"url":"https://api.github.com/repos/spree/spree/issues/7124","repository_url":"https://api.github.com/repos/spree/spree","labels_url":"https://api.github.com/repos/spree/spree/issues/7124/labels{/name}","comments_url":"https://api.github.com/repos/spree/spree/issues/7124/comments","events_url":"https://api.github.com/repos/spree/spree/issues/7124/events","html_url":"https://github.com/spree/spree/issues/7124","id":136349078,"number":7124,"title":"Custom Role Authentication Always Fails After First Failure","user":{"login":"scan","id":450679,"avatar_url":"https://avatars.githubusercontent.com/u/450679?v=3","gravatar_id":"","url":"https://api.github.com/users/scan","html_url":"https://github.com/scan","followers_url":"https://api.github.com/users/scan/followers","following_url":"https://api.github.com/users/scan/following{/other_user}","gists_url":"https://api.github.com/users/scan/gists{/gist_id}","starred_url":"https://api.github.com/users/scan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scan/subscriptions","organizations_url":"https://api.github.com/users/scan/orgs","repos_url":"https://api.github.com/users/scan/repos","events_url":"https://api.github.com/users/scan/events{/privacy}","received_events_url":"https://api.github.com/users/scan/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/spree/spree/labels/address_feedback","name":"address_feedback","color":"e11d21"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2016-02-25T10:45:03Z","updated_at":"2016-02-25T11:50:15Z","closed_at":null,"body":"I have a very, very weird bug I can't figure out. First up: I'm using Spree 3.0.6.1 and `spree_auth_devise`. I have a custom role called `'editor'`, and added the following\r\n\r\n```ruby\r\n# app/models/spree/user_decorator.rb\r\nSpree::User.class_eval do\r\n  def editor?\r\n    has_spree_role?('editor')\r\n  end\r\nend\r\n```\r\n\r\nAbility (part):\r\n\r\n```ruby\r\nclass Ability\r\n  include CanCan::Ability\r\n\r\n  def initialize(user)\r\n    if user.respond_to?(:has_spree_role?) && user.has_spree_role?('editor')\r\n      can [:admin, :manage], Spree::Product\r\n    end\r\n  end\r\nend\r\n```\r\n\r\nMy initializer (part):\r\n```ruby\r\nSpree::Auth::Config[:confirmable] = true\r\nSpree::Ability.register_ability(Ability)\r\n\r\n# Ensure role exists\r\nSpree::Role.find_or_create_by(name: 'editor')\r\n\r\nSpree.user_class = 'Spree::User'\r\n```\r\n\r\nAnd finally, to redirect the user after logging into the admin area:\r\n\r\n```ruby\r\n    # app/controllers/spree/admin/root_controller_decorator.rb\r\n    Spree::Admin::RootController.class_eval do\r\n      protected\r\n\r\n      def admin_root_redirect_path\r\n        if spree_current_user.editor?\r\n          spree.admin_products_path\r\n        else\r\n          spree.admin_orders_path\r\n        end\r\n      end\r\n    end\r\n```\r\n\r\nThis works fine, the editor user is able to login and view the Products... until they click on something the Ability is not configured for. Then they get redirected to `admin/authorization_failure`. From that point on, **all custom role authorization fails, always**. No matter what admin page I visit, I get `unauthorized`. Even the admin sidebar is empty, because all authorization fails. This is until I restart the rails server - not even Logout/Login solves the problem.\r\n\r\nA quick look into the logs confirms that for some reason, the custom ability is never called\r\n\r\n````\r\nStarted GET \"/admin/\" for 127.0.0.1 at 2016-02-25 11:27:22 +0100\r\nProcessing by Spree::Admin::RootController#index as HTML\r\n  Spree::User Load (0.2ms)  SELECT  \"spree_users\".* FROM \"spree_users\" WHERE \"spree_users\".\"deleted_at\" IS NULL AND \"spree_users\".\"id\" = $1  ORDER BY \"spree_users\".\"id\" ASC LIMIT 1  [[\"id\", 5]]\r\n   (0.2ms)  SELECT COUNT(*) FROM \"spree_roles\" INNER JOIN \"spree_roles_users\" ON \"spree_roles\".\"id\" = \"spree_roles_users\".\"role_id\" WHERE \"spree_roles_users\".\"user_id\" = $1 AND \"spree_roles\".\"name\" = $2  [[\"user_id\", 5], [\"name\", \"editor\"]]\r\nRedirected to http://localhost:3000/admin/products\r\nCompleted 302 Found in 35ms (ActiveRecord: 4.4ms)\r\n\r\n\r\nStarted GET \"/admin/products\" for 127.0.0.1 at 2016-02-25 11:27:23 +0100\r\nProcessing by Spree::Admin::ProductsController#index as HTML\r\n  Spree::User Load (0.3ms)  SELECT  \"spree_users\".* FROM \"spree_users\" WHERE \"spree_users\".\"deleted_at\" IS NULL AND \"spree_users\".\"id\" = $1  ORDER BY \"spree_users\".\"id\" ASC LIMIT 1  [[\"id\", 5]]\r\n   (0.2ms)  SELECT COUNT(*) FROM \"spree_roles\" INNER JOIN \"spree_roles_users\" ON \"spree_roles\".\"id\" = \"spree_roles_users\".\"role_id\" WHERE \"spree_roles_users\".\"user_id\" = $1 AND \"spree_roles\".\"name\" = $2  [[\"user_id\", 5], [\"name\", \"admin\"]]\r\nRedirected to http://localhost:3000/admin/authorization_failure\r\nCompleted 302 Found in 65ms (ActiveRecord: 1.5ms)\r\n```\r\n\r\nJust as I started writing about this issue, I noticed all examples use `AbilityDecorator`, and I used CanCan's default `Ability`. Now that I changed the class name to `AbilityDecorator`, and it seemed to work fine for a moment, but after another server restart, the problem persists.\r\n "},"comment":{"url":"https://api.github.com/repos/spree/spree/issues/comments/188750441","html_url":"https://github.com/spree/spree/issues/7124#issuecomment-188750441","issue_url":"https://api.github.com/repos/spree/spree/issues/7124","id":188750441,"user":{"login":"scan","id":450679,"avatar_url":"https://avatars.githubusercontent.com/u/450679?v=3","gravatar_id":"","url":"https://api.github.com/users/scan","html_url":"https://github.com/scan","followers_url":"https://api.github.com/users/scan/followers","following_url":"https://api.github.com/users/scan/following{/other_user}","gists_url":"https://api.github.com/users/scan/gists{/gist_id}","starred_url":"https://api.github.com/users/scan/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scan/subscriptions","organizations_url":"https://api.github.com/users/scan/orgs","repos_url":"https://api.github.com/users/scan/repos","events_url":"https://api.github.com/users/scan/events{/privacy}","received_events_url":"https://api.github.com/users/scan/received_events","type":"User","site_admin":false},"created_at":"2016-02-25T11:50:15Z","updated_at":"2016-02-25T11:50:15Z","body":"To investigate here, I changed the order of inits in my initializer, changed it to:\r\n\r\n```ruby\r\n# Make sure designer role exists\r\nSpree::Role.find_or_create_by(name: 'editor')\r\n\r\nSpree.user_class = 'Spree::User'\r\n\r\nSpree::Auth::Config[:confirmable] = true\r\nSpree::Ability.register_ability(AbilityDecorator)\r\n```\r\n\r\nNow I get the error when I refresh on a site I was able to access before. I go to `/admin/products`, everything is fine. I refresh the page, I get `unauthorized`.\r\n\r\nAgain, in the logs, when auth works properly, I see:\r\n\r\n```\r\nStarted GET \"/admin/products\" for 127.0.0.1 at 2016-02-25 12:46:53 +0100\r\nProcessing by Spree::Admin::ProductsController#index as HTML\r\n  Spree::User Load (0.4ms)  SELECT  \"spree_users\".* FROM \"spree_users\" WHERE \"spree_users\".\"deleted_at\" IS NULL AND \"spree_users\".\"id\" = $1  ORDER BY \"spree_users\".\"id\" ASC LIMIT 1  [[\"id\", 5]]\r\n   (0.4ms)  SELECT COUNT(*) FROM \"spree_roles\" INNER JOIN \"spree_roles_users\" ON \"spree_roles\".\"id\" = \"spree_roles_users\".\"role_id\" WHERE \"spree_roles_users\".\"user_id\" = $1 AND \"spree_roles\".\"name\" = $2  [[\"user_id\", 5], [\"name\", \"admin\"]]\r\n   (0.4ms)  SELECT COUNT(*) FROM \"spree_roles\" INNER JOIN \"spree_roles_users\" ON \"spree_roles\".\"id\" = \"spree_roles_users\".\"role_id\" WHERE \"spree_roles_users\".\"user_id\" = $1 AND \"spree_roles\".\"name\" = $2  [[\"user_id\", 5], [\"name\", \"editor\"]]\r\n[...]\r\n[View rendering]\r\n```\r\n\r\nWhen it fails, I see\r\n\r\n```\r\nStarted GET \"/admin/products\" for 127.0.0.1 at 2016-02-25 12:43:56 +0100\r\nProcessing by Spree::Admin::ProductsController#index as HTML\r\n  Spree::User Load (0.3ms)  SELECT  \"spree_users\".* FROM \"spree_users\" WHERE \"spree_users\".\"deleted_at\" IS NULL AND \"spree_users\".\"id\" = $1  ORDER BY \"spree_users\".\"id\" ASC LIMIT 1  [[\"id\", 5]]\r\n   (0.3ms)  SELECT COUNT(*) FROM \"spree_roles\" INNER JOIN \"spree_roles_users\" ON \"spree_roles\".\"id\" = \"spree_roles_users\".\"role_id\" WHERE \"spree_roles_users\".\"user_id\" = $1 AND \"spree_roles\".\"name\" = $2  [[\"user_id\", 5], [\"name\", \"admin\"]]\r\nRedirected to http://localhost:3000/admin/authorization_failure\r\nCompleted 302 Found in 93ms (ActiveRecord: 5.9ms)\r\n```\r\n\r\nNote that Spree is not doing a select for the user role after checking for `admin`. It doesn't check for `editor`, which leads me to believe that for some reason, the custom `AbilityDecorator` is ignored or unloaded after the first request."}}