Permalink
Browse files

First public commit

  • Loading branch information...
0 parents commit 613026699bfe5095b6686f4d03870201e290c025 @milann committed Jan 20, 2010
@@ -0,0 +1,170 @@
+TO DO
++ Add Right model generator and DB-backed way of handling rights in addition to inlined "permit" checks
++ Added namespacing to @options instance variable to prevent possible name clashes
++ Add test generator instead of handling tests in test apps
++ Add support for groups
++ Extend grammar to allow "(admin or moderator or some_role) of some_model" (?) [Chris Hapgood]
++ Extend coverage to models. Look at Bruce Perens's ModelSecurity and access with_scope. (9/3006 - Recently investigated extension to model and the most programmer-friendly DSLs may require too much hacking on ActiveRecord.)
+
+
+CHANGES (from most recent to oldest)
+
+
+=== 1.0.10 release (February 27, 2008)
+
+* Patch Series : Granular redirection configuration submitted by Thomas Weibel
+
+ WARNING : If you are upgrading from a previous install you may need
+ to change some configuration settings in your environment.rb file.
+
+ Remove DEFAULT_REDIRECTION_HASH config
+ Added granular LOGIN_REQUIRED_REDIRECTION hash or path config
+ Added granular PERMISSION_DENIED_REDIRECTION hash or path config
+ Added STORE_LOCATION_METHOD config
+ Support custom flash messages for each redirection type
+ Updated README.txt to provide instructions.
+ Enhanced support for integration with restful_authentication plugin.
+
+=== 1.0.9 release (February 26, 2008)
+
+* Patch #8571 : Add type argument to is_role_of_what submitted by Aslak Hellesøy (aslak_hellesoy)
+
+ In my RESTful index views for an AR type I often want to list all of the records *for a given type* for which the current
+ user has the role "show". (As opposed to getting *any* record for which the user has the role)
+
+ In order to achieve this, I have patched identity.rb so tht I can do this:
+
+ def index
+ if current_user.permit? 'admin'
+ # show all projects
+ @projects = Project.find(:all)
+ else
+ @projects = current_user.is_show_for_what(Project)
+ end
+ end
+
+=== 1.0.8 release (February 26, 2008)
+
+* Patch #11352 : Fixes a bug with role_regex and simple quoted roles submitted by 'a French RoR developer'
+
+ Documentation says:
+
+ <role> ::= /\w+/ | /'.*'/
+
+ But the next permission string isn't well parsed: " 'abcd:efgh' or 'abcd:ijkl' "
+ You get an error because the role_regex defined in parser.rb eats every simple quote between the first and the last
+ simple quote in the string.
+
+ So i patched the two instances of role_regex in parser.rb, from this:
+ role_regex = '\s*(\'\s*(.+)\s*\'|([A-Za-z]\w*))\s*'
+
+ to this (the question mark ends the first pattern as soon as possible, avoiding the inner simple quotes to be eaten):
+ role_regex = '\s*(\'\s*(.+?)\s*\'|([A-Za-z]\w*))\s*'
+
+=== 1.0.7 release (February 25, 2008)
+
+* Patch #9431 : Fixes a bug in identity.rb submitted by Michel Martens (blaumag)
+
+ If some authorizable instance accepts a role, then it responds true when queried for has_[role_name]?
+
+ Example:
+ country.has_kings? #=> false
+
+ user.has_role "king", country
+ country.has_kings? #=> true
+
+ user.has_no_role "king", country
+ country.has_kings? #=> true
+
+ The last time, country.has_kings? should be false.
+
+=== 1.0.6 release (February 25, 2008)
+
+* Patch #12170 : Additional HABTM options for acts_as_authorized_user
+ A very simple patch that allows options to be passed to the has_and_belogs_to_many relationship. This seems necessary
+ if the "User" object has a different name from the table name. has_and_belong_to_many does not automatically
+ use the table set by the "User" object so it must be specified (along with the foreign key if applicable).
+
+ Patch submitted by Eric Anderson (eric1234)
+
+=== 1.0.5 release (February 25, 2008)
+
+* Feature : Add additional test for current_user being set to the symbol ':false'.
+ This is for compatibility with the restful_authentication plugin which will
+ set current_user to :false on a bad login. Previously we were only testing
+ for current_user.nil? which was incomplete.
+
+=== 1.0.4 release (February 25, 2008)
+
+* Bugfix : RubyForge bug #9368. Problems with about.yml
+ Fixes a minor bug in the about.yml plugin metadata file
+ so that it will parse cleanly. [GR]
+
+=== 1.0.3 release (February 17, 2008)
+
+* Minor changes to USAGE text for ./script/generate role_model
+
+=== 1.0.2 release (February 17, 2008)
+
+* From this release forward the plugin requires use of Ruby on Rails version 2.x. Version 1.0.1 is the final release fully compatible with Rails 1.2.x.
+* Upgraded the database migration generator to create the new Rails 2.0.x style 'sexy migrations'.
+
+=== 1.0.1 release (February 17, 2008)
+
+* Moved source code to public Git repository at GitHub.com (http://github.com/DocSavage/rails-authorization-plugin/tree/master)
+* Removed attr_protected declaration from acts_as_authorized_user, acts_as_authorizable methods. These conflicted with usage of the Authorization plugin with models generated by the restful_authentication generator or any model that specified the safer attr_accessible whitelist. RA encourages the safer attr_accessible whitelisting of attributes that are accessible from its models. You cannot apply both attr_accessible and attr_protected in the same model. Users are encouraged to specify a whitelist of attr_accessible model attributes for their applications security. [grempe]
+
+=== SVN
+
+* Performance improvement for has_role? [Sean Geoghegan]
+
+* Allow customization of message on redirection after failed authorization (:redirect_message option) [Joey Geiger]
+
+* Patch to allow authorizable objects that use single table inheritance (STI) [Sean Geoghegan]
+
+=== 1.0 release (Sept 13, 2006)
+
+* Added attr_protected for habtm and has_many role ids to block security concern if developers use update_attributes(params[:auth_obj]) on an authorizable object [Michael Schuerig]
+
+* Use before_filter rather than prepend_before_filter so necessary instance variables (and methods) can be established before trying authorization checks. This fix came about for Mephisto blog where a class-level permit "admin of site" was used. The site attribute was set in a before_filter. If you prepend your authorization filter, it will execute before any other before_filter, which is probably not a good idea.
+
+* Add "about" yaml for future Rails plugin directory.
+
+* Cleaned up exception handling a little [due to suggestion by Michael Schuerig]
+
+* Add generator for role model and migration, e.g., "script/generate role_model Role".
+ Role model must be called "Role" at this time. More general naming as a TO DO.
+
+* Removed simple_roles_table to simplify plugin.
+
+* Moved all files in Authorization namespace into /publishare subdirectory
+ to reduce danger of clashes in load path [nod to Michael Schuerig].
+
+* Small code refinement patch [Michael Schuerig]
+
+* The colon preceding a model name in the authorization expression is now optional. The parser uses accepted prepositions to disambiguate models from roles.
+
+* Change default parser from Recursive Descent parser to Eval parser.
+Currently implemented recursive descent parser doesn't handle left-sided
+boolean expressions well. Eval parser relies on Ruby (good thing), but
+wherever there's an eval, we have to be more careful.
+
+* Will start linking to and monitoring forum area at RubyForge
+http://rubyforge.org/forum/?group_id=1797
+
+* Added changelog :)
+
+* Added return false to handle_redirection to short-circuit filters if
+redirect occurs. This is second fix to prevent double renders.
+
+* Changed the requires to pull files from the plugin directory. (Necessary for name conflicts between plugin and apps)
+
+* Minor fixes to update documentation
+
+=== 1.0 rc3 (July 19, 2006)
+
+* Fix to prevent double redirect
+
+* Fix to migration examples
+
+... see svn log
@@ -0,0 +1,20 @@
+Copyright (c) 2006 William T Katz
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,181 @@
+= Guardian
+
+Guardian is an authorization plugin for Rails build on top of the powerful rails-authorization-plugin[http://github.com/DocSavage/rails-authorization-plugin].
+It is to rails-authorization-plugin as Ubuntu is to Debian - a more user-friendly distribution.
+
+The main features are:
+* declarative role definition in the authorized user model as well as database based role definition
+* declarative permissions definition at one place (per controller) using a simple and very readable micro DSL
+* uses a concept of an authorized context for declaratively marking the parts of your code that should be checked for permissions
+* really fine-grained access control (you are not restricted to controller actions access control only but can go further)
+* easy to start with
+* versatile in its possibilities (courtesy of rails-authorization-plugin[http://github.com/DocSavage/rails-authorization-plugin].)
+
+Some of the other improvements or additions to the rails-authorization-plugin:
+* a more standard way of defining the configuration constants
+* added a concept of superuser - a role that has a universal access to all context without explicitly declaring it
+* on_access_denied event handler for controllers
+* on_login_required event handler for controllers
+* shorter name & shorter installation and usage instructions :)
+
+WARNING: I'm not going to cover all the possibilities of this thing here. If you think you are familiar with the basics I describe here,
+jump right to the rails-authorization-plugin home page and read the stuff that's written there (mainly the parts about the authorized user API and the authorizable models API).
+
+== Assumptions
+
+Your controllers have to implement the current_user method.
+This should be no problem with the Rails authentication systems used these days.
+
+== Installation
+
+First, install the plugin:
+
+ ./script/plugin install git://github.com/milan-novota/guardian.git
+
+Add this to your <code>/config/preinitializer.rb</code> file (create it if it doesn't exist):
+
+ USE_ROLES_TABLE = true # false if you don't plan to use the database table for saving the roles
+ AUTHORIZABLE_BY_DEFAULT = true # false if you don't want all the models to be authorizable by default
+
+Create file <code>config/initializers/authorization.rb</code>, add these lines and set the constants to whatever you think seems OK:
+
+ SUPERUSER_ROLE = 'admin' # this role will have full acces in any authorized context without explicitly defining it
+ LOGIN_REQUIRED_REDIRECTION = '/login'
+ LOGIN_REQUIRED_MESSAGE = 'Log in first'
+ PERMISSION_DENIED_REDIRECTION = ''
+ PERMISSION_DENIED_MESSAGE = "You are not cool enough to do this."
+ STORE_LOCATION_METHOD = :store_location # how to store actual location before we redirect after login required event
+
+If you plan to use the database for persisting the roles and users to roles relationships (recommended):
+
+ ./script/generate role_model Role
+ rake db:migrate
+
+Add this to your User model:
+
+ acts_as_authorized_user
+
+That's it!
+
+== Usage
+
+Just to make things clear - as you probably know, there are three main parts to every authorization system - users, roles and permissions, which consists
+of a user in some role and a context (in which this user is allowed to operate). Guardian is not different in this.
+
+Users are easy (you should have your User model ready by now). Let's start with roles.
+
+=== Roles
+
+Role can be based on virtually any condition that you think should affect the fact, that at some moment in time some users have access to some feature of the system and some don't. And when I say any, I mean any:
+
+ class Users
+ acts_as_authorized_user
+ has_role 'lucky bastard', :if => lambda { rand == 0.32456112353 } # really ephemeric role - changes randomly no matter of conditions
+ has_role 'self of user', :if => lambda {|u1, u2| u1.id == u2.id } # ehternal role - user will occupy it as long as she exists
+ has_role 'author of post',:if => lambda {|u,p| p.author == u } # user has this role for the time the post exists (or he makes up his mind about the authorship of the post)
+ has_role 'adult', :if => lambda {|u| u.adult? }
+
+ def adult?
+ age > 18
+ end
+
+ ...
+
+ end
+
+That was a role definition by function. Another way of assigning a role to a user is by doing it in a database via a set of methods provided by r-a-p:
+
+ user.has_role "admin"
+ user.has_role "manager of", user2
+
+You can query your objects whether they have some role or they are in a specific relationships with other objects:
+
+ user.has_role? "admin"
+ user.has_role? "manager of", user2
+ user2.accepts_role "manager", user
+
+Actually, you can do much more, just check out the r-a-p documentation.
+
+=== Permissions - Contexts
+
+Let's say you are about to build a mini app which will serve as your online diary. Your permissions definition could look like this:
+
+ class DiaryContoller << ApplicationController
+
+ grant do
+ grant "author of post"
+ can "update post"
+
+ grant "self of user or friend of user"
+ can "get all user's posts"
+
+ grant "author of post or 'lucky bastard'"
+ can "get post"
+ end
+
+ def index
+ @user = params[:user]
+ authorized_context "get all users's posts" do
+ @posts = @user.posts
+ end
+ end
+
+ def show
+ @post = Post.find(params[:id])
+ authorized_context "get post"
+ end
+
+ def edit
+ @post = Post.find(params[:id])
+ authorized_context "update post"
+ end
+
+ def update
+ @post = Post.find(params[:id])
+ authorized_context "update post" do
+ ...
+ end
+ end
+
+ end
+
+Use of authorized_context in every method might seem quite chatty for some people, I know. However, you don't need to use the authorized_context declaration if you really don't need to.
+You can easily identify these contexts with particular actions.
+
+ grant do
+ grant "author of post"
+ can "update post" => [:edit, :update]
+
+ grant "self of user or friend of user"
+ can "get all user's posts"
+
+ grant "author of post or 'lucky bastard'"
+ can "get post" => :show
+ end
+
+When using this form of permission declaration, the contexts are checked in a before_filter, which means you need to set up the instance variables needed for authorization before these are evaluated.
+
+If you want to know more, check the r-a-p documentation.
+
+=== Ideological background
+
+The basic concept of authorization, as I understand it, is a role. Role can express various things:
+
+ 1. relation of a user to the system as a whole (eg. to be an admin of the system)
+ 2. relation of a user to some kind of entities (eg. to be a moderator of comments)
+ 3. relation of a user to some particular entity (eg. to be an owner of some resource)
+ 4. some other complex relation (eg. to be a friend of a user that is a owner of some resource)
+ 5. that user has some attribute(s) or it responds to some message in some particular way (eg. to be a teenager)
+
+A really fine grained authorization system should allow you to define role for a user based on any of the above mentioned criteria. Furthermore, it should allow you to set more than one role for a user. (The simplest forms of authorization plugins for Rails usually allow you define just the first kind of roles and set just one role for a user.)
+
+
+The other part of authoriation is a mechanism that decides which part of code to run (or not to run) based on the fact if a user fits into some role (set of roles) or not. To apply this mechanism, we have to find the points where the authorization should take place and select roles for which the code should or should not be run.
+
+The way that works for me in Rails is to define roles on the model level and to leave authorization mechanism (setting allowed roles for parts of code that I want to be authorized and asking if current user has the role that is permitted to run the part) entirely for controllers/views.
+
+For this I use this plugin. rails-authorization-plugin has all the possibilities I just mentioned built right into it (various kinds of roles, many roles for one user, authorization on controller and view level). My wrapper on top of it provides me with some more conveniences such as authorized contexts and computed roles.
+
+=== Disclaimer
+
+This plugin is a work in progress and I don't recommend to use it in any circumstances.
Oops, something went wrong.

0 comments on commit 6130266

Please sign in to comment.