开发者

Rails3 and Devise as part of basic CRM

开发者 https://www.devze.com 2023-03-29 12:05 出处:网络
We\'ve built a custom CRM for managing our customers and orders in Rails3 with devise for authentication and cancan doing the permission magic.

We've built a custom CRM for managing our customers and orders in Rails3 with devise for authentication and cancan doing the permission magic.

Companies have many people, orders and invoices. Pretty simple.

On top of this we have our users through devise who can login etc.开发者_开发知识库

What I really want to do is combine the admin users and people - for example, we sometimes want customers to login. It seems a bit ott to have admin users separate from the people? We'd like to specify that a customer can login to save adding them through devise twice.

Initially I though everyone should be added through devise registration but I'm not sure this is right.

I hope someone's tried this or can share some advise. Is there a good, simple way to achieve this?

-- EDIT --

Further to the answers below, I've updated to make a little more clear.

We need to be able to add users to the CRM without making them an admin OR having to provide them with a password (that devise seems to insist on).

  1. Create customer / user with blank / no password
  2. If customer needs to login, mark admin checkbox and specify roles (through cancan)
  3. Unchecking admin flag should disallow access

Currently, we have a list of people that is separate to our list of devise users. We want to somehow combine.


I think that has no problem to have the same model for all kind of users. You only need to define the user role, through a database column for example.

But in many cases, you'll need more than a user role to deny or allow access, you'll need to verify if the current_user has requested the current Order, for example. So you can do this:

Suppose you have this model:

class User < ActiveRecord::Base
  devise :database_authenticatable, :confirmab...
  ...

  def admin?
    role == 'admin'
  end
end

So you can verify User role through some method in your model like admin?.

Now you can use Can Can for your authorization, as you can see here how to define your abilities.

Abilty class:

class Ability
  include CanCan::Ability

  def initialize(user)
    user ||= User.new # guest user (not logged in)
    if user.admin?
      can :manage, :all
    else
      can :read, :all
    end
  end
end

Understands how CanCan works is an important thing: look here.

Suppose you want to get params into your ability class that allows you to verify objects in your database before load the page, allowing or not the user access. In your application_controller file, put something like this:

  ...
  def current_ability
    @current_ability ||= Ability.new(params, current_user)
  end
  ...

In your ability, change arguments of initialize method and uses params as you need:

class Ability
  include CanCan::Ability

  def initialize(params, user)
    user ||= User.new # guest user (not logged in)
    if user.admin?
      can :manage, :all
    else
      # Verify the record for atuhorization
      can :manage, Order if Order.find(params[:id]).requester_id == user.id
    end
  end
end


If your app is not user centeric (e.g parts of your app is not scoped to a user) and login is only necessary to a small part of "people", you can have the user functionalities (authentication roles and so on) added with a one to one relationship :

class Person < AR::Base
  has_one :user
  belongs_to :company 
  ...
end

class User < AR::Base
  belongs_to :person
  devise :database_authenticatable, ...
end

That way you can import your customers in a simple person db (without worrying about devise validation), and add the small set of "users" afterwards.

It is also quit flexible : whenever someone needs access to your admin panel or whenever you want to change the app to a user based feature (e.g every user has his own page etc) you can easily upgrade without breaking your domain model...

It's pure separation of concern


If I have understood what you mean, the easiest way is to use a admin boolean in your user Model. That's all !


Create customer / user with blank / no password :

To do that you'll need to override (actually decorate) the validation process that prevents you from creating a user without password

class User < AR

  devise :database_authenticatable, validatable #, etc..

  module ValidatableDecorator
    # commented are the original methods
    #def password_required?
    #  !persisted? || !password.nil? || !password_confirmation.nil?
    #end

    #def email_required?
    #  true
    #end

    def password_required?
      myspecial_condition && super
    end

    def email_required?
      my(other)special_condition && super 
    end

    def myspecial_condition
      false #if ...someattribute is false
    end
  end
  include ValidatableDecorator
end

Another solution is to generate a password.... but read below first

If customer needs to login, mark admin checkbox and specify roles (through cancan)

There's one flaw here : if a user has no password then anybody could use his email to enter the admin section once he is granted the right! So first you'll need a password for the user...

I suggest you use the recoverable module provided by devise, that''ll send him an email with a secret link to let him reset his password (except he doesn't have any yet

Unchecking admin flag should disallow access

Granting/ungranting admin rights is rather easy : https://github.com/plataformatec/devise/wiki/How-To:-Add-an-Admin-role

0

精彩评论

暂无评论...
验证码 换一张
取 消