How to assign different licenses to different user dynamically

37 views
Skip to first unread message

Farukh D.M

unread,
Dec 20, 2012, 11:41:59 PM12/20/12
to cant...@googlegroups.com
I am kind of noob to catango.

So I've a requirement where i need to restrict access to user by creating licenses.

Lets say I've created two licenses viz 'editor'(can only edit things) and 'manager'(can edit and delete things)

Now I've to assign 'editor' license to userA and 'manager' license to userB.

Now how do I do it dynamically and where to hook the code.

So far this is what I've done:

-------------------------------------------------------------------
# in user_permit.rb

class UserPermit < CanTango::UserPermit
   .
   .
   .
   .
  def permit_rules
    licenses :editor # I've created a license class already containing the rules
  end
   .
   .
   .
end
----------------------------------------------

so, if we go by the code above every logged in user would have license as 'editor'. But I need to set it dynamically based on some criteria(which I would manage). I need to know how to do that.

Thanks in advance.

Farukh D.M

unread,
Dec 21, 2012, 2:47:09 AM12/21/12
to cant...@googlegroups.com
Never mind, i got the solution.

i get access to user object as #user
This worked for me.

Thanks

Kristian Mandrup

unread,
Dec 21, 2012, 4:56:08 AM12/21/12
to cant...@googlegroups.com
Great! Yeah, you have several helper methods available from inside a permit. You are most welcome to create a wiki page with your findings and solutions. There is a need to improve the docs by having more examples of real-life typical scenarios. Thanks!

Farukh D.M

unread,
Dec 21, 2012, 5:47:59 AM12/21/12
to cant...@googlegroups.com
sure will do once i get my job done completely :). Currently in middle of something.
Well, could you direct me to the helper methods page, as I've another requirement and just thinking if other methods could help.
Thanks Kristian

Kristian Mandrup

unread,
Dec 21, 2012, 6:17:12 AM12/21/12
to cant...@googlegroups.com
You might also be interested in this project:


The helper methods


I can see that #user isn't mentioned in the list at the top, but only in the example snippets...

can :update, Project do |project|
  user.lucky? 
end

Following example is typical in CanCan:

can :update, Project if user.lucky?
Will update it now. I think the #account is also available.
Message has been deleted

Kristian Mandrup

unread,
Dec 21, 2012, 11:11:55 AM12/21/12
to cant...@googlegroups.com
You can put whatever logic you want in a license. I think it is a good idea to enable loading permits from a permit_store from permits according to whatever logic makes sense.
Perhaps you could extract a subset of the current datastore logic into its own reusable component for use in this kind of scenario.

I think you can create an instance of this directly in your license file:


def editor_store
@editor_store ||= CanTango::PermissionEngine::YamlStore.new :editor, path: Rails.root.join('config', 'permits', 'licenses')
end

Will load a YamlStore from app/config/permits/licenses/editor.yml

You should then be able to do sth like

editor_store.permissions # return/execute the permissions from said Yaml Store.



I think that inside your license you could then do sth like:

puts "before: #(permit.ability_rules}"
puts "loaded rules: #{editor_store.permissions}"

permit.ability_rules.merge! editor_store.permissions

puts "after: #(permit.ability_rules}"

Since the editor_store.permissions should return a hash with the rules, it should be possible somehow to achieve sth like this:

editor_store.permissions['users'][user.email]

In order to load the permissions individually for each user. This would require the permissions loaded to have a top level key matching the user email.
Cantango should already support this!

Good luck!

Let me know if/how you made it work ;) Cheers!

On Dec 21, 2012, at 12:27 PM, "Farukh D.M" <faru...@gmail.com> wrote:

cool thanks so much.
Getting to it.

Well I've one more question Kristian, if you don't mind :D

So, I've license classes with set of rules defined.
Is there a way to set rules in those license class(or elsewhere) via some file(like permission store) or a hash(that could be generated from database) and adding dynamically to the licenses class.

Let me know if i am not clear

Thanks again.

Kristian Mandrup

unread,
Dec 21, 2012, 1:33:34 PM12/21/12
to cant...@googlegroups.com
Would be very nice if you integrated then solution I sketched out in my previous answer into cantango, fx as a pull request. Or at least came up with a method (or module to be included) which nicely wraps this functionality…
Cheers!

On Dec 21, 2012, at 12:27 PM, "Farukh D.M" <faru...@gmail.com> wrote:

cool thanks so much.
Getting to it.

Well I've one more question Kristian, if you don't mind :D

So, I've license classes with set of rules defined.
Is there a way to set rules in those license class(or elsewhere) via some file(like permission store) or a hash(that could be generated from database) and adding dynamically to the licenses class.

Let me know if i am not clear

Thanks again.

Farukh D.M

unread,
Dec 23, 2012, 11:37:25 PM12/23/12
to cant...@googlegroups.com
Wow seems like a tough nut to crack for me(being a noob :D ).

But this is what I've to say. I'm on it.

Thanks again

Farukh D.M

unread,
Dec 24, 2012, 2:56:47 AM12/24/12
to cant...@googlegroups.com
Hey Kristian,

  The statement:
   editor = CanTango::PermissionEngine::YamlStore.new :editor, path: Rails.root.join('config', 'permits', 'licenses')
  is loading the file, but if i do instance.permissions, it returns nil
  editor.permissions => nil
  i tried editor.load_from_hash({ "licenses"=>{"editors"=>{"can"=>{"edit"=>"Post"} } } })
  but that didn't work either, editor.permissions still returns nil.

  Could you tell me how to load permissions from a hash?

Thanks

Kristian Mandrup

unread,
Dec 24, 2012, 4:25:08 AM12/24/12
to cant...@googlegroups.com
I guess you will have to dive deeper into the code. You can see if you can find any spec which uses YamlStore and see how it loads permissions…


  context 'Loading permissions' do
    let (:store) do
      @store ||= CanTango::PermissionEngine::YamlStore.new 'permissions', :path => config_folder
    end

    before(:each) do
      store.load!
    end

    it_should_behave_like "Having permissions"
  end

So it looks like you have to do store.load!

shared_examples_for "Having permissions" do
  it 'should contain bloggers permission allowing to read Comments' do
    store.role_groups_permissions['bloggers'].static_rules.can.read.should include('Article')
  end
 
  it 'should contain editors permission allowing to write Posts' do
    store.role_groups_permissions['editors'].static_rules.cannot.write.should include('Post')
  end
end

Farukh D.M

unread,
Dec 24, 2012, 4:45:53 AM12/24/12
to cant...@googlegroups.com
Thanks Kristian

Will look into it.
Appreciate your help.

Farukh D.M

unread,
Dec 25, 2012, 6:34:38 AM12/25/12
to cant...@googlegroups.com
Hey Kristian,

  I've created a wiki page from some of my findings/work.

  I hope this helps someone in need. 
  I would get back to the other things you have said sometime later.

  Thanks

Farukh D M
Reply all
Reply to author
Forward
0 new messages