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

Use an authorisation framework #1626

Closed
gravitystorm opened this Issue Aug 30, 2017 · 4 comments

Comments

Projects
None yet
2 participants
@gravitystorm
Collaborator

gravitystorm commented Aug 30, 2017

Our codebase currently has a home-grown permissions system. The logic of who can do what is built into every controller action, which is becoming unwieldy, particularly when we want to allow multiple types of user to do something (e.g. allow the user, moderators and admins to delete something). We also have a "default allow" system, where each action is permitted to all users, unless we add permissions checks. I'd like to make it easier to add more roles (e.g. like allowing people to moderate diaries without being able to block users). And as with much of what I work on here, I'd like to tack towards standard solutions.

So I'd like to move to a third-party authorisation framework. I'd like to see in particular:

  • A default deny policy, so that actions aren't accidentally accessible.
  • A centralised authorisation configuration, so that permissions aren't scattered all over the site.
  • A system that's powerful enough that we can write complex authorisation rules.

I'm particularly fond of decl_auth but unfortunately that is now unmaintained and none of the forks have gathered any momentum. The best alternative that I've found is CanCanCan, which behaves similarly to decl_auth, but their Ability class looks a bit clunky compared to the decl_auth authorisation_rules DSL.

https://www.ruby-toolbox.com/categories/rails_authorization.html has a list of alternatives.

Because this will be a bit of an invasive surgery, I'd like to get other people's thoughts before jumping in at the deep end.

@gravitystorm

This comment has been minimized.

Collaborator

gravitystorm commented Aug 30, 2017

For a non-trivial but also not-over-the-top example of a central rules file, I've previously worked on this one (using decl_auth):

https://github.com/cyclestreets/cyclescape/blob/staging/config/authorization_rules.rb

@tomhughes

This comment has been minimized.

Member

tomhughes commented Aug 31, 2017

Sounds like a good idea to me, and I agree that CanCanCan looks like it's probably the best option from what I've seen so far.

I have to say that having read quite a bit of the CanCanCan documentation now I still don't entirely understand how the ability objects get created and attached to the request so that he controllers and views can see them, but I'm sure there's something entirely obvious that I've missed that you will be able to figure out ;-)

@gravitystorm

This comment has been minimized.

Collaborator

gravitystorm commented Apr 18, 2018

For reference I made a start on integrating CanCanCan a few weeks ago, and the proof of concept worked (just allowing sign in and viewing the /welcome page).

What became quickly apparent is that the whole thing will be much easier to implement if we refactor the majority of the routes first, to use resourceful routing much more widely, so that's what I'm working towards.

@gravitystorm

This comment has been minimized.

Collaborator

gravitystorm commented Oct 24, 2018

As an update, #2023 is coming together, and I hope we can resolve any remaining aspects soon and get it merged. For reference, the process after that will be roughly:

  • Refactor various controllers to remove the need for require_moderator and require_administrator. These can be checked with the abilities instead.
  • Refactor various controllers and views to remove role checks e.g. if current_user.moderator?, and replace with permission checks e.g. can? :delete @note.
  • Refactor remaining controllers to avoid needing the require_user filter
  • Review the need for require_cability and friends, and migrate to using the new capabilities approach
  • Mark any other controllers as not needing authorization, and then add check_authorization to application controller
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment