Maybe we could give a try for negative captcha? I use it on many sites and it's seems to work better than classic captchas.. and without people harassment.
I think it's our responsibility to take the time to report the spam. The problem is that the ahole that is doing this knows that there is a flood of activity every monday morning so he's probably adding the spam manually.
When you delete
@article = Article.find(params[:id]) and @article =Article.new... from the ArticlesController. You say it is now handled by the filter_resource_access before filter.
Where is this implemented? What happens if my controller differs and I need something other then .find(params[:id]) for instance when using pagination? Can we use a different before filter?
Hey Ryan, great work,
However I wonder how to go about doing a role based management with accounts (subdomains). So if some user has manage access in account 1 and guest access in account 2. How would you go about setting that up in declarative_authorization?
Authorization plugins are a hard find. Some have barely any features, some are overly complex. One issue I'd like to point out is if someone is not authorized, it should throw perhaps a 401
I'm a user (and guys at my company aswell) of base_auth, a pretty simple yet powerful authorization plugin. I think you could do a Railscast on that one too, now that you've touched the topic of authorization.
http://blog.aenima.pl/2008/12/8/base-auth-a-complete-tutorial-to-securing-your-rails-application
Ryan - excellent, useful information this week. I've been a satisfied user of your nifty_authentication generator. For a tiny app I'm doing at work, I'd like the staff to be able to do just about anything except create a new user - I'd like only an admin to be able to do that. I've been trying to figure out how to do roles with nifty_authentication since for this project even something as straightforward as authlogic is more complexity than I need. So here's my encouragement for an rbates authorization solution that's just a LITTLE more full featured than nifty_authentication!
For those who need to control non-action related content and keep the declarative approach - this is what works perfectly for me:
- Create a dummy action in the controller (e.g. "admin", "no_admin")
- define the corresponding role-based rules
- and use the Authorization view_helper (e.g "if permitted_to? :admin, :articles) in the view
The benefit is that you don't have to update your views when adding roles.
It's me or the iPhone/iPod version has some artifacts and a couple times the screen gets freeze...
Except for this ;-) I think you're doing an amazing job. Thank you.
Nice solution! But if I don't want to hard code the acl, what's the alternatives for storing everything in the database? I think it would be more flexible to be able to create permissions on the fly and then assign them to user groups perhaps.
Sven Fuchs and I have written a really generic (and therefore powerful and not quite easy to use) RBAC implementation. You can find it here: http://github.com/svenfuchs/rbac
We use it in adva-cms (http://github.com/svenfuchs/adva_cms - http://adva-cms.org), so you can check the implementation there if you want to.
Why not say a codeword at the end of the railscast that is needed to post a comment for it? Or some obfuscated ruby code to display a password? That might discourage the spammer...
Cool cast, I build my on plugin for this, much more client oriented, but this still is cool.
(I'm submitting this comment to see if the recaptcha is really working)
As a viewer from the beginning (or very close) I second the idea of registering to be able to comment or something like that. A passcode at the end of the cast might work, too. For whatever reason reCaptcha isn't working at all.
Your approach to putting access control on non-action based content in intriguing, but I cannot understand your explanation well enough to implement it. Where can I go to see this in more detail?
For example, where do you put the content to be controlled? Is it hard-coded in the view? And is the dummy controller completely empty?
Hi! I'm having this problem: i have, in my user table, a boolean column named "admin"..in my user.rb i wrote:
def role_symbol
[:admin] if admin?
end
and in my authorization_rules i have:
role :admin do
has_permission_on [:artists, :albums, :events, :neews], :to => [:index, :show, :new, :create, :edit, :update, :destroy]
end
the problem is that when i login as an admin user(which has admin = true) i can't reach any model which has "filter_resource_access" in its controller, i see the "You are not allowed to access this action." page...why?
Thanks a lot!
A couple of thoughts/temporary fixes on the spam issue.
1. If enough users click on "Report as Spam" for a message, hide the detail of the message. Put a "Flagged as Spam" message and an "Unhide" link - that way, you can scroll through the comments quicker.
2. Assign basic moderator functionality and assign a handful of trusted readers to remove the spam.
3. Implement the keyword blacklist that others have suggested. If a few valid comments don't make it through, it isn't that big a deal. It's not like we're sending an innocent man to jail.
YaY! Spam is gone. I see from the Github repo that you implemented a question based spam captcha. But I'm not seeing it appear here... site needs an update?
When I took out the model reference stuff (@articles = Article.find(:all) ) I ended up with no data. Any reason why filter_resource_access wouldn't be doing what it's supposed to?
if i want to update, it is only
possible if the Controller will not
be filtered, otherwise it says that
the method isn't found. Well, i added
the method tho the authorization-file.
@psingh: starting at 6:30, the cast explains that if you add "filter_resource_access" to a controller declaration, the gem will automatically take care of that for you.
I have been experimenting with lockdown on my current project and liked it alot, configuration is all in one file, links are automatically hidden if the user doesn't have permission and you don't need to add any code to the controllers. However I found it quite difficult setting up persmissions based on the current user and also got annoyed by the requirement to restrat the server for permissions to take effect. It is a good system, but I think I will give declarative authorization a go it looks far more intuitive, it would be handy to have the lniks automatically hiden as with lockdown though, so I might have a go at implementing that in a fork.
class ApplicationController < ActionController::Base
around_filter :authorize_redirect
def authorize_redirect
yield
if response.body == "You are not allowed to access this action."
response.redirect('/login', 550)
end
end
end
but the authorization magick has already rendered, so I cannot render or redirect :(
Ok, sorry. After spending some time going through the source I found that I can just define permission_denied on my controller and it will be called and I can do whatever I want! Problem solved!
hi i wanna ask that
in this program can we show user's article..what i mean when we login can we just see the article who logins..if its possible how we can do it
Hi, how to authorize acces to custom methods other than CRUD? By default all non standard methods are just blocked, how to deal with it?
has_permission_on :foos, :to => :ownmethod doesnt work :/
For those who are having trouble seeing roles in your sign up, its because you haven't populated your database with any roles.
So fire up your console (script/console) and enter
http://pastie.org/797950
You can use whatever names you want, but remember to change config/authorization_rules.rb files accordingly.
After spending some time going through the source I found that I can just define permission_denied on my controller and it will be called and I can do whatever I want! Problem solved!
I noticed that your example didn't include authorization for the UserController or UserSesssionController. If you were to implement authorization for these controllers would you use Authlogic's authorization (:require_no_user) or declarative_authorizations and why?
I have to investigate if it's powerful for the policies of the application I'm designing but the DSL seems flexible enough. I'll look at the gem's documentation, thank you very much as always ;)
If you're using namespaces for your controllers, add a context for the view helpers as well. Like so:
if permitted_to? :create, :model, context: :namespace_model
Using filter_resource_access, the create action was reverting to non strong_parameters framework causing ActiveModel::ForbiddenAttributesError. Had to use filter_access_to :all instead. I hope that's not wrong... if not, I hope it helps others.
was waiting for this ;)
We use easy_roles at platform45, for simple role based authorization.
Its more of a light weight solution, and has basic usage, not comparable to declarative authorization.
I think it's worth checking out tho!
http://github.com/platform45/easy_roles
Wonderful stuff.
Wonderful gem.
Wonderful railscast.
Wonferful you !
Thanks again Ryan !
Hi Ryan,
There's no need to create an article on this line:
<% if permitted_to? :create, Article.new %>
instead, you can do just this:
<% if permitted_to? :create, :articles %>
Appart from that, great stuff!
Awesome Ryan, thanks again for your amazing screencasts. I'm going to implement this in my app today.
I'm making a PayPal donation, please keep the episodes coming.
can someone please explaine, what this line do in ApplicationController:
include Authentication
Sadly reCAPTCHA seems to not keep em away.
>Sadly reCAPTCHA seems to not keep em away.
Maybe we could give a try for negative captcha? I use it on many sites and it's seems to work better than classic captchas.. and without people harassment.
I think it's our responsibility to take the time to report the spam. The problem is that the ahole that is doing this knows that there is a flood of activity every monday morning so he's probably adding the spam manually.
As Ryan mentioned earlier, this could be a human spammer. Maybe time for blocking some ip.
anyway great cast Ryan
When you delete
@article = Article.find(params[:id]) and @article =Article.new... from the ArticlesController. You say it is now handled by the filter_resource_access before filter.
Where is this implemented? What happens if my controller differs and I need something other then .find(params[:id]) for instance when using pagination? Can we use a different before filter?
You just made my day :)
@ARTSIOM
"include Authentication"
is for AuthLogic
@kikito
<% if permitted_to? :create, Article.new %>
instead, you can do just this:
<% if permitted_to? :create, :articles %>
that is not always the correct behavior, Article.new allows for if_attribute checks - :articles inhibits this feature
This is rather timely as I've been redoing some role based permissioning stuff lately. I may have to get dirty with this. Thanks Ryan.
On a side note: The ugg spam is getting a little absurd. It's obviously some jerk doing it manually. I wonder if a banned word list would help.
@Walter
filter_access_to does not auto-load these objects, filter_resource_access is a newer feature of DA
check the README
Hey Ryan, great work,
However I wonder how to go about doing a role based management with accounts (subdomains). So if some user has manage access in account 1 and guest access in account 2. How would you go about setting that up in declarative_authorization?
Thanks again,
Andrew
I like the Aegis plugin (http://github.com/makandra/aegis).
It has a lot less magic than the declarative auth plugin, but it's straightforward and clean.
We use this kind of approach from quite some time here at Lipsiasoft with our admin, Lipsiadmin.
Check it out.
http://www.lipsiadmin.com/
looks pretty nice, fyi there's shorthand for the :to parameter so you don't have to explicitly state every approved action.
Such as :to => :manage or :to => :all
You have a typo in the links. It says "Authologic" but should be "Authlogic".
Authorization plugins are a hard find. Some have barely any features, some are overly complex. One issue I'd like to point out is if someone is not authorized, it should throw perhaps a 401
What is missing from this gem to tempt you to write your own role authorization plugin (according to your tweet)?
I'm a user (and guys at my company aswell) of base_auth, a pretty simple yet powerful authorization plugin. I think you could do a Railscast on that one too, now that you've touched the topic of authorization.
http://blog.aenima.pl/2008/12/8/base-auth-a-complete-tutorial-to-securing-your-rails-application
Great 'cast by the way, keep up the good work!
I've been using this for awhile, it's a wonderful plugin, and Steffan is always in the google forums helping out users.
I was wondering when you would do a screen cast about this wonderful gem!
Thanks for all you do, you're always saving me time, and showing me something new!
Thank you so much, great screencast.
Ryan - excellent, useful information this week. I've been a satisfied user of your nifty_authentication generator. For a tiny app I'm doing at work, I'd like the staff to be able to do just about anything except create a new user - I'd like only an admin to be able to do that. I've been trying to figure out how to do roles with nifty_authentication since for this project even something as straightforward as authlogic is more complexity than I need. So here's my encouragement for an rbates authorization solution that's just a LITTLE more full featured than nifty_authentication!
Thanks for all your work, Ryan. These are great, and your time and effort are much appreciated.
I'm sorry you've gotten hammered by the comment spammers. Really sucks that you have to deal with that. Wish I could help!
I really like this declarative approach!
For those who need to control non-action related content and keep the declarative approach - this is what works perfectly for me:
- Create a dummy action in the controller (e.g. "admin", "no_admin")
- define the corresponding role-based rules
- and use the Authorization view_helper (e.g "if permitted_to? :admin, :articles) in the view
The benefit is that you don't have to update your views when adding roles.
It's me or the iPhone/iPod version has some artifacts and a couple times the screen gets freeze...
Except for this ;-) I think you're doing an amazing job. Thank you.
Nice solution! But if I don't want to hard code the acl, what's the alternatives for storing everything in the database? I think it would be more flexible to be able to create permissions on the fly and then assign them to user groups perhaps.
I do love the typo "Authologic" in the show notes. Looking forward to watching the episode tomorrow. Keep up the good work, Ryan!
Sven Fuchs and I have written a really generic (and therefore powerful and not quite easy to use) RBAC implementation. You can find it here: http://github.com/svenfuchs/rbac
We use it in adva-cms (http://github.com/svenfuchs/adva_cms - http://adva-cms.org), so you can check the implementation there if you want to.
Nice episode once again! Thanks a lot!
how do i dynamic change the role in this program?
It looks like that I need to revise manually. I can not revise it online.
Thanks Ryan, I use ACL9 gem, and I know there are probably like 100's of ways to go about authorization. Excellent screen cast as usual.
Why not say a codeword at the end of the railscast that is needed to post a comment for it? Or some obfuscated ruby code to display a password? That might discourage the spammer...
Is there a way to handle dynamics RBAC / allow admin users to handle RBAC instead of such hardcode ?
What here for clause? It is A lot of spam.
Pretty good & very useful thought for SAS model applications.
Cool cast, I build my on plugin for this, much more client oriented, but this still is cool.
(I'm submitting this comment to see if the recaptcha is really working)
Another try with just one word of the recaptcha
As a viewer from the beginning (or very close) I second the idea of registering to be able to comment or something like that. A passcode at the end of the cast might work, too. For whatever reason reCaptcha isn't working at all.
@Jochen Kempf:
Your approach to putting access control on non-action based content in intriguing, but I cannot understand your explanation well enough to implement it. Where can I go to see this in more detail?
For example, where do you put the content to be controlled? Is it hard-coded in the view? And is the dummy controller completely empty?
Hi! I'm having this problem: i have, in my user table, a boolean column named "admin"..in my user.rb i wrote:
def role_symbol
[:admin] if admin?
end
and in my authorization_rules i have:
role :admin do
has_permission_on [:artists, :albums, :events, :neews], :to => [:index, :show, :new, :create, :edit, :update, :destroy]
end
the problem is that when i login as an admin user(which has admin = true) i can't reach any model which has "filter_resource_access" in its controller, i see the "You are not allowed to access this action." page...why?
Thanks a lot!
Ryan,
A couple of thoughts/temporary fixes on the spam issue.
1. If enough users click on "Report as Spam" for a message, hide the detail of the message. Put a "Flagged as Spam" message and an "Unhide" link - that way, you can scroll through the comments quicker.
2. Assign basic moderator functionality and assign a handful of trusted readers to remove the spam.
3. Implement the keyword blacklist that others have suggested. If a few valid comments don't make it through, it isn't that big a deal. It's not like we're sending an innocent man to jail.
Used Declarative Authorization and Authlogic in a project together, it added some really cool advantages.
Hope the new spam system works! :)
YaY! Spam is gone. I see from the Github repo that you implemented a question based spam captcha. But I'm not seeing it appear here... site needs an update?
@Kieran, the question only shows up if the comment looks like spam. As long as you aren't grunting like a caveman (ugg, ugg) then you should be fine.
Awesome cast again! thanks!
@Ryan, your sense of humor gets me every time.
@ryan, I think the spammer is just playing with you at this point. You may want to consider blocking IPs.
On a related note, very excited about CanCan, will be giving it a trial run in one of my apps very soon.
Thanks for post.
By the way, How can be the script/console result shown like Mysql command line result?(grid like)
Is that a kind of plug-in?
@kikiki, http://github.com/cldwalker/hirb
I still like my stab at authorization: http://github.com/Adman65/AccessControl
very excited about CanCan, will be giving it a trial run in one of my apps very soon.
Hi,
I'm using authlogic + delcarative auth.
How to I get the access the name of a logged-in user's role? I need it for routing, too.
e.g.,
if session[:role] == 'admin'
redirect_to admin_path
else
redriect_to employee_path
end
I've tried find_by_name, but without success.
Thanks.
Steve
Thanks for the post. For the views we can replace the
<%if ..%>
<link_to ....
<%end%>
with link_to_if method. It is much nicer.
Cheers
Behrang
Why you didn't use your gem can can?
When I took out the model reference stuff (@articles = Article.find(:all) ) I ended up with no data. Any reason why filter_resource_access wouldn't be doing what it's supposed to?
Thanks for the very helpful show.
Evan
I have a Problem with observed_field
if i want to update, it is only
possible if the Controller will not
be filtered, otherwise it says that
the method isn't found. Well, i added
the method tho the authorization-file.
Strange thing... can anyone help?
I found a dark corner in declarative_authorization usage. If you defined a privilege in authorization_rules.rb:
privilege :update, :includes => :edit
you can't just use:
filter_access_to :update
in the controller definition when you really mean:
filter_access_to [:edit, :update]
even if we hide links using below code, any one can directly go to the url and access the page:
<% if permitted_to? :edit, @article %>
<%= link_to "Edit", edit_article_path(@article) %> |
<% end %>
what if guest goes and types
/articles/new
?
don't we also need to put the check in controller?
@psingh: starting at 6:30, the cast explains that if you add "filter_resource_access" to a controller declaration, the gem will automatically take care of that for you.
I have been experimenting with lockdown on my current project and liked it alot, configuration is all in one file, links are automatically hidden if the user doesn't have permission and you don't need to add any code to the controllers. However I found it quite difficult setting up persmissions based on the current user and also got annoyed by the requirement to restrat the server for permissions to take effect. It is a good system, but I think I will give declarative authorization a go it looks far more intuitive, it would be handy to have the lniks automatically hiden as with lockdown though, so I might have a go at implementing that in a fork.
hi, I'm not getting the roles in the sign-up page...
I might be something very obvious, can someone point me in the right direction?
Thanks!
The only way I can populate the roles is if I do this:
<%= f.select :roles, (controller.authorization_engine.roles + (@user.roles || [])).uniq, {}, {:multiple => true} %>
but I cant save it... :(
Is there a way to customize the message or do a redirect instead of just sending "You are not allowed to access this action." if authorization fails?
Surely there are much better ways than this:
class ApplicationController < ActionController::Base
around_filter :authorize_redirect
def authorize_redirect
yield
if response.body == "You are not allowed to access this action."
response.redirect('/login', 550)
end
end
end
but the authorization magick has already rendered, so I cannot render or redirect :(
Ok, sorry. After spending some time going through the source I found that I can just define permission_denied on my controller and it will be called and I can do whatever I want! Problem solved!
hi i wanna ask that
in this program can we show user's article..what i mean when we login can we just see the article who logins..if its possible how we can do it
Hi, how to authorize acces to custom methods other than CRUD? By default all non standard methods are just blocked, how to deal with it?
has_permission_on :foos, :to => :ownmethod doesnt work :/
For those who are having trouble seeing roles in your sign up, its because you haven't populated your database with any roles.
So fire up your console (script/console) and enter
http://pastie.org/797950
You can use whatever names you want, but remember to change config/authorization_rules.rb files accordingly.
How would stay this example if I want to use the Authlogic? thank you ...
Artisiom:
Look at the example source in lib>authentication.rb
(Also, I accidentally clicked "Report as Spam" on your post. Sorry!)
After spending some time going through the source I found that I can just define permission_denied on my controller and it will be called and I can do whatever I want! Problem solved!
@Senthil http://pastie.org/797950
To those using that reference I must correct it. Instead of doing the initiation of a new and then save, follow this pattern.
Role.create!(:role => "admin")
Role.create!(:role => "user")
Way faster, and saves you the typing ;)
@Fredrik
You're absolutely right. I have no idea why I didn't use create at the time.
I noticed that your example didn't include authorization for the UserController or UserSesssionController. If you were to implement authorization for these controllers would you use Authlogic's authorization (:require_no_user) or declarative_authorizations and why?
Thanks.
@Ryan, what do I do if I need a nested controller like
"Admin::Home"
What would has_permission_on look like? (:admin_home?)
Is it possible to add a scope to the authorisation? For example.
If an application has many accounts, and each account has many users.
The user has the permission to read a record, but only if they share the same account_id
Michael
I have to investigate if it's powerful for the policies of the application I'm designing but the DSL seems flexible enough. I'll look at the gem's documentation, thank you very much as always ;)
If you're using namespaces for your controllers, add a context for the view helpers as well. Like so:
if permitted_to? :create, :model, context: :namespace_model
Using filter_resource_access, the create action was reverting to non strong_parameters framework causing ActiveModel::ForbiddenAttributesError. Had to use filter_access_to :all instead. I hope that's not wrong... if not, I hope it helps others.