Permalink
Browse files

added docu

  • Loading branch information...
1 parent 5152237 commit 6d4748c096e3acad74215d3b83d467110f3c71e6 @mkristian committed Feb 19, 2012
Showing with 109 additions and 105 deletions.
  1. +109 −0 README.md
  2. +0 −105 README.textile
View
109 README.md
@@ -0,0 +1,109 @@
+# ixtlan guard #
+
+it is an simple authorization framework for restful rails especially using rails as API server.
+
+the idea is simple:
+
+* each user belongs to set of groups
+* each controller/action pair permits a set of groups to execute it
+* the guard class checks if the user has any group which is allowed by the controller/action pair
+
+## current\_user\_groups method ##
+
+this is similar to the **current_user** method common on authentication. the **current_user_groups** method is an array of object which responds to __:name__. call these objects groups which have name. the name is used in the permission config of the controller.
+
+having something like PosixAccounts and PosixGroups (as know from ldap) would lead to an implementation like (which is the default when there is no such method)
+
+ def current_user_groups
+ current_user.groups
+ end
+
+## config for a controller
+
+this is a yaml file in **RAILS_ROOT/app/guards/my\_users\_guard.yml**. for example
+
+ my_users:
+ index:
+ - root
+ - user-admin
+ - app-admin
+ show: [root,app-admin,guest]
+ new: [root]
+ create: [root]
+ edit: [root,app-admin]
+ update: [root,app-admin]
+ destroy: [root]
+
+with the special action **defaults** this can be reduced to
+
+ my_users:
+ defaults: [root]
+ index:
+ - root
+ - user-admin
+ - app-admin
+ show: [root,app-admin,guest]
+ edit: [root,app-admin]
+ update: [root,app-admin]
+
+and since **root** is handle by the guard anyways it can be further reduced to
+
+ my_users:
+ defaults: []
+ index:
+ - user-admin
+ - app-admin
+ show: [app-admin,guest]
+ edit: [app-admin]
+ update: [app-admin]
+
+## rails helper methods
+
+### authorize method of controller
+
+ the authorize method asked the Guard if a certain action on a controller is allowed by the current_user, if not the method raises an Error. this method is registered as before-filter on the application-contrller. so **skip-before-filter :authorize** will disable the guard.
+
+### allowed? method of controller
+
+the call `allowed?(:destroy)` will give the permissions for the given action on the current controller.
+
+### allowed? method of views
+
+it takes two arguments since the controller name (or resource name) is needed as well. the call `allowed?(:users, :destroy)` will give the permissions for the given action controller pair.
+
+### getting the Guard instance
+
+to get an instance of the **Guard** on the controller itself just call `guard`. otherwise `Rails.application.config.guard` will give you such an instance.
+
+# more advanced
+
+sometimes you want to bind resource to a user/group pair, i.e. given an organizations which have report-writers and report-readers. example as rails before-filter:
+
+ skip-before-filter :authorize
+ before-filter :authorize_organization_reader, :only => [:show]
+ before-filter :authorize_organization_writer, :only => [:edit, :update]
+
+ def authorize_organization_writer
+ authorize(Organisation.find(params[:org_id])) do |group, org|
+ org.writer? current_user
+ end
+ end
+
+ def authorize_organization_reader
+ authorize(Organisation.find(params[:org_id])) do |group, org|
+ org.reader? current_user || org.writer? current_user
+ end
+ end
+
+of course you can organize such relations also like that
+
+ skip-before-filter :authorize
+ before-filter :authorize_organization
+
+ def authorize_organization
+ authorize(Organisation.find(params[:org_id])) do |group, org|
+ GroupsOrganizationsUser.where(:org_id => org.id,
+ :user_id => current_user.id,
+ :group_id => group.id).size == 1
+ end
+ end
View
@@ -1,105 +0,0 @@
-h1. Guard the Rails Controller Actions
-
-h2. installation for rails3
-
-p. just add
-
-bc. gem 'ixtlan-guard'
-
-p. into your _Gemfile_
-
-h2. how it works
-
-p. the main idea is like a posix authorization with a user belonging to one or more groups. each rails controller gets a *Guard* which maps each action of the controller to a set of allowed groups.
-
-p. the default block which retrieves the logged in user from *current_user* method of the controller and collect the groups of this user. which makes it compatible with _restful_authentication_. in case there are no current_user the Guard will allow everything assuming there have no authentication and no authorization for this controller.
-
-bc. Proc.new do |controller|
- user = controller.send :current_user
- user.groups if user
- end
-
-p. you can define a superuser group which default is *root* and that group is implicit added to all guards.
-
-bc. class UsersGuard
- def initialize(guard)
- guard.aliases = {:new=>:create, :edit=>:update}
- guard.actions= {
- :index => [:users],
- :show => [:users],
- :create => [:users],
- :update => [:users],
- :destroy => [:users]
- }
- end
- end
-
-
-h2. restrict the access even further
-
-p. assume you can translate your web application and have a translator group but you want to restrict each translator to its language. then you can use the guard to enforce this restriction.
-
-p. let's add the following to your TranslationsController
-
-bc. before-filter :locale_authorization
- skip-before-filter :authorization
- def locale_authorization
- @locale = Locale.find_by_code(params[:locale])
- authorization do |group|
- if controller.respond_to? :current_user
- user = self.send :current_user
- !GroupsLocalesUsers.first(:conditions => ["user_id = ? AND group_name = ? AND locale_name = ?", user.id, group.to_s, @locale).nil?
- end
- end
- end
-
-p. this you can easily use for other use cases like having different domains. each domain has its own set of users. even allowing users to be associated with more then one domain.
-
-h2. allowed? method in controller/view
-
-p. both the rails controller as well the view have a methods *allowed?* to ask the guard if a particular action is allowed by the *current_user*.
-
-p. the controller *allowed?* just needs the action as argument.
-
-p. the view *allowed?* needs the resource name and the action to answer the quest.
-
-h2. rails3 generators
-
-p. per default the *scaffold*, *resource* and *controller* will add a guard for the actions of the generated controller. the views of the scaffold will use *allowed?* to determine if a link or button leads to an action which is allowed for the *current_user*
-
-h2. maintanance mode
-
-p. since the guard is the ideal place to temporary disallow or block some groups, the guard offers some helper methods for this:
-* block_groups(array_of_groups)
-* blocked_groups
-* current_user_restricted?(controller)
-with this you can easily block all groups but the *root* which remains as it is.
-
-h2. play together with authentication frameworks
-
-p. the guard plays nicely together with authentication frameworks like *restful-authentication*, *devise* or any homegrown authentication which provides a *current_user* method for all controllers. see demo of that gem.
-
-p. even if you can not provide *current_user* method you can use the guard with a custom block. pass in an block on initialization which returns the current user from somewhere. for example add something like this in an confug/initializer:
-
-bc. Rails.configuration.guard.block = Proc.new { Session.user }
-
-h2. other authorization libraries
-
-p. *cancan* . . .
-
-h1. Guard the Rails3 Controller Actions
-
-p. info about the actual gem please look into the directory http://github.org/mkristian/ixtlan-guard/gem:gem
-
-
-h2. run all the specs, features + integrations-tests in one go
-
-p. first you need jruby for this ! then you need to install
-
-bc. jruby -S gem 'ruby-maven'
-
-p. which allows to run the integration-tests from the demo with jetty.
-
-p. now you can execute
-
-bc. rmvn verify

0 comments on commit 6d4748c

Please sign in to comment.