ccls-simply_authorized 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.rdoc +53 -0
- data/app/models/role.rb +34 -0
- data/generators/ccls_simply_authorized/USAGE +0 -0
- data/generators/ccls_simply_authorized/ccls_simply_authorized_generator.rb +98 -0
- data/generators/ccls_simply_authorized/templates/autotest_simply_authorized.rb +3 -0
- data/generators/ccls_simply_authorized/templates/controllers/roles_controller.rb +38 -0
- data/generators/ccls_simply_authorized/templates/fixtures/roles.yml +36 -0
- data/generators/ccls_simply_authorized/templates/functional/roles_controller_test.rb +142 -0
- data/generators/ccls_simply_authorized/templates/migrations/create_roles.rb +14 -0
- data/generators/ccls_simply_authorized/templates/migrations/create_roles_users.rb +14 -0
- data/generators/ccls_simply_authorized/templates/simply_authorized.rake +6 -0
- data/generators/ccls_simply_authorized/templates/stylesheets/authorized.css +0 -0
- data/generators/ccls_simply_authorized/templates/unit/role_test.rb +30 -0
- data/lib/ccls-simply_authorized.rb +1 -0
- data/lib/simply_authorized.rb +42 -0
- data/lib/simply_authorized/authorization.rb +68 -0
- data/lib/simply_authorized/autotest.rb +33 -0
- data/lib/simply_authorized/controller.rb +87 -0
- data/lib/simply_authorized/core_extension.rb +16 -0
- data/lib/simply_authorized/factories.rb +15 -0
- data/lib/simply_authorized/factory_test_helper.rb +47 -0
- data/lib/simply_authorized/helper.rb +28 -0
- data/lib/simply_authorized/permissive_controller.rb +27 -0
- data/lib/simply_authorized/resourceful_controller.rb +83 -0
- data/lib/simply_authorized/tasks.rb +1 -0
- data/lib/simply_authorized/test_tasks.rb +47 -0
- data/lib/simply_authorized/user_model.rb +166 -0
- data/lib/tasks/application.rake +40 -0
- data/lib/tasks/common_lib.rake +7 -0
- data/lib/tasks/database.rake +52 -0
- data/lib/tasks/documentation.rake +68 -0
- data/lib/tasks/rcov.rake +44 -0
- data/rails/init.rb +4 -0
- data/test/unit/authorized/role_test.rb +30 -0
- metadata +141 -0
data/README.rdoc
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
= SimplyAuthorized
|
2
|
+
|
3
|
+
This is a rails app built around a ruby gem for testing.
|
4
|
+
|
5
|
+
== ToDo
|
6
|
+
|
7
|
+
* merge authorized/controller.rb into authorized/permissive_controller.rb
|
8
|
+
* perhaps include authorized/resourceful_controller.rb as well
|
9
|
+
* remove hard coded :users from Role model
|
10
|
+
* build a full development testing app
|
11
|
+
* Too many quirks to keep controllers and views in gem so install them in app with generator.
|
12
|
+
|
13
|
+
== Required Gem Sources
|
14
|
+
|
15
|
+
== Required Gems
|
16
|
+
|
17
|
+
== Other Required
|
18
|
+
|
19
|
+
* current_user method
|
20
|
+
|
21
|
+
== Installation (as a plugin/engine)
|
22
|
+
|
23
|
+
config.gem "ccls-simply_authorized",
|
24
|
+
:source => 'http://rubygems.org'
|
25
|
+
|
26
|
+
class User
|
27
|
+
simply_authorized
|
28
|
+
end
|
29
|
+
|
30
|
+
script/generate simply_authorized
|
31
|
+
|
32
|
+
== Testing (as an app)
|
33
|
+
|
34
|
+
rake db:migrate
|
35
|
+
rake db:fixtures:load
|
36
|
+
rake test
|
37
|
+
script/server
|
38
|
+
|
39
|
+
== Gemified with Jeweler
|
40
|
+
|
41
|
+
vi Rakefile
|
42
|
+
rake version:write
|
43
|
+
|
44
|
+
rake version:bump:patch
|
45
|
+
rake version:bump:minor
|
46
|
+
rake version:bump:major
|
47
|
+
|
48
|
+
rake gemspec
|
49
|
+
|
50
|
+
rake install
|
51
|
+
rake release
|
52
|
+
|
53
|
+
Copyright (c) 2010 [Jake Wendt], released under the MIT license
|
data/app/models/role.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# #82 new
|
2
|
+
# Roles and Users
|
3
|
+
#
|
4
|
+
# Reported by Magee | August 9th, 2010 @ 02:11 PM
|
5
|
+
#
|
6
|
+
# Currently we should have four roles (three in
|
7
|
+
# the system right now). They are effectively as follows:
|
8
|
+
#
|
9
|
+
# 1. Reader -- users with login accounts who can
|
10
|
+
# view contents of sections but not edit anything.
|
11
|
+
# 2. Editor -- users with the ability to add or edit
|
12
|
+
# content to the system. These are the users for
|
13
|
+
# whom an "edit" button displays on content details
|
14
|
+
# pages allowing them to make changes
|
15
|
+
# (or an "add" button as appropriate)
|
16
|
+
# 3. Administrator -- users who have administrative
|
17
|
+
# rights to the system to add users, etc.
|
18
|
+
# 4. Superuser -- Magee and Jake
|
19
|
+
#
|
20
|
+
# There may not be any system behaviors defined for
|
21
|
+
# Superusers. They may strictly be Conceptual Roles
|
22
|
+
# to describe users who may make backend or other
|
23
|
+
# changes outside of the scope of normal system
|
24
|
+
# operations. If necessary, a system role may be
|
25
|
+
# added in the future to address functions only
|
26
|
+
# for that group.
|
27
|
+
#
|
28
|
+
class Role < ActiveRecord::Base
|
29
|
+
acts_as_list
|
30
|
+
default_scope :order => :position
|
31
|
+
has_and_belongs_to_many :users, :uniq => true
|
32
|
+
validates_presence_of :name
|
33
|
+
validates_uniqueness_of :name
|
34
|
+
end
|
File without changes
|
@@ -0,0 +1,98 @@
|
|
1
|
+
class CclsSimplyAuthorizedGenerator < Rails::Generator::Base
|
2
|
+
|
3
|
+
def manifest
|
4
|
+
# See Rails::Generator::Commands::Create
|
5
|
+
# rails-2.3.10/lib/rails_generator/commands.rb
|
6
|
+
# for code methods for record (Manifest)
|
7
|
+
record do |m|
|
8
|
+
|
9
|
+
# The autotest file will require that the app actually
|
10
|
+
# looks for autotest files.
|
11
|
+
m.directory('config/autotest')
|
12
|
+
m.file('autotest_simply_authorized.rb', 'config/autotest/simply_authorized.rb')
|
13
|
+
|
14
|
+
# *.rake files in the lib/tasks/ directory are automatically
|
15
|
+
# loaded so nothing is required to include this.
|
16
|
+
m.directory('lib/tasks')
|
17
|
+
m.file('simply_authorized.rake', 'lib/tasks/simply_authorized.rake')
|
18
|
+
|
19
|
+
%w( create_roles create_roles_users ).each do |migration|
|
20
|
+
m.migration_template "migrations/#{migration}.rb",
|
21
|
+
'db/migrate', :migration_file_name => migration
|
22
|
+
end
|
23
|
+
dot = File.dirname(__FILE__)
|
24
|
+
m.directory('public/javascripts')
|
25
|
+
Dir["#{dot}/templates/javascripts/*js"].each{|file|
|
26
|
+
f = file.split('/').slice(-2,2).join('/')
|
27
|
+
m.file(f, "public/javascripts/#{File.basename(file)}")
|
28
|
+
}
|
29
|
+
m.directory('public/stylesheets')
|
30
|
+
Dir["#{dot}/templates/stylesheets/*css"].each{|file|
|
31
|
+
f = file.split('/').slice(-2,2).join('/')
|
32
|
+
m.file(f, "public/stylesheets/#{File.basename(file)}")
|
33
|
+
}
|
34
|
+
|
35
|
+
# Dir["#{dot}/templates/app/views/*/**/"].each do |dir|
|
36
|
+
# last_dir = dir.split('/').last
|
37
|
+
# m.directory("app/views/#{last_dir}")
|
38
|
+
# Dir["#{dot}/templates/views/#{last_dir}/*rb"].each do |file|
|
39
|
+
# f = file.split('/').slice(-3,3).join('/')
|
40
|
+
# m.file(f, "app/views/#{last_dir}/#{File.basename(file)}")
|
41
|
+
# end
|
42
|
+
# end
|
43
|
+
|
44
|
+
m.directory('app/controllers')
|
45
|
+
Dir["#{dot}/templates/controllers/*rb"].each{|file|
|
46
|
+
f = file.split('/').slice(-2,2).join('/')
|
47
|
+
m.file(f, "app/controllers/#{File.basename(file)}")
|
48
|
+
}
|
49
|
+
m.directory('test/functional/simply_authorized')
|
50
|
+
Dir["#{dot}/templates/functional/*rb"].each{|file|
|
51
|
+
f = file.split('/').slice(-2,2).join('/')
|
52
|
+
m.file(f, "test/functional/simply_authorized/#{File.basename(file)}")
|
53
|
+
}
|
54
|
+
|
55
|
+
m.directory('test/fixtures')
|
56
|
+
Dir["#{dot}/templates/fixtures/*yml"].each{|file|
|
57
|
+
f = file.split('/').slice(-2,2).join('/')
|
58
|
+
m.file(f, "test/fixtures/#{File.basename(file)}")
|
59
|
+
}
|
60
|
+
|
61
|
+
# m.directory('test/unit/authorized')
|
62
|
+
# Dir["#{dot}/templates/unit/*rb"].each{|file|
|
63
|
+
# f = file.split('/').slice(-2,2).join('/')
|
64
|
+
# m.file(f, "test/unit/authorized/#{File.basename(file)}")
|
65
|
+
# }
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
module Rails::Generator::Commands
|
71
|
+
class Create
|
72
|
+
def migration_template(relative_source,
|
73
|
+
relative_destination, template_options = {})
|
74
|
+
migration_directory relative_destination
|
75
|
+
migration_file_name = template_options[
|
76
|
+
:migration_file_name] || file_name
|
77
|
+
if migration_exists?(migration_file_name)
|
78
|
+
puts "Another migration is already named #{migration_file_name}: #{existing_migrations(migration_file_name).first}: Skipping"
|
79
|
+
else
|
80
|
+
template(relative_source, "#{relative_destination}/#{next_migration_string}_#{migration_file_name}.rb", template_options)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end # Create
|
84
|
+
class Base
|
85
|
+
protected
|
86
|
+
# the loop through migrations happens so fast
|
87
|
+
# that they all have the same timestamp which
|
88
|
+
# won't work when you actually try to migrate.
|
89
|
+
# All the timestamps MUST be unique.
|
90
|
+
def next_migration_string(padding = 3)
|
91
|
+
@s = (!@s.nil?)? @s.to_i + 1 : if ActiveRecord::Base.timestamped_migrations
|
92
|
+
Time.now.utc.strftime("%Y%m%d%H%M%S")
|
93
|
+
else
|
94
|
+
"%.#{padding}d" % next_migration_number
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end # Base
|
98
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
class RolesController < ApplicationController
|
2
|
+
|
3
|
+
before_filter :may_assign_roles_required
|
4
|
+
before_filter :user_id_required
|
5
|
+
before_filter :may_not_be_user_required
|
6
|
+
before_filter :id_required
|
7
|
+
|
8
|
+
def update
|
9
|
+
@user.roles << @role
|
10
|
+
flash[:notice] = 'User was successfully updated.'
|
11
|
+
redirect_to @user
|
12
|
+
end
|
13
|
+
|
14
|
+
def destroy
|
15
|
+
@user.roles.delete @role
|
16
|
+
flash[:notice] = 'User was successfully updated.'
|
17
|
+
redirect_to @user
|
18
|
+
end
|
19
|
+
|
20
|
+
protected
|
21
|
+
|
22
|
+
def user_id_required
|
23
|
+
if !params[:user_id].blank? and User.exists?(params[:user_id])
|
24
|
+
@user = User.find(params[:user_id])
|
25
|
+
else
|
26
|
+
access_denied("user id required!", users_path)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def id_required
|
31
|
+
if !params[:id].blank? and Role.exists?(:name => params[:id])
|
32
|
+
@role = Role.find_by_name(params[:id])
|
33
|
+
else
|
34
|
+
access_denied("id required!", @user)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
#
|
2
|
+
# Do not change id, key or code
|
3
|
+
# 'id' could be referenced by existing data
|
4
|
+
# 'key' or 'code' is used in the rails code for searching
|
5
|
+
#
|
6
|
+
# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
|
7
|
+
|
8
|
+
superuser:
|
9
|
+
id: 1
|
10
|
+
position: 1
|
11
|
+
name: superuser
|
12
|
+
|
13
|
+
admin:
|
14
|
+
id: 2
|
15
|
+
position: 2
|
16
|
+
name: administrator
|
17
|
+
|
18
|
+
editor:
|
19
|
+
id: 3
|
20
|
+
position: 3
|
21
|
+
name: editor
|
22
|
+
|
23
|
+
reader:
|
24
|
+
id: 4
|
25
|
+
position: 5
|
26
|
+
name: reader
|
27
|
+
|
28
|
+
# The IDs MUST REMAIN AS THEY ARE or it could inadvertantly
|
29
|
+
# give an existing user more (or less) power as the join
|
30
|
+
# tables already exist.
|
31
|
+
|
32
|
+
interviewer:
|
33
|
+
id: 5
|
34
|
+
position: 4
|
35
|
+
name: interviewer
|
36
|
+
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class SimplyAuthorized::RolesControllerTest < ActionController::TestCase
|
4
|
+
tests RolesController
|
5
|
+
|
6
|
+
# no user_id
|
7
|
+
assert_no_route(:put, :update, :id => 'reader')
|
8
|
+
assert_no_route(:delete, :destroy, :id => 'reader')
|
9
|
+
|
10
|
+
%w( super_user admin ).each do |cu|
|
11
|
+
|
12
|
+
test "should update with #{cu} login" do
|
13
|
+
login_as send(cu)
|
14
|
+
u = active_user
|
15
|
+
assert !u.reload.role_names.include?('reader')
|
16
|
+
assert_difference("User.find(#{u.id}).roles.length",1){
|
17
|
+
put :update, :user_id => u.id, :id => 'reader'
|
18
|
+
}
|
19
|
+
assert u.reload.role_names.include?('reader')
|
20
|
+
assert_not_nil flash[:notice]
|
21
|
+
assert_redirected_to user_path(assigns(:user))
|
22
|
+
end
|
23
|
+
|
24
|
+
test "should destroy with #{cu} login" do
|
25
|
+
login_as send(cu)
|
26
|
+
u = active_user
|
27
|
+
u.roles << Role.find_or_create_by_name('reader')
|
28
|
+
assert u.reload.role_names.include?('reader')
|
29
|
+
assert_difference("User.find(#{u.id}).roles.length",-1){
|
30
|
+
delete :destroy, :user_id => u.id, :id => 'reader'
|
31
|
+
}
|
32
|
+
assert !u.reload.role_names.include?('reader')
|
33
|
+
assert_not_nil flash[:notice]
|
34
|
+
assert_redirected_to user_path(assigns(:user))
|
35
|
+
end
|
36
|
+
|
37
|
+
test "should NOT update without valid user_id with #{cu} login" do
|
38
|
+
login_as send(cu)
|
39
|
+
put :update, :user_id => 0, :id => 'reader'
|
40
|
+
assert_not_nil flash[:error]
|
41
|
+
assert_redirected_to users_path
|
42
|
+
end
|
43
|
+
|
44
|
+
test "should NOT destroy without valid user_id with #{cu} login" do
|
45
|
+
login_as send(cu)
|
46
|
+
delete :destroy, :user_id => 0, :id => 'reader'
|
47
|
+
assert_not_nil flash[:error]
|
48
|
+
assert_redirected_to users_path
|
49
|
+
end
|
50
|
+
|
51
|
+
test "should NOT update self with #{cu} login" do
|
52
|
+
u = send(cu)
|
53
|
+
login_as u
|
54
|
+
assert_difference("User.find(#{u.id}).roles.length",0){
|
55
|
+
put :update, :user_id => u.id, :id => 'reader'
|
56
|
+
}
|
57
|
+
assert_not_nil flash[:error]
|
58
|
+
assert_equal u, assigns(:user)
|
59
|
+
assert_redirected_to user_path(assigns(:user))
|
60
|
+
# assert_redirected_to root_path
|
61
|
+
end
|
62
|
+
|
63
|
+
test "should NOT destroy self with #{cu} login" do
|
64
|
+
u = send(cu)
|
65
|
+
login_as u
|
66
|
+
assert_difference("User.find(#{u.id}).roles.length",0){
|
67
|
+
delete :destroy, :user_id => u.id, :id => 'reader'
|
68
|
+
}
|
69
|
+
assert_not_nil flash[:error]
|
70
|
+
assert_equal u, assigns(:user)
|
71
|
+
assert_redirected_to user_path(assigns(:user))
|
72
|
+
# assert_redirected_to root_path
|
73
|
+
end
|
74
|
+
|
75
|
+
test "should NOT update without valid role_name with #{cu} login" do
|
76
|
+
login_as send(cu)
|
77
|
+
u = active_user
|
78
|
+
assert_difference("User.find(#{u.id}).roles.length",0){
|
79
|
+
put :update, :user_id => u.id, :id => 'bogus_role_name'
|
80
|
+
}
|
81
|
+
assert_not_nil flash[:error]
|
82
|
+
assert_redirected_to user_path(assigns(:user))
|
83
|
+
end
|
84
|
+
|
85
|
+
test "should NOT destroy without valid role_name with #{cu} login" do
|
86
|
+
login_as send(cu)
|
87
|
+
u = active_user
|
88
|
+
assert_difference("User.find(#{u.id}).roles.length",0){
|
89
|
+
delete :destroy, :user_id => u.id, :id => 'bogus_role_name'
|
90
|
+
}
|
91
|
+
assert_not_nil flash[:error]
|
92
|
+
assert_redirected_to user_path(assigns(:user))
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
%w( interviewer reader editor active_user ).each do |cu|
|
98
|
+
|
99
|
+
test "should NOT update with #{cu} login" do
|
100
|
+
login_as send(cu)
|
101
|
+
u = active_user
|
102
|
+
assert !u.reload.role_names.include?('administrator')
|
103
|
+
assert_difference("User.find(#{u.id}).roles.length",0){
|
104
|
+
put :update, :user_id => u.id, :id => 'administrator'
|
105
|
+
}
|
106
|
+
assert !u.reload.role_names.include?('administrator')
|
107
|
+
assert_not_nil flash[:error]
|
108
|
+
assert_redirected_to root_path
|
109
|
+
end
|
110
|
+
|
111
|
+
test "should NOT destroy with #{cu} login" do
|
112
|
+
login_as send(cu)
|
113
|
+
u = active_user
|
114
|
+
u.roles << Role.find_or_create_by_name('administrator')
|
115
|
+
assert u.reload.role_names.include?('administrator')
|
116
|
+
assert_difference("User.find(#{u.id}).roles.length",0){
|
117
|
+
delete :destroy, :user_id => u.id, :id => 'administrator'
|
118
|
+
}
|
119
|
+
assert u.reload.role_names.include?('administrator')
|
120
|
+
assert_not_nil flash[:error]
|
121
|
+
assert_redirected_to root_path
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
test "should NOT update without login" do
|
127
|
+
u = active_user
|
128
|
+
assert_difference("User.find(#{u.id}).roles.length",0){
|
129
|
+
put :update, :user_id => u.id, :id => 'administrator'
|
130
|
+
}
|
131
|
+
assert_redirected_to_login
|
132
|
+
end
|
133
|
+
|
134
|
+
test "should NOT destroy without login" do
|
135
|
+
u = active_user
|
136
|
+
assert_difference("User.find(#{u.id}).roles.length",0){
|
137
|
+
delete :destroy, :user_id => u.id, :id => 'administrator'
|
138
|
+
}
|
139
|
+
assert_redirected_to_login
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
class CreateRolesUsers < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :roles_users, :id => false do |t|
|
4
|
+
t.references :role
|
5
|
+
t.references :user
|
6
|
+
end
|
7
|
+
add_index :roles_users, :role_id
|
8
|
+
add_index :roles_users, :user_id
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.down
|
12
|
+
drop_table :roles_users
|
13
|
+
end
|
14
|
+
end
|