I''m using single table inheritance to handle several types/roles of users within my application. I want to be able to authorize certain actions based on user type. I''ve seen Chad Fowler''s recipe for users|roles|rights, but I like the simplicity of STI and don''t really want to introduce any other tables/ models if I can help it. Could anyone suggest some ideas for authorizing users by type within controllers? Thanks. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Jim, Don''t know if this is what you''re looking for but Rails supports a type of single inheritance that you could use Here''s an example (this goes in the model file, so in this case user.rb): class User < ActiveRecord::Base def self.inheritance_column ''usertype'' end end class Visitor < User; end class Editor < User; end class Admin < User; end So, in your ''users'' table you''d define a field (a varchar - make it as big as necessary) called ''usertype''. The above code defines a class called User which declares that it''s inheritance_column is ''usertype''. When I create users I don''t create them from the User class, but rather from one of the subclasses (Visitor, Editor and Admin - you can define as many as you like). So instead of saying something like @this_user = User.new(params[:user]) I''d do something like @this_user = Visitor.new(params[:user]) Which creates an entry in the ''users'' table and puts ''Visitor'' in the ''usertype'' field. At some later point I could do something like check_user = User.find(params[:id]) if check_user.usertype == ''Admin'' etc... end Notice here that I have used the User class again, rather than Visitor, that''s because it''s the parent class and I don''t know what type of user it will return. Hope this helps some. Dale On Mar 13, 8:23 pm, "jim" <jjones35...-/E1597aS9LQAvxtiuMwx3w@public.gmane.org> wrote:> I''m using single table inheritance to handle several types/roles of > users within my application. > > I want to be able to authorize certain actions based on user type. > > I''ve seen Chad Fowler''s recipe for users|roles|rights, but I like the > simplicity of STI and don''t really want to introduce any other tables/ > models if I can help it. > > Could anyone suggest some ideas for authorizing users by type within > controllers? > > Thanks.--~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Wed, Mar 14, 2007 at 04:23:56AM -0000, jim wrote :> Could anyone suggest some ideas for authorizing users by type within > controllers?You could just add a row ''rights'' in your user table? In your user model, you could add such methods: def is_admin? self.rights == ''admin'' end So, in your controllers, you''ll be able to add easily before_filter methods based on rights. If you like STI, add an Admin<User model and write methods like: def self.find_all(id) find(:all, :conditions => [''rights = admin'']) end and add a before_save: before_save :admin_rights def admin_rights self.rights = "admin" end So, you''ll be able to do Admin.create(:nom => ''pam'') whithout think of the row ''rights'' in your controller. My $0.02. -- ,========================. | Pierre-Alexandre Meyer | | email : pam-1sEOgp2Wo8Qdnm+yROfE0A@public.gmane.org | `========================'' --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Dear Pierre-Alexandre, First my apologies for just droping in like this. I''m looking for something similar and can''t seem to get a grasp on how to do this. I have a proper loginsystem running and would like to enable/disable the restricted action on per user/controller base. I''m thinking about an extra field in de user model called areas, where 1 or more controllers are mentioned. So a user either can or can''t CRUD the records of a model. I would like to do this with as little tampering on the existing code as possible, to keep things tidy. I''ve been messing with an allowed_users list in the model.rb but I go blank when I have to start hacking on the loginsystem code. Your help would be highly appreciated. Again sorry to drop in like this. Regards, Gerard.> On Wed, Mar 14, 2007 at 04:23:56AM -0000, jim wrote : >> Could anyone suggest some ideas for authorizing users by type within >> controllers? > > You could just add a row ''rights'' in your user table? > In your user model, you could add such methods: > > def is_admin? > self.rights == ''admin'' > end > > So, in your controllers, you''ll be able to add easily before_filter > methods based on rights. > > If you like STI, add an Admin<User model and write methods like: > > def self.find_all(id) > find(:all, :conditions => [''rights = admin'']) > end > > and add a before_save: > > before_save :admin_rights > > def admin_rights > self.rights = "admin" > end > > So, you''ll be able to do Admin.create(:nom => ''pam'') whithout think of > the row ''rights'' in your controller. > > My $0.02. > > -- > ,========================. > | Pierre-Alexandre Meyer | > | email : pam-1sEOgp2Wo8Qdnm+yROfE0A@public.gmane.org | > `========================''-- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Wed, Mar 14, 2007 at 04:30:59PM +0100, Gerard Petersen wrote :> I have a proper loginsystem running and would like to > enable/disable the restricted action on per user/controller base.What do you mean by ''per user/controller base''? If you just want to restrict access of some actions (may be in several controllers), just add in your controllers: before_filter :authorize, :only => [my_restricted_actions] That is to say, it will call the method ''authorize'' before each action in [my_restricted_actions]. The method authorize could be similar to (put it in application.rb): def authorize if User.find(session[:user_id]).rights == ''admin'' return true else flash[:warning]="Hey! You''re not admin!" redirect_to :controller => "user", :action => "show" return false end end If the User.find(session[:user_id]) user is not an admin, the called method (destroy, update, ... whatever you want) won''t be executed.> I''m thinking about an extra field in de user model called areas, where 1 > or more > controllers are mentioned.You don''t have to think about controllers in your tables. Just add an extra row ''rights'' in your users table and play with the snippet above.> I would like to do this with as little tampering on the existing code as > possible, to keep things tidy.So I guess my method will suit to you :) Hope that helps, -- ,========================. | Pierre-Alexandre Meyer | | email : pam-1sEOgp2Wo8Qdnm+yROfE0A@public.gmane.org | `========================'' --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Pierre-Alexandre, Thanx for your quick response. replies inline ...> What do you mean by ''per user/controller base''?That the, password protected, editing can be enabled for the users per controller (well model actually). e.g. User: mark Areas: Book CD So in this case the user mark is allowed to edit the models Book and CD> def authorize > if User.find(session[:user_id]).rights == ''admin'' > return true > else > flash[:warning]="Hey! You''re not admin!" > redirect_to :controller => "user", :action => "show" > return false > end > end > > If the User.find(session[:user_id]) user is not an admin, the called > method > (destroy, update, ... whatever you want) won''t be executed. > >> I''m thinking about an extra field in de user model called areas, where 1 >> or more >> controllers are mentioned. > > You don''t have to think about controllers in your tables. Just add an > extra row ''rights'' in your users table and play with the snippet above.Looks clear! I''ll play with it. Still wondering how ik can restrict this to a specific model. Use something like this maybe? .... User.find(session[:user_id]).rights == ''modelname_admin'' Use the model name for the ''rights'' value. Hmm ... maybe just check for the value book (in the field area) with the method "authorize" and then it''s based on the available models.> Hope that helps,It definitely does. Thanks so much, Gerard.> > -- > ,========================. > | Pierre-Alexandre Meyer | > | email : pam-1sEOgp2Wo8Qdnm+yROfE0A@public.gmane.org | > `========================''-- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Gerard Petersen <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> That the, password protected, editing can be enabled for the users per > controller (well model actually). e.g. > > User: mark > Areas: Book CD > > So in this case the user mark is allowed to edit the models Book and CDWell, if you are going to have multiple areas, you probably want a separate table to list them, then do something like group = Group.find_by_name("Book") if users.groups.include?(group) # user can edit books ... Or, with the "do" block I was emailing about last night, it just becomes: if users.groups.include?("Book") # ... I hammered this out last night... I''ve got it to the point where a controller can say: require_group :Admin , etc, to restrict access. it''s not ready for "release" yet, but if anybody wants to take a look at the models/migrations/authenticatedSystem, send me an email off-list. Cheers, Tyler --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Wed, Mar 14, 2007 at 06:59:37PM +0100, Gerard Petersen wrote :> That the, password protected, editing can be enabled for the users per > controller (well model actually). e.g. > > User: mark > Areas: Book CD > > So in this case the user mark is allowed to edit the models Book and CDOk, it''s clear now. You want to define areas in you app in which you can manage rights for your users.> Looks clear! I''ll play with it. Still wondering how ik can restrict > this to a specific model. Use something like this maybe? > > .... User.find(session[:user_id]).rights == ''modelname_admin'' > > Use the model name for the ''rights'' value.You could handle your rights like this. But what happens if your modelname change tomorrows? By the way, mark is admin of the book shop AND the CD shop. How will you handle it?> Hmm ... maybe just check for the value book (in the field area) with the > method "authorize" and then it''s based on the available models.I suggest you to create a table for your areas: create_table "admin_areas", :force => true do |t| t.column "name", :string t.column "user_id", :integer end class User < ActiveRecord::Base has_many :admin_areas def is_admin_for?(area) AdminArea.find_by_name_and_user_id(area,self.id) end end The second method return true if it finds something or nil if it doesn''t. Assuming you have @area=''book'' in your controller book_controller.rb, you can define in your application.rb: def authorize if User.find(session[:user_id]).is_admin_for?(@area) return true else flash[:warning]="Hey! You''re not admin for area #{@area}!" redirect_to :controller => "user", :action => "show" return false end end> It definitely does.Cool :) -- ,========================. | Pierre-Alexandre Meyer | | email : pam-1sEOgp2Wo8Qdnm+yROfE0A@public.gmane.org | `========================'' --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
On Wed, Mar 14, 2007 at 11:16:47AM -0700, Tyler MacDonald wrote :> group = Group.find_by_name("Book") > if users.groups.include?(group) > # user can edit books > ... > Or, with the "do" block I was emailing about last night, it just becomes: > > if users.groups.include?("Book") > # ...The point is, what if the variable ''users'' change one day? Or if you want to change ''Book'' to ''bookshelf''? The code is much cleaner and easier to improve if you don''t put such logic in each method in your controllers.> I hammered this out last night... I''ve got it to the point where a > controller can say: > > require_group :Admin > > , etc, to restrict access. it''s not ready for "release" yet, but if > anybody wants to take a look at the models/migrations/authenticatedSystem, > send me an email off-list.Great! I''m gonna send you an email right now :) ++ -- ,========================. | Pierre-Alexandre Meyer | | email : pam-1sEOgp2Wo8Qdnm+yROfE0A@public.gmane.org | `========================'' --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Tyler,> I hammered this out last night... I''ve got it to the point where a > controller can say: > > require_group :AdminThen I''m only curious where the ''rest'' of the code goes best. Would you put this in /lib/login_system.rb? Anyway I''ll send you an email Thanx a lot! Gerard. -- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Tyler,> send me an email off-list.Couldn''t find your userid (number) on this list to send you an email .. :-/ Would you be so kind to send me one on: gjp-CHh3ssHty8s@public.gmane.org Thanx! Regards, Gerard.> > Cheers, > Tyler-- Posted via http://www.ruby-forum.com/. --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---
Gerard Petersen <rails-mailing-list-ARtvInVfO7ksV2N9l4h3zg@public.gmane.org> wrote:> > I hammered this out last night... I''ve got it to the point where a > > controller can say: > > > > require_group :Admin > Then I''m only curious where the ''rest'' of the code goes best. Would you > put this in /lib/login_system.rb?Yep, it''s in my authenticated_system.rb, which is included by the application controller. Cheers, Tyler --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---