logical_authz 0.1.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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