andrewzielinski-lockdown 0.9.6
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +195 -0
- data/README.txt +36 -0
- data/Rakefile +41 -0
- data/lib/lockdown.rb +70 -0
- data/lib/lockdown/context.rb +41 -0
- data/lib/lockdown/database.rb +105 -0
- data/lib/lockdown/frameworks/rails.rb +146 -0
- data/lib/lockdown/frameworks/rails/controller.rb +147 -0
- data/lib/lockdown/frameworks/rails/view.rb +61 -0
- data/lib/lockdown/helper.rb +95 -0
- data/lib/lockdown/orms/active_record.rb +68 -0
- data/lib/lockdown/permission.rb +204 -0
- data/lib/lockdown/rules.rb +289 -0
- data/lib/lockdown/session.rb +57 -0
- data/lib/lockdown/system.rb +57 -0
- data/rails_generators/lockdown/lockdown_generator.rb +273 -0
- data/rails_generators/lockdown/templates/app/controllers/permissions_controller.rb +22 -0
- data/rails_generators/lockdown/templates/app/controllers/sessions_controller.rb +39 -0
- data/rails_generators/lockdown/templates/app/controllers/user_groups_controller.rb +122 -0
- data/rails_generators/lockdown/templates/app/controllers/users_controller.rb +117 -0
- data/rails_generators/lockdown/templates/app/helpers/permissions_helper.rb +2 -0
- data/rails_generators/lockdown/templates/app/helpers/user_groups_helper.rb +2 -0
- data/rails_generators/lockdown/templates/app/helpers/users_helper.rb +2 -0
- data/rails_generators/lockdown/templates/app/models/permission.rb +13 -0
- data/rails_generators/lockdown/templates/app/models/profile.rb +10 -0
- data/rails_generators/lockdown/templates/app/models/user.rb +95 -0
- data/rails_generators/lockdown/templates/app/models/user_group.rb +15 -0
- data/rails_generators/lockdown/templates/app/views/permissions/index.html.erb +16 -0
- data/rails_generators/lockdown/templates/app/views/permissions/show.html.erb +26 -0
- data/rails_generators/lockdown/templates/app/views/sessions/new.html.erb +12 -0
- data/rails_generators/lockdown/templates/app/views/user_groups/edit.html.erb +33 -0
- data/rails_generators/lockdown/templates/app/views/user_groups/index.html.erb +20 -0
- data/rails_generators/lockdown/templates/app/views/user_groups/new.html.erb +31 -0
- data/rails_generators/lockdown/templates/app/views/user_groups/show.html.erb +29 -0
- data/rails_generators/lockdown/templates/app/views/users/edit.html.erb +51 -0
- data/rails_generators/lockdown/templates/app/views/users/index.html.erb +22 -0
- data/rails_generators/lockdown/templates/app/views/users/new.html.erb +50 -0
- data/rails_generators/lockdown/templates/app/views/users/show.html.erb +33 -0
- data/rails_generators/lockdown/templates/config/initializers/lockit.rb +1 -0
- data/rails_generators/lockdown/templates/db/migrate/create_admin_user.rb +17 -0
- data/rails_generators/lockdown/templates/db/migrate/create_permissions.rb +19 -0
- data/rails_generators/lockdown/templates/db/migrate/create_profiles.rb +26 -0
- data/rails_generators/lockdown/templates/db/migrate/create_user_groups.rb +19 -0
- data/rails_generators/lockdown/templates/db/migrate/create_users.rb +17 -0
- data/rails_generators/lockdown/templates/lib/lockdown/README +42 -0
- data/rails_generators/lockdown/templates/lib/lockdown/init.rb +122 -0
- data/spec/lockdown/database_spec.rb +158 -0
- data/spec/lockdown/frameworks/rails/controller_spec.rb +224 -0
- data/spec/lockdown/frameworks/rails/view_spec.rb +125 -0
- data/spec/lockdown/frameworks/rails_spec.rb +175 -0
- data/spec/lockdown/permission_spec.rb +156 -0
- data/spec/lockdown/rules_spec.rb +109 -0
- data/spec/lockdown/session_spec.rb +89 -0
- data/spec/lockdown/system_spec.rb +59 -0
- data/spec/lockdown_spec.rb +19 -0
- data/spec/rcov.opts +5 -0
- data/spec/spec.opts +3 -0
- data/spec/spec_helper.rb +1 -0
- metadata +112 -0
@@ -0,0 +1,57 @@
|
|
1
|
+
module Lockdown
|
2
|
+
module Session
|
3
|
+
|
4
|
+
protected
|
5
|
+
|
6
|
+
def add_lockdown_session_values(user = nil)
|
7
|
+
user ||= current_user
|
8
|
+
|
9
|
+
if user
|
10
|
+
session[:access_rights] = Lockdown::System.access_rights_for_user(user)
|
11
|
+
session[:current_user_id] = user.id
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def logged_in?
|
16
|
+
current_user_id.to_i > 0
|
17
|
+
end
|
18
|
+
|
19
|
+
def current_user_id
|
20
|
+
session[:current_user_id]
|
21
|
+
end
|
22
|
+
|
23
|
+
def current_user_is_admin?
|
24
|
+
session[:access_rights] == :all
|
25
|
+
end
|
26
|
+
|
27
|
+
def current_user_access_in_group?(grp)
|
28
|
+
return true if current_user_is_admin?
|
29
|
+
Lockdown::System.user_groups[grp].each do |perm|
|
30
|
+
return true if access_in_perm?(perm)
|
31
|
+
end
|
32
|
+
false
|
33
|
+
end
|
34
|
+
|
35
|
+
def access_in_perm?(perm)
|
36
|
+
if Lockdown::System.permissions[perm]
|
37
|
+
Lockdown::System.permissions[perm].each do |ar|
|
38
|
+
return true if session_access_rights_include?(ar)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
false
|
42
|
+
end
|
43
|
+
|
44
|
+
def session_access_rights_include?(str)
|
45
|
+
return false unless session[:access_rights]
|
46
|
+
session[:access_rights].include?(str)
|
47
|
+
end
|
48
|
+
|
49
|
+
def reset_lockdown_session
|
50
|
+
[:expiry_time, :current_user_id, :access_rights].each do |val|
|
51
|
+
session[val] = nil if session[val]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
alias_method :nil_lockdown_values, :reset_lockdown_session
|
56
|
+
end # Session
|
57
|
+
end # Lockdown
|
@@ -0,0 +1,57 @@
|
|
1
|
+
module Lockdown
|
2
|
+
class System
|
3
|
+
extend Lockdown::Rules
|
4
|
+
|
5
|
+
def self.configure(&block)
|
6
|
+
set_defaults
|
7
|
+
|
8
|
+
# Defined by the framework
|
9
|
+
load_controller_classes
|
10
|
+
|
11
|
+
# Lockdown::Rules defines the methods that are used inside block
|
12
|
+
instance_eval(&block)
|
13
|
+
|
14
|
+
# Lockdown::Rules defines process_rules
|
15
|
+
process_rules
|
16
|
+
|
17
|
+
Lockdown::Database.sync_with_db unless skip_sync?
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.fetch(key)
|
21
|
+
(@options||={})[key]
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.call(object, system_option)
|
25
|
+
method = fetch(system_option)
|
26
|
+
if method.is_a?(Symbol) && object.respond_to?(method)
|
27
|
+
object.send(method)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
|
33
|
+
def self.paths_for(str_sym, *methods)
|
34
|
+
str_sym = str_sym.to_s if str_sym.is_a?(Symbol)
|
35
|
+
if methods.empty?
|
36
|
+
klass = fetch_controller_class(str_sym)
|
37
|
+
methods = available_actions(klass)
|
38
|
+
end
|
39
|
+
path_str = str_sym.gsub("__","\/")
|
40
|
+
|
41
|
+
controller_actions = methods.flatten.collect{|m| m.to_s}
|
42
|
+
|
43
|
+
paths = controller_actions.collect{|meth| "#{path_str}/#{meth.to_s}" }
|
44
|
+
|
45
|
+
if controller_actions.include?("index")
|
46
|
+
paths += [path_str]
|
47
|
+
end
|
48
|
+
|
49
|
+
paths
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.fetch_controller_class(str)
|
53
|
+
controller_classes[Lockdown.controller_class_name(str)]
|
54
|
+
end
|
55
|
+
|
56
|
+
end # System class
|
57
|
+
end # Lockdown
|
@@ -0,0 +1,273 @@
|
|
1
|
+
@override_next_migration_string = false
|
2
|
+
|
3
|
+
if Rails::VERSION::MAJOR >= 2 && Rails::VERSION::MINOR >= 1
|
4
|
+
if Rails::VERSION::TINY == 0
|
5
|
+
@override_next_migration_string = true
|
6
|
+
elsif ActiveRecord::Base.timestamped_migrations
|
7
|
+
@override_next_migration_string = true
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
if @override_next_migration_string
|
12
|
+
class Rails::Generator::Commands::Base
|
13
|
+
protected
|
14
|
+
def next_migration_string(padding = 3)
|
15
|
+
sleep(1)
|
16
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class LockdownGenerator < Rails::Generator::Base
|
22
|
+
attr_accessor :file_name, :action_name, :namespace, :view_path, :controller_path
|
23
|
+
|
24
|
+
def initialize(runtime_args, runtime_options = {})
|
25
|
+
super
|
26
|
+
if Rails::VERSION::MAJOR >= 2 && Rails::VERSION::MINOR >= 1
|
27
|
+
@action_name = "action_name"
|
28
|
+
else
|
29
|
+
@action_name = "@action_name"
|
30
|
+
end
|
31
|
+
|
32
|
+
@namespace = options[:namespace] if options[:namespace]
|
33
|
+
|
34
|
+
# so if the namespace option exists it sets the correct view path and controller path
|
35
|
+
@view_path = "app/views"
|
36
|
+
@controller_path = "app/controllers"
|
37
|
+
@helper_path = "app/helpers"
|
38
|
+
@lib_path = "lib/lockdown"
|
39
|
+
|
40
|
+
@initializer = "config/environment.rb"
|
41
|
+
|
42
|
+
if @namespace
|
43
|
+
@view_path += "/#{@namespace}"
|
44
|
+
@controller_path += "/#{@namespace}"
|
45
|
+
@helper_path += "/#{@namespace}"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def manifest
|
50
|
+
record do |@m|
|
51
|
+
# Ensure appropriate folder(s) exists
|
52
|
+
@m.directory @view_path
|
53
|
+
@m.directory @controller_path
|
54
|
+
@m.directory @helper_path
|
55
|
+
@m.directory @lib_path
|
56
|
+
|
57
|
+
unless options[:skip_rules]
|
58
|
+
@m.file "lib/lockdown/README", "lib/lockdown/README"
|
59
|
+
@m.file "lib/lockdown/init.rb", "lib/lockdown/init.rb"
|
60
|
+
end
|
61
|
+
|
62
|
+
add_management if options[:add_management]
|
63
|
+
|
64
|
+
add_login if options[:add_login]
|
65
|
+
|
66
|
+
add_models
|
67
|
+
|
68
|
+
@m.file "config/initializers/lockit.rb", "config/initializers/lockit.rb"
|
69
|
+
end #record do |m|
|
70
|
+
end
|
71
|
+
|
72
|
+
protected
|
73
|
+
|
74
|
+
def add_management
|
75
|
+
@m.directory "#{@view_path}/users"
|
76
|
+
@m.directory "#{@view_path}/user_groups"
|
77
|
+
@m.directory "#{@view_path}/permissions"
|
78
|
+
|
79
|
+
write_controller("permissions")
|
80
|
+
write_controller("users")
|
81
|
+
write_controller("user_groups")
|
82
|
+
|
83
|
+
copy_views("users")
|
84
|
+
|
85
|
+
copy_views("user_groups")
|
86
|
+
|
87
|
+
@m.template "app/views/permissions/index.html.erb",
|
88
|
+
"#{@view_path}/permissions/index.html.erb"
|
89
|
+
|
90
|
+
@m.template "app/views/permissions/show.html.erb",
|
91
|
+
"#{@view_path}/permissions/show.html.erb"
|
92
|
+
|
93
|
+
add_management_routes
|
94
|
+
add_management_permissions
|
95
|
+
end
|
96
|
+
|
97
|
+
def add_login
|
98
|
+
@m.directory "app/views/sessions"
|
99
|
+
|
100
|
+
@m.template "app/controllers/sessions_controller.rb",
|
101
|
+
"app/controllers/sessions_controller.rb"
|
102
|
+
|
103
|
+
@m.template "app/views/sessions/new.html.erb",
|
104
|
+
"app/views/sessions/new.html.erb"
|
105
|
+
|
106
|
+
add_login_routes
|
107
|
+
add_login_permissions
|
108
|
+
end
|
109
|
+
|
110
|
+
def add_models
|
111
|
+
@m.directory 'app/models'
|
112
|
+
|
113
|
+
write_model("user_group")
|
114
|
+
write_model("permission")
|
115
|
+
|
116
|
+
if options[:add_lockdown_authentication]
|
117
|
+
write_model("user")
|
118
|
+
write_model("profile")
|
119
|
+
end
|
120
|
+
|
121
|
+
unless options[:skip_migrations]
|
122
|
+
write_migration("create_user_groups")
|
123
|
+
write_migration("create_permissions")
|
124
|
+
|
125
|
+
if options[:add_lockdown_authentication]
|
126
|
+
write_migration("create_profiles")
|
127
|
+
write_migration("create_users")
|
128
|
+
write_migration("create_admin_user")
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
def copy_views(vw)
|
134
|
+
@m.template "app/views/#{vw}/index.html.erb", "#{@view_path}/#{vw}/index.html.erb"
|
135
|
+
@m.template "app/views/#{vw}/show.html.erb", "#{@view_path}/#{vw}/show.html.erb"
|
136
|
+
@m.template "app/views/#{vw}/edit.html.erb", "#{@view_path}/#{vw}/edit.html.erb"
|
137
|
+
@m.template "app/views/#{vw}/new.html.erb", "#{@view_path}/#{vw}/new.html.erb"
|
138
|
+
end
|
139
|
+
|
140
|
+
def add_login_permissions
|
141
|
+
add_permissions "set_permission(:sessions_management).with_controller(:sessions)"
|
142
|
+
|
143
|
+
add_predefined_user_group "set_public_access :sessions_management"
|
144
|
+
end
|
145
|
+
|
146
|
+
def add_management_routes
|
147
|
+
if @namespace.blank?
|
148
|
+
permissions = %Q(\tmap.resources :permissions)
|
149
|
+
users = %Q(\tmap.resources :users)
|
150
|
+
user_groups = %Q(\tmap.resources :user_groups)
|
151
|
+
routes = [permissions, user_groups, users].join("\n\n")
|
152
|
+
else
|
153
|
+
routes = %Q(\tmap.namespace :#{@namespace} do |#{@namespace}|\n\t\t#{@namespace}.resources :permissions\n\t\t#{@namespace}.resources :users\n\t\t#{@namespace}.resources :user_groups\n\tend)
|
154
|
+
end
|
155
|
+
|
156
|
+
write_routes_file(routes)
|
157
|
+
end
|
158
|
+
|
159
|
+
def add_management_permissions
|
160
|
+
perms = []
|
161
|
+
perms << "set_permission(:users_management).with_controller(:#{@namespace.blank? ? "users" : "#{@namespace}__users"})"
|
162
|
+
perms << "set_permission(:user_groups_management).with_controller(:#{@namespace.blank? ? "user_groups" : "#{@namespace}__user_groups"})"
|
163
|
+
perms << "set_permission(:permissions_management).with_controller(:#{@namespace.blank? ? "permissions" : "#{@namespace}__permissions"})"
|
164
|
+
perms << "set_permission(:my_account).with_controller(:#{@namespace.blank? ? "users" : "#{@namespace}__users"}).only_methods(:edit, :update, :show)"
|
165
|
+
|
166
|
+
add_permissions perms.join("\n ")
|
167
|
+
|
168
|
+
add_predefined_user_group "set_protected_access :my_account"
|
169
|
+
end
|
170
|
+
|
171
|
+
def add_permissions(str)
|
172
|
+
sentinel = '# Define your permissions here:'
|
173
|
+
write_init_file(sentinel, str)
|
174
|
+
end
|
175
|
+
|
176
|
+
def add_predefined_user_group(str)
|
177
|
+
sentinel = '# Define the built-in user groups here:'
|
178
|
+
write_init_file(sentinel, str)
|
179
|
+
end
|
180
|
+
|
181
|
+
def add_login_routes
|
182
|
+
sessions = %Q(\tmap.resources :sessions)
|
183
|
+
home = %Q(\tmap.home '', :controller => 'sessions', :action => 'new')
|
184
|
+
login = %Q(\tmap.login '/login', :controller => 'sessions', :action => 'new')
|
185
|
+
logout = %Q(\tmap.logout '/logout', :controller => 'sessions', :action => 'destroy')
|
186
|
+
routes = [sessions, home, login, logout].join("\n\n")
|
187
|
+
|
188
|
+
write_routes_file(routes)
|
189
|
+
end
|
190
|
+
|
191
|
+
def banner
|
192
|
+
<<-EOS
|
193
|
+
Installs the lockdown framework to managing users user_groups
|
194
|
+
and viewing permissions. Also includes a login screen.
|
195
|
+
|
196
|
+
By default the entire set of stubs are installed.
|
197
|
+
|
198
|
+
Please use the appropriate options to customize your install.
|
199
|
+
|
200
|
+
USAGE: #{$0} #{spec.name}
|
201
|
+
EOS
|
202
|
+
end
|
203
|
+
|
204
|
+
def add_options!(opt)
|
205
|
+
opt.separator ''
|
206
|
+
opt.separator 'Options:'
|
207
|
+
|
208
|
+
opt.on("--namespace=admin",
|
209
|
+
"Install lockdown templates with a namespace, in this example 'admin'.") do |v|
|
210
|
+
options[:namespace] = v
|
211
|
+
end
|
212
|
+
|
213
|
+
opt.on("--add-lockdown-authentication",
|
214
|
+
"Create user model + --add-login functionality.") do |v|
|
215
|
+
options[:add_lockdown_authentication] = v
|
216
|
+
end
|
217
|
+
|
218
|
+
opt.on("--add-management",
|
219
|
+
"Create user, user_group, permission management controllers and views.") do |v|
|
220
|
+
options[:add_management] = v
|
221
|
+
end
|
222
|
+
|
223
|
+
opt.on("--add-login",
|
224
|
+
"Create session controller and views.") do |v|
|
225
|
+
options[:add_login] = v
|
226
|
+
end
|
227
|
+
|
228
|
+
opt.on("--skip-rules",
|
229
|
+
"Skip installation of lib/lockdown/init.rb lib/lockdown/session.rb") do |v|
|
230
|
+
options[:skip_rules] = v
|
231
|
+
end
|
232
|
+
|
233
|
+
opt.on("--skip-migrations",
|
234
|
+
"Skip migrations installation") do |v|
|
235
|
+
options[:skip_migrations] = v
|
236
|
+
end
|
237
|
+
end
|
238
|
+
|
239
|
+
def write_migration(str)
|
240
|
+
@m.migration_template "db/migrate/#{str}.rb", "db/migrate",
|
241
|
+
:migration_file_name => str
|
242
|
+
end
|
243
|
+
|
244
|
+
def write_model(str)
|
245
|
+
@m.file "app/models/#{str}.rb", "app/models/#{str}.rb"
|
246
|
+
end
|
247
|
+
|
248
|
+
def write_controller(str)
|
249
|
+
@m.template "app/controllers/#{str}_controller.rb",
|
250
|
+
"#{@controller_path}/#{str}_controller.rb"
|
251
|
+
write_helper(str)
|
252
|
+
end
|
253
|
+
|
254
|
+
def write_helper(str)
|
255
|
+
@m.template "app/helpers/#{str}_helper.rb",
|
256
|
+
"#{@helper_path}/#{str}_helper.rb"
|
257
|
+
end
|
258
|
+
|
259
|
+
def write_routes_file(routes)
|
260
|
+
sentinel = 'ActionController::Routing::Routes.draw do |map|'
|
261
|
+
|
262
|
+
@m.gsub_file 'config/routes.rb', /(#{Regexp.escape(sentinel)})/mi do |match|
|
263
|
+
"#{match}\n #{routes}\n"
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
def write_init_file(sentinel, str)
|
268
|
+
@m.gsub_file 'lib/lockdown/init.rb', /(#{Regexp.escape(sentinel)})/mi do |match|
|
269
|
+
"#{match}\n #{str}"
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class <%= "#{namespace.camelcase}::" unless namespace.blank? %>PermissionsController < ApplicationController
|
2
|
+
# GET /permissions
|
3
|
+
# GET /permissions.xml
|
4
|
+
def index
|
5
|
+
@permissions = Permission.find(:all)
|
6
|
+
|
7
|
+
respond_to do |format|
|
8
|
+
format.html # index.html.erb
|
9
|
+
format.xml { render :xml => @permissions }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
# GET /permissions/1
|
14
|
+
# GET /permissions/1.xml
|
15
|
+
def show
|
16
|
+
@permission = Permission.find(params[:id])
|
17
|
+
respond_to do |format|
|
18
|
+
format.html # show.html.erb
|
19
|
+
format.xml { render :xml => @permission }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class SessionsController < ApplicationController
|
2
|
+
|
3
|
+
# This controller handles the login/logout function of the site.
|
4
|
+
def new
|
5
|
+
#Stub required for Lockdown to grant access
|
6
|
+
end
|
7
|
+
|
8
|
+
def create
|
9
|
+
password_authentication(params[:login], params[:password])
|
10
|
+
end
|
11
|
+
|
12
|
+
def destroy
|
13
|
+
logger.info "resetting session in sessions controller"
|
14
|
+
reset_session
|
15
|
+
flash[:notice] = "You have been logged out."
|
16
|
+
redirect_back_or_default('/')
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
def password_authentication(login, password)
|
22
|
+
set_session_user(User.authenticate(login, password))
|
23
|
+
if logged_in?
|
24
|
+
successful_login
|
25
|
+
else
|
26
|
+
failed_login
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def failed_login(message = 'Authentication failed.')
|
31
|
+
flash[:error] = message
|
32
|
+
redirect_back_or_default login_path
|
33
|
+
end
|
34
|
+
|
35
|
+
def successful_login
|
36
|
+
flash[:notice] = "Logged in successfully"
|
37
|
+
redirect_back_or_default Lockdown::System.fetch(:successful_login_path)
|
38
|
+
end
|
39
|
+
end
|