Rokku 2.0.0 released

Hi all,

as mentioned in the post about Tachiban, I released the authorization gem as well. Rokku 2.0.0 can now be used with Hanami 2.3 appsl.

Thanks for releasing this, Sebastjan! As the authorization gem I was using for my project apparently became unmaintained, I took a look at this today. This was, admittedly, very superficial look, but here’s some feedback/questions:

  1. The readme does not show a policy file, which was a bit surprising. Only after I generated one, I could see how it looks.
  2. Does it support non-CRUD actions? Is it enough to define e.g. lock? method in the policy for Lock action?
  3. How do you envision doing something more fine-grained, such as “I can edit if I’m admin or author of the article”? I understand that I can pass any object to authorized?, not necessarily a user, but then it’s automatically converted to just the list of roles inside the policy. Is there a way to provide some wider context? Or maybe you consider this out of scope of Rokku (which is fine too)?

Hi Paweł,

thank you for checking out Rokku and thank you for the feedback.

It’s quite embarrassing that I left out the policy file out of the documentation, given that it’s the basis for the functionality. I apologize. I’ll push a fix for that, but I’ll go over everything again first, just to be sure it’s all there. I was pressed for time, I needed 2.0 for my current app and I apparently released too soon; not an excuse, just the reason :slight_smile: .

Non-CRUD actions should work, Rokku is just testing against the namespace as it is, so adding lock? for Lock action would work. I have StatisticsReport::Index, but there so no real CRUD going on, I could have just used StatisticsReport::Report.

Maybe I could change the generator to allow for these scenarios:

  • create only default CRUD actions,
  • create default CRUD actions and optional custom actions,
  • create only custom actions.

Or a more simpler approach of:

  • create default CRUD actions and optional custom actions.

As for more fine-grained approach, I agree. Rokku should be enhanced. The current scope of functionality is a reflection of my current requirements. I did try out the approach you suggest in the past (0.5.1 I believe) with is_author?(object) so then I could do authorized?(@controller_name, @action_name) && is_author?(@task).

I would like to revisit this and provide more granular approach. I’ll try to do this in the scope of my current application I’m working on and prepare a proposal. Of course any suggestions are most welcome :slight_smile: .

1 Like

Hi Paweł,

so I’ve found myself needing the additional features discussed above and I’m testing them in my current app. For policy creation, I’ll most likely implement “create default CRUD actions and optional custom actions”.

As for authoring, I have difficulties deciding on the best approach. I have two requirements:

  1. User can edit user if they are super_admin or they want to edit their own profile.
  2. User can edit an entity, if they “own” it, “are responsible for” it, have “created” it and so on. The wording is different, the effect is the same. The important distinction being, someone maybe responsible for an entity, but has not created it.

So, I’m testing these two for the above requirements:

def is_self?(request, user:)
  logged_in_user = request.session[:current_user] #returns user id
  logged_in_user == user.id
end

def is_owner?(request, entity:)
  logged_in_user = request.session[:current_user] #returns user id
  logged_in_user == entity.user_id # required attribute on the entity
end

In an action that requires such combination I then do:

# frozen_string_literal: true

module Myapp
  module Actions
    module Users
      class Edit < Myapp::Action
        include Deps["repos.user_repo"]

        def handle(request, response)
          
          user = user_repo.find_by_id(request.params[:id])
          current_user = user_repo.find_by_id(request.session[:current_user])

          if is_self?(request, user: user) || authorized?(current_user)
            response.flash[:success_notice] = "Can edit"
          else
            response.flash[:failed_notice] = "Cannot edit"
            response.redirect_to "/users"
          end

        end

        private

        def check_authorization;; end
      end
    end
  end
end

I’m overwriting the def check_authorization; end, otherwise would be called in the before block for each action.

This is a crude example, but it works as expected.

I’m not too happy with the method names. Maybe is_account_owner? and is_responsible_for?.

Also, the code is similar in the both, but maybe in such case duplication would be acceptable?

What do you think?

Best, Sebastjan

>>>EDIT: grammar