Git Product home page Git Product logo

canard's People

Contributors

aledalgrande avatar dsalko avatar dwbutler avatar james2m avatar jgeiger avatar jondkinney avatar justbuchanan avatar kevthedev avatar kipkosek avatar ninetwentyfour avatar pkuczynski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

canard's Issues

User abilities don't include guest abilities

I ended up not using Canard for a recent project because the "additive" nature of abilities does not include guest abilities.

I think the behavior should be, for example: guest, user, manager, admin
Instead it is: user, manager, admin

So any abilities defined for guest have to be duplicated in user. Not very DRY. While I realize this is a breaking change, to be perfectly honest, I can't think of any real world examples where a user would be denied from doing something that a guest can do.

test_unit[not found]

I'm using the canard gem to set up user roles and am running into a test_unit[not found] error. I tried adding test-unit to the Gemfile but it still fails. Disclaimer: I'm still relatively novice at Rails.

 $ rails g canard:ability user can:create:post
    conflict  app/abilities/users.rb
Overwrite /home/ubuntu/project/app/abilities/users.rb? (enter "h" for help) [Ynaqdh] Y
       force  app/abilities/users.rb
       error  test_unit [not found]

.has_role? :user returns false

Great job wrapping up role_model! This is actually a role_model suggestion but I guess I want to point that the example:

class User < ActiveRecord::Base

acts_as_user :roles => :manager, :admin

end

suggests that abilities are checked in the following order:

app/abilities/users.rb
app/abilities/manager.rb
app/abilities/admin.rb

And indeed, I confirmed that /users.rb is called for users with empty roles, and yet of course has_role? :user returns false. Since, of course, you're keeping canard consistent with role_model, then an end-user work around would explicitly specify the :user role in the list of roles and explicitly set each new user to be a :user,

acts_as_user :roles => :user, :manager, :admin

Of course, while it's easy to add a :user role later and add the :user role to every existing user if someone really feels the need to do this, maybe it would be worth documenting a sentence or two about this inconsistency.

cancancan support

Hi there,

Thanks for this gem, I like it quite a bit. I'm curious about support for cancancan. I noticed that it seems to be in the gemspec on github, but perhaps the latest code is not released as a gem? For now I've specified the master branch of this repo on my gemfile and then cancancan was installed as a dependency of canard. Any plans to release those 6 month old changes to gem land? Or perhaps I'm just doing something wrong since I was still seeing cancan installed when just using gem 'canard' in my gemfile.

Thanks!

Support for rolify?

I really like how canard simplifies authorization and roles. However, for my particular application I have been agonizing over role_model's inability to scope a role to a particular resource. I also have nightmares in my sleep thinking about when I need to add a new role and migrate all the bitmasks over. shudder

I'd like to try out rolify but I don't want to give up canard!

After looking things over, I think it might be possible to support rolify in canard. For example, most of the stuff in ::acts_as_user and the Adapters aren't necessary, because rolify already defines scopes for ActiveRecord and Mongoid. This stuff could conditionally be loaded only if the model is_a? RoleModel or perhaps via a configuration option.

If this sounds plausible/interesting to you, I'd be willing to give it a shot.

How to use cancard with separate context?

Hello,
First of all I would like to say thank you for great and well tested open source project.
I have trouble with getting out of my problem so I decided to ask for help. Currently I am trying to make system with couple separate interfaces but with one User model. There is Admin, Partner and User interface. User could have many global roles (cancard fit there very good) but User could have many roles as PartnerUser (model which contains relation user_id, partner_id, role). I dont know how to set up before_filter in my Partner base namespace to add this separate context (role of user for selected partner).

Please checkout my relations:

class PartnerUser < ActiveRecord::Base
  ROLES = {
    owner: 0,
    employee: 1 
  }

  belongs_to :user
  belongs_to :partner

  has_many :transactions, class_name: "Transaction"

  validate :role, inclussion: { in: ROLES }
class Partner < ActiveRecord::Base

  has_many :partner_users, include: :user
  has_many :users, through: :partner_users
class User < ActiveRecord::Base
  ALLOWED_ROLES = [:manager, :admin, :reporter]
  acts_as_user roles: ALLOWED_ROLES

  # Partner
  has_many :partner_users
  has_many :partners, through: :partner_users

Partner base controller

# -*- encoding : utf-8 -*-
class Partner::BaseController < InheritedResources::Base
  layout 'admin/index'

  before_filter :authenticate_user!
  before_filter :authorize_for_subdomain!

  helper_method :current_user_role
  helper_method :current_partner

  rescue_from ActiveRecord::RecordNotFound, with: :partner_not_found

  add_crumb(I18n.t('partner.dashboard.singular')) { |instance| instance.send :partner_root_path }

  def authorize_for_subdomain!
    @subdomain = request.subdomain.to_s.split('.').first
    @current_partner = Partner.find_by_url(@subdomain)

    raise ActiveRecord::RecordNotFound unless @current_partner.present?
    @current_partner_user = @current_partner.partner_users.where(user_id: @current_user.id).try(:first)

    raise CanCan::AccessDenied unless @current_partner_user.present?

    @current_user_role = @current_partner_user.current_role || :employee
    current_user
  end

  private

  def current_user_role
    authorize_for_subdomain! unless @current_user_role.present?
    @current_user_role
  end

  def current_partner
    authorize_for_subdomain! unless @current_partner.present?
    @current_partner
  end

  protected

  def partner_not_found
    flash[:error] = "Poszukiwana strona nie istnieje"
    redirect_to root_path
  end

  def begin_of_association_chain
    current_partner
  end

  def set_current_user_for_acl
    @current_ability ||= Ability.new(current_admin)
  end


end

Thanks in advantage for any suggestions :).
Have a nice day!

Allow one role to inherit abilities of other roles

Though one can assign multiple roles to user, to try to keep the abilities DRY, we would prefer to get the same affect when assigning a single role to a user. For example, if I had the following roles

  • User - access only to login and own profile
  • Writer - Can do everything a User can do, and create content
  • Editor - Can do everything a writer can do, can assign stories, can publish
  • Manager - Can do everything an editor can do, can agree to jobs, can remove published stories, etc
  • Supervisor - etc

Instead of making sure that the Supervisor user also was assigned to all of the preceding roles, I would like to define the Supervisor's abilities so that it inherited from all of the preceding abilities.

I am thinking that at the top of an abilities definition, I include a call like:

includes_abilities_of :user, :writer, :editor, :manager

Then add the following to the Ability class:

  def includes_abilities_of(*other_roles)
    other_roles.each { |other_role| append_abilities(other_role) }
  end

If this makes sense to you, i am happy to issue a pull request

Bundler won't install canard unless Rails is already installed

This stems from the require 'rails' on line 4 of the gemspec. I see why you're doing that, so you can check whether to use cancan or cancancan, but it doesn't seem like this is safe. I even added a runtime_dependency to the gemspec for rails and it still didn't try to install rails before trying to install canard. I'm sure there is a way, but I'm not sure what it is. Can you help?

There was a LoadError while loading canard.gemspec:
cannot load such file -- rails from
  /rails/github/canard/canard.gemspec:4:in `<main>'

This is from my local branch, which is why the path is not maybe what you'd expect.

Thanks!

Get All Available Roles

I'm trying to get the available roles for the user model defined, so I can display them in my view. I know with the role model gem I can call User.valid_roles to return all the available roles declared. Is there a way to do this with canard? If I do use ".valid_roles" on my user object it gives me an undefined method error.

Help with this will be appreciated

EDIT - my mistake, saw I was calling it on the user object instead of on the User model - is working now.

Non-inherited Roles

Is it possible to create roles that don't inherit abilities from "lesser" roles? I need two separate roles that are disjoint, and it seems that's not possible atm.

Multiple Abilities?

It would be awesome to have multiple ability definitions for applications that have multiple "apps" with different permissions (primary example being an admin app vs the standard app).

I know this is a relatively common use-case in plain old CanCan(Can), but was wondering how you'd suggest doing so with Canard?

I have a rudimentary solution working, but it requires me to create a custom Ability class from yours (partly due to the methods being private over protected, partly to provide a hook)

class CustomAbility < Ability
  def initialize(object=nil)
    @user = object.respond_to?(:user) ? object.user : object
    setup_abilities
  end

protected

  def setup_abilities
  end

  def add_role_abilities(roles)
    roles = [roles] unless roles.is_a? Array
    roles.each{ |role| self.send(:append_abilities, role) }
  end

  def get_ability_key(class_name)
    self.send(:ability_key, class_name)
  end
end

and then for my "custom" ablities, inheriting from the new class, and adjusting as necessary (currently by just simply appending admin_ to the front, just to see if it'd work)

class AdminAbility < CustomAbility
protected
  def setup_abilities
    return unless @user

    user_class_name = String(@user.class.name)
    add_role_abilities get_ability_key("admin_#{user_class_name}") unless user_class_name.empty?

    # If user has roles get those abilities
    add_role_abilities @user.roles.map{ |role| role.to_s.prepend('admin_').to_sym } if @user.respond_to?(:roles)
  end
end

Heroku, devise, and canard fails on rake assets:precompile

With Rails 4.0 beta1, devise loads the user model which, in turn, loads canard which checks it for a role matrix. This is fine if the database exists, but as many of us know from painful experience Heroku does not bring the database up before running the precompile. As a result you see:

Preparing app for Rails asset pipeline
       Running: rake assets:precompile
       rake aborted!
       could not connect to server: Connection refused
       Is the server running on host "127.0.0.1" and accepting
       TCP/IP connections on port 5432?
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/postgresql_adapter.rb:771:in `initialize'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/postgresql_adapter.rb:771:in `new'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/postgresql_adapter.rb:771:in `connect'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/postgresql_adapter.rb:493:in `initialize'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/postgresql_adapter.rb:41:in `new'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/postgresql_adapter.rb:41:in `postgresql_c
onnection'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/abstract/connection_pool.rb:446:in `new_c
onnection'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/abstract/connection_pool.rb:456:in `check
out_new_connection'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/abstract/connection_pool.rb:427:in `acqui
re_connection'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/abstract/connection_pool.rb:364:in `block
 in checkout'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/abstract/connection_pool.rb:363:in `check
out'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/abstract/connection_pool.rb:273:in `block
 in connection'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/abstract/connection_pool.rb:272:in `conne
ction'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_adapters/abstract/connection_pool.rb:552:in `retri
eve_connection'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_handling.rb:79:in `retrieve_connection'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/connection_handling.rb:53:in `connection'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/activerecord-4.0.0.beta1/lib/active_record/model_schema.rb:203:in `table_exists?'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/canard-0.4.1/lib/canard/adapters/active_record.rb:30:in `active_record_table?'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/canard-0.4.1/lib/canard/adapters/active_record.rb:35:in `has_roles_mask_accessors?'
       /tmp/build_2sfjhhr6toicw/vendor/bundle/ruby/2.0.0/gems/canard-0.4.1/lib/canard/user_model.rb:74:in `acts_as_user'
       /tmp/build_2sfjhhr6toicw/app/models/user.rb:12:in `<class:User>'
       /tmp/build_2sfjhhr6toicw/app/models/user.rb:1:in `<top (required)>'

The workaround that got Heroku back up and running was to only run the canard helper if the connection is present.

  # must test for the connection because of a precompile problem on Heroku 
  acts_as_user :roles => [:timekeeper, :admin] if ActiveRecord::Base.connected?

Not sure if anything can be done on the code side but if it was built in to the matrix check that would help. Possible? Necessary? Thanks so much for the wonderful work on this gem. I rolled my own at first and then appreciated the hard work that went into this gem all the more.

Instalation

HI,
One question about instalation. Should I define any column for storing role attributes? I could not find any details about this in readme and sourcecode.

How to stub the ability in the step_definitions

Hi,
I am having a code like can? :access, :project in my views. Based on that I am showing the link.
So that is defined in the abilities file as usual which is working fine.

i.e., eg:
app/abilities/admin.rb
I am using can :access, :project

app/abilities/employee.rb
I am using cannot :access, :project

Now I wanted to test in the following way in cucumber with the help of step_definition:

  • Login as User (Any User Admin/Employee)
  • In one test case I wanted to pass the value as true for :access, :project and test the project link
  • In another test case I wanted to pass the value as false for :access, :project and test the project link

So this means I wanted to dynamically change the ability and ensure the test pass.
How DO I do this?
I have done something like this which is not working.

@user.ability.stub(:can?).with(:access, :project).and_return(false)

The reason behind this is tomorrow we might change employee ability also to can :access, :project hence i want this dynamic behavior.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.