action_policy 0.4.0 → 0.5.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.
Files changed (100) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +233 -171
  3. data/LICENSE.txt +1 -1
  4. data/README.md +7 -11
  5. data/lib/action_policy.rb +7 -1
  6. data/lib/action_policy/behaviour.rb +22 -16
  7. data/lib/action_policy/behaviours/policy_for.rb +10 -3
  8. data/lib/action_policy/behaviours/scoping.rb +2 -1
  9. data/lib/action_policy/behaviours/thread_memoized.rb +1 -3
  10. data/lib/action_policy/ext/module_namespace.rb +1 -6
  11. data/lib/action_policy/ext/policy_cache_key.rb +15 -33
  12. data/lib/action_policy/ext/{symbol_classify.rb → symbol_camelize.rb} +6 -6
  13. data/lib/action_policy/i18n.rb +1 -1
  14. data/lib/action_policy/lookup_chain.rb +41 -21
  15. data/lib/action_policy/policy/aliases.rb +7 -12
  16. data/lib/action_policy/policy/authorization.rb +14 -17
  17. data/lib/action_policy/policy/cache.rb +34 -18
  18. data/lib/action_policy/policy/core.rb +25 -12
  19. data/lib/action_policy/policy/defaults.rb +3 -9
  20. data/lib/action_policy/policy/execution_result.rb +3 -9
  21. data/lib/action_policy/policy/pre_check.rb +19 -58
  22. data/lib/action_policy/policy/reasons.rb +30 -20
  23. data/lib/action_policy/policy/scoping.rb +5 -6
  24. data/lib/action_policy/rails/controller.rb +6 -1
  25. data/lib/action_policy/rails/ext/active_record.rb +7 -0
  26. data/lib/action_policy/rails/policy/instrumentation.rb +1 -1
  27. data/lib/action_policy/rspec/be_authorized_to.rb +5 -9
  28. data/lib/action_policy/rspec/dsl.rb +3 -3
  29. data/lib/action_policy/rspec/have_authorized_scope.rb +5 -7
  30. data/lib/action_policy/testing.rb +1 -1
  31. data/lib/action_policy/utils/pretty_print.rb +21 -24
  32. data/lib/action_policy/utils/suggest_message.rb +1 -3
  33. data/lib/action_policy/version.rb +1 -1
  34. data/lib/generators/action_policy/install/templates/{application_policy.rb → application_policy.rb.tt} +1 -1
  35. data/lib/generators/action_policy/policy/policy_generator.rb +4 -1
  36. data/lib/generators/action_policy/policy/templates/{policy.rb → policy.rb.tt} +0 -0
  37. data/lib/generators/rspec/templates/{policy_spec.rb → policy_spec.rb.tt} +0 -0
  38. data/lib/generators/test_unit/templates/{policy_test.rb → policy_test.rb.tt} +0 -0
  39. metadata +30 -119
  40. data/.gitattributes +0 -2
  41. data/.github/FUNDING.yml +0 -1
  42. data/.github/ISSUE_TEMPLATE.md +0 -18
  43. data/.github/PULL_REQUEST_TEMPLATE.md +0 -29
  44. data/.gitignore +0 -15
  45. data/.rubocop.yml +0 -54
  46. data/.tidelift.yml +0 -6
  47. data/.travis.yml +0 -31
  48. data/Gemfile +0 -22
  49. data/Rakefile +0 -27
  50. data/action_policy.gemspec +0 -44
  51. data/benchmarks/namespaced_lookup_cache.rb +0 -71
  52. data/bin/console +0 -14
  53. data/bin/setup +0 -8
  54. data/docs/.nojekyll +0 -0
  55. data/docs/CNAME +0 -1
  56. data/docs/README.md +0 -77
  57. data/docs/_sidebar.md +0 -27
  58. data/docs/aliases.md +0 -122
  59. data/docs/assets/docsify-search.js +0 -364
  60. data/docs/assets/docsify.min.js +0 -3
  61. data/docs/assets/fonts/FiraCode-Medium.woff +0 -0
  62. data/docs/assets/fonts/FiraCode-Regular.woff +0 -0
  63. data/docs/assets/images/banner.png +0 -0
  64. data/docs/assets/images/cache.png +0 -0
  65. data/docs/assets/images/cache.svg +0 -70
  66. data/docs/assets/images/layer.png +0 -0
  67. data/docs/assets/images/layer.svg +0 -35
  68. data/docs/assets/prism-ruby.min.js +0 -1
  69. data/docs/assets/styles.css +0 -347
  70. data/docs/assets/vue.min.css +0 -1
  71. data/docs/authorization_context.md +0 -92
  72. data/docs/behaviour.md +0 -113
  73. data/docs/caching.md +0 -273
  74. data/docs/controller_action_aliases.md +0 -109
  75. data/docs/custom_lookup_chain.md +0 -48
  76. data/docs/custom_policy.md +0 -53
  77. data/docs/debugging.md +0 -55
  78. data/docs/decorators.md +0 -27
  79. data/docs/favicon.ico +0 -0
  80. data/docs/graphql.md +0 -302
  81. data/docs/i18n.md +0 -44
  82. data/docs/index.html +0 -43
  83. data/docs/instrumentation.md +0 -84
  84. data/docs/lookup_chain.md +0 -17
  85. data/docs/namespaces.md +0 -77
  86. data/docs/non_rails.md +0 -28
  87. data/docs/pre_checks.md +0 -57
  88. data/docs/pundit_migration.md +0 -80
  89. data/docs/quick_start.md +0 -118
  90. data/docs/rails.md +0 -120
  91. data/docs/reasons.md +0 -120
  92. data/docs/scoping.md +0 -255
  93. data/docs/testing.md +0 -333
  94. data/docs/writing_policies.md +0 -107
  95. data/gemfiles/jruby.gemfile +0 -8
  96. data/gemfiles/rails42.gemfile +0 -8
  97. data/gemfiles/rails6.gemfile +0 -8
  98. data/gemfiles/railsmaster.gemfile +0 -6
  99. data/lib/action_policy/ext/string_match.rb +0 -14
  100. data/lib/action_policy/ext/yield_self_then.rb +0 -25
@@ -1,2 +0,0 @@
1
- docs/**/* linguist-vendored
2
- .github/**/* linguist-vendored
@@ -1 +0,0 @@
1
- tidelift: "rubygems/action_policy"
@@ -1,18 +0,0 @@
1
- <!--
2
- This template is for bug reports. If you are reporting a bug, please continue on. If you are here for another reason,
3
- feel free to skip the rest of this template.
4
- -->
5
-
6
- ### Tell us about your environment
7
-
8
- **Ruby Version:**
9
-
10
- **Framework Version (Rails, whatever):**
11
-
12
- **Action Policy Version:**
13
-
14
- ### What did you do?
15
-
16
- ### What did you expect to happen?
17
-
18
- ### What actually happened?
@@ -1,29 +0,0 @@
1
- <!--
2
- First of all, thanks for contributing!
3
-
4
- If it's a typo fix or minor documentation update feel free to skip the rest of this template!
5
- -->
6
-
7
- <!--
8
- If it's a bug fix, then link it to the issue, for example:
9
-
10
- Fixes #xxx
11
- -->
12
-
13
-
14
- <!--
15
- Otherwise, describe the changes:
16
-
17
- ### What is the purpose of this pull request?
18
-
19
- ### What changes did you make? (overview)
20
-
21
- ### Is there anything you'd like reviewers to focus on?
22
-
23
- -->
24
-
25
- PR checklist:
26
-
27
- - [ ] Tests included
28
- - [ ] Documentation updated
29
- - [ ] Changelog entry added
data/.gitignore DELETED
@@ -1,15 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
10
- Gemfile.local
11
-
12
- spec/dummy/log/*
13
- spec/dummy/db/*.sqlite3
14
- spec/dummy/db/*.sqlite3-journal
15
- spec/dummy/tmp/
@@ -1,54 +0,0 @@
1
- require:
2
- - standard/cop/semantic_blocks
3
- - rubocop-md
4
-
5
- inherit_gem:
6
- standard: config/base.yml
7
-
8
- AllCops:
9
- Exclude:
10
- - 'bin/*'
11
- - 'tmp/**/*'
12
- - 'Gemfile'
13
- - 'vendor/**/*'
14
- - 'gemfiles/**/*'
15
- - 'lib/generators/**/templates/**/*'
16
- DisplayCopNames: true
17
- TargetRubyVersion: 2.4
18
-
19
- Standard/SemanticBlocks:
20
- Enabled: false
21
-
22
- Style/FrozenStringLiteralComment:
23
- Enabled: true
24
-
25
- Style/TrailingCommaInArrayLiteral:
26
- EnforcedStyleForMultiline: no_comma
27
-
28
- Style/TrailingCommaInHashLiteral:
29
- EnforcedStyleForMultiline: no_comma
30
-
31
- Layout/AlignParameters:
32
- EnforcedStyle: with_first_parameter
33
-
34
- Lint/Void:
35
- Exclude:
36
- - '**/*.md'
37
-
38
- # See https://github.com/rubocop-hq/rubocop/issues/4222
39
- Lint/AmbiguousBlockAssociation:
40
- Exclude:
41
- - 'spec/**/*'
42
- - '**/*.md'
43
-
44
- Lint/DuplicateMethods:
45
- Exclude:
46
- - '**/*.md'
47
-
48
- Naming/FileName:
49
- Exclude:
50
- - '**/*.md'
51
-
52
- Layout/InitialIndentation:
53
- Exclude:
54
- - 'CHANGELOG.md'
@@ -1,6 +0,0 @@
1
- ci:
2
- type:
3
- development:
4
- tests:
5
- unlicensed: skip
6
- outdated: skip
@@ -1,31 +0,0 @@
1
- sudo: false
2
- language: ruby
3
- cache: bundler
4
- notifications:
5
- email: false
6
-
7
- before_install:
8
- - gem uninstall -v '>= 2' -i $(rvm gemdir)@global -ax bundler || true
9
- - gem install bundler -v '< 2'
10
-
11
- script:
12
- - bundle exec rake test:ci
13
-
14
- matrix:
15
- fast_finish: true
16
- include:
17
- - rvm: ruby-head
18
- gemfile: gemfiles/railsmaster.gemfile
19
- - rvm: jruby-9.2.8.0
20
- gemfile: gemfiles/jruby.gemfile
21
- - rvm: 2.6.0
22
- gemfile: gemfiles/rails6.gemfile
23
- - rvm: 2.5.3
24
- gemfile: Gemfile
25
- - rvm: 2.4.3
26
- gemfile: gemfiles/rails42.gemfile
27
- allow_failures:
28
- - rvm: ruby-head
29
- gemfile: gemfiles/railsmaster.gemfile
30
- - rvm: jruby-9.2.8.0
31
- gemfile: gemfiles/jruby.gemfile
data/Gemfile DELETED
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- source "https://rubygems.org"
4
-
5
- gemspec
6
-
7
- gem "pry-byebug", platform: :mri
8
-
9
- gem "method_source"
10
- gem "unparser"
11
-
12
- gem 'sqlite3', "~> 1.3.0", platform: :mri
13
- gem 'activerecord-jdbcsqlite3-adapter', '~> 50.0', platform: :jruby
14
- gem 'jdbc-sqlite3', platform: :jruby
15
-
16
- local_gemfile = File.join(__dir__, "Gemfile.local")
17
-
18
- if File.exist?(local_gemfile)
19
- eval(File.read(local_gemfile)) # rubocop:disable Security/Eval
20
- else
21
- gem "rails", "~> 5.0"
22
- end
data/Rakefile DELETED
@@ -1,27 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "rake/testtask"
4
- require "rubocop/rake_task"
5
- require "rspec/core/rake_task"
6
-
7
- RuboCop::RakeTask.new
8
-
9
- RSpec::Core::RakeTask.new(:spec)
10
-
11
- Rake::TestTask.new(:test) do |t|
12
- t.libs << "test"
13
- t.libs << "lib"
14
- t.test_files = FileList["test/**/*_test.rb"]
15
- end
16
-
17
- namespace :test do
18
- task :isolated do
19
- Dir.glob("test/**/*_test.rb").all? do |file|
20
- sh(Gem.ruby, "-w", "-Ilib:test", file)
21
- end || raise("Failures")
22
- end
23
-
24
- task ci: %w[rubocop test:isolated spec]
25
- end
26
-
27
- task default: [:rubocop, :test, :spec]
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- lib = File.expand_path("lib", __dir__)
4
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require "action_policy/version"
6
-
7
- Gem::Specification.new do |spec|
8
- spec.name = "action_policy"
9
- spec.version = ActionPolicy::VERSION
10
- spec.authors = ["Vladimir Dementyev"]
11
- spec.email = ["dementiev.vm@gmail.com"]
12
-
13
- spec.summary = "Authorization framework for Ruby/Rails application"
14
- spec.description = "Authorization framework for Ruby/Rails application"
15
- spec.homepage = "https://github.com/palkan/action_policy"
16
- spec.license = "MIT"
17
-
18
- spec.files = `git ls-files -z`.split("\x0").reject do |f|
19
- f.match(%r{^(test|spec|features)/})
20
- end
21
-
22
- spec.metadata = {
23
- "bug_tracker_uri" => "http://github.com/palkan/action_policy/issues",
24
- "changelog_uri" => "https://github.com/palkan/action_policy/blob/master/CHANGELOG.md",
25
- "documentation_uri" => "https://actionpolicy.evilmartians.io/",
26
- "homepage_uri" => "https://actionpolicy.evilmartians.io/",
27
- "source_code_uri" => "http://github.com/palkan/action_policy"
28
- }
29
-
30
- spec.require_paths = ["lib"]
31
-
32
- spec.required_ruby_version = ">= 2.4.0"
33
-
34
- spec.add_development_dependency "ammeter", "~> 1.1.3"
35
- spec.add_development_dependency "bundler", ">= 1.15"
36
- spec.add_development_dependency "minitest", "~> 5.0"
37
- spec.add_development_dependency "rake", "~> 10.0"
38
- spec.add_development_dependency "rspec", "~> 3.3"
39
- spec.add_development_dependency "rubocop", "~> 0.67.0"
40
- spec.add_development_dependency "rubocop-md", "~> 0.2"
41
- spec.add_development_dependency "standard", "~> 0.0.39"
42
- spec.add_development_dependency "benchmark-ips", "~> 2.7.0"
43
- spec.add_development_dependency "i18n"
44
- end
@@ -1,71 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- #
4
- # This benchmark measures the efficiency of NamespaceCache.
5
- #
6
- # Run it multiple times with cache on/off to see the results:
7
- #
8
- # $ bundle exec ruby namespaced_lookup_cache.rb
9
- # $ bundle exec ruby namespaced_lookup_cache.rb
10
- # $ NO_CACHE=1 bundle exec ruby namespaced_lookup_cache.rb
11
- # $ NO_CACHE=1 bundle exec ruby namespaced_lookup_cache.rb
12
- #
13
-
14
- $LOAD_PATH.unshift File.expand_path("../lib", __dir__)
15
-
16
- require "action_policy"
17
- require "benchmark/ips"
18
-
19
- GC.disable
20
-
21
- class A; end
22
-
23
- class B; end
24
-
25
- module X
26
- class BPolicy < ActionPolicy::Base; end
27
-
28
- module Y
29
- module Z
30
- class APolicy < ActionPolicy::Base; end
31
- end
32
- end
33
- end
34
-
35
- a = A.new
36
- b = B.new
37
-
38
- if ENV["NO_CACHE"]
39
- ActionPolicy::LookupChain.namespace_cache_enabled = false
40
- end
41
-
42
- Benchmark.ips do |x|
43
- x.warmup = 0
44
-
45
- x.report("cache A") do
46
- ActionPolicy.lookup(a, namespace: X::Y::Z)
47
- end
48
-
49
- x.report("cache B") do
50
- ActionPolicy.lookup(b, namespace: X::Y::Z)
51
- end
52
-
53
- x.report("no cache A") do
54
- ActionPolicy.lookup(a, namespace: X::Y::Z)
55
- end
56
-
57
- x.report("no cache B") do
58
- ActionPolicy.lookup(b, namespace: X::Y::Z)
59
- end
60
-
61
- x.hold! "temp_results"
62
-
63
- x.compare!
64
- end
65
-
66
- #
67
- # Comparison:
68
- # cache B: 178577.4 i/s
69
- # cache A: 173061.4 i/s - same-ish: difference falls within error
70
- # no cache A: 97991.7 i/s - same-ish: difference falls within error
71
- # no cache B: 42505.4 i/s - 4.20x slower
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "action_policy"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start(__FILE__)
data/bin/setup DELETED
@@ -1,8 +0,0 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
5
-
6
- bundle install
7
-
8
- # Do any other automated setup that you need to do here
File without changes
data/docs/CNAME DELETED
@@ -1 +0,0 @@
1
- actionpolicy.evilmartians.io
@@ -1,77 +0,0 @@
1
- [![Gem Version](https://badge.fury.io/rb/action_policy.svg)](https://badge.fury.io/rb/action_policy)
2
- [![Build Status](https://travis-ci.org/palkan/action_policy.svg?branch=master)](https://travis-ci.org/palkan/action_policy)
3
-
4
- ## Action Policy
5
-
6
- > Authorization framework for Ruby and Rails.
7
- <br>Composable. Extensible. Performant.
8
-
9
- **NOTE:** this documentation is for the version "0.3.0+".
10
-
11
- ## What is it?
12
-
13
- _Authorization_ is an act of giving **someone** official
14
- permission to **do something** (to not be confused with [_authentication_](https://en.wikipedia.org/wiki/Authentication)).
15
-
16
- Action Policy provides flexible tools to build an _authorization layer_ for your application.
17
-
18
- <div class="chart-container">
19
- <img src="assets/images/layer.svg" alt="Authorization layer" width="80%">
20
- </div>
21
-
22
- **NOTE:** Action Policy does not force you to use a specific authorization model (i.e., roles, permissions, etc.) and does not provide one. It only answers a single question: **How to verify access?**
23
-
24
- ## Where to go from here?
25
- - [Quick start](./quick_start.md)
26
- - [Using with Rails](./rails.md)
27
- - [Using with other Ruby frameworks](./non_rails.md)
28
- - [Using with GraphQL Ruby](./graphql.md)
29
-
30
- ## Project State
31
-
32
- The project is being used in production since mid 2018. Major features have been implemented, API has been stabilized. Check out our [development board](https://github.com/palkan/action_policy/projects/1) to see what's coming next.
33
-
34
- ## History
35
-
36
- Action Policy gem is an _extraction_-kind of a library. Most of the code has been used in production for several years in different [Evil Martians][] projects.
37
-
38
- We have decided to collect all our authorization techniques and pack them into a standalone gem–and that is how Action Policy was born!
39
-
40
- ## What about the existing solutions?
41
-
42
- Why did we decide to build our own authorization gem instead of using the existing solutions, such as [Pundit][] and [CanCanCan][]?
43
-
44
- **TL;DR they didn't solve all of our problems.**
45
-
46
- [Pundit][] has been our framework of choice for a long time. Being too _dead-simple_, it required a lot of hacking to fulfill business logic requirements.
47
-
48
- These _hacks_ later became Action Policy (initially, we even called it "Pundit, re-visited").
49
-
50
- We also took a few ideas from [CanCanCan][]—such as [default rules and rule aliases](./aliases.md).
51
-
52
- It is also worth noting that Action Policy (despite having a _Railsy_ name) is designed to be **Rails-free**. On the other hand, it contains some Rails-specific extensions and seamlessly integrates into the framework.
53
-
54
- So, what are the main reasons to consider Action Policy as your authorization tool?
55
-
56
- - **Performance**: multiple [caching strategies](./caching.md) out-of-the-box make authorization overhead as small as possible–especially useful when your rules involve DB queries; you can also monitor the performance and detect the bottlenecks using the built-in [instrumentation](./instrumentation) features.
57
-
58
- - **Composition & Customization**: use [only the features you need](./custom_policy.md) or easily extend the functionality–it's just Ruby classes and modules, (almost) zero magic! And you can add authorization [anywhere in your code](./non_rails.md), not only in controllers.
59
-
60
- - **Code Organization**: use [namespaces](./namespaces.md) to organize your policies (for example, when you have multiple authorization strategies); add [pre-checks](./pre_checks.md) to make rules more readable and better express your business-logic.
61
-
62
- - **...and more**: [testability](./testing.md), [i18n](./i18n.md) integrations, [actionable errors](./reasons.md).
63
-
64
- Learn more about the motivation behind the Action Policy and its features by watching this [RailsConf talk](https://www.youtube.com/watch?v=NVwx0DARDis).
65
-
66
- ## Resources
67
-
68
- - Seattle.rb, 2019 "A Denial!" talk [[slides](https://speakerdeck.com/palkan/seattle-dot-rb-2019-a-denial)]
69
-
70
- - RailsConf, 2018 "Access Denied" talk [[video](https://www.youtube.com/watch?v=NVwx0DARDis), [slides](https://speakerdeck.com/palkan/railsconf-2018-access-denied-the-missing-guide-to-authorization-in-rails)]
71
-
72
- <a href="https://evilmartians.com/?utm_source=action_policy">
73
- <img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a>
74
-
75
- [CanCanCan]: https://github.com/CanCanCommunity/cancancan
76
- [Pundit]: https://github.com/varvet/pundit
77
- [Evil Martians]: https://evilmartians.com