lockdown 0.1.2 → 0.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. data/History.txt +7 -1
  2. data/Manifest.txt +35 -0
  3. data/config/hoe.rb +0 -1
  4. data/lib/lockdown/version.rb +1 -1
  5. data/rails_generators/lockdown_all/USAGE +5 -0
  6. data/rails_generators/lockdown_all/lockdown_all_generator.rb +69 -0
  7. data/rails_generators/lockdown_all/templates/app/controllers/permissions_controller.rb +22 -0
  8. data/rails_generators/lockdown_all/templates/app/controllers/sessions_controller.rb +37 -0
  9. data/rails_generators/lockdown_all/templates/app/controllers/user_groups_controller.rb +113 -0
  10. data/rails_generators/lockdown_all/templates/app/controllers/users_controller.rb +124 -0
  11. data/rails_generators/lockdown_all/templates/app/helpers/permissions_helper.rb +13 -0
  12. data/rails_generators/lockdown_all/templates/app/helpers/user_groups_helper.rb +35 -0
  13. data/rails_generators/lockdown_all/templates/app/helpers/users_helper.rb +78 -0
  14. data/rails_generators/lockdown_all/templates/app/models/permission.rb +80 -0
  15. data/rails_generators/lockdown_all/templates/app/models/user.rb +96 -0
  16. data/rails_generators/lockdown_all/templates/app/models/user_group.rb +177 -0
  17. data/rails_generators/lockdown_all/templates/app/views/permissions/_data.html.erb +13 -0
  18. data/rails_generators/lockdown_all/templates/app/views/permissions/index.html.erb +16 -0
  19. data/rails_generators/lockdown_all/templates/app/views/permissions/show.html.erb +3 -0
  20. data/rails_generators/lockdown_all/templates/app/views/sessions/new.html.erb +9 -0
  21. data/rails_generators/lockdown_all/templates/app/views/user_groups/_data.html.erb +15 -0
  22. data/rails_generators/lockdown_all/templates/app/views/user_groups/_form.html.erb +11 -0
  23. data/rails_generators/lockdown_all/templates/app/views/user_groups/edit.html.erb +6 -0
  24. data/rails_generators/lockdown_all/templates/app/views/user_groups/index.html.erb +20 -0
  25. data/rails_generators/lockdown_all/templates/app/views/user_groups/new.html.erb +5 -0
  26. data/rails_generators/lockdown_all/templates/app/views/user_groups/show.html.erb +6 -0
  27. data/rails_generators/lockdown_all/templates/app/views/users/_data.html.erb +32 -0
  28. data/rails_generators/lockdown_all/templates/app/views/users/_form.html.erb +18 -0
  29. data/rails_generators/lockdown_all/templates/app/views/users/_password.html.erb +5 -0
  30. data/rails_generators/lockdown_all/templates/app/views/users/edit.html.erb +6 -0
  31. data/rails_generators/lockdown_all/templates/app/views/users/index.html.erb +22 -0
  32. data/rails_generators/lockdown_all/templates/app/views/users/new.html.erb +5 -0
  33. data/rails_generators/lockdown_all/templates/app/views/users/show.html.erb +4 -0
  34. data/rails_generators/lockdown_all/templates/db/migrate/create_permissions.rb +15 -0
  35. data/rails_generators/lockdown_all/templates/db/migrate/create_profile.rb +19 -0
  36. data/rails_generators/lockdown_all/templates/db/migrate/create_user_groups.rb +15 -0
  37. data/rails_generators/lockdown_all/templates/db/migrate/create_users.rb +20 -0
  38. data/website/index.html +1 -1
  39. metadata +36 -1
@@ -0,0 +1,13 @@
1
+ module PermissionsHelper
2
+ def permission_name_value
3
+ h @permission.name
4
+ end
5
+
6
+ def permission_access_rights_value
7
+ @permission.access_rights.collect{|r| r}.join("<br/>") if @permission.access_rights
8
+ end
9
+
10
+ def permission_users_value
11
+ @permission.all_users.collect{|u| link_to_or_show(u.full_name, u)}.join("<br/>")
12
+ end
13
+ end
@@ -0,0 +1,35 @@
1
+ module UserGroupsHelper
2
+ def user_group_name_value
3
+ if @action_name == "show"
4
+ h @user_group.name
5
+ else
6
+ text_field_tag "user_group[name]", @user_group.name
7
+ end
8
+ end
9
+
10
+ def user_group_permissions_value
11
+ if @action_name == "show"
12
+ @user_group.permissions.collect{|p| p.name + "<br/>"}
13
+ else
14
+ rvalue = %{<ul id="all_permissions" class="checklist">}
15
+ @all_permissions.each_with_index do |perm,i|
16
+ bg = row_class(i)
17
+ input_id = "perm_#{perm.id}"
18
+ checked = (@user_group.permission_ids.include?(perm.id) ? "checked" : "")
19
+ bg << "_" << checked if checked.length > 0
20
+ rvalue << <<-HTML
21
+ <li class="#{bg}">
22
+ <label id="lbl_#{input_id}" for="#{input_id}" onclick="do_highlight('#{input_id}')">
23
+ <input id="#{input_id}" name="#{input_id}" type="checkbox" #{checked}/>&nbsp;&nbsp;#{perm.name}
24
+ </label>
25
+ </li>
26
+ HTML
27
+ end
28
+ rvalue << "</ul>"
29
+ end
30
+ end
31
+
32
+ def user_group_users_value
33
+ @user_group.all_users.collect{|u| link_to_or_show(u.full_name, u)}.join("<br/>")
34
+ end
35
+ end
@@ -0,0 +1,78 @@
1
+ module UsersHelper
2
+ def profile_first_name_value
3
+ if @action_name == "show"
4
+ h @profile.first_name
5
+ else
6
+ text_field_tag "profile[first_name]", @profile.first_name
7
+ end
8
+ end
9
+
10
+ def profile_last_name_value
11
+ if @action_name == "show"
12
+ h @profile.last_name
13
+ else
14
+ text_field_tag "profile[last_name]", @profile.last_name
15
+ end
16
+ end
17
+
18
+ def profile_email_value
19
+ if @action_name == "show"
20
+ h @profile.email
21
+ else
22
+ text_field_tag "profile[email]", @profile.email
23
+ end
24
+ end
25
+
26
+ def user_login_value
27
+ if @action_name == "show"
28
+ h @user.login
29
+ else
30
+ text_field_tag "user[login]", @user.login
31
+ end
32
+ end
33
+
34
+ def user_password_value
35
+ if @action_name == "show"
36
+ h "Hidden for security..."
37
+ else
38
+ %{<input autocomplete="off" type="password" name="user[password]" id="user_password"/>}
39
+ end
40
+ end
41
+
42
+ def user_password_confirmation_value
43
+ if @action_name == "show"
44
+ h "Hidden for security..."
45
+ else
46
+ %{<input autocomplete="off" type="password" name="user[password_confirmation]" id="user_password_confirmation"/>}
47
+ end
48
+ end
49
+
50
+ def user_user_groups_value
51
+ if @action_name == "show"
52
+ @user.user_groups.collect{|ug| ug.name + "<br/>"}
53
+ else
54
+ rvalue = %{<ul id="all_user_groups" class="checklist">}
55
+ #
56
+ # Restrict user group list to the list of the current user.
57
+ # This prevents a user from creating someone with more access than
58
+ # him/herself.
59
+ #
60
+ @user_groups_for_user.each_with_index do |ug,i|
61
+ bg = row_class(i)
62
+ input_id = "ug_#{ug.id}"
63
+ checked = (@user.user_group_ids.include?(ug.id) ? "checked" : "")
64
+ bg << "_" << checked if checked.length > 0
65
+ rvalue << <<-HTML
66
+ <li class="#{bg}">
67
+ <label id="lbl_#{input_id}" for="#{input_id}" onclick="do_highlight('#{input_id}')">
68
+ <input id="#{input_id}" name="#{input_id}" type="checkbox" #{checked}/>&nbsp;&nbsp;#{ug.name}
69
+ </label>
70
+ </li>
71
+ HTML
72
+ end
73
+ rvalue << "</ul>"
74
+ end
75
+ end
76
+
77
+
78
+ end
@@ -0,0 +1,80 @@
1
+ #
2
+ # This is merely an extension of the Lockdown::Permissions module to
3
+ # allow for database manipulation of Permissions
4
+ #
5
+ # This is typically done via management screens.
6
+ #
7
+ class Permission < ActiveRecord::Base
8
+ include Lockdown::Helper
9
+ has_and_belongs_to_many :user_groups
10
+
11
+ before_save :ensure_lockdown_permission_exists
12
+
13
+ class << self
14
+ include Lockdown::Helper
15
+ #
16
+ # Use this in your migrations to create a db record for management
17
+ # functionality.
18
+ #
19
+ # Permission must be defined in:
20
+ # RAILS_ROOT/config/initializers/lockdown/access.rb
21
+ #
22
+ def create_record(sym)
23
+ raise NameError.new("#{sym} is not defined.") unless Lockdown::Permissions.respond_to?(sym)
24
+ create(:name => convert_reference_name(sym) )
25
+ end
26
+
27
+ #
28
+ # Use this in your migrations to delete the permission identified by sym.
29
+ #
30
+ def delete_record(sym)
31
+ privi = find_by_sym(sym)
32
+ privi.destroy unless privi.nil?
33
+ end
34
+
35
+
36
+ def find_by_sym(sym)
37
+ if ENV['RAILS_ENV'] == "test"
38
+ new(:name => convert_reference_name(sym))
39
+ else
40
+ find_by_name(convert_reference_name(sym))
41
+ end
42
+ end
43
+
44
+ def all_but_public
45
+ find(:all).delete_if do |perm|
46
+ Lockdown::UserGroups.public_access.include?(convert_reference_name(perm.name))
47
+ end
48
+ end
49
+ end # end class block
50
+
51
+
52
+ def access_rights
53
+ sym = convert_reference_name(self.name)
54
+ Lockdown::Permissions[sym]
55
+ end
56
+
57
+ def all_users
58
+ User.find_by_sql <<-SQL
59
+ select users.*
60
+ from users, user_groups_users, permissions_user_groups
61
+ where users.id = user_groups_users.user_id
62
+ and user_groups_users.user_group_id = permissions_user_groups.user_group_id
63
+ and permissions_user_groups.permission_id = #{self.id}
64
+ SQL
65
+ end
66
+ protected
67
+ #
68
+ # Cannot create a permission record in the db that is not defined
69
+ # in config/initializers/lock_down_access
70
+ #
71
+ # Creating a db record is to simplify the creation of user groups
72
+ # via management screens.
73
+ #
74
+ def ensure_lockdown_permission_exists
75
+ unless Lockdown::Permissions.respond_to?(convert_reference_name(self.name))
76
+ raise NameError.new("#{sym} is not defined.")
77
+ end
78
+ end
79
+
80
+ end
@@ -0,0 +1,96 @@
1
+ require 'digest/sha1'
2
+ class User < ActiveRecord::Base
3
+ include Lockdown::Helper
4
+ has_and_belongs_to_many :user_groups
5
+ belongs_to :profile
6
+
7
+ # Virtual attributes
8
+ attr_accessor :password
9
+
10
+ validates_presence_of :login
11
+ validates_presence_of :password, :if => :password_required?
12
+ validates_presence_of :password_confirmation, :if => :password_required?
13
+ validates_length_of :password, :within => 4..40, :if => :password_required?
14
+ validates_confirmation_of :password, :if => :password_required?
15
+ validates_length_of :login, :within => 3..40
16
+ validates_uniqueness_of :login, :case_sensitive => false
17
+
18
+ validates_presence_of :profile
19
+ validates_associated :profile
20
+
21
+ before_save :prepare_for_save
22
+
23
+ after_create :assign_registered_users_user_group
24
+
25
+ attr_accessible :login, :password, :password_confirmation
26
+
27
+ # Authenticates a user by their login name and unencrypted password. Returns the user or nil.
28
+ def self.authenticate(login, password)
29
+ u = find :first, :conditions => ['login = ?', login] # need to get the salt
30
+ u && u.authenticated?(password) ? u : nil
31
+ end
32
+
33
+ # Encrypts some data with the salt.
34
+ def self.encrypt(password, salt)
35
+ Digest::SHA1.hexdigest("--#{salt}--#{password}--")
36
+ end
37
+
38
+ def self.all
39
+ find :all, :include => [:profile, :user_groups]
40
+ end
41
+
42
+ # Encrypts the password with the user salt
43
+ def encrypt(password)
44
+ self.class.encrypt(password, salt)
45
+ end
46
+
47
+ def authenticated?(password)
48
+ crypted_password == encrypt(password)
49
+ end
50
+
51
+ def access_rights
52
+ rvalue = Lockdown::UserGroups[:public_access]
53
+ self.user_groups.each{|grp| rvalue += grp.access_rights}
54
+ rvalue
55
+ end
56
+
57
+ def email
58
+ self.profile.email
59
+ end
60
+
61
+ def full_name
62
+ self.profile.first_name + " " + self.profile.last_name
63
+ end
64
+
65
+ def administrator?
66
+ has_user_group? :administrators
67
+ end
68
+
69
+ def has_user_group?(sym)
70
+ self.user_groups.each do |ug|
71
+ return true if convert_reference_name(ug.name) == sym
72
+ end
73
+ false
74
+ end
75
+
76
+ protected
77
+ def assign_registered_users_user_group
78
+ self.user_groups << UserGroup.find_by_sym(:registered_users)
79
+ end
80
+
81
+ def prepare_for_save
82
+ encrypt_password
83
+ self.profile.save
84
+ end
85
+
86
+ def encrypt_password
87
+ return if password.blank?
88
+ self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record?
89
+ self.crypted_password = encrypt(password)
90
+ end
91
+
92
+ def password_required?
93
+ (crypted_password.blank? || !password.blank?)
94
+ end
95
+
96
+ end
@@ -0,0 +1,177 @@
1
+ class UserGroup < ActiveRecord::Base
2
+ include Lockdown::Helper
3
+ has_and_belongs_to_many :permissions
4
+ has_and_belongs_to_many :users
5
+
6
+ validates_presence_of :name
7
+
8
+ before_update :protect_private
9
+ before_destroy :protect_private_and_protected
10
+
11
+ class << self
12
+ include Lockdown::Helper
13
+ #
14
+ # Pull from the Lockdown::UserGroups module if defined.
15
+ # Otherwise. load from db.
16
+ #
17
+ def [](sym)
18
+ return Lockdown::UserGroups[sym] if Lockdown::UserGroups.respond_to? sym
19
+ ug = UserGroup.find_by_name(convert_reference_name(sym))
20
+ ug.access_rights
21
+ end
22
+
23
+ def find_by_sym(sym)
24
+ if ENV['RAILS_ENV'] == "test"
25
+ new(:name => convert_reference_name(sym))
26
+ else
27
+ find_by_name(convert_reference_name(sym))
28
+ end
29
+ end
30
+
31
+ def find_by_name(str)
32
+ find :first, :conditions => ["name = ?",str]
33
+ end
34
+
35
+ #
36
+ # Use this in your migrations to create a db record for management
37
+ # functionality.
38
+ #
39
+ def create_record(sym)
40
+ raise NameError.new("#{sym} is not defined.") unless Lockdown::UserGroups.respond_to?(sym)
41
+ ug = create(:name => convert_reference_name(sym))
42
+ unless Lockdown::UserGroups.private_records.include?(sym)
43
+ Lockdown::UserGroups.permissions(sym).each do |perm|
44
+ ug.permissions << Permission.find_or_create_by_name(convert_reference_name(perm))
45
+ end
46
+ end
47
+ end
48
+
49
+ #
50
+ # Use this in your migrations to add permissions to a user group
51
+ # identified by sym.
52
+ #
53
+ # privies are param(s) of symbols
54
+ # e.g. add_permissions(:public_access, :view_catalog)
55
+ #
56
+ def add_permissions(sym, *privies)
57
+ ug = find_by_sym(sym)
58
+ raise NameError.new("#{sym} is not defined.") if ug.nil?
59
+ privies.each do |priv|
60
+ ug.permissions << Permission.find_or_create_by_name(convert_reference_name(priv))
61
+ end
62
+ end
63
+
64
+ #
65
+ # Use this in your migrations to remove permissions from a user group
66
+ # identified by sym.
67
+ #
68
+ # privies are param(s) of symbols
69
+ # e.g. add_permissions(:catalog_management, :manage_categories,
70
+ # :manage_products)
71
+ #
72
+ def remove_permissions(sym, *privies)
73
+ ug = find_by_sym(sym)
74
+ raise NameError.new("#{sym} is not defined.") if ug.nil?
75
+ privies.each do |priv|
76
+ ug.permissions.delete Permission.find_by_name(convert_reference_name(priv))
77
+ end
78
+ end
79
+
80
+ #
81
+ # Use this in your migrations to delete the user group identified by sym.
82
+ #
83
+ def delete_record(sym)
84
+ ug = find_by_sym(sym)
85
+ ug.destroy unless ug.nil?
86
+ end
87
+
88
+ #
89
+ # Use this for the management screen to restrict user group list to the
90
+ # user. This will prevent a user from creating a user with more power than
91
+ # him/herself.
92
+ #
93
+ # Public Access and Registered Users groups are automatically assigned,
94
+ # so having it on the management screen is just confusing and will lead
95
+ # to errors by mistakingly removing them.
96
+ #
97
+ def find_assignable_for_user(usr)
98
+ if usr.administrator?
99
+ find :all,
100
+ :conditions => "name != 'Public Access' and name != 'Registered Users'",
101
+ :order => :name
102
+ else
103
+ find_by_sql <<-SQL
104
+ select user_groups.* from user_groups, user_groups_users
105
+ where user_groups.id = user_groups_users.user_group_id
106
+ and user_groups.name != 'Public Access'
107
+ and user_groups.name != 'Registered Users'
108
+ and user_groups_users.user_id = #{usr.id}
109
+ order by user_groups.name
110
+ SQL
111
+ end
112
+ end
113
+
114
+ #
115
+ # Use this for the content associations to restrict user group list for
116
+ # content association to the current user.
117
+ #
118
+ # For example, in a content management system, I may be able creat pages
119
+ # but want to restrict the users who can view the page. This will return
120
+ # a list of user groups I can grant access to this page.
121
+ #
122
+ #
123
+ def find_content_assignable_for_user(usr)
124
+ if usr.administrator?
125
+ find :all
126
+ else
127
+ find_by_sql <<-SQL
128
+ select user_groups.* from user_groups, user_groups_users
129
+ where user_groups.id = user_groups_users.user_group_id
130
+ and user_groups_users.user_id = #{usr.id}
131
+ order by user_groups.name
132
+ SQL
133
+ end
134
+ end
135
+ end # end class block
136
+
137
+ #
138
+ # Return an array of the permissions for the UserGroup object
139
+ #
140
+ def all_permissions
141
+ if permissions.empty?
142
+ sym = convert_reference_name(self.name)
143
+ Lockdown::UserGroups.static_permissions(sym)
144
+ else
145
+ syms_from_names(permissions)
146
+ end
147
+ rescue Exception => e
148
+ []
149
+ end
150
+
151
+ def all_users
152
+ User.find_by_sql <<-SQL
153
+ select users.*
154
+ from users, user_groups_users
155
+ where users.id = user_groups_users.user_id
156
+ and user_groups_users.user_group_id = #{self.id}
157
+ SQL
158
+ end
159
+
160
+ def access_rights
161
+ Lockdown::Permissions.access_rights_for syms_from_names(self.permissions)
162
+ end
163
+
164
+ def private_record?
165
+ Lockdown::UserGroups.respond_to? convert_reference_name(self.name)
166
+ end
167
+
168
+ def system_assigned?
169
+ self.private_record?
170
+ end
171
+
172
+ def protect_private
173
+ if self.private_record?
174
+ raise SecurityError, "Trying to update a private UserGroup"
175
+ end
176
+ end
177
+ end