permitter 0.0.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.
Files changed (77) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +302 -0
  4. data/Rakefile +32 -0
  5. data/lib/generators/permitter/permission/USAGE +5 -0
  6. data/lib/generators/permitter/permission/permission_generator.rb +16 -0
  7. data/lib/generators/permitter/permission/templates/permission.rb +22 -0
  8. data/lib/generators/permitter/permission/templates/permission_spec.rb +17 -0
  9. data/lib/permitter.rb +4 -0
  10. data/lib/permitter/controller_additions.rb +43 -0
  11. data/lib/permitter/exceptions.rb +17 -0
  12. data/lib/permitter/matchers.rb +11 -0
  13. data/lib/permitter/model_additions.rb +30 -0
  14. data/lib/permitter/permission.rb +72 -0
  15. data/lib/permitter/version.rb +3 -0
  16. data/spec/README.rdoc +21 -0
  17. data/spec/controllers/projects_controller_spec.rb +243 -0
  18. data/spec/controllers/users_controller_spec.rb +77 -0
  19. data/spec/dummy/Rakefile +6 -0
  20. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  21. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  22. data/spec/dummy/app/controllers/application_controller.rb +19 -0
  23. data/spec/dummy/app/controllers/projects_controller.rb +49 -0
  24. data/spec/dummy/app/controllers/users_controller.rb +17 -0
  25. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  26. data/spec/dummy/app/models/permission.rb +26 -0
  27. data/spec/dummy/app/models/project.rb +3 -0
  28. data/spec/dummy/app/models/user.rb +3 -0
  29. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  30. data/spec/dummy/app/views/projects/edit.html.erb +0 -0
  31. data/spec/dummy/app/views/projects/index.html.erb +0 -0
  32. data/spec/dummy/app/views/projects/new.html.erb +0 -0
  33. data/spec/dummy/app/views/projects/show.html.erb +0 -0
  34. data/spec/dummy/app/views/users/index.html.erb +0 -0
  35. data/spec/dummy/app/views/users/show.html.erb +0 -0
  36. data/spec/dummy/bin/bundle +3 -0
  37. data/spec/dummy/bin/rails +4 -0
  38. data/spec/dummy/bin/rake +4 -0
  39. data/spec/dummy/config.ru +4 -0
  40. data/spec/dummy/config/application.rb +23 -0
  41. data/spec/dummy/config/boot.rb +5 -0
  42. data/spec/dummy/config/database.yml +25 -0
  43. data/spec/dummy/config/environment.rb +5 -0
  44. data/spec/dummy/config/environments/development.rb +29 -0
  45. data/spec/dummy/config/environments/production.rb +80 -0
  46. data/spec/dummy/config/environments/test.rb +36 -0
  47. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  48. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  49. data/spec/dummy/config/initializers/inflections.rb +16 -0
  50. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  51. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  52. data/spec/dummy/config/initializers/session_store.rb +3 -0
  53. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  54. data/spec/dummy/config/locales/en.yml +23 -0
  55. data/spec/dummy/config/routes.rb +59 -0
  56. data/spec/dummy/db/development.sqlite3 +0 -0
  57. data/spec/dummy/db/migrate/20131205175023_create_projects.rb +10 -0
  58. data/spec/dummy/db/migrate/20131205175100_create_users.rb +10 -0
  59. data/spec/dummy/db/migrate/20131210152022_add_columns_to_projects.rb +5 -0
  60. data/spec/dummy/db/schema.rb +31 -0
  61. data/spec/dummy/db/test.sqlite3 +0 -0
  62. data/spec/dummy/log/development.log +825 -0
  63. data/spec/dummy/log/test.log +44662 -0
  64. data/spec/dummy/public/404.html +58 -0
  65. data/spec/dummy/public/422.html +58 -0
  66. data/spec/dummy/public/500.html +57 -0
  67. data/spec/dummy/public/favicon.ico +0 -0
  68. data/spec/factories/project.rb +6 -0
  69. data/spec/factories/user.rb +10 -0
  70. data/spec/models/permission_spec.rb +72 -0
  71. data/spec/permitter/controller_additions_spec.rb +44 -0
  72. data/spec/permitter/exceptions_spec.rb +36 -0
  73. data/spec/permitter/matchers_spec.rb +9 -0
  74. data/spec/permitter/model_additions_spec.rb +138 -0
  75. data/spec/permitter/permission_spec.rb +84 -0
  76. data/spec/spec_helper.rb +32 -0
  77. metadata +278 -0
@@ -0,0 +1,17 @@
1
+ module Permitter
2
+ class Unauthorized < StandardError
3
+ attr_reader :action, :subject
4
+ attr_writer :default_message
5
+
6
+ def initialize(message = nil, action = nil, subject = nil)
7
+ @message = message
8
+ @action = action
9
+ @subject = subject
10
+ @default_message = "You are not authorized to access this page."
11
+ end
12
+
13
+ def to_s
14
+ @message || @default_message
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,11 @@
1
+ RSpec::Matchers.define :allow_action do |*args|
2
+ match do |permission|
3
+ expect(permission.allowed_action?(*args)).to be true
4
+ end
5
+ end
6
+
7
+ RSpec::Matchers.define :allow_param do |*args|
8
+ match do |permission|
9
+ expect(permission.allowed_param?(*args)).to be true
10
+ end
11
+ end
@@ -0,0 +1,30 @@
1
+ module Permitter
2
+ module ModelAdditions
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ require 'squeel'
7
+ end
8
+
9
+ module ClassMethods
10
+
11
+ def permitted_by(permissions, action = :show)
12
+ status = permissions.allow_all? ? true : permissions.allowed_action(self.table_name, action)
13
+
14
+ if status.class == Proc
15
+ where(&status)
16
+ else
17
+ status ? all : none
18
+ end
19
+
20
+ end
21
+
22
+ end
23
+ end
24
+ end
25
+
26
+ if defined? ActiveRecord::Base
27
+ ActiveRecord::Base.class_eval do
28
+ include Permitter::ModelAdditions
29
+ end
30
+ end
@@ -0,0 +1,72 @@
1
+ module Permitter
2
+ module Permission
3
+
4
+ def allowed_action?(controller, action, resource = nil)
5
+ if allow_all?
6
+ true
7
+ elsif @allowed_actions
8
+ allowed = @allowed_actions[[controller.to_s, action.to_s]]
9
+ (allowed && (allowed == true || resource && allowed.call(resource))) == true
10
+ else
11
+ false
12
+ end
13
+ end
14
+
15
+ def allowed_param?(resource, attribute)
16
+ if allow_all?
17
+ true
18
+ elsif @allowed_params && @allowed_params[resource]
19
+ @allowed_params[resource].include? attribute
20
+ else
21
+ false
22
+ end
23
+ end
24
+
25
+ def allowed_action(controller, action)
26
+ if @allowed_actions
27
+ @allowed_actions[[controller.to_s, action.to_s]]
28
+ end
29
+ end
30
+
31
+ def allow_action(controllers, actions, &block)
32
+ @allowed_actions ||= {}
33
+ Array(controllers).flatten.each do |controller|
34
+ Array(actions).flatten.each do |action|
35
+ @allowed_actions[[controller.to_s, action.to_s]] = block || true
36
+ end
37
+ end
38
+ end
39
+
40
+ def allow_param(resources, attributes)
41
+ @allowed_params ||= {}
42
+ resource_array = Array(resources).flatten
43
+ attribute_array = Array(attributes).flatten
44
+
45
+ resource_array.each do |resource|
46
+ @allowed_params[resource] ||= []
47
+ @allowed_params[resource] += attribute_array
48
+ end
49
+ end
50
+
51
+ def allow_all
52
+ @allow_all = true
53
+ end
54
+
55
+ def allow_all?
56
+ @allow_all ||= false
57
+ end
58
+
59
+ def permit_params!(params)
60
+ if @allow_all
61
+ params.permit!
62
+ elsif @allowed_params
63
+ @allowed_params.each do |resource, attributes|
64
+ if params[resource].respond_to? :permit
65
+ params[resource] = params[resource].permit(*attributes)
66
+ end
67
+ end
68
+ end
69
+ end
70
+
71
+ end
72
+ end
@@ -0,0 +1,3 @@
1
+ module Permitter
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,21 @@
1
+ = Permitter Specs
2
+
3
+ == Running the specs
4
+
5
+ To run the specs first run the +bundle+ command to install the necessary gems.
6
+
7
+ bundle
8
+
9
+ Then the migrations for the dummy app must be run. Move to the dummy app root and run the migrations.
10
+
11
+ cd spec/dummy
12
+ rake db:migrate
13
+ rake test:prepare
14
+ cd ../..
15
+
16
+ Finally, from the root of the gem, run the +rake+ command to run the specs.
17
+
18
+ rake
19
+
20
+ The specs currently require Ruby >= 1.9.3
21
+ They may or may not work with other Ruby versions.
@@ -0,0 +1,243 @@
1
+ require "spec_helper"
2
+
3
+ describe ProjectsController do
4
+ before { @controller.stub(:current_user) { nil } }
5
+ let(:user) { build(:user) }
6
+ let(:user1) { create(:user) }
7
+ let(:user2) { create(:user) }
8
+ let(:admin) { build(:admin) }
9
+ let(:project) { create(:project) }
10
+ let(:project1) { create(:project, user: user1) }
11
+ let(:project2) { create(:project, user: user2) }
12
+
13
+ describe "GET #index" do
14
+ before { get :index }
15
+
16
+ it "responds successfully" do
17
+ expect(response).to be_success
18
+ expect(response.status).to eq(200)
19
+ end
20
+
21
+ it "renders the index template" do
22
+ expect(response).to render_template("index")
23
+ end
24
+
25
+ it "loads all of the projects into @projects" do
26
+ expect(assigns(:projects)).to eq(Project.all)
27
+ end
28
+ end
29
+
30
+
31
+ describe "GET #show" do
32
+ before do
33
+ unless example.metadata[:skip_before]
34
+ @controller.stub(:current_user) { user }
35
+ get :show, id: project.id
36
+ end
37
+ end
38
+
39
+ it "responds unsuccessfully if user not signed in", skip_before: true do
40
+ get :show, id: project.id
41
+ expect(response).to_not be_success
42
+ expect(response.status).to eq(302)
43
+ expect(response).to redirect_to(projects_url)
44
+ expect(flash.alert).to eq("You are not authorized to access this page.")
45
+ end
46
+
47
+ it "responds successfully if user signed in" do
48
+ expect(response).to be_success
49
+ expect(response.status).to eq(200)
50
+ end
51
+
52
+ it "renders the show template" do
53
+ expect(response).to render_template("show")
54
+ end
55
+
56
+ it "loads the project into @project" do
57
+ expect(assigns(:project)).to eq(project)
58
+ end
59
+ end
60
+
61
+
62
+ describe "GET #new" do
63
+ before do
64
+ unless example.metadata[:skip_before]
65
+ @controller.stub(:current_user) { user }
66
+ get :new
67
+ end
68
+ end
69
+
70
+ it "responds unsuccessfully if user not signed in", skip_before: true do
71
+ get :new
72
+ expect(response).to_not be_success
73
+ expect(response.status).to eq(302)
74
+ expect(response).to redirect_to(projects_url)
75
+ expect(flash.alert).to eq("You are not authorized to access this page.")
76
+ end
77
+
78
+ it "responds successfully if user signed in" do
79
+ expect(response).to be_success
80
+ expect(response.status).to eq(200)
81
+ end
82
+
83
+ it "renders the new template" do
84
+ expect(response).to render_template("new")
85
+ end
86
+
87
+ it "builds a new project into @project" do
88
+ expect(assigns(:project)).to be_a_new(Project)
89
+ end
90
+ end
91
+
92
+
93
+ describe "POST #create" do
94
+ let(:title) { 'Title' }
95
+ let(:sticky) { true }
96
+ before do
97
+ unless example.metadata[:skip_before]
98
+ @controller.stub(:current_user) { user }
99
+ post :create, project: {title: title, sticky: sticky}
100
+ end
101
+ end
102
+
103
+ it "responds unsuccessfully if user not signed in", skip_before: true do
104
+ post :create
105
+ expect(response.status).to eq(302)
106
+ expect(response).to redirect_to(projects_url)
107
+ expect(flash.alert).to eq("You are not authorized to access this page.")
108
+ end
109
+
110
+ it "responds successfully if user signed in" do
111
+ expect(response.status).to eq(302)
112
+ expect(response).to redirect_to(project_url(assigns(:project)))
113
+ expect(flash.notice).to eq("Project was successfully created.")
114
+ end
115
+
116
+ it "creates a new project" do
117
+ expect(assigns(:project)).to eq(Project.last)
118
+ end
119
+
120
+ it "does not assign sticky variable" do
121
+ expect(assigns(:project).title).to eq(title)
122
+ expect(assigns(:project).sticky).to be_nil
123
+ end
124
+ end
125
+
126
+
127
+ describe "GET #edit" do
128
+ before do
129
+ unless example.metadata[:skip_before]
130
+ @controller.stub(:current_user) { user1 }
131
+ get :edit, id: project1.id
132
+ end
133
+ end
134
+
135
+ it "responds unsuccessfully if user not signed in", skip_before: true do
136
+ get :edit, id: project.id
137
+ expect(response).to_not be_success
138
+ expect(response.status).to eq(302)
139
+ expect(response).to redirect_to(projects_url)
140
+ expect(flash.alert).to eq("You are not authorized to access this page.")
141
+ end
142
+
143
+ it "responds unsuccessfully if user not associated with project", skip_before: true do
144
+ @controller.stub(:current_user) { user1 }
145
+ get :edit, id: project2.id
146
+ expect(response).to_not be_success
147
+ expect(response.status).to eq(302)
148
+ expect(response).to redirect_to(projects_url)
149
+ expect(flash.alert).to eq("You are not authorized to access this page.")
150
+ end
151
+
152
+ it "responds successfully if user associated with project" do
153
+ expect(response.status).to eq(200)
154
+ end
155
+
156
+ it "renders the edit template" do
157
+ expect(response).to render_template("edit")
158
+ end
159
+
160
+ it "loads the project into @project" do
161
+ expect(assigns(:project)).to eq(project1)
162
+ end
163
+ end
164
+
165
+
166
+ describe "PATCH #update" do
167
+ let(:title) { 'Updated Title' }
168
+ let(:sticky) { true }
169
+
170
+ before do
171
+ unless example.metadata[:skip_before]
172
+ @controller.stub(:current_user) { user1 }
173
+ @original_title = project1.title
174
+ @original_sticky = project1.sticky
175
+ patch :update, id: project1.id, project: {title: title, sticky: sticky}
176
+ end
177
+ end
178
+
179
+ it "responds unsuccessfully if user not signed in", skip_before: true do
180
+ patch :update, id: project.id
181
+ expect(response).to_not be_success
182
+ expect(response.status).to eq(302)
183
+ expect(response).to redirect_to(projects_url)
184
+ expect(flash.alert).to eq("You are not authorized to access this page.")
185
+ end
186
+
187
+ it "responds unsuccessfully if user not associated with project", skip_before: true do
188
+ @controller.stub(:current_user) { user1 }
189
+ patch :update, id: project2.id
190
+ expect(response).to_not be_success
191
+ expect(response.status).to eq(302)
192
+ expect(response).to redirect_to(projects_url)
193
+ expect(flash.alert).to eq("You are not authorized to access this page.")
194
+ end
195
+
196
+ it "responds successfully if user associated with project" do
197
+ expect(response.status).to eq(302)
198
+ expect(response).to redirect_to(project_url(assigns(:project)))
199
+ expect(flash.notice).to eq("Project was successfully updated.")
200
+ end
201
+
202
+ it "updates a project" do
203
+ expect(assigns(:project).title).to eq(title)
204
+ expect(assigns(:project).title).to_not eq(@original_title)
205
+ end
206
+
207
+ it "does not update sticky" do
208
+ expect(assigns(:project).sticky).to eq(@original_sticky)
209
+ expect(assigns(:project).sticky).to_not eq(sticky)
210
+ end
211
+ end
212
+
213
+
214
+ describe "DELETE #destroy" do
215
+
216
+ it "responds unsuccessfully if user not signed in" do
217
+ delete :destroy, id: project.id
218
+ expect(flash.alert).to eq("You are not authorized to access this page.")
219
+ end
220
+
221
+ it "responds unsuccessfully if user not an admin" do
222
+ @controller.stub(:current_user) { user1 }
223
+ delete :destroy, id: project1.id
224
+ expect(flash.alert).to eq("You are not authorized to access this page.")
225
+ end
226
+
227
+ it "responds successfully if user an admin" do
228
+ @controller.stub(:current_user) { admin }
229
+ delete :destroy, id: project.id
230
+ expect(flash.alert).to be nil
231
+ end
232
+
233
+ it "destroys a project" do
234
+ expect(Project.all).to include(project)
235
+
236
+ @controller.stub(:current_user) { admin }
237
+ delete :destroy, id: project.id
238
+ expect(Project.all).to_not include(project)
239
+ end
240
+ end
241
+
242
+
243
+ end
@@ -0,0 +1,77 @@
1
+ require "spec_helper"
2
+
3
+ describe UsersController do
4
+ let(:user) { create(:user) }
5
+ let(:admin) { create(:admin) }
6
+
7
+ describe "GET #index" do
8
+ before do
9
+ unless example.metadata[:skip_before]
10
+ @controller.stub(:current_user) { user }
11
+ get :index
12
+ end
13
+ end
14
+
15
+ it "responds successfully" do
16
+ expect(response).to be_success
17
+ expect(response.status).to eq(200)
18
+ end
19
+
20
+ it "renders the index template" do
21
+ expect(response).to render_template("index")
22
+ end
23
+
24
+ it "loads all of the users into @projects if admin", skip_before: true do
25
+ @controller.stub(:current_user) { admin }
26
+ get :index
27
+ expect(assigns(:users)).to eq(User.all)
28
+ end
29
+
30
+ it "loads only current user into @projects if not admin" do
31
+ expect(assigns(:users)).to eq([user])
32
+ end
33
+
34
+ end
35
+
36
+
37
+ describe "GET #show" do
38
+ before do
39
+ unless example.metadata[:skip_before]
40
+ @controller.stub(:current_user) { user }
41
+ get :show, id: user.id
42
+ end
43
+ end
44
+
45
+ it "responds unsuccessfully if user not signed in", skip_before: true do
46
+ @controller.stub(:current_user) { nil }
47
+ get :show, id: user.id
48
+ expect(response).to_not be_success
49
+ expect(response.status).to eq(302)
50
+ expect(response).to redirect_to(projects_url)
51
+ expect(flash.alert).to eq("You are not authorized to access this page.")
52
+ end
53
+
54
+ it "responds unsuccessfully if user signed in and not current user", skip_before: true do
55
+ @controller.stub(:current_user) { user }
56
+ get :show, id: admin.id
57
+ expect(response).to_not be_success
58
+ expect(response.status).to eq(302)
59
+ expect(response).to redirect_to(projects_url)
60
+ expect(flash.alert).to eq("You are not authorized to access this page.")
61
+ end
62
+
63
+ it "responds successfully if user signed in and current user" do
64
+ expect(response).to be_success
65
+ expect(response.status).to eq(200)
66
+ end
67
+
68
+ it "renders the show template" do
69
+ expect(response).to render_template("show")
70
+ end
71
+
72
+ it "loads the user into @user" do
73
+ expect(assigns(:user)).to eq(user)
74
+ end
75
+ end
76
+
77
+ end