A lot has happened since my first post about a little project called Action Control back then.
I've learned a lot along the way using my gem and the problems that come with it down the road when scaling a code base with my gem.
This is why we've chosen to change some things from back then. We've introduced policies, moved the auth logic out of the controller, we've made it a lot more stable and secure, have implemented a solid test suite and the most obvious, a new name.
You'll find Active Entry on GitHub.
Add the gem to your
bundle install. 1.1. (Optional but recommended) Add
ApplicationControllerto never forget to perform it in your controllers.
Implement policies for the controllers where you want to control access. The methods that carry the logic are called decision makers. Every
showaction has a complementary
show?decision maker in the policy.
pass!(for both) in your actions to actually perform the authentication check and authorization.
Rescue from AuthErrors (e.g. redirect to login if user not signed in). If the authentication or authorization check fails, an exception is raised, that can be caught in your controller using
You find a detailed introduction in the README on GitHub.
If you've skimmed over my old post, you've maybe noticed that the old way was to put the authentication and authorization logic directly into the controller. However, there were multiple reasons why we moved the logic into policies.
With growing applications came more complexity and a bigger code base. The old way of doing things was great for quickly bootstrapping an application, but we realized it's not that great when the code base grows.
It's way easier, more reliable and faster to test "plain Ruby objects" than controllers. Simply create a test file for every policy and test the logic without running through the Rails stack.
Whenever we've introduced a link where special privileges were required (e.g. being admin), we had to replicate the logic in our views. And as we all know, duplicated logic is bad and too much logic in views is bad in general. Now you can simply ask the corresponding policy if a user has access and show or hide the link. We've added a few view helpers to make that even easier.
<%= link_to "Admin Dashboard", admin_dashboard_path if Current.user.admin? %>
<%= link_to_if_authorized "Admin Dashboard", admin_dashboard_path %> or <%= link_to "Admin Dashboard", admin_dashboard_path \ if authorized_for?(:admin_dashboards, :show) %> or <%= link_to "Admin Dashboard", admin_dashboard_path \ if AdminDashboardsPolicy.pass?(:show) %>
This DRYs up the code A LOT.
If we change our logic down the road in the old way, we would have to change it also in every view that replicates the logic. Like in the first example.
It also lowers the risk for bugs. If you change your logic in one place and forget to change in another, you are going to either show something to your users, that they shouldn't see, or they don't see something that they should!
It's simply none of the controllers business.
Right now the gem still depends on Rails. However, we've built it in a way in which it can be used in plain Ruby objects. Just create a corresponding
Policy for your class and call
pass! in the method you want to check.
There is not a lot to do to decouple it from Rails. If you are interested in that, feel free to create a pull request. :)
Shoutout to all these amazing gems! Active Entry is not better or worse than these other gems. It's just another way of doing it. We believe in choice and the awesome thing about open source is that we are all in one boat. Different perspectives and ways of doing things make us only stronger.
In the README, we've written down the key differences to the most similar authorization gem Action Policy.
If you like another gem more, feel free to choose the other without any guilt. Every one of the other gems have been battle tested in big applications, so they can all scale with your code base without messing everything up.
For the same reason why you wouldn't build your web application with Ruby from the ground up. You don't want to reinvent the wheel. There are cases, where you want to write your own code, but this is not one of them. A proven way of doing it is better most of the time.
We are just starting with this gem. A big code base of ours depends on it, so we will support it in the long term, even if traction is low and no other contributors join.
We are also planning new features down the road. We haven't had much time to write down a lot of our ideas. Hopefully we find that soon. Feel free to propose your own ideas!
Every feedback on Active Entry is really appreciated!