banken 0.0.1 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6b535c2ea0ee44062ee539386142447ab1db0054
4
- data.tar.gz: 74d457b467b4ec2c8a4d39899732aad37ff90d36
3
+ metadata.gz: 5fa23a2a65fb5297370655ef973516a3615be3d4
4
+ data.tar.gz: 5965509ce31efeb8243a1796191b4da0c416e429
5
5
  SHA512:
6
- metadata.gz: 0aa2d9fd1a1eb732252d0093fa407f654fc6d47396b16888771d35c719226ebb9c151d51650354856959dc90b3ddd2987508c8f02a8ce90ed883ed697aae3133
7
- data.tar.gz: e081bc1f541fe7476cd46170a72dcac38fc12c01ef4709c7d1c6da27dc20154242dbedccfeb0cd60550507daba95ba2b7a737659ba16a3ce8c7d70ffeec74d59
6
+ metadata.gz: 763ee80874810e27d2d9edfa8dca6298e8f6694fa097ac558ac9857c23848b57d638b000410126e1bb427e183afb17ce4c37690a07d4c4701f4c3b9a50295d71
7
+ data.tar.gz: d8ea1e7142b0b3badd6bf538dc6a1498b921a858683e53d6b735bd5cd73bd6a02b848727d5f6fae4867fe7d69d894fa89f6458f8d2d634fa6a6c94e5083522cb
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --order rand
data/.travis.yml ADDED
@@ -0,0 +1,8 @@
1
+ language: ruby
2
+ sudo: false
3
+ script: "bundle exec rake"
4
+ rvm:
5
+ - 2.0.0
6
+ - 2.1.5
7
+ - 2.2.3
8
+ - rbx-2
data/Gemfile CHANGED
@@ -1,5 +1,3 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Specify your gem's dependencies in banken.gemspec
4
- gem "rspec", ENV["RSPEC_VERSION"] unless ENV["RSPEC_VERSION"].to_s.empty?
5
3
  gemspec
data/README.md CHANGED
@@ -1,41 +1,405 @@
1
1
  # Banken
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/banken`. To experiment with that code, run `bin/console` for an interactive prompt.
3
+ [![Build Status](https://img.shields.io/travis/kyuden/banken/master.svg)](https://travis-ci.org/kyuden/banken)
4
+ [![Code Climate](https://codeclimate.com/github/kyuden/banken/badges/gpa.svg)](https://codeclimate.com/github/kyuden/banken)
5
+ [![Gem Version](https://badge.fury.io/rb/banken.svg)](https://badge.fury.io/rb/banken)
4
6
 
5
- TODO: Delete this and the text above, and describe your gem
7
+ Banken provides a set of helpers which guide you in leveraging regular Ruby
8
+ classes and object oriented design patterns to build a simple, robust and
9
+ scaleable authorization system.
6
10
 
7
11
  ## Installation
8
12
 
9
- Add this line to your application's Gemfile:
13
+ ``` ruby
14
+ gem "banken"
15
+ ```
16
+
17
+ Include Banken in your application controller:
18
+
19
+ ``` ruby
20
+ # app/controllers/application_controller.rb
21
+ class ApplicationController < ActionController::Base
22
+ include Banken
23
+ protect_from_forgery
24
+ end
25
+ ```
26
+
27
+ Optionally, you can run the generator, which will set up an application loyalty
28
+ with some useful defaults for you:
29
+
30
+ ``` sh
31
+ rails g banken:install
32
+ ```
33
+
34
+ After generating your application loyalty, restart the Rails server so that Rails
35
+ can pick up any classes in the new `app/loyalties/` directory.
36
+
37
+ ## Policies
38
+
39
+ Banken is focused around the notion of loyalty classes. We suggest that you put
40
+ these classes in `app/loyalties`. This is a simple example that allows updating
41
+ a post if the user is an admin, or if the post is unpublished:
42
+
43
+ ``` ruby
44
+ # app/loyalties/posts_loyalty.rb
45
+ class PostsLoyalty
46
+ attr_reader :user, :post
47
+
48
+ def initialize(user, post)
49
+ @user = user
50
+ @post = post
51
+ end
52
+
53
+ def update?
54
+ user.admin? || post.unpublished?
55
+ end
56
+ end
57
+ ```
58
+
59
+ As you can see, this is just a plain Ruby class. Banken makes the following
60
+ assumptions about this class:
61
+
62
+ - The class has the same name as some kind of controller class, only suffixed
63
+ with the word "Loyalty".
64
+ - The first argument is a user. In your controller, Banken will call the
65
+ `current_user` method to retrieve what to send into this argument
66
+ - The second argument is optional, whose authorization you want to check.
67
+ This does not need to be an ActiveRecord or even an ActiveModel object,
68
+ it can be anything really.
69
+ - The class implements some kind of query method, in this case `update?`.
70
+ Usually, this will map to the name of a particular controller action.
71
+
72
+ That's it really.
73
+
74
+ Usually you'll want to inherit from the application loyalty created by the
75
+ generator, or set up your own base class to inherit from:
76
+
77
+ ``` ruby
78
+ # app/loyalties/posts_loyalty.rb
79
+ class PostsLoyalty < ApplicationLoyalty
80
+ def update?
81
+ user.admin? || record.unpublished?
82
+ end
83
+ end
84
+ ```
85
+
86
+ In the generated `ApplicationLoyalty`, the optional object is called `record`.
87
+
88
+ Supposing that you are in PostsController, Banken now lets you do
89
+ this in your controller:
90
+
91
+ ``` ruby
92
+ # app/controllers/posts_controller.rb
93
+ class PostsController < ApplicationController
94
+ def update
95
+ @post = Post.find(params[:id])
96
+ authorize! @post
97
+ if @post.update(post_params)
98
+ redirect_to @post
99
+ else
100
+ render :edit
101
+ end
102
+ end
103
+ end
104
+ ```
105
+
106
+ The authorize method automatically infers from controller name that `Posts` will have a matching
107
+ `PostsLoyalty` class, and instantiates this class, handing in the current user
108
+ and the given optional object. It then infers from the action name, that it should call
109
+ `update?` on this instance of the loyalty. In this case, you can imagine that
110
+ `authorize!` would have done something like this:
111
+
112
+ ``` ruby
113
+ raise "not authorized" unless PostsLoyalty.new(current_user, @post).update?
114
+ ```
115
+
116
+ If you don't have an optional object for the first argument to `authorize!`, then you can pass
117
+ the class. For example:
118
+
119
+ Loyalty:
120
+ ```ruby
121
+ # app/loyalties/posts_loyalty.rb
122
+ class PostsLoyalty < ApplicationLoyalty
123
+ def admin_list?
124
+ user.admin?
125
+ end
126
+ end
127
+ ```
128
+
129
+ Controller:
130
+ ```ruby
131
+ # app/controllers/posts_controller.rb
132
+ class PostsController < ApplicationController
133
+ def admin_list
134
+ authorize!
135
+ # Rest of controller action
136
+ end
137
+ end
138
+ ```
139
+
140
+ You can easily get a hold of an instance of the loyalty through the `loyalty`
141
+ method in both the view and controller. This is especially useful for
142
+ conditionally showing links or buttons in the view:
143
+
144
+ ``` erb
145
+ <% if loyalty(@post, :posts).update? %>
146
+ <%= link_to "Edit post", edit_post_path(@post) %>
147
+ <% end %>
148
+ ```
149
+
150
+ ## Ensuring loyalties are used
151
+
152
+ Banken adds a method called `verify_authorized` to your controllers. This
153
+ method will raise an exception if `authorize!` has not yet been called. You
154
+ should run this method in an `after_action` to ensure that you haven't
155
+ forgotten to authorize the action. For example:
156
+
157
+ ``` ruby
158
+ # app/controllers/application_controller.rb
159
+ class ApplicationController < ActionController::Base
160
+ after_action :verify_authorized, except: :index
161
+ end
162
+ ```
163
+
164
+
165
+ If you're using `verify_authorized` in your controllers but need to
166
+ conditionally bypass verification, you can use `skip_authorization`.
167
+ These are useful in circumstances where you don't want to disable verification for the
168
+ entire action, but have some cases where you intend to not authorize.
169
+
170
+ ```ruby
171
+ # app/controllers/posts_controller.rb
172
+ class PostsController < ApplicationController
173
+ def show
174
+ record = Record.find_by(attribute: "value")
175
+ if record.present?
176
+ authorize record
177
+ else
178
+ skip_authorization
179
+ end
180
+ end
181
+ end
182
+ ```
183
+
184
+ If you need to perform some more sophisticated logic or you want to raise a custom
185
+ exception you can use the two lower level method `banken_loyalty_authorized?` which
186
+ return `true` or `false` depending on whether `authorize!` have been called, respectively.
187
+
188
+ ## Just plain old Ruby
189
+
190
+ As you can see, Banken doesn't do anything you couldn't have easily done
191
+ yourself. It's a very small library, it just provides a few neat helpers.
192
+ Together these give you the power of building a well structured, fully working
193
+ authorization system without using any special DSLs or funky syntax or
194
+ anything.
195
+
196
+ Remember that all of the loyalty is just plain Ruby classes,
197
+ which means you can use the same mechanisms you always use to DRY things up.
198
+ Encapsulate a set of permissions into a module and include them in multiple
199
+ loyalties. Use `alias_method` to make some permissions behave the same as
200
+ others. Inherit from a base set of permissions. Use metaprogramming if you
201
+ really have to.
202
+
203
+ ## Generator
204
+
205
+ Use the supplied generator to generate loyalties:
206
+
207
+ ``` sh
208
+ rails g banken:loyalty posts
209
+ ```
210
+
211
+ ## Closed systems
212
+
213
+ In many applications, only logged in users are really able to do anything. If
214
+ you're building such a system, it can be kind of cumbersome to check that the
215
+ user in a loyalty isn't `nil` for every single permission.
216
+
217
+ We suggest that you define a filter that redirects unauthenticated users to the
218
+ login page. As a secondary defence, if you've defined an ApplicationLoyalty, it
219
+ might be a good idea to raise an exception if somehow an unauthenticated user
220
+ got through. This way you can fail more gracefully.
221
+
222
+ ``` ruby
223
+ # app/loyalties/application_loyalty.rb
224
+ class ApplicationLoyalty
225
+ def initialize(user, record)
226
+ raise Banken::NotAuthorizedError, "must be logged in" unless user
227
+ @user = user
228
+ @record = record
229
+ end
230
+ end
231
+ ```
232
+
233
+ ## Rescuing a denied Authorization in Rails
234
+
235
+ Banken raises a `Banken::NotAuthorizedError` you can
236
+ [rescue_from](http://guides.rubyonrails.org/action_controller_overview.html#rescue-from)
237
+ in your `ApplicationController`. You can customize the `user_not_authorized`
238
+ method in every controller.
239
+
240
+ ```ruby
241
+ # app/controllers/application_controller.rb
242
+ class ApplicationController < ActionController::Base
243
+ protect_from_forgery
244
+ include Banken
245
+
246
+ rescue_from Banken::NotAuthorizedError, with: :user_not_authorized
247
+
248
+ private
249
+
250
+ def user_not_authorized
251
+ flash[:alert] = "You are not authorized to perform this action."
252
+ redirect_to(request.referrer || root_path)
253
+ end
254
+ end
255
+ ```
256
+
257
+ ## Creating custom error messages
258
+
259
+ `NotAuthorizedError`s provide information on what query (e.g. `:create?`), what
260
+ controller (e.g. `PostsController`), and what loyalty (e.g. an instance of
261
+ `PostsLoyalty`) caused the error to be raised.
262
+
263
+ One way to use these `query`, `record`, and `loyalty` properties is to connect
264
+ them with `I18n` to generate error messages. Here's how you might go about doing
265
+ that.
10
266
 
11
267
  ```ruby
12
- gem 'banken'
268
+ # app/controllers/application_controller.rb
269
+ class ApplicationController < ActionController::Base
270
+ rescue_from Banken::NotAuthorizedError, with: :user_not_authorized
271
+
272
+ private
273
+
274
+ def user_not_authorized(exception)
275
+ loyalty_name = exception.loyalty.class.to_s.underscore
276
+
277
+ flash[:error] = t "#{loyalty_name}.#{exception.query}", scope: "banken", default: :default
278
+ redirect_to(request.referrer || root_path)
279
+ end
280
+ end
281
+ ```
282
+
283
+ ```yaml
284
+ en:
285
+ banken:
286
+ default: 'You cannot perform this action.'
287
+ posts_loyalty:
288
+ update?: 'You cannot edit this post!'
289
+ create?: 'You cannot create posts!'
13
290
  ```
14
291
 
15
- And then execute:
292
+ Of course, this is just an example. Banken is agnostic as to how you implement
293
+ your error messaging.
16
294
 
17
- $ bundle
295
+ ## Customize Banken user
18
296
 
19
- Or install it yourself as:
297
+ In some cases your controller might not have access to `current_user`, or your
298
+ `current_user` is not the method that should be invoked by Banken. Simply
299
+ define a method in your controller called `banken_user`.
20
300
 
21
- $ gem install banken
301
+ ```ruby
302
+ def banken_user
303
+ User.find_by_other_means
304
+ end
305
+ ```
306
+
307
+ ## Additional context
22
308
 
23
- ## Usage
309
+ Banken strongly encourages you to model your application in such a way that the
310
+ only context you need for authorization is a user object and a domain model that
311
+ you want to check authorization for. If you find yourself needing more context than
312
+ that, consider whether you are authorizing the right domain model, maybe another
313
+ domain model (or a wrapper around multiple domain models) can provide the context
314
+ you need.
24
315
 
25
- TODO: Write usage instructions here
316
+ Banken does not allow you to pass additional arguments to loyalties for precisely
317
+ this reason.
26
318
 
27
- ## Development
319
+ However, in very rare cases, you might need to authorize based on more context than just
320
+ the currently authenticated user. Suppose for example that authorization is dependent
321
+ on IP address in addition to the authenticated user. In that case, one option is to
322
+ create a special class which wraps up both user and IP and passes it to the loyalty.
28
323
 
29
- After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
324
+ ``` ruby
325
+ class UserContext
326
+ attr_reader :user, :ip
30
327
 
31
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
328
+ def initialize(user, ip)
329
+ @user = user
330
+ @ip = ip
331
+ end
332
+ end
32
333
 
33
- ## Contributing
334
+ # app/controllers/application_controller.rb
335
+ class ApplicationController
336
+ include Banken
34
337
 
35
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/banken. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
338
+ def banken_user
339
+ UserContext.new(current_user, request.ip)
340
+ end
341
+ end
342
+ ```
343
+
344
+ ## Strong parameters
36
345
 
346
+ In Rails 4 (or Rails 3.2 with the
347
+ [strong_parameters](https://github.com/rails/strong_parameters) gem),
348
+ mass-assignment protection is handled in the controller. With Banken you can
349
+ control which attributes a user has access to update via your loyalties. You can
350
+ set up a `permitted_attributes` method in your loyalty like this:
37
351
 
38
- ## License
352
+ ```ruby
353
+ # app/loyalties/posts_loyalty.rb
354
+ class PostsLoyalty < ApplicationLoyalty
355
+ def permitted_attributes
356
+ if user.admin? || user.owner_of?(post)
357
+ [:title, :body, :tag_list]
358
+ else
359
+ [:tag_list]
360
+ end
361
+ end
362
+ end
363
+ ```
364
+
365
+ You can now retrieve these attributes from the loyalty:
366
+
367
+ ```ruby
368
+ # app/controllers/posts_controller.rb
369
+ class PostsController < ApplicationController
370
+ def update
371
+ @post = Post.find(params[:id])
372
+ if @post.update_attributes(post_params)
373
+ redirect_to @post
374
+ else
375
+ render :edit
376
+ end
377
+ end
378
+
379
+ private
380
+
381
+ def post_params
382
+ params.require(:post).permit(loyalty(@post).permitted_attributes)
383
+ end
384
+ end
385
+ ```
386
+
387
+ However, this is a bit cumbersome, so Banken provides a convenient helper method:
388
+
389
+ ```ruby
390
+ # app/controllers/posts_controller.rb
391
+ class PostsController < ApplicationController
392
+ def update
393
+ @post = Post.find(params[:id])
394
+ if @post.update_attributes(permitted_attributes(@post))
395
+ redirect_to @post
396
+ else
397
+ render :edit
398
+ end
399
+ end
400
+ end
401
+ ```
39
402
 
40
- The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
403
+ # License
41
404
 
405
+ Licensed under the MIT license, see the separate LICENSE.txt file.
data/Rakefile CHANGED
@@ -1 +1,17 @@
1
- require "bundler/gem_tasks"
1
+ require 'rubygems'
2
+ require 'bundler/gem_tasks'
3
+ require 'rspec/core/rake_task'
4
+ require 'yard'
5
+
6
+ desc "Run all examples"
7
+ RSpec::Core::RakeTask.new(:spec) do |t|
8
+ #t.rspec_path = 'bin/rspec'
9
+ t.rspec_opts = %w[--color]
10
+ end
11
+
12
+ YARD::Rake::YardocTask.new do |t|
13
+ t.files = ['lib/**/*.rb']
14
+ #t.options = ['--any', '--extra', '--opts'] # optional
15
+ end
16
+
17
+ task :default => [:spec]
data/banken.gemspec CHANGED
@@ -26,4 +26,5 @@ Gem::Specification.new do |spec|
26
26
  spec.add_development_dependency "rspec", ">=2.0.0"
27
27
  spec.add_development_dependency "pry"
28
28
  spec.add_development_dependency "rake"
29
+ spec.add_development_dependency "yard"
29
30
  end
data/lib/banken.rb CHANGED
@@ -4,67 +4,52 @@ require "active_support/core_ext/object/blank"
4
4
  require "active_support/core_ext/module/introspection"
5
5
  require "banken/version"
6
6
  require "banken/error"
7
- require "banken/helper"
8
- require "banken/policy_finder"
7
+ require "banken/loyalty_finder"
9
8
 
10
9
  module Banken
11
10
  extend ActiveSupport::Concern
12
11
 
13
12
  included do
14
- # TODO
15
- # helper Helper if respond_to?(:helper)
16
13
  if respond_to?(:helper_method)
17
- # TODO
18
- # helper_method :banken_policy_scope
14
+ helper_method :loyalty
19
15
  helper_method :banken_user
20
16
  end
17
+
21
18
  if respond_to?(:hide_action)
22
- hide_action :policy_scope
23
19
  hide_action :permitted_attributes
24
- hide_action :policy
20
+ hide_action :loyalty
25
21
  hide_action :banken_user
26
22
  hide_action :skip_authorization
27
- hide_action :skip_policy_scope
28
23
  hide_action :verify_authorized
29
- hide_action :verify_policy_scoped
30
- hide_action :policies
31
- hide_action :policy_scopes
24
+ hide_action :loyalties
32
25
  end
33
26
  end
34
27
 
35
28
  class << self
36
- def policy_scope!(controller, user, scope)
37
- PolicyFinder.new(controller).scope!.new(user, scope).resolve
38
- end
39
-
40
- def policy!(controller, user, record)
41
- PolicyFinder.new(controller).policy!.new(user, record)
29
+ def loyalty!(controller_name, user, record=nil)
30
+ LoyaltyFinder.new(controller_name).loyalty!.new(user, record)
42
31
  end
43
32
  end
44
33
 
45
34
  def authorize!(record=nil)
46
- @_banken_policy_authorized = true
35
+ @_banken_loyalty_authorized = true
47
36
 
48
- policy = policy(record)
49
- unless policy.public_send("#{banken_action_name}?")
50
- raise NotAuthorizedError.new(controller: banken_controller_name, action: banken_action_name, policy: policy)
37
+ loyalty = loyalty(record)
38
+ unless loyalty.public_send(banken_query_name)
39
+ raise NotAuthorizedError.new(controller: banken_controller_name, query: banken_query_name, loyalty: loyalty)
51
40
  end
52
41
 
53
42
  true
54
43
  end
55
44
 
56
- def policy_scope(scope)
57
- @_banken_policy_scoped = true
58
- banken_policy_scope(scope)
59
- end
60
-
61
45
  def permitted_attributes(record)
62
46
  name = record.class.to_s.demodulize.underscore
63
- params.require(name).permit(policy(record).permitted_attributes)
47
+ params.require(name).permit(loyalty(record).permitted_attributes)
64
48
  end
65
49
 
66
- def policy(record)
67
- policies[banken_action_name] ||= Banken.policy!(banken_controller_name, banken_user, record)
50
+ def loyalty(record=nil, controller_name=nil)
51
+ controller_name = banken_controller_name unless controller_name
52
+ loyalties[controller_name.to_s] ||= Banken.loyalty!(controller_name, banken_user, record)
68
53
  end
69
54
 
70
55
  def banken_user
@@ -72,48 +57,32 @@ module Banken
72
57
  end
73
58
 
74
59
  def skip_authorization
75
- @_banken_policy_authorized = true
76
- end
77
-
78
- def skip_policy_scope
79
- @_banken_policy_scoped = true
60
+ @_banken_loyalty_authorized = true
80
61
  end
81
62
 
82
63
  def verify_authorized
83
- raise AuthorizationNotPerformedError unless banken_policy_authorized?
84
- end
85
-
86
- def verify_policy_scoped
87
- raise PolicyScopingNotPerformedError unless banken_policy_scoped?
64
+ raise AuthorizationNotPerformedError unless banken_loyalty_authorized?
88
65
  end
89
66
 
90
- def banken_policy_authorized?
91
- !!@_banken_policy_authorized
67
+ def banken_loyalty_authorized?
68
+ !!@_banken_loyalty_authorized
92
69
  end
93
70
 
94
- def banken_policy_scoped?
95
- !!@_banken_policy_scoped
96
- end
97
-
98
- def policies
99
- @_banken_policies ||= {}
100
- end
101
-
102
- def policy_scopes
103
- @_banken_policy_scopes ||= {}
71
+ def loyalties
72
+ @_banken_loyalties ||= {}
104
73
  end
105
74
 
106
75
  private
107
76
 
108
- def banken_policy_scope(scope)
109
- policy_scopes[scope] ||= Banken.policy_scope!(banken_controller_name, banken_user, scope)
110
- end
111
-
112
77
  def banken_action_name
113
- params[:action].to_s
78
+ params[:action]
114
79
  end
115
80
 
116
81
  def banken_controller_name
117
- params[:controller].to_s
82
+ params[:controller]
83
+ end
84
+
85
+ def banken_query_name
86
+ "#{banken_action_name}?"
118
87
  end
119
88
  end
data/lib/banken/error.rb CHANGED
@@ -2,17 +2,17 @@ module Banken
2
2
  class Error < StandardError; end
3
3
 
4
4
  class NotAuthorizedError < Error
5
- attr_reader :controller, :action, :policy
5
+ attr_reader :controller, :query, :loyalty
6
6
 
7
7
  def initialize(options={})
8
8
  if options.is_a? String
9
9
  message = options
10
10
  else
11
11
  @controller = options[:controller]
12
- @action = options[:action]
13
- @policy = options[:policy]
12
+ @query = options[:query]
13
+ @loyalty = options[:loyalty]
14
14
 
15
- message = options.fetch(:message) { "not allowed to #{action} of #{controller} by #{policy.inspect}" }
15
+ message = options.fetch(:message) { "not allowed to #{query} of #{controller} by #{loyalty.inspect}" }
16
16
  end
17
17
 
18
18
  super(message)
@@ -22,5 +22,5 @@ module Banken
22
22
  class NotDefinedError < Error; end
23
23
  class AuthorizationNotPerformedError < Error; end
24
24
 
25
- class PolicyScopingNotPerformedError < AuthorizationNotPerformedError; end
25
+ class LoyaltyScopingNotPerformedError < AuthorizationNotPerformedError; end
26
26
  end
@@ -0,0 +1,28 @@
1
+ module Banken
2
+ class LoyaltyFinder
3
+ SUFFIX = "Loyalty"
4
+
5
+ attr_reader :controller
6
+
7
+ def initialize(controller)
8
+ @controller = controller.to_s
9
+ end
10
+
11
+ def loyalty
12
+ loyalty_name.constantize
13
+ rescue NameError
14
+ nil
15
+ end
16
+
17
+ def loyalty!
18
+ raise NotDefinedError, "unable to find loyalty of nil" unless controller
19
+ loyalty || raise(NotDefinedError, "unable to find loyalty `#{loyalty_name}` for `#{controller}`")
20
+ end
21
+
22
+ private
23
+
24
+ def loyalty_name
25
+ "#{controller.camelize}#{SUFFIX}"
26
+ end
27
+ end
28
+ end
@@ -1,3 +1,3 @@
1
1
  module Banken
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.1"
3
3
  end
@@ -1,2 +1,2 @@
1
1
  Description:
2
- Generates an application policy as a starting point for your application.
2
+ Generates an application loyalty as a starting point for your application.
@@ -3,8 +3,8 @@ module Banken
3
3
  class InstallGenerator < ::Rails::Generators::Base
4
4
  source_root File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
5
5
 
6
- def copy_application_policy
7
- template 'application_policy.rb', 'app/policies/application_policy.rb'
6
+ def copy_application_loyalty
7
+ template 'application_loyalty.rb', 'app/loyalties/application_loyalty.rb'
8
8
  end
9
9
  end
10
10
  end
@@ -1,4 +1,4 @@
1
- class ApplicationPolicy
1
+ class ApplicationLoyalty
2
2
  attr_reader :user, :record
3
3
 
4
4
  def initialize(user, record)
@@ -11,7 +11,7 @@ class ApplicationPolicy
11
11
  end
12
12
 
13
13
  def show?
14
- scope.where(:id => record.id).exists?
14
+ false
15
15
  end
16
16
 
17
17
  def create?
@@ -33,21 +33,4 @@ class ApplicationPolicy
33
33
  def destroy?
34
34
  false
35
35
  end
36
-
37
- def scope
38
- Scope.new(user, record.class).resolve
39
- end
40
-
41
- class Scope
42
- attr_reader :user, :scope
43
-
44
- def initialize(user, scope)
45
- @user = user
46
- @scope = scope
47
- end
48
-
49
- def resolve
50
- scope
51
- end
52
- end
53
36
  end
@@ -0,0 +1,8 @@
1
+ Description:
2
+ Generates a loyalty for a controller with the given name.
3
+
4
+ Example:
5
+ rails generate banken:loyalty users
6
+
7
+ This will create:
8
+ app/loyalties/users_loyalty.rb
@@ -0,0 +1,13 @@
1
+ module Banken
2
+ module Generators
3
+ class LoyaltyGenerator < ::Rails::Generators::NamedBase
4
+ source_root File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
5
+
6
+ def create_loyalty
7
+ template 'loyalty.rb', File.join('app/loyalties', class_path, "#{file_name}_loyalty.rb")
8
+ end
9
+
10
+ hook_for :test_framework
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,4 @@
1
+ <% module_namespacing do -%>
2
+ class <%= class_name %>Loyalty < ApplicationLoyalty
3
+ end
4
+ <% end -%>
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: banken
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - kyuden
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-30 00:00:00.000000000 Z
11
+ date: 2015-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -108,6 +108,20 @@ dependencies:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: yard
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
111
125
  description: Object oriented authorization like pundit for Rails applications.
112
126
  email:
113
127
  - msmsms.um@gmail.com
@@ -116,6 +130,8 @@ extensions: []
116
130
  extra_rdoc_files: []
117
131
  files:
118
132
  - ".gitignore"
133
+ - ".rspec"
134
+ - ".travis.yml"
119
135
  - CODE_OF_CONDUCT.md
120
136
  - Gemfile
121
137
  - LICENSE.txt
@@ -124,15 +140,14 @@ files:
124
140
  - banken.gemspec
125
141
  - lib/banken.rb
126
142
  - lib/banken/error.rb
127
- - lib/banken/helper.rb
128
- - lib/banken/policy_finder.rb
143
+ - lib/banken/loyalty_finder.rb
129
144
  - lib/banken/version.rb
130
145
  - lib/generators/banken/install/USAGE
131
146
  - lib/generators/banken/install/install_generator.rb
132
- - lib/generators/banken/install/templates/application_policy.rb
133
- - lib/generators/banken/policy/USAGE
134
- - lib/generators/banken/policy/policy_generator.rb
135
- - lib/generators/banken/policy/templates/policy.rb
147
+ - lib/generators/banken/install/templates/application_loyalty.rb
148
+ - lib/generators/banken/loyalty/USAGE
149
+ - lib/generators/banken/loyalty/loyalty_generator.rb
150
+ - lib/generators/banken/loyalty/templates/loyalty.rb
136
151
  homepage: https://github.com/kyuden/banken
137
152
  licenses:
138
153
  - MIT
@@ -158,3 +173,4 @@ signing_key:
158
173
  specification_version: 4
159
174
  summary: OO authorization for Rails.
160
175
  test_files: []
176
+ has_rdoc:
data/lib/banken/helper.rb DELETED
@@ -1,8 +0,0 @@
1
- module Banken
2
- module Helper
3
- # TODO
4
- # def policy_scope(scope)
5
- # banken_policy_scope(scope)
6
- # end
7
- end
8
- end
@@ -1,41 +0,0 @@
1
- module Banken
2
- class PolicyFinder
3
- SUFFIX = "Policy"
4
-
5
- attr_reader :controller
6
-
7
- def initialize(controller)
8
- @controller = controller
9
- end
10
-
11
- def scope
12
- policy::Scope if policy
13
- rescue NameError
14
- nil
15
- end
16
-
17
- def policy
18
- klass = find
19
- klass = klass.constantize if klass.is_a?(String)
20
- klass
21
- rescue NameError
22
- nil
23
- end
24
-
25
- def scope!
26
- raise NotDefinedError, "unable to find policy scope of nil" unless controller
27
- scope || raise(NotDefinedError, "unable to find scope `#{find}::Scope` for `#{controller}`")
28
- end
29
-
30
- def policy!
31
- raise NotDefinedError, "unable to find policy of nil" unless controller
32
- policy || raise(NotDefinedError, "unable to find policy `#{find}` for `#{controller}`")
33
- end
34
-
35
- private
36
-
37
- def find
38
- "#{controller.camelize}#{SUFFIX}"
39
- end
40
- end
41
- end
@@ -1,8 +0,0 @@
1
- Description:
2
- Generates a policy for a controller with the given name.
3
-
4
- Example:
5
- rails generate banken:policy users
6
-
7
- This will create:
8
- app/policies/users_policy.rb
@@ -1,13 +0,0 @@
1
- module Banken
2
- module Generators
3
- class PolicyGenerator < ::Rails::Generators::NamedBase
4
- source_root File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
5
-
6
- def create_policy
7
- template 'policy.rb', File.join('app/policies', class_path, "#{file_name}_policy.rb")
8
- end
9
-
10
- hook_for :test_framework
11
- end
12
- end
13
- end
@@ -1,9 +0,0 @@
1
- <% module_namespacing do -%>
2
- class <%= class_name %>Policy < ApplicationPolicy
3
- class Scope < Scope
4
- def resolve
5
- scope
6
- end
7
- end
8
- end
9
- <% end -%>