lockdown 0.2.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +11 -1
- data/Manifest.txt +3 -3
- data/README.txt +2 -1
- data/app_generators/lockdown/lockdown_generator.rb +1 -1
- data/app_generators/lockdown/templates/init.rb +81 -0
- data/app_generators/lockdown/templates/session.rb +0 -3
- data/bin/lockdown +5 -9
- data/lib/lockdown.rb +11 -61
- data/lib/lockdown/controller.rb +7 -5
- data/lib/lockdown/controller_inspector.rb +6 -8
- data/lib/lockdown/helper.rb +17 -1
- data/lib/lockdown/model.rb +0 -2
- data/lib/lockdown/system.rb +169 -0
- data/lib/lockdown/version.rb +2 -2
- data/rails_generators/lockdown_all/lockdown_all_generator.rb +72 -34
- data/rails_generators/lockdown_all/templates/app/controllers/user_groups_controller.rb +2 -2
- data/rails_generators/lockdown_all/templates/app/controllers/users_controller.rb +2 -2
- data/rails_generators/lockdown_all/templates/app/models/permission.rb +0 -67
- data/rails_generators/lockdown_all/templates/app/models/user.rb +17 -40
- data/rails_generators/lockdown_all/templates/app/models/user_group.rb +0 -166
- data/rails_generators/lockdown_all/templates/db/migrate/create_admin_user_and_user_group.rb +25 -0
- data/rails_generators/lockdown_all/templates/db/migrate/create_profiles.rb +9 -0
- data/website/index.txt +17 -27
- metadata +5 -5
- data/app_generators/lockdown/templates/access.rb +0 -110
- data/rails_generators/lockdown_all/templates/db/migrate/create_base_user_groups.rb +0 -11
- data/website/index.html +0 -302
@@ -1,157 +1,9 @@
|
|
1
1
|
class UserGroup < ActiveRecord::Base
|
2
|
-
include Lockdown::Helper
|
3
2
|
has_and_belongs_to_many :permissions
|
4
3
|
has_and_belongs_to_many :users
|
5
4
|
|
6
5
|
validates_presence_of :name
|
7
|
-
|
8
|
-
before_update :protect_private
|
9
|
-
before_destroy :protect_private_and_protected
|
10
6
|
|
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
|
-
return [] if usr.nil?
|
99
|
-
|
100
|
-
if usr.administrator?
|
101
|
-
find :all,
|
102
|
-
:conditions => "name != 'Public Access' and name != 'Registered Users'",
|
103
|
-
:order => :name
|
104
|
-
else
|
105
|
-
find_by_sql <<-SQL
|
106
|
-
select user_groups.* from user_groups, user_groups_users
|
107
|
-
where user_groups.id = user_groups_users.user_group_id
|
108
|
-
and user_groups.name != 'Public Access'
|
109
|
-
and user_groups.name != 'Registered Users'
|
110
|
-
and user_groups_users.user_id = #{usr.id}
|
111
|
-
order by user_groups.name
|
112
|
-
SQL
|
113
|
-
end
|
114
|
-
end
|
115
|
-
|
116
|
-
#
|
117
|
-
# Use this for the content associations to restrict user group list for
|
118
|
-
# content association to the current user.
|
119
|
-
#
|
120
|
-
# For example, in a content management system, I may be able creat pages
|
121
|
-
# but want to restrict the users who can view the page. This will return
|
122
|
-
# a list of user groups I can grant access to this page.
|
123
|
-
#
|
124
|
-
#
|
125
|
-
def find_content_assignable_for_user(usr)
|
126
|
-
return [] if usr.nil?
|
127
|
-
|
128
|
-
if usr.administrator?
|
129
|
-
find :all
|
130
|
-
else
|
131
|
-
find_by_sql <<-SQL
|
132
|
-
select user_groups.* from user_groups, user_groups_users
|
133
|
-
where user_groups.id = user_groups_users.user_group_id
|
134
|
-
and user_groups_users.user_id = #{usr.id}
|
135
|
-
order by user_groups.name
|
136
|
-
SQL
|
137
|
-
end
|
138
|
-
end
|
139
|
-
end # end class block
|
140
|
-
|
141
|
-
#
|
142
|
-
# Return an array of the permissions for the UserGroup object
|
143
|
-
#
|
144
|
-
def all_permissions
|
145
|
-
if permissions.empty?
|
146
|
-
sym = convert_reference_name(self.name)
|
147
|
-
Lockdown::UserGroups.static_permissions(sym)
|
148
|
-
else
|
149
|
-
syms_from_names(permissions)
|
150
|
-
end
|
151
|
-
rescue Exception => e
|
152
|
-
[]
|
153
|
-
end
|
154
|
-
|
155
7
|
def all_users
|
156
8
|
User.find_by_sql <<-SQL
|
157
9
|
select users.*
|
@@ -160,22 +12,4 @@ class UserGroup < ActiveRecord::Base
|
|
160
12
|
and user_groups_users.user_group_id = #{self.id}
|
161
13
|
SQL
|
162
14
|
end
|
163
|
-
|
164
|
-
def access_rights
|
165
|
-
Lockdown::Permissions.access_rights_for syms_from_names(self.permissions)
|
166
|
-
end
|
167
|
-
|
168
|
-
def private_record?
|
169
|
-
Lockdown::UserGroups.respond_to? convert_reference_name(self.name)
|
170
|
-
end
|
171
|
-
|
172
|
-
def system_assigned?
|
173
|
-
self.private_record?
|
174
|
-
end
|
175
|
-
|
176
|
-
def protect_private
|
177
|
-
if self.private_record?
|
178
|
-
raise SecurityError, "Trying to update a private UserGroup"
|
179
|
-
end
|
180
|
-
end
|
181
15
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class CreateAdminUserAndUserGroup < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
#
|
4
|
+
# Creating an administrators user group database record
|
5
|
+
# to allow for the creation of other administrators
|
6
|
+
#
|
7
|
+
Lockdown::System.create_administrator_user_group
|
8
|
+
|
9
|
+
# TODO: Change the password
|
10
|
+
u = User.new( :password => "password",
|
11
|
+
:password_confirmation => "password",
|
12
|
+
:login => "admin")
|
13
|
+
|
14
|
+
u.profile = Profile.create(:first_name => "Administrator",
|
15
|
+
:last_name => "User",
|
16
|
+
:email => "administrator@a.com")
|
17
|
+
u.save
|
18
|
+
|
19
|
+
Lockdown::System.make_user_administrator(u)
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.down
|
23
|
+
#Nothing to see here...
|
24
|
+
end
|
25
|
+
end
|
@@ -9,6 +9,15 @@ class CreateProfiles < ActiveRecord::Migration
|
|
9
9
|
|
10
10
|
t.timestamps
|
11
11
|
end
|
12
|
+
|
13
|
+
# The System profile is used as the updated_by reference when records
|
14
|
+
# are created programatically and the responsible user cannot be determined
|
15
|
+
# or is simply not available.
|
16
|
+
# TODO: Change email address
|
17
|
+
Profile.create(:first_name => "System",
|
18
|
+
:last_name => "User",
|
19
|
+
:email => "system@a.com")
|
20
|
+
|
12
21
|
end
|
13
22
|
|
14
23
|
def self.down
|
data/website/index.txt
CHANGED
@@ -6,7 +6,7 @@ h3. Lockdown has not been officially released! This page is a Work-In-Progress.
|
|
6
6
|
|
7
7
|
h2. What
|
8
8
|
|
9
|
-
Lockdown is a authentication/authorization system for RubyOnRails and Merb designed for simplicity and extensibility. All access rules are
|
9
|
+
Lockdown is a authentication/authorization system for RubyOnRails and Merb designed for simplicity and extensibility. All access rules are defined in lib/lockdown/init.rb. With the included ORM support (ActiveRecord or DataMapper) and management screens you can add user defined rules to the system.
|
10
10
|
|
11
11
|
If there is a "spec" directory, a test helper file will be included to provied some basic functionality for use with RSpec. This will show you how to create mock user objects and sign in as an adminstrator.
|
12
12
|
|
@@ -24,7 +24,14 @@ $ cd <your_project_directory>
|
|
24
24
|
$ lockdown .
|
25
25
|
</pre>
|
26
26
|
|
27
|
-
This will create a "lockdown" directory in the lib dir add two files:
|
27
|
+
This will create a "lockdown" directory in the lib dir add two files: init.rb and session.rb. Modify init.rb to set defaults and define the rules that apply to your system.
|
28
|
+
|
29
|
+
If you want the full 'subsystem' (models, views, controllers, helpers):
|
30
|
+
|
31
|
+
<pre>
|
32
|
+
$ cd <your_project_directory>
|
33
|
+
$ ./script/generate lockdown_all
|
34
|
+
</pre>
|
28
35
|
|
29
36
|
I recommend reading this page to get a feel for Lockdown's functionality.
|
30
37
|
|
@@ -43,7 +50,7 @@ Lockdown stores an array of access rights in the session. For example, if you h
|
|
43
50
|
|
44
51
|
The above list will be stored in the session as an array and each request is tested against this list. So this means, you <strong>should not use client side session storage</strong>. If you can, I recommend using memcache, but a database session store will suffice.
|
45
52
|
|
46
|
-
To define access rights you need to modify lib/lockdown/
|
53
|
+
To define access rights you need to modify lib/lockdown/init.rb. This is the default init.rb included with Lockdown:
|
47
54
|
<pre syntax="ruby">
|
48
55
|
require "lockdown"
|
49
56
|
|
@@ -143,8 +150,11 @@ To define access rights you need to modify lib/lockdown/access.rb. This is the
|
|
143
150
|
#
|
144
151
|
# All newly created users are assigned to this User Group by default
|
145
152
|
#
|
153
|
+
# Sample registered_users permission:
|
154
|
+
# [:my_account]
|
155
|
+
#
|
146
156
|
def registered_users
|
147
|
-
|
157
|
+
[]
|
148
158
|
end
|
149
159
|
|
150
160
|
#
|
@@ -156,13 +166,13 @@ To define access rights you need to modify lib/lockdown/access.rb. This is the
|
|
156
166
|
</pre>
|
157
167
|
|
158
168
|
|
169
|
+
|
159
170
|
h2. Some History
|
160
171
|
|
161
172
|
Lockdown was initially designed as a authentication/authorization system to be configured by system administrators. This means it was database driven and had an interface to manage the access rights. I didn't like the static methodology of using code scattered amongst the controllers to define my access rights for the system. I also didn't like the fact that everything was accessible unless you restricted access. So, I designed Lockdown to restrict access to all resources unless rights have been granted.
|
162
173
|
|
163
174
|
The system was nice and worked well until I had a project that required RSpec tests. I don't have anything against testing frameworks (now that I've see the light) but what bothered me most what the fact that I would have to duplicate the information I already defined in my migrations as mock data. I simply refused to do that extra work. So, a serious refactoring of Lockdown was required.
|
164
175
|
|
165
|
-
<blockquote>This is where the access.rb file was born. This file contains the rules that grant/deny access to your system. More on this later.</blockquote>
|
166
176
|
|
167
177
|
After the RSpec project was completed, the refactoring continued. This time the focus was on releasing the code to the masses. I like this system a lot and think both the system itself and the community could benefit from releasing this as an open source project.
|
168
178
|
|
@@ -173,30 +183,10 @@ There is code in place for using Lockdown with Rails, after all, that's where Lo
|
|
173
183
|
Writing code for public release is difficult and much different from architecting/coding for a closed source project. A lot of things you could get by with in a proprietary application won't be well received by the general public. In addition, if you don't make things easy, the adoption rate will probably be non-existent.
|
174
184
|
|
175
185
|
|
176
|
-
h2. Features
|
177
|
-
|
178
|
-
<strong>I have these components (for the most part)...figuring out how to package them. The following is just an idea right now... </strong>
|
179
|
-
<br/>
|
180
|
-
<br/>
|
181
|
-
The goal of Lockdown is to give you only what you want from the system.
|
182
|
-
|
183
|
-
The initial install is all that is required to lock down your system. However, you'll probably want the authorization functionality. You can get this by:
|
184
|
-
|
185
|
-
<pre syntax="ruby">rake lockdown:install:authorization</pre>
|
186
|
-
|
187
|
-
If you want to install ORM support:
|
188
|
-
|
189
|
-
<pre syntax="ruby">rake lockdown:install:orm</pre>
|
190
|
-
|
191
|
-
If you want to install management screens (ORM support included):
|
192
|
-
<pre syntax="ruby">rake lockdown:install:management</pre>
|
193
|
-
|
194
|
-
If you want to install authorization + management screens:
|
195
|
-
<pre syntax="ruby">rake lockdown:install:all</pre>
|
196
|
-
|
197
|
-
|
198
186
|
h2. Forum
|
199
187
|
|
188
|
+
If you are having a problem understanding how to use Lockdown, please post your question on the lockdown group. If it's documentation related, I will keep this page updated to help everyone.
|
189
|
+
|
200
190
|
"http://groups.google.com/group/stonean_lockdown?hl=en":http://groups.google.com/group/stonean_lockdown?hl=en
|
201
191
|
|
202
192
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lockdown
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Stone
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-04-
|
12
|
+
date: 2008-04-30 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -46,7 +46,7 @@ files:
|
|
46
46
|
- app_generators/lockdown/USAGE
|
47
47
|
- app_generators/lockdown/lockdown_generator.rb
|
48
48
|
- app_generators/lockdown/lockdown_generator.rb.orig
|
49
|
-
- app_generators/lockdown/templates/
|
49
|
+
- app_generators/lockdown/templates/init.rb
|
50
50
|
- app_generators/lockdown/templates/session.rb
|
51
51
|
- bin/lockdown
|
52
52
|
- config/hoe.rb
|
@@ -56,6 +56,7 @@ files:
|
|
56
56
|
- lib/lockdown/controller_inspector.rb
|
57
57
|
- lib/lockdown/helper.rb
|
58
58
|
- lib/lockdown/model.rb
|
59
|
+
- lib/lockdown/system.rb
|
59
60
|
- lib/lockdown/version.rb
|
60
61
|
- lib/lockdown/view.rb
|
61
62
|
- rails_generators/lockdown_all/USAGE
|
@@ -88,7 +89,7 @@ files:
|
|
88
89
|
- rails_generators/lockdown_all/templates/app/views/users/index.html.erb
|
89
90
|
- rails_generators/lockdown_all/templates/app/views/users/new.html.erb
|
90
91
|
- rails_generators/lockdown_all/templates/app/views/users/show.html.erb
|
91
|
-
- rails_generators/lockdown_all/templates/db/migrate/
|
92
|
+
- rails_generators/lockdown_all/templates/db/migrate/create_admin_user_and_user_group.rb
|
92
93
|
- rails_generators/lockdown_all/templates/db/migrate/create_permissions.rb
|
93
94
|
- rails_generators/lockdown_all/templates/db/migrate/create_profiles.rb
|
94
95
|
- rails_generators/lockdown_all/templates/db/migrate/create_user_groups.rb
|
@@ -107,7 +108,6 @@ files:
|
|
107
108
|
- test/test_lockdown_all_generator.rb
|
108
109
|
- test/test_lockdown_generator.rb
|
109
110
|
- test/test_lockdown_models_generator.rb
|
110
|
-
- website/index.html
|
111
111
|
- website/index.txt
|
112
112
|
- website/javascripts/rounded_corners_lite.inc.js
|
113
113
|
- website/stylesheets/screen.css
|
@@ -1,110 +0,0 @@
|
|
1
|
-
require "lockdown"
|
2
|
-
|
3
|
-
module Lockdown
|
4
|
-
#
|
5
|
-
#
|
6
|
-
# Permissions are used to group access rights into logical components.
|
7
|
-
# Each method defined in the Permissions module represents an array
|
8
|
-
# of methods from a controller (or multiple controllers.)
|
9
|
-
#
|
10
|
-
# Controller methods available are:
|
11
|
-
#
|
12
|
-
# # Returns all methods from all controllers
|
13
|
-
# all_controllers
|
14
|
-
#
|
15
|
-
# # Returns all methods from all controllers listed
|
16
|
-
# all_methods :controller1, controller2, ...
|
17
|
-
#
|
18
|
-
# # For a single controller, returns only methods listed
|
19
|
-
# only_methods :controller1, :method1, :method2, ...
|
20
|
-
#
|
21
|
-
# # For a single controller, returns all methods except the methods listed
|
22
|
-
# all_except_methods :controller1, :method1, :method2, ...
|
23
|
-
#
|
24
|
-
# They all return an array of controller/action. For example, if you had a
|
25
|
-
# standard REST controller called products this would be the result:
|
26
|
-
#
|
27
|
-
#
|
28
|
-
# all_methods :products => [ "products/index , "products/show",
|
29
|
-
# "products/new", "products/edit",
|
30
|
-
# "products/create", "products/update",
|
31
|
-
# "products/destroy"]
|
32
|
-
#
|
33
|
-
module Permissions
|
34
|
-
class << self
|
35
|
-
|
36
|
-
def sessions_management
|
37
|
-
# all_methods :sessions
|
38
|
-
end
|
39
|
-
|
40
|
-
end # end class block
|
41
|
-
end # end Permissions module
|
42
|
-
|
43
|
-
#
|
44
|
-
# UserGroups are used to group Permissions together to define role type
|
45
|
-
# functionality. Users may belong to multiple groups.
|
46
|
-
#
|
47
|
-
module UserGroups
|
48
|
-
class << self
|
49
|
-
#
|
50
|
-
# This method defines which UserGroups cannot be managed
|
51
|
-
# via the management screens.
|
52
|
-
#
|
53
|
-
# Users can still be assigned to these groups.
|
54
|
-
#
|
55
|
-
def private_records
|
56
|
-
[:administrators]
|
57
|
-
end
|
58
|
-
#
|
59
|
-
# This method defines which UserGroups have limited access
|
60
|
-
# via the management screens. Deletion is not allowed.
|
61
|
-
#
|
62
|
-
# Users can still be assigned to these groups.
|
63
|
-
#
|
64
|
-
def protected_records
|
65
|
-
[:public_access, :registered_users]
|
66
|
-
end
|
67
|
-
|
68
|
-
# ** The administrator method is "special", please don't rename.
|
69
|
-
# If you remove/rename, etc... YOU WILL BREAK STUFF
|
70
|
-
#
|
71
|
-
# Standard administrator user group.
|
72
|
-
# Please don't alter without careful consideration.
|
73
|
-
#
|
74
|
-
def administrators
|
75
|
-
[:all]
|
76
|
-
end
|
77
|
-
|
78
|
-
# ** The public_access method is "special", please don't rename.
|
79
|
-
# If you remove/rename, etc... YOU WILL BREAK STUFF
|
80
|
-
#
|
81
|
-
# Standard public_access user group.
|
82
|
-
#
|
83
|
-
# Feel free to add Permissions to the array without issue.
|
84
|
-
#
|
85
|
-
# **Notice: All permissions added to this public_access group will not be
|
86
|
-
# restricted to logged in users.
|
87
|
-
# So be careful what you add here!
|
88
|
-
#
|
89
|
-
def public_access
|
90
|
-
[:sessions_management]
|
91
|
-
end
|
92
|
-
|
93
|
-
# ** The registered_users method is "special", please don't rename.
|
94
|
-
# Not as special as the others, but still...
|
95
|
-
#
|
96
|
-
# All newly created users are assigned to this User Group by default
|
97
|
-
#
|
98
|
-
# Sample registered user permission:
|
99
|
-
# [:my_account]
|
100
|
-
def registered_users
|
101
|
-
[]
|
102
|
-
end
|
103
|
-
|
104
|
-
#
|
105
|
-
# Define your own user groups below
|
106
|
-
#
|
107
|
-
|
108
|
-
end # end class block
|
109
|
-
end # end UserGroups module
|
110
|
-
end # end Lockdown module
|