lockdown_vail 1.6.2.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +6 -0
- data/README.txt +36 -0
- data/Rakefile +38 -0
- data/VERSION +1 -0
- data/lib/lockdown/context.rb +41 -0
- data/lib/lockdown/database.rb +41 -0
- data/lib/lockdown/errors.rb +11 -0
- data/lib/lockdown/frameworks/rails/controller.rb +187 -0
- data/lib/lockdown/frameworks/rails/view.rb +50 -0
- data/lib/lockdown/frameworks/rails.rb +114 -0
- data/lib/lockdown/helper.rb +111 -0
- data/lib/lockdown/orms/active_record.rb +68 -0
- data/lib/lockdown/permission.rb +222 -0
- data/lib/lockdown/references.rb +19 -0
- data/lib/lockdown/rspec_helper.rb +114 -0
- data/lib/lockdown/rules.rb +372 -0
- data/lib/lockdown/session.rb +66 -0
- data/lib/lockdown/system.rb +58 -0
- data/lib/lockdown.rb +87 -0
- data/lockdown.gemspec +118 -0
- data/lockdown_vail.gemspec +120 -0
- data/rails_generators/lockdown/lockdown_generator.rb +274 -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 +136 -0
- data/spec/lockdown/context_spec.rb +191 -0
- data/spec/lockdown/database_spec.rb +66 -0
- data/spec/lockdown/frameworks/rails/controller_spec.rb +240 -0
- data/spec/lockdown/frameworks/rails/view_spec.rb +87 -0
- data/spec/lockdown/frameworks/rails_spec.rb +163 -0
- data/spec/lockdown/permission_spec.rb +156 -0
- data/spec/lockdown/rspec_helper_spec.rb +41 -0
- data/spec/lockdown/rules_spec.rb +245 -0
- data/spec/lockdown/session_spec.rb +125 -0
- data/spec/lockdown/system_spec.rb +51 -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 +8 -0
- metadata +140 -0
@@ -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
|
@@ -0,0 +1,122 @@
|
|
1
|
+
class <%= "#{namespace.camelcase}::" unless namespace.blank? %>UserGroupsController < ApplicationController
|
2
|
+
before_filter :find_user_group, :only => [:show, :edit, :update, :destroy]
|
3
|
+
after_filter :update_permissions, :only => [:create, :update]
|
4
|
+
|
5
|
+
# GET /user_groups
|
6
|
+
# GET /user_groups.xml
|
7
|
+
def index
|
8
|
+
@user_groups = UserGroup.find(:all)
|
9
|
+
|
10
|
+
respond_to do |format|
|
11
|
+
format.html # index.html.erb
|
12
|
+
format.xml { render :xml => @user_groups }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# GET /user_groups/1
|
17
|
+
# GET /user_groups/1.xml
|
18
|
+
def show
|
19
|
+
@all_permissions = Lockdown::System.permissions_assignable_for_user(current_user)
|
20
|
+
respond_to do |format|
|
21
|
+
format.html # show.html.erb
|
22
|
+
format.xml { render :xml => @user_group }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
# GET /user_groups/new
|
27
|
+
# GET /user_groups/new.xml
|
28
|
+
def new
|
29
|
+
@user_group = UserGroup.new
|
30
|
+
@all_permissions = Lockdown::System.permissions_assignable_for_user(current_user)
|
31
|
+
|
32
|
+
respond_to do |format|
|
33
|
+
format.html # new.html.erb
|
34
|
+
format.xml { render :xml => @user_group }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# GET /user_groups/1/edit
|
39
|
+
def edit
|
40
|
+
@all_permissions = Lockdown::System.permissions_assignable_for_user(current_user)
|
41
|
+
end
|
42
|
+
|
43
|
+
# POST /user_groups
|
44
|
+
# POST /user_groups.xml
|
45
|
+
def create
|
46
|
+
@user_group = UserGroup.new(params[:user_group])
|
47
|
+
|
48
|
+
respond_to do |format|
|
49
|
+
if @user_group.save
|
50
|
+
flash[:notice] = 'UserGroup was successfully created.'
|
51
|
+
<% if namespace %>
|
52
|
+
format.html { redirect_to(<%= namespace %>_user_group_path(@user_group)) }
|
53
|
+
<% else %>
|
54
|
+
format.html { redirect_to(user_group_path(@user_group)) }
|
55
|
+
<% end %>
|
56
|
+
format.xml { render :xml => @user_group, :status => :created, :location => @user_group }
|
57
|
+
else
|
58
|
+
@all_permissions = Lockdown::System.permissions_assignable_for_user(current_user)
|
59
|
+
format.html { render :action => "new" }
|
60
|
+
format.xml { render :xml => @user_group.errors, :status => :unprocessable_entity }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# PUT /user_groups/1
|
66
|
+
# PUT /user_groups/1.xml
|
67
|
+
def update
|
68
|
+
respond_to do |format|
|
69
|
+
if @user_group.update_attributes(params[:user_group])
|
70
|
+
flash[:notice] = 'UserGroup was successfully updated.'
|
71
|
+
<% if namespace %>
|
72
|
+
format.html { redirect_to(<%= namespace %>_user_group_path(@user_group)) }
|
73
|
+
<% else %>
|
74
|
+
format.html { redirect_to(user_group_path(@user_group)) }
|
75
|
+
<% end %>
|
76
|
+
format.xml { head :ok }
|
77
|
+
else
|
78
|
+
@all_permissions = Lockdown::System.permissions_assignable_for_user(current_user)
|
79
|
+
format.html { render :action => "edit" }
|
80
|
+
format.xml { render :xml => @user_group.errors, :status => :unprocessable_entity }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# DELETE /user_groups/1
|
86
|
+
# DELETE /user_groups/1.xml
|
87
|
+
def destroy
|
88
|
+
@user_group.destroy
|
89
|
+
|
90
|
+
respond_to do |format|
|
91
|
+
format.html { redirect_to(<%= namespace.blank? ? 'user_groups_path' : "#{namespace}_user_groups_path" %>) }
|
92
|
+
format.xml { head :ok }
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
private
|
97
|
+
|
98
|
+
def find_user_group
|
99
|
+
@user_group = UserGroup.find(params[:id])
|
100
|
+
if <%= action_name %> != "show" && Lockdown::System.has_user_group?(@user_group)
|
101
|
+
raise SecurityError,"Invalid attempt to modify user group."
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def update_permissions
|
106
|
+
new_perm_ids = params.collect{|p| p[0].split("_")[1].to_i if p[0] =~ /^perm_/}.compact
|
107
|
+
#
|
108
|
+
# Removed previously associated permissions if not checked this time.
|
109
|
+
#
|
110
|
+
@user_group.permissions.dup.each do |p|
|
111
|
+
@user_group.permissions.delete(p) unless new_perm_ids.include?(p.id)
|
112
|
+
end
|
113
|
+
|
114
|
+
#
|
115
|
+
# Add in the new permissions
|
116
|
+
#
|
117
|
+
new_perm_ids.each do |id|
|
118
|
+
next if @user_group.permission_ids.include?(id)
|
119
|
+
@user_group.permissions << Permission.find(id)
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
class <%= "#{namespace.camelcase}::" unless namespace.blank? %>UsersController < ApplicationController
|
2
|
+
before_filter :find_user, :only => [:show, :edit, :update, :destroy]
|
3
|
+
after_filter :update_user_groups, :only => [:create, :update]
|
4
|
+
# GET /users
|
5
|
+
# GET /users.xml
|
6
|
+
def index
|
7
|
+
@users = User.find :all, :include => [:profile, :user_groups]
|
8
|
+
respond_to do |format|
|
9
|
+
format.html # index.html.erb
|
10
|
+
format.xml { render :xml => @users }
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
# GET /users/1
|
15
|
+
# GET /users/1.xml
|
16
|
+
def show
|
17
|
+
@user_groups_for_user = Lockdown::System.user_groups_assignable_for_user(current_user)
|
18
|
+
respond_to do |format|
|
19
|
+
format.html # show.html.erb
|
20
|
+
format.xml { render :xml => @user }
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# GET /users/new
|
25
|
+
# GET /users/new.xml
|
26
|
+
def new
|
27
|
+
@user = User.new
|
28
|
+
@user_groups_for_user = Lockdown::System.user_groups_assignable_for_user(current_user)
|
29
|
+
respond_to do |format|
|
30
|
+
format.html # new.html.erb
|
31
|
+
format.xml { render :xml => @user }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# GET /users/1/edit
|
36
|
+
def edit
|
37
|
+
@user_groups_for_user = Lockdown::System.user_groups_assignable_for_user(current_user)
|
38
|
+
end
|
39
|
+
|
40
|
+
# POST /users
|
41
|
+
# POST /users.xml
|
42
|
+
def create
|
43
|
+
@user = User.new(params[:user])
|
44
|
+
|
45
|
+
if @user.save
|
46
|
+
flash[:notice] = "Thanks for signing up!"
|
47
|
+
redirect_to(<%= namespace.blank? ? 'user_path(@user)' : "#{namespace}_user_path(@user)" %>)
|
48
|
+
else
|
49
|
+
@user_groups_for_user = Lockdown::System.user_groups_assignable_for_user(current_user)
|
50
|
+
flash[:error] = "Please correct the following issues"
|
51
|
+
render :action => "new"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
# PUT /users/1
|
56
|
+
# PUT /users/1.xml
|
57
|
+
def update
|
58
|
+
@user.attributes = params[:user]
|
59
|
+
|
60
|
+
respond_to do |format|
|
61
|
+
if @user.save
|
62
|
+
flash[:notice] = 'User was successfully updated.'
|
63
|
+
format.html { redirect_to(<%= namespace.blank? ? 'user_path(@user)' : "#{namespace}_user_path(@user)"%>) }
|
64
|
+
format.xml { head :ok }
|
65
|
+
else
|
66
|
+
@user_groups_for_user = Lockdown::System.user_groups_assignable_for_user(current_user)
|
67
|
+
format.html { render :action => "edit" }
|
68
|
+
format.xml { render :xml => @user.errors, :status => :unprocessable_entity }
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# DELETE /users/1
|
74
|
+
# DELETE /users/1.xml
|
75
|
+
def destroy
|
76
|
+
@user.destroy
|
77
|
+
|
78
|
+
respond_to do |format|
|
79
|
+
format.html { redirect_to(<%= namespace.blank? ? 'users_path' : "#{namespace}_users_path" %>) }
|
80
|
+
format.xml { head :ok }
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def change_password
|
85
|
+
render :update do |page|
|
86
|
+
page.replace_html 'password', :partial => 'password'
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def find_user
|
93
|
+
# Skip test if current user is an administrator
|
94
|
+
unless current_user_is_admin?
|
95
|
+
# Raise error if id not = current logged in user
|
96
|
+
raise SecurityError.new if (current_user_id != params[:id].to_i)
|
97
|
+
end
|
98
|
+
@user = User.find(params[:id])
|
99
|
+
raise SecurityError.new if @user.nil?
|
100
|
+
end
|
101
|
+
|
102
|
+
def update_user_groups
|
103
|
+
new_ug_ids = params.collect{|p| p[0].split("_")[1].to_i if p[0] =~ /^ug_/}.compact
|
104
|
+
# Removed previously associated user_groups if not checked this time.
|
105
|
+
#
|
106
|
+
@user.user_groups.dup.each do |g|
|
107
|
+
@user.user_groups.delete(g) unless new_ug_ids.include?(g.id)
|
108
|
+
end
|
109
|
+
|
110
|
+
# Add in the new permissions
|
111
|
+
#
|
112
|
+
new_ug_ids.each do |id|
|
113
|
+
next if @user.user_group_ids.include?(id)
|
114
|
+
@user.user_groups << UserGroup.find(id)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
class Permission < ActiveRecord::Base
|
2
|
+
has_and_belongs_to_many :user_groups
|
3
|
+
|
4
|
+
def all_users
|
5
|
+
User.find_by_sql <<-SQL
|
6
|
+
select users.*
|
7
|
+
from users, user_groups_users, permissions_user_groups
|
8
|
+
where users.id = user_groups_users.user_id
|
9
|
+
and user_groups_users.user_group_id = permissions_user_groups.user_group_id
|
10
|
+
and permissions_user_groups.permission_id = #{self.id}
|
11
|
+
SQL
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class Profile < ActiveRecord::Base
|
2
|
+
SYSTEM = 1
|
3
|
+
|
4
|
+
validates_presence_of :email, :first_name, :last_name
|
5
|
+
|
6
|
+
validates_length_of :email, :within => 5..100
|
7
|
+
validates_format_of :email, :with => /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
|
8
|
+
|
9
|
+
validates_uniqueness_of :email, :case_sensitive => false
|
10
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
class User < ActiveRecord::Base
|
3
|
+
has_and_belongs_to_many :user_groups
|
4
|
+
belongs_to :profile
|
5
|
+
|
6
|
+
# Virtual attributes
|
7
|
+
attr_accessor :password
|
8
|
+
|
9
|
+
validates_presence_of :login
|
10
|
+
validates_presence_of :password, :if => :password_required?
|
11
|
+
validates_presence_of :password_confirmation, :if => :password_required?
|
12
|
+
validates_length_of :password, :within => 4..40, :if => :password_required?
|
13
|
+
validates_confirmation_of :password, :if => :password_required?
|
14
|
+
validates_length_of :login, :within => 3..40
|
15
|
+
validates_uniqueness_of :login, :case_sensitive => false
|
16
|
+
|
17
|
+
before_save :encrypt_password
|
18
|
+
before_save :save_profile
|
19
|
+
|
20
|
+
attr_accessible :login, :password, :password_confirmation,
|
21
|
+
:first_name, :last_name, :email
|
22
|
+
|
23
|
+
# Authenticates a user by their login name and unencrypted password.
|
24
|
+
# Returns the user or nil.
|
25
|
+
def self.authenticate(login, password)
|
26
|
+
u = find :first, :conditions => ['login = ?', login] # need to get the salt
|
27
|
+
u && u.authenticated?(password) ? u : nil
|
28
|
+
end
|
29
|
+
|
30
|
+
# Encrypts some data with the salt.
|
31
|
+
def self.encrypt(password, salt)
|
32
|
+
Digest::SHA1.hexdigest("--#{salt}--#{password}--")
|
33
|
+
end
|
34
|
+
|
35
|
+
# Encrypts the password with the user salt
|
36
|
+
def encrypt(password)
|
37
|
+
self.class.encrypt(password, salt)
|
38
|
+
end
|
39
|
+
|
40
|
+
def authenticated?(password)
|
41
|
+
crypted_password == encrypt(password)
|
42
|
+
end
|
43
|
+
|
44
|
+
def full_name
|
45
|
+
first_name + " " + last_name
|
46
|
+
end
|
47
|
+
|
48
|
+
# Profile information
|
49
|
+
def first_name
|
50
|
+
user_profile.first_name
|
51
|
+
end
|
52
|
+
|
53
|
+
def first_name=(string)
|
54
|
+
user_profile.first_name = string
|
55
|
+
end
|
56
|
+
|
57
|
+
def last_name
|
58
|
+
user_profile.last_name
|
59
|
+
end
|
60
|
+
|
61
|
+
def last_name=(string)
|
62
|
+
user_profile.last_name = string
|
63
|
+
end
|
64
|
+
|
65
|
+
def email
|
66
|
+
user_profile.email
|
67
|
+
end
|
68
|
+
|
69
|
+
def email=(string)
|
70
|
+
user_profile.email = string
|
71
|
+
end
|
72
|
+
|
73
|
+
def user_profile
|
74
|
+
self.profile || self.profile = Profile.new
|
75
|
+
end
|
76
|
+
|
77
|
+
protected
|
78
|
+
|
79
|
+
def encrypt_password
|
80
|
+
return if password.blank?
|
81
|
+
if new_record?
|
82
|
+
self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--")
|
83
|
+
end
|
84
|
+
self.crypted_password = encrypt(password)
|
85
|
+
end
|
86
|
+
|
87
|
+
def save_profile
|
88
|
+
profile.save
|
89
|
+
end
|
90
|
+
|
91
|
+
def password_required?
|
92
|
+
(crypted_password.blank? || !password.blank?)
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
class UserGroup < ActiveRecord::Base
|
2
|
+
has_and_belongs_to_many :permissions
|
3
|
+
has_and_belongs_to_many :users
|
4
|
+
|
5
|
+
validates_presence_of :name
|
6
|
+
|
7
|
+
def all_users
|
8
|
+
User.find_by_sql <<-SQL
|
9
|
+
select users.*
|
10
|
+
from users, user_groups_users
|
11
|
+
where users.id = user_groups_users.user_id
|
12
|
+
and user_groups_users.user_group_id = #{self.id}
|
13
|
+
SQL
|
14
|
+
end
|
15
|
+
end
|