lockdown 0.1.2 → 0.1.3
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +7 -1
- data/Manifest.txt +35 -0
- data/config/hoe.rb +0 -1
- data/lib/lockdown/version.rb +1 -1
- data/rails_generators/lockdown_all/USAGE +5 -0
- data/rails_generators/lockdown_all/lockdown_all_generator.rb +69 -0
- data/rails_generators/lockdown_all/templates/app/controllers/permissions_controller.rb +22 -0
- data/rails_generators/lockdown_all/templates/app/controllers/sessions_controller.rb +37 -0
- data/rails_generators/lockdown_all/templates/app/controllers/user_groups_controller.rb +113 -0
- data/rails_generators/lockdown_all/templates/app/controllers/users_controller.rb +124 -0
- data/rails_generators/lockdown_all/templates/app/helpers/permissions_helper.rb +13 -0
- data/rails_generators/lockdown_all/templates/app/helpers/user_groups_helper.rb +35 -0
- data/rails_generators/lockdown_all/templates/app/helpers/users_helper.rb +78 -0
- data/rails_generators/lockdown_all/templates/app/models/permission.rb +80 -0
- data/rails_generators/lockdown_all/templates/app/models/user.rb +96 -0
- data/rails_generators/lockdown_all/templates/app/models/user_group.rb +177 -0
- data/rails_generators/lockdown_all/templates/app/views/permissions/_data.html.erb +13 -0
- data/rails_generators/lockdown_all/templates/app/views/permissions/index.html.erb +16 -0
- data/rails_generators/lockdown_all/templates/app/views/permissions/show.html.erb +3 -0
- data/rails_generators/lockdown_all/templates/app/views/sessions/new.html.erb +9 -0
- data/rails_generators/lockdown_all/templates/app/views/user_groups/_data.html.erb +15 -0
- data/rails_generators/lockdown_all/templates/app/views/user_groups/_form.html.erb +11 -0
- data/rails_generators/lockdown_all/templates/app/views/user_groups/edit.html.erb +6 -0
- data/rails_generators/lockdown_all/templates/app/views/user_groups/index.html.erb +20 -0
- data/rails_generators/lockdown_all/templates/app/views/user_groups/new.html.erb +5 -0
- data/rails_generators/lockdown_all/templates/app/views/user_groups/show.html.erb +6 -0
- data/rails_generators/lockdown_all/templates/app/views/users/_data.html.erb +32 -0
- data/rails_generators/lockdown_all/templates/app/views/users/_form.html.erb +18 -0
- data/rails_generators/lockdown_all/templates/app/views/users/_password.html.erb +5 -0
- data/rails_generators/lockdown_all/templates/app/views/users/edit.html.erb +6 -0
- data/rails_generators/lockdown_all/templates/app/views/users/index.html.erb +22 -0
- data/rails_generators/lockdown_all/templates/app/views/users/new.html.erb +5 -0
- data/rails_generators/lockdown_all/templates/app/views/users/show.html.erb +4 -0
- data/rails_generators/lockdown_all/templates/db/migrate/create_permissions.rb +15 -0
- data/rails_generators/lockdown_all/templates/db/migrate/create_profile.rb +19 -0
- data/rails_generators/lockdown_all/templates/db/migrate/create_user_groups.rb +15 -0
- data/rails_generators/lockdown_all/templates/db/migrate/create_users.rb +20 -0
- data/website/index.html +1 -1
- 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}/> #{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}/> #{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
|