logical_authz 0.1.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/app/controllers/groups_controller.rb +77 -0
  2. data/app/controllers/groups_users_controller.rb +27 -0
  3. data/app/controllers/permissions_controller.rb +63 -0
  4. data/app/helpers/logical_authz_helper.rb +158 -0
  5. data/app/views/groups/_controls.html.haml +18 -0
  6. data/app/views/groups/_form.html.haml +4 -0
  7. data/app/views/groups/create.rjs +1 -0
  8. data/app/views/groups/edit.html.haml +1 -0
  9. data/app/views/groups/index.html.haml +14 -0
  10. data/app/views/groups/new.html.haml +2 -0
  11. data/app/views/groups/show.html.haml +6 -0
  12. data/app/views/permissions/_controls.html.haml +18 -0
  13. data/app/views/permissions/_form.html.haml +8 -0
  14. data/app/views/permissions/create.rjs +1 -0
  15. data/app/views/permissions/edit.html.haml +1 -0
  16. data/app/views/permissions/index.html.haml +20 -0
  17. data/app/views/permissions/new.html.haml +2 -0
  18. data/config/initializers/activate.rb +1 -0
  19. data/generators/logical_authz/logical_authz_generator.rb +13 -0
  20. data/generators/logical_authz/templates/README +11 -0
  21. data/generators/logical_authz/templates/app/controllers/authz_controller.rb.erb +4 -0
  22. data/generators/logical_authz/templates/app/views/layouts/_explain_authz.html.haml.erb +21 -0
  23. data/generators/logical_authz_models/logical_authz_models_generator.rb +22 -0
  24. data/generators/logical_authz_routes/logical_authz_routes_generator.rb +12 -0
  25. data/generators/logical_authz_specs/logical_authz_specs_generator.rb +26 -0
  26. data/lib/logical_authz/access_control.rb +343 -0
  27. data/lib/logical_authz/application.rb +350 -0
  28. data/lib/logical_authz/authn_facade/authlogic.rb +13 -0
  29. data/lib/logical_authz/configuration.rb +64 -0
  30. data/lib/logical_authz/engine.rb +18 -0
  31. data/lib/logical_authz/generator.rb +22 -0
  32. data/lib/logical_authz/generators/controllers/generator.rb +15 -0
  33. data/lib/logical_authz/generators/controllers/templates/app/controllers/authz_controller.rb +6 -0
  34. data/lib/logical_authz/generators/models/generator.rb +109 -0
  35. data/lib/logical_authz/generators/models/templates/app/models/group.rb +33 -0
  36. data/lib/logical_authz/generators/models/templates/app/models/permission.rb +3 -0
  37. data/lib/logical_authz/generators/models/templates/config/initializers/logical_authz.rb +20 -0
  38. data/lib/logical_authz/generators/models/templates/db/seeds_logical_authz.rb +21 -0
  39. data/lib/logical_authz/generators/models/templates/migrations/create_groups.rb +12 -0
  40. data/lib/logical_authz/generators/models/templates/migrations/create_permissions.rb +15 -0
  41. data/lib/logical_authz/generators/models/templates/migrations/create_users_groups.rb +13 -0
  42. data/lib/logical_authz/generators/routes/generator.rb +21 -0
  43. data/lib/logical_authz/generators/specs/generator.rb +57 -0
  44. data/lib/logical_authz/generators/specs/templates/spec/controllers/groups_controller_spec.rb +102 -0
  45. data/lib/logical_authz/generators/specs/templates/spec/controllers/groups_users_controller_spec.rb +47 -0
  46. data/lib/logical_authz/generators/specs/templates/spec/controllers/permissions_controller_spec.rb +24 -0
  47. data/lib/logical_authz/generators/specs/templates/spec/factories/az_accounts.rb +7 -0
  48. data/lib/logical_authz/generators/specs/templates/spec/factories/az_groups.rb +7 -0
  49. data/lib/logical_authz/generators/specs/templates/spec/factories/permissions.rb +2 -0
  50. data/lib/logical_authz/generators/specs/templates/spec/helpers/logical_authz_helper_spec.rb +90 -0
  51. data/lib/logical_authz/generators/specs/templates/spec/support/logical_authz.rb +1 -0
  52. data/lib/logical_authz/generators/specs/templates/spec/support/mock_auth.rb +30 -0
  53. data/lib/logical_authz/spec_helper.rb +75 -0
  54. data/lib/logical_authz.rb +110 -0
  55. data/lib/tasks/rspec.rake +15 -0
  56. data/spec/gem_test_suite.rb +17 -0
  57. data/spec/spec_helper.rb +43 -0
  58. metadata +127 -0
@@ -0,0 +1,77 @@
1
+ require 'logical_authz'
2
+
3
+ #TODO: R3 respond_with
4
+ class GroupsController < AuthzController
5
+
6
+ PER_PAGE = 20
7
+
8
+ # GET /groups
9
+ # GET /groups.xml
10
+ def index
11
+ @groups = Group.all
12
+
13
+ respond_to do |format|
14
+ format.html # index.html.erb
15
+ format.xml { render :xml => @groups }
16
+ end
17
+ end
18
+
19
+ def edit
20
+ @group = Group.find(params[:id])
21
+ end
22
+
23
+ def update
24
+ @group = Group.find(params[:id])
25
+ if @group.update_attributes(params[:group])
26
+ flash[:notice] = 'Group was successfully updated.'
27
+ redirect_to(@group)
28
+ else
29
+ render :action => "edit"
30
+ end
31
+ end
32
+
33
+ def show
34
+ @group = Group.find(params[:id])
35
+ end
36
+
37
+ # GET /groups/new
38
+ # GET /groups/new.xml
39
+ def new
40
+ @group = Group.new
41
+
42
+ respond_to do |format|
43
+ format.html # new.html.erb
44
+ format.xml { render :xml => @group }
45
+ end
46
+ end
47
+
48
+ # POST /groups
49
+ # POST /groups.xml
50
+ def create
51
+ @group = Group.new(params[:group])
52
+
53
+ respond_to do |format|
54
+ if @group.save
55
+ flash[:notice] = 'Group was successfully created.'
56
+ format.html { redirect_to(groups_path) }
57
+ format.xml { render :xml => @group, :status => :created, :location => @group }
58
+ else
59
+ format.html { render :action => "new" }
60
+ format.xml { render :xml => @group.errors, :status => :unprocessable_entity }
61
+ end
62
+ end
63
+ end
64
+
65
+ # DELETE /groups/1
66
+ # DELETE /groups/1.xml
67
+ def destroy
68
+ @group = Group.find(params[:id])
69
+ @group.destroy
70
+
71
+ respond_to do |format|
72
+ format.html { redirect_to(groups_url) }
73
+ format.xml { head :ok }
74
+ end
75
+ end
76
+
77
+ end
@@ -0,0 +1,27 @@
1
+ class GroupsUsersController < AuthzController
2
+ before_filter :get_instance_vars
3
+
4
+ def create
5
+ if @user && @group
6
+ @user.groups << @group
7
+ end
8
+ respond_to do |format|
9
+ format.html { redirect_to :back }
10
+ end
11
+ end
12
+
13
+ def destroy
14
+ if @user && @group
15
+ @user.groups.delete(@group)
16
+ end
17
+ respond_to do |format|
18
+ format.html { redirect_to :back }
19
+ end
20
+ end
21
+
22
+ private
23
+ def get_instance_vars
24
+ @user = Group.member_class.find_by_id(params[:user_id])
25
+ @group = Group.find_by_id(params[:group_id])
26
+ end
27
+ end
@@ -0,0 +1,63 @@
1
+
2
+ class PermissionsController < AuthzController
3
+ needs_authorization
4
+ admin_authorized
5
+
6
+ before_filter :get_permission, :only => [:edit, :update, :destroy]
7
+
8
+ def index
9
+ @permissions = Permission.all
10
+ end
11
+
12
+ def new
13
+ @permission = Permission.new
14
+ end
15
+
16
+ def edit
17
+ end
18
+
19
+ def update
20
+ if @permssion.update_attributes(params[:permission])
21
+ flash[:notice] = "Permission updated"
22
+ redirect_to permissions_path
23
+ else
24
+ render :action => :edit
25
+ end
26
+ end
27
+
28
+ def destroy
29
+ @permission.try(:destroy)
30
+ redirect_to permissions_path
31
+ end
32
+
33
+ def create
34
+ group = Group.find_by_id(params[:group])
35
+ return if group.nil?
36
+
37
+ permission_selector = {
38
+ :controller => params[:p_controller],
39
+ :action => params[:p_action],
40
+ :subject_id => params[:object],
41
+ :group_id => group.id
42
+ }
43
+
44
+ if params["permission"] == "true"
45
+ Permission.create!(permission_selector)
46
+ else
47
+ perms = group.permissions.find(:all, :conditions => permission_selector)
48
+ perms.each {|perm| perm.destroy}
49
+ end
50
+
51
+ respond_to do |format|
52
+ format.js
53
+ format.html do
54
+ redirect_to :back
55
+ end
56
+ end
57
+ end
58
+
59
+ private
60
+ def get_permission
61
+ @permission = Permission.find_by_id(params[:id])
62
+ end
63
+ end
@@ -0,0 +1,158 @@
1
+ require 'logical_authz/configuration'
2
+
3
+ module LogicalAuthz
4
+ class << self
5
+ def laz_debug
6
+ if block_given? and LogicalAuthz::Configuration::debugging?
7
+ Rails::logger::debug do
8
+ msg = yield
9
+ String === msg ? msg : msg.inspect
10
+ end
11
+ end
12
+ end
13
+ end
14
+
15
+ module Helper
16
+ def laz_debug
17
+ if block_given?
18
+ LogicalAuthz::laz_debug{yield}
19
+ end
20
+ end
21
+
22
+ def authorized?(criteria=nil)
23
+ criteria ||= {}
24
+
25
+ laz_debug{"Helper authorizing: #{LogicalAuthz.inspect_criteria(criteria)}"}
26
+
27
+ criteria = {
28
+ :controller => controller_path,
29
+ :action => action_name,
30
+ :id => params[:id]
31
+ }.merge(criteria)
32
+ criteria[:params] = criteria.dup
33
+
34
+ unless criteria.has_key?(:group) or criteria.has_key?(:user)
35
+ controller = case self
36
+ when ActionView::Base
37
+ self.controller
38
+ else
39
+ self #XXX ???
40
+ end
41
+ criteria[:user] = AuthnFacade.current_user(controller)
42
+ end
43
+
44
+ result = LogicalAuthz.is_authorized?(criteria)
45
+
46
+ return result
47
+ end
48
+
49
+ # returns an array of group names and ids (suitable for select_tag)
50
+ # for which <user> is not a member
51
+ def nonmembered_groups(user)
52
+ (LogicalAuthz::group_model.all - user.groups).map { |g| [ g.name, g.id ] }
53
+ end
54
+
55
+ def groups
56
+ LogicalAuthz::group_model.all.map do |group|
57
+ [group.name, group.id ]
58
+ end
59
+ end
60
+
61
+ def controller_pairs
62
+ controllers = ActionController::Routing::possible_controllers
63
+ controllers -= %w{rails/info application authz rails_info}
64
+ controllers.map{|c| [c.classify, c]}
65
+ end
66
+
67
+ def criteria_from_url(url, html_options = nil)
68
+ return nil if url.nil?
69
+ uri = URI.parse(url_for(url))
70
+ path = uri.path
71
+ querystring = uri.query
72
+ http_method = (html_options.nil? ? nil : html_options[:method]) || :get
73
+ begin
74
+ params = Rails.application.routes.recognize_path(path, :method => http_method)
75
+ rescue ActionController::RoutingError => ex
76
+ Rails.logger.info{"Asked to authorize url: #{html_options.inspect} - couldn't route: #{ex.class.name}: #{ex.message}"}
77
+ return nil
78
+ end
79
+ querystring.blank? ? params : params.merge(Rack::Utils.parse_query(querystring).symbolize_keys!)
80
+ end
81
+
82
+ def authorized_url?(options, html_options = nil)
83
+ html_options ||= {}
84
+ params = {}
85
+ if Hash === options
86
+ params = options
87
+ else
88
+ params = criteria_from_url(options)
89
+ end
90
+ if params.nil?
91
+ true #We can't work out where it is, so we have no opinion
92
+ #XXX: Shouldn't this be false?
93
+ else
94
+ authorized?(params)
95
+ end
96
+ end
97
+
98
+ def authorized_menu(*items)
99
+ yield(items) if items.all? do |item|
100
+ authorized_url? [*item].last
101
+ end
102
+ end
103
+
104
+ def link_to_if_authorized(name, options = nil, html_options = nil)
105
+ options ||= {}
106
+ html_options ||= {}
107
+ url = options
108
+ if(authorized_url?(url, html_options))
109
+ link_to(name, options, html_options)
110
+ else
111
+ if block_given?
112
+ yield
113
+ else
114
+ ""
115
+ end
116
+ end
117
+ end
118
+
119
+ def button_to_if_authorized(name, options = {}, html_options = {})
120
+ url = options
121
+ if(authorized_url?(url, html_options))
122
+ button_to(name, options, html_options)
123
+ else
124
+ if block_given?
125
+ yield
126
+ else
127
+ ""
128
+ end
129
+ end
130
+ end
131
+
132
+ def link_to_remote_if_authorized(name, options = {}, html_options = nil)
133
+ url = options[:url]
134
+ if(authorized_url?(url, html_options))
135
+ link_to_remote(name, options, html_options)
136
+ else
137
+ if block_given?
138
+ yield
139
+ else
140
+ ""
141
+ end
142
+ end
143
+ end
144
+
145
+ def button_to_remote_if_authorized(name, options = {}, html_options = nil)
146
+ url = options[:url]
147
+ if(authorized_url?(url, html_options))
148
+ button_to_remote(name, options, html_options)
149
+ else
150
+ if block_given?
151
+ yield
152
+ else
153
+ ""
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
@@ -0,0 +1,18 @@
1
+ -page ||= @page
2
+
3
+ - content_for(:aux) do
4
+ - page_block("Admin Tool: Permissions", :cssclass => "narrowcolumn admin") do
5
+
6
+ %p Set view and edit permissions on this page.
7
+ %table.listing
8
+ %tr
9
+ %th Group
10
+ %th View?
11
+ %th Edit?
12
+
13
+ - for group in Group.all
14
+ %tr
15
+ %td= h group.name
16
+
17
+
18
+
@@ -0,0 +1,4 @@
1
+ = error_messages_for :group
2
+ - form_for @group, :url => groups_path do |f|
3
+ = labeled_input f, :name
4
+ = unlabeled_submit(f)
@@ -0,0 +1 @@
1
+ page.replace_html :permissions, :partial => 'permissions/controls', :locals => { :page => page }
@@ -0,0 +1 @@
1
+ = render :partial => "form"
@@ -0,0 +1,14 @@
1
+ -set_headline "Groups"
2
+
3
+ %ul.actions
4
+ %li= link_to_if_authorized("Create New Group", new_group_path)
5
+
6
+ %table.listing
7
+ %tr
8
+ %th Group Name
9
+ - @groups.each do |group|
10
+ %tr
11
+ %td= link_to_if_authorized(group.name, group_path(group))
12
+ %td
13
+ = link_to_if_authorized("Edit", edit_group_path(group))
14
+ = link_to_if_authorized("Delete", group_path(group), :method => :delete)
@@ -0,0 +1,2 @@
1
+ - set_headline "Grant Permission"
2
+ = render :partial => "form.html.haml"
@@ -0,0 +1,6 @@
1
+ -set_headline "Group: " + @group.name
2
+
3
+ %h3 Members
4
+ %ul
5
+ -@group.members.each do |member|
6
+ %li= member.name
@@ -0,0 +1,18 @@
1
+ -page ||= @page
2
+
3
+ - content_for(:aux) do
4
+ - page_block("Admin Tool: Permissions", :cssclass => "narrowcolumn admin") do
5
+
6
+ %p Set view and edit permissions on this page.
7
+ %table.listing
8
+ %tr
9
+ %th Group
10
+ %th View?
11
+ %th Edit?
12
+
13
+ - for group in Group.all
14
+ %tr
15
+ %td= h group.name
16
+
17
+
18
+
@@ -0,0 +1,8 @@
1
+ = error_messages_for :permission
2
+ - form_for @permission, :url => permissions_path do |f|
3
+ = hidden_field_tag(:permission, true)
4
+ = labeled_input f, :group, :input => select(:permission, :group_id, groups)
5
+ = labeled_input f, :controller, :input => select(:permission, :controller, controller_pairs)
6
+ = labeled_input f, :action
7
+ = labeled_input f, :subject_id, :text => "id"
8
+ = unlabeled_submit(f)
@@ -0,0 +1 @@
1
+ page.replace_html :permissions, :partial => 'permissions/controls', :locals => { :page => page }
@@ -0,0 +1 @@
1
+ = render :partial => _form.html.haml
@@ -0,0 +1,20 @@
1
+ -set_headline "Permissions"
2
+
3
+ %ul.actions
4
+ %li= link_to_if_authorized("Grant New Permission", new_permission_path)
5
+
6
+ %table.listing
7
+ %tr
8
+ %th Group
9
+ %th Controller
10
+ %th Action
11
+ %th Object ID
12
+ - @permissions.each do |permission|
13
+ %tr
14
+ %td= permission.group.name
15
+ %td= permission.controller
16
+ %td= permission.action || "*"
17
+ %td= permission.subject_id || "*"
18
+ %td
19
+ = link_to_if_authorized("Edit", edit_permission_path(permission))
20
+ = link_to_if_authorized("Delete", permission_path(permission), :method => :delete)
@@ -0,0 +1,2 @@
1
+ - set_headline "Grant Permission"
2
+ = render :partial => "form.html.haml"
@@ -0,0 +1 @@
1
+ require 'logical_authz'
@@ -0,0 +1,13 @@
1
+ class LogicalAuthzGenerator < LogicalAuthz::Generator
2
+ def manifest
3
+ record do |manifest|
4
+ manifest.dependency "logical_authz_models", [], options
5
+ manifest.dependency "logical_authz_specs", [], options
6
+ manifest.dependency "logical_authz_routes", [], options
7
+
8
+ manifest.template "app/controllers/authz_controller.rb.erb", "app/controllers/authz_controller.rb"
9
+ manifest.template "app/views/layouts/_explain_authz.html.haml", "app/views/layouts/_explain_authz.html.haml.erb"
10
+ manifest.readme "README"
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+
2
+
3
+
4
+ You'll want to add this to your db/seeds.rb:
5
+ require 'db/logical_authz_seeds'
6
+
7
+ You'll also want to add this to your ApplicationController:
8
+ include LogicalAuthz::Application
9
+
10
+
11
+ Thanks for using Logical Authorization!
@@ -0,0 +1,4 @@
1
+ class AuthzController < ApplicationController
2
+ needs_authorization
3
+ admin_authorized
4
+ end
@@ -0,0 +1,21 @@
1
+ - unless flash.has_key? :logical_authz_record
2
+ -# Authorization not required
3
+ - else
4
+ - if flash[:logical_authz_record][:result]
5
+ -# Authorization successful
6
+ - else
7
+ - laz_rec = flash[:logical_authz_record]
8
+ - if LogicalAuthz::AuthnFacade::current_user(controller).nil?
9
+ You aren't
10
+ = link_to("logged in", login_path)
11
+ - else
12
+ - case laz_rec[:reason]
13
+ - when :default, :rule_triggered
14
+ You aren't permitted to access
15
+ = laz_rec[:authz_path]
16
+ - when :no_authorization_needed
17
+ You were denied access to
18
+ = laz_rec[:authz_path]
19
+ although authorization isn't required - something is probably wrong.
20
+ - else
21
+ You were denied authorization
@@ -0,0 +1,22 @@
1
+ class LogicalAuthzModelsGenerator < LogicalAuthz::Generator
2
+ default_options(:permission_class => "Permission",
3
+ :group_class => "Group",
4
+ :admin_group => "Administration")
5
+
6
+ def manifest
7
+ raise "User class name (--user) is required!" unless options[:user_class]
8
+
9
+ record do |manifest|
10
+ #Yeah, I know, and I'm sorry. It should be okay, though.
11
+ ActiveRecord::Base.timestamped_migrations = false
12
+ manifest.class_collisions options[:group_class], options[:permission_class]
13
+ manifest.template "app/models/group.rb.erb", "app/models/#{template_data[:group_field]}.rb", :assigns => template_data
14
+ manifest.template "app/models/permission.rb.erb", "app/models/#{template_data[:permission_field]}.rb", :assigns => template_data
15
+ manifest.template "config/initializers/logical_authz.rb.erb", "config/initializers/logical_authz.rb", :assigns => template_data
16
+ manifest.template "db/seeds_logical_authz.rb.erb", "db/seeds_logical_authz.rb", :assigns => template_data
17
+ manifest.migration_template "migrations/create_groups.rb.erb", "db/migrate", :migration_file_name => "create_#{template_data[:group_table]}", :assigns => template_data
18
+ manifest.migration_template "migrations/create_permissions.rb.erb", "db/migrate", :migration_file_name => "create_#{template_data[:permission_table]}", :assigns => template_data
19
+ manifest.migration_template "migrations/create_users_groups.rb.erb", "db/migrate", :migration_file_name => "create_#{template_data[:user_table]}_#{template_data[:group_table]}", :assigns => template_data
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,12 @@
1
+ class LogicalAuthzRoutesGenerator < LogicalAuthz::Generator
2
+ def manifest
3
+ record do |manifest|
4
+ manifest.named_route :group_user, '/group_user', :controller => 'groups_users', :action => 'create', :conditions => { :method => :post }
5
+ manifest.named_route :ungroup_user, '/ungroup_user', :controller => 'groups_users', :action => 'destroy', :conditions => { :method => :delete }
6
+ manifest.named_route :permit_page, '/permit', :controller => 'permissions', :action => 'create', :conditions => { :method => :post }
7
+ manifest.named_route :forbid_page, '/forbid', :controller => 'permissions', :action => 'destroy', :conditions => { :method => :delete }
8
+ manifest.route_resources :groups
9
+ manifest.named_route :default_unauthorized, '/', :controller => "home", :action => "index"
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,26 @@
1
+ class LogicalAuthzSpecsGenerator < LogicalAuthz::Generator
2
+ default_options(:permission_class => "Permission",
3
+ :group_class => "Group",
4
+ :admin_group => "Administration")
5
+
6
+ def manifest
7
+ record do |manifest|
8
+ manifest.directory "spec/factories"
9
+ manifest.directory "spec/support"
10
+ manifest.directory "spec/controllers"
11
+ manifest.directory "spec/helpers"
12
+
13
+ manifest.with_options :assigns => template_data do |templ|
14
+ templ.template "spec/factories/az_accounts.rb.erb", "spec/factories/logical_authz_#{template_data[:user_table]}.rb"
15
+ templ.template "spec/factories/az_groups.rb.erb", "spec/factories/logical_authz_#{template_data[:group_table]}.rb"
16
+ templ.template "spec/factories/permissions.rb.erb", "spec/factories/logical_authz_#{template_data[:permission_table]}.rb"
17
+ templ.template "spec/support/logical_authz.rb.erb", "spec/support/logical_authz.rb"
18
+ templ.template "spec/support/mock_auth.rb.erb", "spec/support/mock_auth.rb"
19
+ templ.template "spec/controllers/permissions_controller_spec.rb.erb", "spec/controllers/permissions_controller_spec.rb"
20
+ templ.template "spec/controllers/groups_controller_spec.rb.erb", "spec/controllers/groups_controller_spec.rb"
21
+ templ.template "spec/controllers/groups_users_controller_spec.rb.erb", "spec/controllers/groups_users_controller_spec.rb"
22
+ templ.template "spec/helpers/logical_authz_helper_spec.rb.erb", "spec/helpers/logical_authz_helper_spec.rb"
23
+ end
24
+ end
25
+ end
26
+ end