ccls-simply_authorized 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (35) hide show
  1. data/README.rdoc +53 -0
  2. data/app/models/role.rb +34 -0
  3. data/generators/ccls_simply_authorized/USAGE +0 -0
  4. data/generators/ccls_simply_authorized/ccls_simply_authorized_generator.rb +98 -0
  5. data/generators/ccls_simply_authorized/templates/autotest_simply_authorized.rb +3 -0
  6. data/generators/ccls_simply_authorized/templates/controllers/roles_controller.rb +38 -0
  7. data/generators/ccls_simply_authorized/templates/fixtures/roles.yml +36 -0
  8. data/generators/ccls_simply_authorized/templates/functional/roles_controller_test.rb +142 -0
  9. data/generators/ccls_simply_authorized/templates/migrations/create_roles.rb +14 -0
  10. data/generators/ccls_simply_authorized/templates/migrations/create_roles_users.rb +14 -0
  11. data/generators/ccls_simply_authorized/templates/simply_authorized.rake +6 -0
  12. data/generators/ccls_simply_authorized/templates/stylesheets/authorized.css +0 -0
  13. data/generators/ccls_simply_authorized/templates/unit/role_test.rb +30 -0
  14. data/lib/ccls-simply_authorized.rb +1 -0
  15. data/lib/simply_authorized.rb +42 -0
  16. data/lib/simply_authorized/authorization.rb +68 -0
  17. data/lib/simply_authorized/autotest.rb +33 -0
  18. data/lib/simply_authorized/controller.rb +87 -0
  19. data/lib/simply_authorized/core_extension.rb +16 -0
  20. data/lib/simply_authorized/factories.rb +15 -0
  21. data/lib/simply_authorized/factory_test_helper.rb +47 -0
  22. data/lib/simply_authorized/helper.rb +28 -0
  23. data/lib/simply_authorized/permissive_controller.rb +27 -0
  24. data/lib/simply_authorized/resourceful_controller.rb +83 -0
  25. data/lib/simply_authorized/tasks.rb +1 -0
  26. data/lib/simply_authorized/test_tasks.rb +47 -0
  27. data/lib/simply_authorized/user_model.rb +166 -0
  28. data/lib/tasks/application.rake +40 -0
  29. data/lib/tasks/common_lib.rake +7 -0
  30. data/lib/tasks/database.rake +52 -0
  31. data/lib/tasks/documentation.rake +68 -0
  32. data/lib/tasks/rcov.rake +44 -0
  33. data/rails/init.rb +4 -0
  34. data/test/unit/authorized/role_test.rb +30 -0
  35. 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
@@ -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,3 @@
1
+ # From `script/generate simply_authorized` ...
2
+ gem 'ccls-simply_authorized'
3
+ require 'simply_authorized/autotest'
@@ -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 CreateRoles < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :roles do |t|
4
+ t.integer :position
5
+ t.string :name
6
+ t.timestamps
7
+ end
8
+ add_index :roles, :name, :unique => true
9
+ end
10
+
11
+ def self.down
12
+ drop_table :roles
13
+ end
14
+ 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