action_policy 0.4.3 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +221 -174
  3. data/LICENSE.txt +1 -1
  4. data/README.md +7 -11
  5. data/lib/.rbnext/2.7/action_policy/behaviours/policy_for.rb +62 -0
  6. data/lib/.rbnext/2.7/action_policy/i18n.rb +56 -0
  7. data/lib/.rbnext/2.7/action_policy/policy/cache.rb +101 -0
  8. data/lib/.rbnext/2.7/action_policy/policy/pre_check.rb +162 -0
  9. data/lib/.rbnext/2.7/action_policy/rspec/be_authorized_to.rb +89 -0
  10. data/lib/.rbnext/2.7/action_policy/rspec/have_authorized_scope.rb +124 -0
  11. data/lib/.rbnext/2.7/action_policy/utils/pretty_print.rb +159 -0
  12. data/lib/.rbnext/3.0/action_policy/behaviour.rb +115 -0
  13. data/lib/.rbnext/3.0/action_policy/behaviours/policy_for.rb +62 -0
  14. data/lib/.rbnext/3.0/action_policy/behaviours/scoping.rb +35 -0
  15. data/lib/.rbnext/3.0/action_policy/behaviours/thread_memoized.rb +59 -0
  16. data/lib/.rbnext/3.0/action_policy/ext/policy_cache_key.rb +72 -0
  17. data/lib/.rbnext/3.0/action_policy/policy/aliases.rb +69 -0
  18. data/lib/.rbnext/3.0/action_policy/policy/authorization.rb +87 -0
  19. data/lib/.rbnext/3.0/action_policy/policy/cache.rb +101 -0
  20. data/lib/.rbnext/3.0/action_policy/policy/core.rb +161 -0
  21. data/lib/.rbnext/3.0/action_policy/policy/defaults.rb +31 -0
  22. data/lib/.rbnext/3.0/action_policy/policy/execution_result.rb +37 -0
  23. data/lib/.rbnext/3.0/action_policy/policy/pre_check.rb +162 -0
  24. data/lib/.rbnext/3.0/action_policy/policy/reasons.rb +212 -0
  25. data/lib/.rbnext/3.0/action_policy/policy/scoping.rb +160 -0
  26. data/lib/.rbnext/3.0/action_policy/rspec/be_authorized_to.rb +89 -0
  27. data/lib/.rbnext/3.0/action_policy/rspec/have_authorized_scope.rb +124 -0
  28. data/lib/.rbnext/3.0/action_policy/utils/pretty_print.rb +159 -0
  29. data/lib/.rbnext/3.0/action_policy/utils/suggest_message.rb +19 -0
  30. data/lib/action_policy.rb +7 -1
  31. data/lib/action_policy/behaviour.rb +22 -16
  32. data/lib/action_policy/behaviours/policy_for.rb +10 -3
  33. data/lib/action_policy/behaviours/scoping.rb +2 -1
  34. data/lib/action_policy/behaviours/thread_memoized.rb +1 -3
  35. data/lib/action_policy/ext/module_namespace.rb +1 -6
  36. data/lib/action_policy/ext/policy_cache_key.rb +10 -30
  37. data/lib/action_policy/ext/{symbol_classify.rb → symbol_camelize.rb} +6 -6
  38. data/lib/action_policy/i18n.rb +1 -1
  39. data/lib/action_policy/lookup_chain.rb +41 -21
  40. data/lib/action_policy/policy/aliases.rb +7 -12
  41. data/lib/action_policy/policy/authorization.rb +8 -7
  42. data/lib/action_policy/policy/cache.rb +11 -17
  43. data/lib/action_policy/policy/core.rb +25 -12
  44. data/lib/action_policy/policy/defaults.rb +3 -9
  45. data/lib/action_policy/policy/execution_result.rb +3 -9
  46. data/lib/action_policy/policy/pre_check.rb +19 -58
  47. data/lib/action_policy/policy/reasons.rb +32 -20
  48. data/lib/action_policy/policy/scoping.rb +5 -6
  49. data/lib/action_policy/rails/controller.rb +6 -1
  50. data/lib/action_policy/rails/ext/active_record.rb +7 -0
  51. data/lib/action_policy/rails/policy/instrumentation.rb +1 -1
  52. data/lib/action_policy/rspec/be_authorized_to.rb +5 -9
  53. data/lib/action_policy/rspec/dsl.rb +3 -3
  54. data/lib/action_policy/rspec/have_authorized_scope.rb +5 -7
  55. data/lib/action_policy/utils/pretty_print.rb +21 -24
  56. data/lib/action_policy/utils/suggest_message.rb +1 -3
  57. data/lib/action_policy/version.rb +1 -1
  58. data/lib/generators/action_policy/install/templates/{application_policy.rb → application_policy.rb.tt} +1 -1
  59. data/lib/generators/action_policy/policy/policy_generator.rb +4 -1
  60. data/lib/generators/action_policy/policy/templates/{policy.rb → policy.rb.tt} +0 -0
  61. data/lib/generators/rspec/templates/{policy_spec.rb → policy_spec.rb.tt} +0 -0
  62. data/lib/generators/test_unit/templates/{policy_test.rb → policy_test.rb.tt} +0 -0
  63. metadata +55 -119
  64. data/.gitattributes +0 -2
  65. data/.github/FUNDING.yml +0 -1
  66. data/.github/ISSUE_TEMPLATE.md +0 -18
  67. data/.github/PULL_REQUEST_TEMPLATE.md +0 -29
  68. data/.gitignore +0 -15
  69. data/.rubocop.yml +0 -54
  70. data/.tidelift.yml +0 -6
  71. data/.travis.yml +0 -31
  72. data/Gemfile +0 -22
  73. data/Rakefile +0 -27
  74. data/action_policy.gemspec +0 -44
  75. data/benchmarks/namespaced_lookup_cache.rb +0 -71
  76. data/bin/console +0 -14
  77. data/bin/setup +0 -8
  78. data/docs/.nojekyll +0 -0
  79. data/docs/CNAME +0 -1
  80. data/docs/README.md +0 -79
  81. data/docs/_sidebar.md +0 -27
  82. data/docs/aliases.md +0 -122
  83. data/docs/assets/docsify-search.js +0 -364
  84. data/docs/assets/docsify.min.js +0 -3
  85. data/docs/assets/fonts/FiraCode-Medium.woff +0 -0
  86. data/docs/assets/fonts/FiraCode-Regular.woff +0 -0
  87. data/docs/assets/images/banner.png +0 -0
  88. data/docs/assets/images/cache.png +0 -0
  89. data/docs/assets/images/cache.svg +0 -70
  90. data/docs/assets/images/layer.png +0 -0
  91. data/docs/assets/images/layer.svg +0 -35
  92. data/docs/assets/prism-ruby.min.js +0 -1
  93. data/docs/assets/styles.css +0 -347
  94. data/docs/assets/vue.min.css +0 -1
  95. data/docs/authorization_context.md +0 -92
  96. data/docs/behaviour.md +0 -113
  97. data/docs/caching.md +0 -291
  98. data/docs/controller_action_aliases.md +0 -109
  99. data/docs/custom_lookup_chain.md +0 -48
  100. data/docs/custom_policy.md +0 -53
  101. data/docs/debugging.md +0 -55
  102. data/docs/decorators.md +0 -27
  103. data/docs/favicon.ico +0 -0
  104. data/docs/graphql.md +0 -302
  105. data/docs/i18n.md +0 -44
  106. data/docs/index.html +0 -43
  107. data/docs/instrumentation.md +0 -84
  108. data/docs/lookup_chain.md +0 -17
  109. data/docs/namespaces.md +0 -77
  110. data/docs/non_rails.md +0 -28
  111. data/docs/pre_checks.md +0 -57
  112. data/docs/pundit_migration.md +0 -80
  113. data/docs/quick_start.md +0 -118
  114. data/docs/rails.md +0 -120
  115. data/docs/reasons.md +0 -120
  116. data/docs/scoping.md +0 -255
  117. data/docs/testing.md +0 -333
  118. data/docs/writing_policies.md +0 -107
  119. data/gemfiles/jruby.gemfile +0 -8
  120. data/gemfiles/rails42.gemfile +0 -9
  121. data/gemfiles/rails6.gemfile +0 -8
  122. data/gemfiles/railsmaster.gemfile +0 -6
  123. data/lib/action_policy/ext/string_match.rb +0 -14
  124. data/lib/action_policy/ext/yield_self_then.rb +0 -25
@@ -1,55 +0,0 @@
1
- # Debug Helpers
2
-
3
- **NOTE:** this functionality requires two additional gems to be available in the app:
4
- - [unparser](https://github.com/mbj/unparser)
5
- - [method_source](https://github.com/banister/method_source).
6
-
7
- We usually describe policy rules using _boolean expressions_ (e.g. `A or (B and C)` where each of `A`, `B` and `C` is a simple boolean expression or predicate method).
8
-
9
- When dealing with complex policies, it could be hard to figure out which predicate/check made policy to fail.
10
-
11
- The `Policy#pp(rule)` method aims to help debug such situations.
12
-
13
- Consider a (synthetic) example:
14
-
15
- ```ruby
16
- def feed?
17
- (admin? || allowed_to?(:access_feed?)) &&
18
- (user.name == "Jack" || user.name == "Kate")
19
- end
20
-
21
- ```
22
-
23
- Suppose that you want to debug this rule ("Why does it return false?").
24
- You can drop a [`binding.pry`](https://github.com/deivid-rodriguez/pry-byebug) (or `binding.irb`) right at the beginning of the method:
25
-
26
- ```ruby
27
- def feed?
28
- binding.pry # rubocop:disable Lint/Debugger
29
- #...
30
- end
31
- ```
32
-
33
- Now, run your code and trigger the breakpoint (i.e., run the method):
34
-
35
- ```
36
- # now you can preview the execution of the rule using the `pp` method (defined on the policy instance)
37
- pry> pp :feed?
38
- MyPolicy#feed?
39
- ↳ (
40
- admin? #=> false
41
- OR
42
- allowed_to?(:access_feed?) #=> true
43
- )
44
- AND
45
- (
46
- user.name == "Jack" #=> false
47
- OR
48
- user.name == "Kate" #=> true
49
- )
50
-
51
- # you can also check other rules or methods as well
52
- pry> pp :admin?
53
- MyPolicy#admin?
54
- ↳ user.admin? #=> false
55
- ```
@@ -1,27 +0,0 @@
1
- # Dealing with Decorators
2
-
3
- Ref: [action_policy#7](https://github.com/palkan/action_policy/issues/7).
4
-
5
- Since Action Policy [lookup mechanism](./lookup_chain.md) relies on the target
6
- record's class properties (names, methods) it could break when using with _decorators_.
7
-
8
- To make `authorize!` and other [behaviour](./behaviour.md) methods work seamlessly with decorated
9
- objects, you might want to _enhance_ the `policy_for` method.
10
-
11
- For example, when using the [Draper](https://github.com/drapergem/draper) gem:
12
-
13
- ```ruby
14
- module ActionPolicy
15
- module Draper
16
- def policy_for(record:, **opts)
17
- # From https://github.com/GoodMeasuresLLC/draper-cancancan/blob/master/lib/draper/cancancan.rb
18
- record = record.model while record.is_a?(::Draper::Decorator)
19
- super(record: record, **opts)
20
- end
21
- end
22
- end
23
-
24
- class ApplicationController < ActionController::Base
25
- prepend ActionPolicy::Draper
26
- end
27
- ```
Binary file
@@ -1,302 +0,0 @@
1
- # GraphQL integration
2
-
3
- You can use Action Policy as an authorization library for your [GraphQL Ruby](https://graphql-ruby.org/) application via the [`action_policy-graphql` gem](https://github.com/palkan/action_policy-graphql).
4
-
5
- This integration provides the following features:
6
- - Fields & mutations authorization
7
- - List and connections scoping
8
- - [**Exposing permissions/authorization rules in the API**](https://evilmartians.com/chronicles/exposing-permissions-in-graphql-apis-with-action-policy).
9
-
10
- ## Getting Started
11
-
12
- First, add the `action_policy-graphql` gem to your Gemfile (see [installation instructions](https://github.com/palkan/action_policy-graphql#installation)).
13
-
14
- Then, include `ActionPolicy::GraphQL::Behaviour` to your base type (or any other type/mutation where you want to use authorization features):
15
-
16
- ```ruby
17
- # For fields authorization, lists scoping and rules exposing
18
- class Types::BaseObject < GraphQL::Schema::Object
19
- include ActionPolicy::GraphQL::Behaviour
20
- end
21
-
22
- # For using authorization helpers in mutations
23
- class Types::BaseMutation < GraphQL::Schema::Mutation
24
- include ActionPolicy::GraphQL::Behaviour
25
- end
26
-
27
- # For using authorization helpers in resolvers
28
- class Types::BaseResolver < GraphQL::Schema::Resolver
29
- include ActionPolicy::GraphQL::Behaviour
30
- end
31
- ```
32
-
33
- ## Authorization Context
34
-
35
- By default, Action Policy uses `context[:current_user]` as the `user` [authorization context](./authorization_context.md).
36
-
37
- **NOTE:** see below for more information on what's included into `ActionPolicy::GraphQL::Behaviour`.
38
-
39
- ## Authorizing Fields
40
-
41
- You can add `authorize: true` option to any field (=underlying object) to protect the access (it's equal to calling `authorize! object, to: :show?`):
42
-
43
- ```ruby
44
- # authorization could be useful for find-like methods,
45
- # where the object is resolved from the provided params (e.g., ID)
46
- field :home, Home, null: false, authorize: true do
47
- argument :id, ID, required: true
48
- end
49
-
50
- def home(id:)
51
- Home.find(id)
52
- end
53
-
54
- # Without `authorize: true` the code would look like this
55
- def home(id:)
56
- Home.find(id).tap { |home| authorize! home, to: :show? }
57
- end
58
- ```
59
-
60
- You can use authorization options to customize the behaviour, e.g. `authorize: {to: :preview?, with: CustomPolicy}`.
61
-
62
- By default, if a user is not authorized to access the field, an `ActionPolicy::Unauthorized` exception is raised.
63
-
64
- If you want to return a `nil` instead, you should add `raise: false` to the options:
65
-
66
- ```ruby
67
- # NOTE: don't forget to mark your field as nullable
68
- field :home, Home, null: true, authorize: {raise: false}
69
- ```
70
-
71
- You can make non-raising behaviour a default by setting a configuration option:
72
-
73
- ```ruby
74
- ActionPolicy::GraphQL.authorize_raise_exception = false
75
- ```
76
-
77
- You can also change the default `show?` rule globally:
78
-
79
- ```ruby
80
- ActionPolicy::GraphQL.default_authorize_rule = :show_graphql_field?
81
- ```
82
-
83
- If you want to perform authorization before resolving the field value, you can use `preauthorize: *` option:
84
-
85
- ```ruby
86
- field :homes, [Home], null: false, preauthorize: {with: HomePolicy}
87
-
88
- def homes
89
- Home.all
90
- end
91
- ```
92
-
93
- The code above is equal to:
94
-
95
- ```ruby
96
- field :homes, [Home], null: false
97
-
98
- def homes
99
- authorize! "homes", to: :index?, with: HomePolicy
100
- Home.all
101
- end
102
- ```
103
-
104
- **NOTE:** we pass the field's name as the `record` to the policy rule. We assume that preauthorization rules do not depend on
105
- the record itself and pass the field's name for debugging purposes only.
106
-
107
- You can customize the authorization options, e.g. `authorize: {to: :preview?, with: CustomPolicy}`.
108
-
109
- **NOTE:** unlike `authorize: *` you MUST specify the `with: SomePolicy` option.
110
- The default authorization rule depends on the type of the field:
111
-
112
- - for lists we use `index?` (configured by `ActionPolicy::GraphQL.default_preauthorize_list_rule` parameter)
113
- - for _singleton_ fields we use `show?` (configured by `ActionPolicy::GraphQL.default_preauthorize_node_rule` parameter)
114
-
115
- ### Class-level authorization
116
-
117
- You can use Action Policy in the class-level [authorization hooks](https://graphql-ruby.org/authorization/authorization.html) (`self.authorized?`) like this:
118
-
119
- ```ruby
120
- class Types::Friendship < Types::BaseObject
121
- def self.authorized?(object, context)
122
- super &&
123
- allowed_to?(
124
- :show?,
125
- object,
126
- # NOTE: you must provide context explicitly
127
- context: {user: context[:current_user]}
128
- )
129
- end
130
- end
131
- ```
132
-
133
- ## Authorizing Mutations
134
-
135
- A mutation is just a Ruby class with a single API method. There is nothing specific in authorizing mutations: from the Action Policy point of view, they are just [_behaviours_](./behaviour.md).
136
-
137
- If you want to authorize the mutation, you call `authorize!` method. For example:
138
-
139
- ```ruby
140
- class Mutations::DestroyUser < Types::BaseMutation
141
- argument :id, ID, required: true
142
-
143
- def resolve(id:)
144
- user = User.find(id)
145
-
146
- # Raise an exception if the user has not enough permissions
147
- authorize! user, to: :destroy?
148
- # Or check without raising and do what you want
149
- #
150
- # if allowed_to?(:destroy?, user)
151
-
152
- user.destroy!
153
-
154
- {deleted_id: user.id}
155
- end
156
- end
157
- ```
158
-
159
- ## Handling exceptions
160
-
161
- The query would fail with `ActionPolicy::Unauthorized` exception when using `authorize: true` (in raising mode) or calling `authorize!` explicitly.
162
-
163
- That could be useful to handle this exception and send a more detailed error message to the client, for example:
164
-
165
- ```ruby
166
- # in your schema file
167
- rescue_from(ActionPolicy::Unauthorized) do |exp|
168
- raise GraphQL::ExecutionError.new(
169
- # use result.message (backed by i18n) as an error message
170
- exp.result.message,
171
- # use GraphQL error extensions to provide more context
172
- extensions: {
173
- code: :unauthorized,
174
- fullMessages: exp.result.reasons.full_messages,
175
- details: exp.result.reasons.details
176
- }
177
- )
178
- end
179
- ```
180
-
181
- ## Scoping Data
182
-
183
- You can add `authorized_scope: true` option to a field (list or [_connection_](https://graphql-ruby.org/relay/connections.html)) to apply the corresponding policy rules to the data:
184
-
185
- ```ruby
186
- class CityType < ::Common::Graphql::Type
187
- # It would automatically apply the relation scope from the EventPolicy to
188
- # the relation (city.events)
189
- field :events, EventType.connection_type,
190
- null: false,
191
- authorized_scope: true
192
-
193
- # you can specify the policy explicitly
194
- field :events, EventType.connection_type,
195
- null: false,
196
- authorized_scope: {with: CustomEventPolicy}
197
-
198
- # without the option you would write the following code
199
- def events
200
- authorized_scope object.events
201
- # or if `with` option specified
202
- authorized_scope object.events, with: CustomEventPolicy
203
- end
204
- end
205
- ```
206
-
207
- **NOTE:** you cannot use `authorize: *` and `authorized_scope: *` at the same time but you can combine `preauthorize: *` with `authorized_scope: *`.
208
-
209
- See the documenation on [scoping](./scoping.md).
210
-
211
- ## Exposing Authorization Rules
212
-
213
- With `action_policy-graphql` gem, you can easily expose your authorization logic to the client in a standardized way.
214
-
215
- For example, if you want to "tell" the client which actions could be performed against the object you
216
- can use the `expose_authorization_rules` macro to add authorization-related fields to your type:
217
-
218
- ```ruby
219
- class ProfileType < Types::BaseType
220
- # Adds can_edit, can_destroy fields with
221
- # AuthorizationResult type.
222
-
223
- # NOTE: prefix "can_" is used by default, no need to specify it explicitly
224
- expose_authorization_rules :edit?, :destroy?, prefix: "can_"
225
- end
226
- ```
227
-
228
- **NOTE:** you can use [aliases](./aliases.md) here as well as defined rules.
229
-
230
- **NOTE:** This feature relies the [_failure reasons_](./reasons.md) and
231
- the [i18n integration](./i18n.md) extensions. If your policies don't include any of these,
232
- you won't be able to use it.
233
-
234
- Then the client could perform the following query:
235
-
236
- ```gql
237
- {
238
- post(id: $id) {
239
- canEdit {
240
- # (bool) true|false; not null
241
- value
242
- # top-level decline message ("Not authorized" by default); null if value is true
243
- message
244
- # detailed information about the decline reasons; null if value is true or you don't have "failure reasons" extension enabled
245
- reasons {
246
- details # JSON-encoded hash of the form { "event" => [:privacy_off?] }
247
- fullMessages # Array of human-readable reasons
248
- }
249
- }
250
-
251
- canDestroy {
252
- # ...
253
- }
254
- }
255
- }
256
- ```
257
-
258
- You can override a custom authorization field prefix (`can_`):
259
-
260
- ```ruby
261
- ActionPolicy::GraphQL.default_authorization_field_prefix = "allowed_to_"
262
- ```
263
-
264
- You can specify a custom field name as well (only for a single rule):
265
-
266
- ```ruby
267
- class ProfileType < ::Common::Graphql::Type
268
- # Adds can_create_post field.
269
-
270
- expose_authorization_rules :create?, with: PostPolicy, field_name: "can_create_post"
271
- end
272
- ```
273
-
274
- ## Custom Behaviour
275
-
276
- Including the default `ActionPolicy::GraphQL::Behaviour` is equal to adding the following to your base class:
277
-
278
- ```ruby
279
- class Types::BaseObject < GraphQL::Schema::Object
280
- # include Action Policy behaviour and its extensions
281
- include ActionPolicy::Behaviour
282
- include ActionPolicy::Behaviours::ThreadMemoized
283
- include ActionPolicy::Behaviours::Memoized
284
- include ActionPolicy::Behaviours::Namespaced
285
-
286
- # define authorization context
287
- authorize :user, through: :current_user
288
-
289
- # add a method helper to get the current_user from the context
290
- def current_user
291
- context[:current_user]
292
- end
293
-
294
- # extend the field class to add `authorize` and `authorized_scope` options
295
- field_class.prepend(ActionPolicy::GraphQL::AuthorizedField)
296
-
297
- # add `expose_authorization_rules` macro
298
- include ActionPolicy::GraphQL::Fields
299
- end
300
- ```
301
-
302
- Feel free to create your own behaviour by adding only the functionality you need.
@@ -1,44 +0,0 @@
1
- # I18n Support
2
-
3
- `ActionPolicy` integrates with [`i18n`][] to support localizable `full_messages` for [reasons](./reasons.md) and the execution result's `message`:
4
-
5
- ```ruby
6
- class ApplicationController < ActionController::Base
7
- rescue_from ActionPolicy::Unauthorized do |ex|
8
- p ex.result.message #=> "You do not have access to the stage"
9
- p ex.result.reasons.full_messages #=> ["You do not have access to the stage"]
10
- end
11
- end
12
- ```
13
-
14
- The message contains a string for the _rule_ that was called, while `full_messages` contains the list of reasons, why `ActionPolicy::Unauthorized` has been raised. You can find more information about tracking failure reasons [here](./reasons.md).
15
-
16
- ## Configuration
17
-
18
- `ActionPolicy` doesn't provide any localization out-of-the-box and uses "You are not authorized to perform this action" as the default message.
19
-
20
- You can add your app-level default fallback by providing the `action_policy.unauthorized` key value.
21
-
22
- When using **Rails**, all you need is to add translations to any file under the `config/locales` folder (or create a new file, e.g. `config/locales/policies.yml`).
23
-
24
- Non-Rails projets should configure [`i18n`][] gem manually:
25
-
26
- ```ruby
27
- I18n.load_path << Dir[File.expand_path("config/locales") + "/*.yml"]
28
- ```
29
-
30
- ## Translations lookup
31
-
32
- `ActionPolicy` uses the `action_policy` scope. Specific policies translations must be stored inside the `policy` sub-scope.
33
-
34
- The following algorithm is used to find out the translation for a policy with a class `klass` and rule `rule`:
35
- 1. Translation for `"#{klass.identifier}.#{rule}"` key, when `self.identifier =` is not specified then underscored class name without the _Policy_ suffix would be used (e.g. `GuestUserPolicy` turns into `guest_user:` scope)
36
- 2. Repeat step 1 for each ancestor which looks like a policy (`.respond_to?(:identifier)?`) up to `ActionPolicy::Base`
37
- 3. Use `#{rule}` key
38
- 4. Use `en.action_policy.unauthorized` key
39
- 5. Use a default message provided by the gem
40
-
41
- For example, given a `GuestUserPolicy` class which is inherited from `DefaultUserPolicy` and a rule `feed?`, the following list of possible translation keys would be used: `[:"action_policy.policy.guest_user.feed?", :"action_policy.policy.default_user.feed?", :"action_policy.policy.feed?", :"action_policy.unauthorized"]`
42
-
43
-
44
- [`i18n`]: https://github.com/svenfuchs/i18n
@@ -1,43 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <title>Action Policy: authorization framework for Ruby/Rails applications</title>
6
- <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
7
- <meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0" />
8
- <meta itemprop="name" content="Action Policy" />
9
- <meta property="og:title" content="Action Policy" />
10
- <meta name="description" content="Athorization framework for Ruby/Rails application" />
11
- <meta itemprop="description" content="Authorization framework for Ruby/Rails application" />
12
- <meta property="og:description" content="Authorization framework for Ruby/Rails application" />
13
- <meta itemprop="image" content="http://actionpolicy.evilmartians.io/assets/images/banner.png" />
14
- <meta property="og:image" content="http://actionpolicy.evilmartians.io/assets/images/banner.png" />
15
- <meta name="twitter:card" content="summary_large_image" />
16
- <meta name="twitter:site" content="@palkan_tula" />
17
- <meta name="twitter:creator" content="@palkan_tula" />
18
- <meta property="og:site_name" content="Action Policy" />
19
- <meta name="keywords" content="ruby, rails, authorization, open-source" />
20
- <meta name="theme-color" content="#CB2028" />
21
- <link rel="stylesheet" href="assets/vue.min.css">
22
- <link rel="stylesheet" href="assets/styles.css">
23
- </head>
24
- <body>
25
- <div id="app"></div>
26
- <script>
27
- window.$docsify = {
28
- name: 'action_policy',
29
- repo: 'https://github.com/palkan/action_policy',
30
- loadSidebar: true,
31
- subMaxLevel: 3,
32
- ga: 'UA-104346673-3',
33
- auto2top: true,
34
- search: {
35
- namespace: 'action-policy'
36
- }
37
- }
38
- </script>
39
- <script src="assets/docsify.min.js"></script>
40
- <script src="assets/docsify-search.js"></script>
41
- <script src="assets/prism-ruby.min.js"></script>
42
- </body>
43
- </html>