banken 1.0.2 → 1.1.0

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.
@@ -0,0 +1,202 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/concern"
4
+
5
+ module Banken
6
+ # The controller mixin. Include this module, not `Banken` itself:
7
+ #
8
+ # class ApplicationController < ActionController::Base
9
+ # include Banken::Authorization
10
+ # end
11
+ #
12
+ # `include Banken` keeps working, but it also makes every constant under the
13
+ # Banken namespace (Error, VERSION, LoyaltyFinder, Railtie, ...) resolvable
14
+ # inside the controller, shadowing application constants of the same name.
15
+ module Authorization
16
+ extend ActiveSupport::Concern
17
+
18
+ included do
19
+ if respond_to?(:helper_method)
20
+ helper_method :loyalty
21
+ helper_method :banken_user
22
+ end
23
+ end
24
+
25
+ # Rails treats every public instance method of a non-abstract controller
26
+ # as a routable action. Keep Banken's helpers out of that set, so a
27
+ # wildcard route such as `get "posts/:action"` cannot dispatch to
28
+ # `skip_authorization` or `verify_authorized`.
29
+ class_methods do
30
+ def action_methods
31
+ @_banken_action_methods ||= super - Banken::Authorization::HIDDEN_ACTIONS
32
+ end
33
+
34
+ def clear_action_methods!
35
+ @_banken_action_methods = nil
36
+ super
37
+ end
38
+ end
39
+
40
+ def authorize!(record=nil)
41
+ @_banken_authorization_performed = true
42
+
43
+ loyalty = loyalty(record)
44
+ query = banken_query_name
45
+
46
+ unless banken_query(loyalty, query)
47
+ raise Banken::NotAuthorizedError.new(controller: banken_controller_name, query: query, loyalty: loyalty)
48
+ end
49
+
50
+ true
51
+ end
52
+
53
+ def permitted_attributes(record)
54
+ attributes = banken_params_for(record)
55
+ unless attributes.respond_to?(:permit)
56
+ # A scalar or an array where a hash of attributes was expected.
57
+ raise ActionController::ParameterMissing, banken_param_key(record)
58
+ end
59
+ attributes.permit(loyalty(record).permitted_attributes)
60
+ end
61
+
62
+ def loyalty(record=nil, controller_name=nil)
63
+ controller_name = banken_controller_name unless controller_name
64
+ banken_loyalty_class(controller_name).new(banken_user, record)
65
+ end
66
+
67
+ def banken_user
68
+ current_user
69
+ end
70
+
71
+ def skip_authorization
72
+ @_banken_authorization_performed = true
73
+ end
74
+
75
+ def verify_authorized
76
+ return if banken_authorization_performed?
77
+
78
+ where = [self.class.name, banken_action_name.presence].compact.join("#")
79
+ raise Banken::AuthorizationNotPerformedError, "#{where} did not call authorize! or skip_authorization"
80
+ end
81
+
82
+ def banken_authorization_performed?
83
+ !!@_banken_authorization_performed
84
+ end
85
+
86
+ # @deprecated Use banken_authorization_performed? instead.
87
+ def banken_loyalty_authorized?
88
+ Banken.deprecator.warn('banken_loyalty_authorized? is deprecated, use banken_authorization_performed? instead.')
89
+ banken_authorization_performed?
90
+ end
91
+
92
+ # The public helpers above, by name. Computed here so that it always
93
+ # matches what the module actually defines.
94
+ HIDDEN_ACTIONS = public_instance_methods(false).map(&:to_s).sort.freeze
95
+
96
+ private
97
+
98
+ # Rails sets action_name and controller_path on every controller and, unlike
99
+ # params[:controller] / params[:action], they cannot be supplied by the
100
+ # request. On a Rails controller only those are consulted: for routes that
101
+ # target an endpoint directly (`get "/x" => PostsController.action(:destroy)`,
102
+ # `mount`) and for anonymous controllers the path parameters carry no
103
+ # controller or action, and reading params there would let the query
104
+ # string choose the loyalty. params are the source only for hosts that do
105
+ # not provide action_name / controller_path at all (plain Ruby objects).
106
+ def banken_action_name
107
+ if respond_to?(:action_name)
108
+ action_name.presence
109
+ else
110
+ params[:action]
111
+ end
112
+ end
113
+
114
+ def banken_controller_name
115
+ if respond_to?(:controller_path)
116
+ controller_path.presence || raise(Banken::NotDefinedError, "#{self.class} has no controller_path (anonymous controller?); pass the controller name to loyalty explicitly")
117
+ else
118
+ params[:controller]
119
+ end
120
+ end
121
+
122
+ # Calls the query on the loyalty. A query must be defined by the loyalty
123
+ # itself (or a module/superclass of it below Object): ActiveSupport
124
+ # defines `present?` and `duplicable?` on every object and both return
125
+ # true, so an action named `present` would otherwise authorize everyone.
126
+ # Queries answered through method_missing keep working. A missing or
127
+ # private query raises QueryNotDefinedError instead of NoMethodError.
128
+ def banken_query(loyalty, query)
129
+ owner = banken_query_owner(loyalty, query)
130
+ if owner && Object <= owner
131
+ raise Banken::QueryNotDefinedError, "#{loyalty.class}##{query} is not defined by the loyalty (inherited from #{owner})"
132
+ end
133
+
134
+ loyalty.public_send(query)
135
+ rescue NoMethodError => e
136
+ # Only the NoMethodError for this very query on this very loyalty is
137
+ # converted; anything raised inside the query body propagates unchanged.
138
+ raise unless e.name.to_s == query.to_s && banken_error_receiver(e).equal?(loyalty)
139
+
140
+ if loyalty.respond_to?(query, true)
141
+ raise Banken::QueryNotDefinedError, "#{loyalty.class}##{query} is private; queries must be public methods"
142
+ end
143
+ raise Banken::QueryNotDefinedError, "#{loyalty.class}##{query} is not defined"
144
+ end
145
+
146
+ # The module that defines the query, or nil when it is not a statically
147
+ # defined method (method_missing, or a loyalty overriding respond_to?).
148
+ # Kernel#method is called unbound so a loyalty defining its own `method`
149
+ # cannot interfere.
150
+ def banken_query_owner(loyalty, query)
151
+ ::Kernel.instance_method(:method).bind_call(loyalty, query).owner
152
+ rescue NameError, TypeError
153
+ nil
154
+ end
155
+
156
+ # NameError#receiver raises ArgumentError for errors built without one.
157
+ def banken_error_receiver(error)
158
+ error.receiver
159
+ rescue ArgumentError
160
+ nil
161
+ end
162
+
163
+ # Resolving a loyalty class means camelizing and constantizing the controller
164
+ # name (a few microseconds, more for namespaced names); a view may do that
165
+ # dozens of times per request. Memoize the class per controller instance (i.e. per request), so
166
+ # code reloading in development still sees new classes on the next request.
167
+ # Only the class is memoized, never the instance: a loyalty is built fresh
168
+ # for every record and for the current banken_user.
169
+ def banken_loyalty_class(controller_name)
170
+ @_banken_loyalty_classes ||= {}
171
+ @_banken_loyalty_classes[controller_name.to_s] ||= Banken::LoyaltyFinder.new(controller_name).loyalty!
172
+ end
173
+
174
+ # The parameters that hold the attributes of `record`, before filtering.
175
+ # Override (keep it private) to read them from somewhere else; return an
176
+ # ActionController::Parameters.
177
+ def banken_params_for(record)
178
+ params.require(banken_param_key(record))
179
+ end
180
+
181
+ # The params key for `record`, which may be an instance, a class or a
182
+ # Symbol: Post / Post.new -> "post", Admin::Post -> "post", :post -> "post".
183
+ # Override (keep it private) to use e.g. `record.model_name.param_key`
184
+ # ("admin_post").
185
+ def banken_param_key(record)
186
+ return record.to_s if record.is_a?(Symbol)
187
+ raise ArgumentError, "cannot infer a params key for nil; pass a record, a class or a Symbol" if record.nil?
188
+
189
+ klass = record.is_a?(Class) ? record : record.class
190
+ name = klass.name || raise(ArgumentError, "cannot infer a params key for an anonymous class")
191
+ name.demodulize.underscore
192
+ end
193
+
194
+ def banken_query_name
195
+ action = banken_action_name
196
+ if action.blank?
197
+ raise Banken::Error, "unable to infer the query: no action name is available (authorize! must run inside a controller action)"
198
+ end
199
+ "#{action}?"
200
+ end
201
+ end
202
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/deprecation"
4
+
5
+ module Banken
6
+ # Banken's own deprecator. When banken is loaded after Rails (the normal
7
+ # Bundler.require order), Banken::Railtie registers it with
8
+ # `Rails.application.deprecators`, so the application's
9
+ # `config.active_support.deprecation` setting applies to Banken's warnings.
10
+ # Outside Rails, or when banken is required after Rails has initialized, it
11
+ # falls back to ActiveSupport's default behaviour (stderr); such apps can
12
+ # register it themselves: `Rails.application.deprecators[:banken] = Banken.deprecator`.
13
+ #
14
+ # Assigned eagerly rather than memoized so there is exactly one instance
15
+ # regardless of thread timing.
16
+ @deprecator = ActiveSupport::Deprecation.new("2.0", "Banken")
17
+
18
+ class << self
19
+ attr_reader :deprecator
20
+ end
21
+ end
data/lib/banken/error.rb CHANGED
@@ -1,26 +1,50 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Banken
2
4
  class Error < StandardError; end
3
5
 
4
6
  class NotAuthorizedError < Error
5
7
  attr_reader :controller, :query, :loyalty
6
8
 
9
+ # Accepts either a message (`raise Banken::NotAuthorizedError, "must be
10
+ # logged in"`) or an options hash with :controller, :query, :loyalty and
11
+ # an optional :message.
7
12
  def initialize(options={})
8
- if options.is_a? String
9
- message = options
10
- else
13
+ if options.is_a?(Hash)
11
14
  @controller = options[:controller]
12
15
  @query = options[:query]
13
16
  @loyalty = options[:loyalty]
14
17
 
15
- message = options.fetch(:message) { "not allowed to #{query} of #{controller} by #{loyalty.inspect}" }
18
+ message = options.fetch(:message) { default_message }
19
+ else
20
+ message = options
16
21
  end
17
22
 
18
23
  super(message)
19
24
  end
25
+
26
+ private
27
+
28
+ # Names only the loyalty class, the query and the controller. Never
29
+ # inspects the loyalty: its user and record would end up in logs, error
30
+ # trackers and any flash built from the message.
31
+ def default_message
32
+ action = loyalty ? "#{loyalty.class}##{query}" : query.to_s
33
+ parts = ["not allowed to", action, controller && "on #{controller}"]
34
+ parts.reject { |part| part.nil? || part.empty? }.join(" ")
35
+ end
20
36
  end
21
37
 
38
+ # The loyalty class (or the controller name needed to find it) is missing.
22
39
  class NotDefinedError < Error; end
40
+
41
+ # The loyalty exists but does not define the query (or inherits it from
42
+ # Object, or keeps it private). A subclass of NotDefinedError so existing
43
+ # rescues keep working while the two cases stay distinguishable.
44
+ class QueryNotDefinedError < NotDefinedError; end
45
+
23
46
  class AuthorizationNotPerformedError < Error; end
24
47
 
48
+ # Unused: Banken has no scope feature. Kept for compatibility, removed in 2.0.
25
49
  class LoyaltyScopingNotPerformedError < AuthorizationNotPerformedError; end
26
50
  end
@@ -1,28 +1,46 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Banken
2
4
  class LoyaltyFinder
3
5
  SUFFIX = "Loyalty"
4
6
 
5
- attr_reader :controller
7
+ attr_reader :controller_name
6
8
 
7
- def initialize(controller)
8
- @controller = controller.to_s
9
+ def initialize(controller_name)
10
+ @controller_name = controller_name.to_s
9
11
  end
10
12
 
13
+ # Returns the loyalty class, or nil when no such constant exists (or when
14
+ # no controller name was given: an empty name must not resolve a
15
+ # top-level `Loyalty` constant).
16
+ #
17
+ # `safe_constantize` only swallows NameErrors whose name matches a segment
18
+ # of the loyalty name (or that carry no name at all); this includes
19
+ # Zeitwerk's "expected file to define constant" error. Any other error
20
+ # raised while the loyalty file loads, such as a NoMethodError from a typo
21
+ # in the class body, propagates so the real bug is visible.
11
22
  def loyalty
12
- loyalty_name.constantize
13
- rescue NameError
14
- nil
23
+ return nil if controller_name.empty?
24
+
25
+ loyalty_name.safe_constantize
15
26
  end
16
27
 
17
28
  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}`")
29
+ loyalty || raise(NotDefinedError, not_defined_message)
20
30
  end
21
31
 
22
32
  private
23
33
 
24
34
  def loyalty_name
25
- "#{controller.camelize}#{SUFFIX}"
35
+ "#{controller_name.camelize}#{SUFFIX}"
36
+ end
37
+
38
+ def not_defined_message
39
+ if controller_name.empty?
40
+ "unable to find a loyalty: no controller name was given"
41
+ else
42
+ "unable to find loyalty `#{loyalty_name}` for `#{controller_name}` (expected app/loyalties/#{controller_name}_loyalty.rb to define it)"
43
+ end
26
44
  end
27
45
  end
28
46
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Banken
4
+ class Railtie < ::Rails::Railtie
5
+ initializer "banken.deprecator" do |app|
6
+ app.deprecators[:banken] = Banken.deprecator
7
+ end
8
+ end
9
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Banken
2
- VERSION = "1.0.2"
4
+ VERSION = "1.1.0"
3
5
  end
data/lib/banken.rb CHANGED
@@ -1,27 +1,24 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "active_support/concern"
2
4
  require "active_support/core_ext/string/inflections"
3
5
  require "active_support/core_ext/object/blank"
4
- require "active_support/core_ext/module/introspection"
5
6
  require "banken/version"
6
7
  require "banken/error"
7
8
  require "banken/loyalty_finder"
8
-
9
+ require "banken/deprecator"
10
+ require "banken/authorization"
11
+ require "banken/railtie" if defined?(::Rails::Railtie)
12
+
13
+ # Banken's controller helpers live in Banken::Authorization; include that
14
+ # module in your controllers. Including `Banken` itself still works for
15
+ # compatibility: it includes Banken::Authorization, but also brings every
16
+ # constant under this namespace into the controller's constant lookup.
9
17
  module Banken
10
18
  extend ActiveSupport::Concern
11
19
 
12
20
  included do
13
- if respond_to?(:helper_method)
14
- helper_method :loyalty
15
- helper_method :banken_user
16
- end
17
-
18
- if respond_to?(:hide_action)
19
- hide_action :permitted_attributes
20
- hide_action :loyalty
21
- hide_action :banken_user
22
- hide_action :skip_authorization
23
- hide_action :verify_authorized
24
- end
21
+ include Banken::Authorization
25
22
  end
26
23
 
27
24
  class << self
@@ -29,55 +26,4 @@ module Banken
29
26
  LoyaltyFinder.new(controller_name).loyalty!.new(user, record)
30
27
  end
31
28
  end
32
-
33
- def authorize!(record=nil)
34
- @_banken_loyalty_authorized = true
35
-
36
- loyalty = loyalty(record)
37
- unless loyalty.public_send(banken_query_name)
38
- raise NotAuthorizedError.new(controller: banken_controller_name, query: banken_query_name, loyalty: loyalty)
39
- end
40
-
41
- true
42
- end
43
-
44
- def permitted_attributes(record)
45
- name = record.class.to_s.demodulize.underscore
46
- params.require(name).permit(loyalty(record).permitted_attributes)
47
- end
48
-
49
- def loyalty(record=nil, controller_name=nil)
50
- controller_name = banken_controller_name unless controller_name
51
- Banken.loyalty!(controller_name, banken_user, record)
52
- end
53
-
54
- def banken_user
55
- current_user
56
- end
57
-
58
- def skip_authorization
59
- @_banken_loyalty_authorized = true
60
- end
61
-
62
- def verify_authorized
63
- raise AuthorizationNotPerformedError unless banken_loyalty_authorized?
64
- end
65
-
66
- def banken_loyalty_authorized?
67
- !!@_banken_loyalty_authorized
68
- end
69
-
70
- private
71
-
72
- def banken_action_name
73
- params[:action]
74
- end
75
-
76
- def banken_controller_name
77
- params[:controller]
78
- end
79
-
80
- def banken_query_name
81
- "#{banken_action_name}?"
82
- end
83
29
  end
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Banken
2
4
  module Generators
3
5
  class InstallGenerator < ::Rails::Generators::Base
4
6
  source_root File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
5
7
 
6
8
  def copy_application_loyalty
7
- template 'application_loyalty.rb', 'app/loyalties/application_loyalty.rb'
9
+ template 'application_loyalty.rb.tt', 'app/loyalties/application_loyalty.rb'
8
10
  end
9
11
  end
10
12
  end
@@ -1,13 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Banken
2
4
  module Generators
3
5
  class LoyaltyGenerator < ::Rails::Generators::NamedBase
4
6
  source_root File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
5
7
 
6
8
  def create_loyalty
7
- template 'loyalty.rb', File.join('app/loyalties', class_path, "#{file_name}_loyalty.rb")
9
+ template 'loyalty.rb.tt', File.join('app/loyalties', class_path, "#{file_name}_loyalty.rb")
8
10
  end
9
-
10
- hook_for :test_framework
11
11
  end
12
12
  end
13
13
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: banken
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.2
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - kyuden
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2016-01-29 00:00:00.000000000 Z
10
+ date: 1980-01-02 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: activesupport
@@ -16,84 +15,70 @@ dependencies:
16
15
  requirements:
17
16
  - - ">="
18
17
  - !ruby/object:Gem::Version
19
- version: 3.0.0
18
+ version: '7.1'
20
19
  type: :runtime
21
20
  prerelease: false
22
21
  version_requirements: !ruby/object:Gem::Requirement
23
22
  requirements:
24
23
  - - ">="
25
24
  - !ruby/object:Gem::Version
26
- version: 3.0.0
25
+ version: '7.1'
27
26
  - !ruby/object:Gem::Dependency
28
27
  name: activemodel
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
30
  - - ">="
32
31
  - !ruby/object:Gem::Version
33
- version: 3.0.0
32
+ version: '7.1'
34
33
  type: :development
35
34
  prerelease: false
36
35
  version_requirements: !ruby/object:Gem::Requirement
37
36
  requirements:
38
37
  - - ">="
39
38
  - !ruby/object:Gem::Version
40
- version: 3.0.0
39
+ version: '7.1'
41
40
  - !ruby/object:Gem::Dependency
42
41
  name: actionpack
43
42
  requirement: !ruby/object:Gem::Requirement
44
43
  requirements:
45
44
  - - ">="
46
45
  - !ruby/object:Gem::Version
47
- version: 3.0.0
46
+ version: '7.1'
48
47
  type: :development
49
48
  prerelease: false
50
49
  version_requirements: !ruby/object:Gem::Requirement
51
50
  requirements:
52
51
  - - ">="
53
52
  - !ruby/object:Gem::Version
54
- version: 3.0.0
53
+ version: '7.1'
55
54
  - !ruby/object:Gem::Dependency
56
- name: bundler
55
+ name: railties
57
56
  requirement: !ruby/object:Gem::Requirement
58
57
  requirements:
59
- - - "~>"
58
+ - - ">="
60
59
  - !ruby/object:Gem::Version
61
- version: '1.3'
60
+ version: '7.1'
62
61
  type: :development
63
62
  prerelease: false
64
63
  version_requirements: !ruby/object:Gem::Requirement
65
64
  requirements:
66
- - - "~>"
65
+ - - ">="
67
66
  - !ruby/object:Gem::Version
68
- version: '1.3'
67
+ version: '7.1'
69
68
  - !ruby/object:Gem::Dependency
70
- name: rspec
69
+ name: minitest
71
70
  requirement: !ruby/object:Gem::Requirement
72
71
  requirements:
73
72
  - - "~>"
74
73
  - !ruby/object:Gem::Version
75
- version: '3.0'
74
+ version: '5.0'
76
75
  type: :development
77
76
  prerelease: false
78
77
  version_requirements: !ruby/object:Gem::Requirement
79
78
  requirements:
80
79
  - - "~>"
81
80
  - !ruby/object:Gem::Version
82
- version: '3.0'
83
- - !ruby/object:Gem::Dependency
84
- name: pry
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ">="
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ">="
95
- - !ruby/object:Gem::Version
96
- version: '0'
81
+ version: '5.0'
97
82
  - !ruby/object:Gem::Dependency
98
83
  name: rake
99
84
  requirement: !ruby/object:Gem::Requirement
@@ -130,30 +115,31 @@ executables: []
130
115
  extensions: []
131
116
  extra_rdoc_files: []
132
117
  files:
133
- - ".gitignore"
134
- - ".rspec"
135
- - ".travis.yml"
136
- - CODE_OF_CONDUCT.md
137
- - Gemfile
118
+ - CHANGELOG.md
138
119
  - LICENSE.txt
139
120
  - README.md
140
- - Rakefile
141
- - banken.gemspec
121
+ - SECURITY.md
142
122
  - lib/banken.rb
123
+ - lib/banken/authorization.rb
124
+ - lib/banken/deprecator.rb
143
125
  - lib/banken/error.rb
144
126
  - lib/banken/loyalty_finder.rb
127
+ - lib/banken/railtie.rb
145
128
  - lib/banken/version.rb
146
129
  - lib/generators/banken/install/USAGE
147
130
  - lib/generators/banken/install/install_generator.rb
148
- - lib/generators/banken/install/templates/application_loyalty.rb
131
+ - lib/generators/banken/install/templates/application_loyalty.rb.tt
149
132
  - lib/generators/banken/loyalty/USAGE
150
133
  - lib/generators/banken/loyalty/loyalty_generator.rb
151
- - lib/generators/banken/loyalty/templates/loyalty.rb
134
+ - lib/generators/banken/loyalty/templates/loyalty.rb.tt
152
135
  homepage: https://github.com/kyuden/banken
153
136
  licenses:
154
137
  - MIT
155
- metadata: {}
156
- post_install_message:
138
+ metadata:
139
+ source_code_uri: https://github.com/kyuden/banken
140
+ changelog_uri: https://github.com/kyuden/banken/blob/v1.1.0/CHANGELOG.md
141
+ bug_tracker_uri: https://github.com/kyuden/banken/issues
142
+ rubygems_mfa_required: 'true'
157
143
  rdoc_options: []
158
144
  require_paths:
159
145
  - lib
@@ -161,17 +147,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
161
147
  requirements:
162
148
  - - ">="
163
149
  - !ruby/object:Gem::Version
164
- version: '0'
150
+ version: '3.3'
165
151
  required_rubygems_version: !ruby/object:Gem::Requirement
166
152
  requirements:
167
153
  - - ">="
168
154
  - !ruby/object:Gem::Version
169
155
  version: '0'
170
156
  requirements: []
171
- rubyforge_project:
172
- rubygems_version: 2.4.5.1
173
- signing_key:
157
+ rubygems_version: 4.0.20
174
158
  specification_version: 4
175
159
  summary: Simple and lightweight authorization solution for Rails.
176
160
  test_files: []
177
- has_rdoc:
data/.gitignore DELETED
@@ -1,9 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
data/.rspec DELETED
@@ -1,2 +0,0 @@
1
- --color
2
- --order rand
data/.travis.yml DELETED
@@ -1,8 +0,0 @@
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