permitter 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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