declarative_policy 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 8c08845902bc432f4c737ba76d2b9a5f0cc456fed1d0f26353755146ab49b2a1
4
+ data.tar.gz: 0f64e5d7707dff73572484cd700b529704f4d41dfd0b1972c8d675e4281d3582
5
+ SHA512:
6
+ metadata.gz: 0b5bc3cfd66be62b483aa8beb673b8b858121a18a0dcb64bd9f6fa79d268ebf3ddb566ede84c1032beac05bc81f6fa8f0642e846a42f6bcf21083eb04de7fa2c
7
+ data.tar.gz: fabb732587403af0e1cfe8cfcc25033f0d8ccaee066e8310bd0bacf38fba052758e97e3aedbc42e6c62f898a07eaf598885a731f4b80fa9fdf1fe321dfa2901b
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /pkg/
6
+ /spec/reports/
7
+ /tmp/
8
+
9
+ # rspec failure tracking
10
+ .rspec_status
data/.gitlab-ci.yml ADDED
@@ -0,0 +1,48 @@
1
+ image: "ruby:2.7"
2
+
3
+ .tests:
4
+ stage: test
5
+ only:
6
+ refs:
7
+ - master
8
+ - tags
9
+ - merge_requests
10
+
11
+ # Cache gems in between builds
12
+ cache:
13
+ paths:
14
+ - vendor/ruby
15
+
16
+ before_script:
17
+ - ruby -v # Print out ruby version for debugging
18
+ - bundle install -j $(nproc) --path vendor # Install dependencies into ./vendor/ruby
19
+
20
+ rubocop:
21
+ extends: .tests
22
+ script:
23
+ - bundle exec rubocop
24
+
25
+ rspec:
26
+ extends: .tests
27
+ image: "ruby:$RUBY_VERSION"
28
+ script:
29
+ - bundle exec rspec
30
+ parallel:
31
+ matrix:
32
+ - RUBY_VERSION:
33
+ - "2.7"
34
+ - "3.0"
35
+
36
+ danger-review:
37
+ extends: .tests
38
+ needs: []
39
+ script:
40
+ - >
41
+ if [ -z "$DANGER_GITLAB_API_TOKEN" ]; then
42
+ # Force danger to skip CI source GitLab and fallback to "local only git repo".
43
+ unset GITLAB_CI
44
+ # We need to base SHA to help danger determine the base commit for this shallow clone.
45
+ bundle exec danger dry_run --fail-on-errors=true --verbose --base="$CI_MERGE_REQUEST_DIFF_BASE_SHA"
46
+ else
47
+ bundle exec danger --fail-on-errors=true --verbose
48
+ fi
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
4
+ --order rand
data/.rubocop.yml ADDED
@@ -0,0 +1,10 @@
1
+ inherit_gem:
2
+ gitlab-styles:
3
+ - rubocop-default.yml
4
+
5
+ AllCops:
6
+ TargetRubyVersion: 2.6
7
+ NewCops: enable
8
+
9
+ RSpec/MultipleMemoizedHelpers:
10
+ Max: 10
@@ -0,0 +1,74 @@
1
+ # Contributor Covenant Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ In the interest of fostering an open and welcoming environment, we as
6
+ contributors and maintainers pledge to making participation in our project and
7
+ our community a harassment-free experience for everyone, regardless of age, body
8
+ size, disability, ethnicity, gender identity and expression, level of experience,
9
+ nationality, personal appearance, race, religion, or sexual identity and
10
+ orientation.
11
+
12
+ ## Our Standards
13
+
14
+ Examples of behavior that contributes to creating a positive environment
15
+ include:
16
+
17
+ * Using welcoming and inclusive language
18
+ * Being respectful of differing viewpoints and experiences
19
+ * Gracefully accepting constructive criticism
20
+ * Focusing on what is best for the community
21
+ * Showing empathy towards other community members
22
+
23
+ Examples of unacceptable behavior by participants include:
24
+
25
+ * The use of sexualized language or imagery and unwelcome sexual attention or
26
+ advances
27
+ * Trolling, insulting/derogatory comments, and personal or political attacks
28
+ * Public or private harassment
29
+ * Publishing others' private information, such as a physical or electronic
30
+ address, without explicit permission
31
+ * Other conduct which could reasonably be considered inappropriate in a
32
+ professional setting
33
+
34
+ ## Our Responsibilities
35
+
36
+ Project maintainers are responsible for clarifying the standards of acceptable
37
+ behavior and are expected to take appropriate and fair corrective action in
38
+ response to any instances of unacceptable behavior.
39
+
40
+ Project maintainers have the right and responsibility to remove, edit, or
41
+ reject comments, commits, code, wiki edits, issues, and other contributions
42
+ that are not aligned to this Code of Conduct, or to ban temporarily or
43
+ permanently any contributor for other behaviors that they deem inappropriate,
44
+ threatening, offensive, or harmful.
45
+
46
+ ## Scope
47
+
48
+ This Code of Conduct applies both within project spaces and in public spaces
49
+ when an individual is representing the project or its community. Examples of
50
+ representing a project or community include using an official project e-mail
51
+ address, posting via an official social media account, or acting as an appointed
52
+ representative at an online or offline event. Representation of a project may be
53
+ further defined and clarified by project maintainers.
54
+
55
+ ## Enforcement
56
+
57
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
58
+ reported by contacting the project team at akalderimis@gitlab.com. All
59
+ complaints will be reviewed and investigated and will result in a response that
60
+ is deemed necessary and appropriate to the circumstances. The project team is
61
+ obligated to maintain confidentiality with regard to the reporter of an incident.
62
+ Further details of specific enforcement policies may be posted separately.
63
+
64
+ Project maintainers who do not follow or enforce the Code of Conduct in good
65
+ faith may face temporary or permanent repercussions as determined by other
66
+ members of the project's leadership.
67
+
68
+ ## Attribution
69
+
70
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71
+ available at [https://contributor-covenant.org/version/1/4][version]
72
+
73
+ [homepage]: https://contributor-covenant.org
74
+ [version]: https://contributor-covenant.org/version/1/4/
data/Dangerfile ADDED
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'gitlab-dangerfiles'
4
+
5
+ Gitlab::Dangerfiles.import_plugins(danger)
6
+ danger.import_plugin('danger/plugins/*.rb')
7
+
8
+ return if helper.release_automation?
9
+
10
+ danger.import_dangerfile(path: File.join('danger', 'roulette'))
11
+
12
+ anything_to_post = status_report.values.any?(&:any?)
13
+
14
+ if helper.ci? && anything_to_post
15
+ markdown("**If needed, you can retry the [`danger-review` job](#{ENV['CI_JOB_URL']}) that generated this comment.**")
16
+ end
data/Gemfile ADDED
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ # Specify your gem's dependencies in declarative-policy.gemspec
6
+ gemspec
7
+
8
+ gem 'activesupport', '>= 6.0'
9
+ gem 'rake', '~> 12.0'
10
+ gem 'rubocop', require: false
11
+
12
+ group :test do
13
+ gem 'rspec', '~> 3.0'
14
+ gem 'rspec-parameterized', require: false
15
+ gem 'pry-byebug'
16
+ end
17
+
18
+ group :development, :test do
19
+ gem 'gitlab-styles', '~> 6.1.0', require: false
20
+ end
21
+
22
+ group :development, :test, :danger do
23
+ gem 'gitlab-dangerfiles', '~> 1.1.0', require: false
24
+ end
data/Gemfile.lock ADDED
@@ -0,0 +1,197 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ declarative_policy (1.0.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ abstract_type (0.0.7)
10
+ activesupport (6.0.3.4)
11
+ concurrent-ruby (~> 1.0, >= 1.0.2)
12
+ i18n (>= 0.7, < 2)
13
+ minitest (~> 5.1)
14
+ tzinfo (~> 1.1)
15
+ zeitwerk (~> 2.2, >= 2.2.2)
16
+ adamantium (0.2.0)
17
+ ice_nine (~> 0.11.0)
18
+ memoizable (~> 0.4.0)
19
+ addressable (2.7.0)
20
+ public_suffix (>= 2.0.2, < 5.0)
21
+ ast (2.4.2)
22
+ binding_ninja (0.2.3)
23
+ byebug (11.1.3)
24
+ claide (1.0.3)
25
+ claide-plugins (0.9.2)
26
+ cork
27
+ nap
28
+ open4 (~> 1.3)
29
+ coderay (1.1.3)
30
+ colored2 (3.1.2)
31
+ concord (0.1.5)
32
+ adamantium (~> 0.2.0)
33
+ equalizer (~> 0.0.9)
34
+ concurrent-ruby (1.1.8)
35
+ cork (0.3.0)
36
+ colored2 (~> 3.1)
37
+ danger (8.2.3)
38
+ claide (~> 1.0)
39
+ claide-plugins (>= 0.9.2)
40
+ colored2 (~> 3.1)
41
+ cork (~> 0.1)
42
+ faraday (>= 0.9.0, < 2.0)
43
+ faraday-http-cache (~> 2.0)
44
+ git (~> 1.7)
45
+ kramdown (~> 2.3)
46
+ kramdown-parser-gfm (~> 1.0)
47
+ no_proxy_fix
48
+ octokit (~> 4.7)
49
+ terminal-table (>= 1, < 4)
50
+ danger-gitlab (8.0.0)
51
+ danger
52
+ gitlab (~> 4.2, >= 4.2.0)
53
+ diff-lcs (1.4.4)
54
+ equalizer (0.0.11)
55
+ faraday (1.1.0)
56
+ multipart-post (>= 1.2, < 3)
57
+ ruby2_keywords
58
+ faraday-http-cache (2.2.0)
59
+ faraday (>= 0.8)
60
+ git (1.7.0)
61
+ rchardet (~> 1.8)
62
+ gitlab (4.17.0)
63
+ httparty (~> 0.18)
64
+ terminal-table (~> 1.5, >= 1.5.1)
65
+ gitlab-dangerfiles (1.1.0)
66
+ danger-gitlab
67
+ gitlab-styles (6.1.0)
68
+ rubocop (~> 0.91, >= 0.91.1)
69
+ rubocop-gitlab-security (~> 0.1.1)
70
+ rubocop-performance (~> 1.9.2)
71
+ rubocop-rails (~> 2.9)
72
+ rubocop-rspec (~> 1.44)
73
+ httparty (0.18.1)
74
+ mime-types (~> 3.0)
75
+ multi_xml (>= 0.5.2)
76
+ i18n (1.8.9)
77
+ concurrent-ruby (~> 1.0)
78
+ ice_nine (0.11.2)
79
+ kramdown (2.3.1)
80
+ rexml
81
+ kramdown-parser-gfm (1.1.0)
82
+ kramdown (~> 2.0)
83
+ memoizable (0.4.2)
84
+ thread_safe (~> 0.3, >= 0.3.1)
85
+ method_source (1.0.0)
86
+ mime-types (3.3.1)
87
+ mime-types-data (~> 3.2015)
88
+ mime-types-data (3.2020.1104)
89
+ minitest (5.14.3)
90
+ multi_xml (0.6.0)
91
+ multipart-post (2.1.1)
92
+ nap (1.1.0)
93
+ no_proxy_fix (0.1.2)
94
+ octokit (4.20.0)
95
+ faraday (>= 0.9)
96
+ sawyer (~> 0.8.0, >= 0.5.3)
97
+ open4 (1.3.4)
98
+ parallel (1.20.1)
99
+ parser (3.0.0.0)
100
+ ast (~> 2.4.1)
101
+ proc_to_ast (0.1.0)
102
+ coderay
103
+ parser
104
+ unparser
105
+ procto (0.0.3)
106
+ pry (0.13.1)
107
+ coderay (~> 1.1)
108
+ method_source (~> 1.0)
109
+ pry-byebug (3.9.0)
110
+ byebug (~> 11.0)
111
+ pry (~> 0.13.0)
112
+ public_suffix (4.0.6)
113
+ rack (2.2.3)
114
+ rainbow (3.0.0)
115
+ rake (12.3.3)
116
+ rchardet (1.8.0)
117
+ regexp_parser (1.8.2)
118
+ rexml (3.2.4)
119
+ rspec (3.10.0)
120
+ rspec-core (~> 3.10.0)
121
+ rspec-expectations (~> 3.10.0)
122
+ rspec-mocks (~> 3.10.0)
123
+ rspec-core (3.10.1)
124
+ rspec-support (~> 3.10.0)
125
+ rspec-expectations (3.10.1)
126
+ diff-lcs (>= 1.2.0, < 2.0)
127
+ rspec-support (~> 3.10.0)
128
+ rspec-mocks (3.10.2)
129
+ diff-lcs (>= 1.2.0, < 2.0)
130
+ rspec-support (~> 3.10.0)
131
+ rspec-parameterized (0.4.2)
132
+ binding_ninja (>= 0.2.3)
133
+ parser
134
+ proc_to_ast
135
+ rspec (>= 2.13, < 4)
136
+ unparser
137
+ rspec-support (3.10.2)
138
+ rubocop (0.93.1)
139
+ parallel (~> 1.10)
140
+ parser (>= 2.7.1.5)
141
+ rainbow (>= 2.2.2, < 4.0)
142
+ regexp_parser (>= 1.8)
143
+ rexml
144
+ rubocop-ast (>= 0.6.0)
145
+ ruby-progressbar (~> 1.7)
146
+ unicode-display_width (>= 1.4.0, < 2.0)
147
+ rubocop-ast (1.4.1)
148
+ parser (>= 2.7.1.5)
149
+ rubocop-gitlab-security (0.1.1)
150
+ rubocop (>= 0.51)
151
+ rubocop-performance (1.9.2)
152
+ rubocop (>= 0.90.0, < 2.0)
153
+ rubocop-ast (>= 0.4.0)
154
+ rubocop-rails (2.9.1)
155
+ activesupport (>= 4.2.0)
156
+ rack (>= 1.1)
157
+ rubocop (>= 0.90.0, < 2.0)
158
+ rubocop-rspec (1.44.1)
159
+ rubocop (~> 0.87)
160
+ rubocop-ast (>= 0.7.1)
161
+ ruby-progressbar (1.11.0)
162
+ ruby2_keywords (0.0.2)
163
+ sawyer (0.8.2)
164
+ addressable (>= 2.3.5)
165
+ faraday (> 0.8, < 2.0)
166
+ terminal-table (1.8.0)
167
+ unicode-display_width (~> 1.1, >= 1.1.1)
168
+ thread_safe (0.3.6)
169
+ tzinfo (1.2.9)
170
+ thread_safe (~> 0.1)
171
+ unicode-display_width (1.7.0)
172
+ unparser (0.4.7)
173
+ abstract_type (~> 0.0.7)
174
+ adamantium (~> 0.2.0)
175
+ concord (~> 0.1.5)
176
+ diff-lcs (~> 1.3)
177
+ equalizer (~> 0.0.9)
178
+ parser (>= 2.6.5)
179
+ procto (~> 0.0.2)
180
+ zeitwerk (2.4.2)
181
+
182
+ PLATFORMS
183
+ ruby
184
+
185
+ DEPENDENCIES
186
+ activesupport (>= 6.0)
187
+ declarative_policy!
188
+ gitlab-dangerfiles (~> 1.1.0)
189
+ gitlab-styles (~> 6.1.0)
190
+ pry-byebug
191
+ rake (~> 12.0)
192
+ rspec (~> 3.0)
193
+ rspec-parameterized
194
+ rubocop
195
+
196
+ BUNDLED WITH
197
+ 2.1.4
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2021 Alex Kalderimis
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,144 @@
1
+ # `DeclarativePolicy`: A Declarative Authorization Library
2
+
3
+ This library provides a DSL for writing authorization policies.
4
+
5
+ It can be used to separate logic from permissions, and has been
6
+ used at scale in production at [GitLab.com](https://gitlab.com).
7
+
8
+ The original author of this library is [Jeanine Adkisson](http://jneen.net),
9
+ and copyright is held by GitLab.
10
+
11
+ ## Installation
12
+
13
+ Add this line to your application's Gemfile:
14
+
15
+ ```ruby
16
+ gem 'declarative_policy'
17
+ ```
18
+
19
+ And then execute:
20
+
21
+ $ bundle install
22
+
23
+ Or install it yourself as:
24
+
25
+ $ gem install declarative_policy
26
+
27
+ ## Usage
28
+
29
+
30
+ The core abstraction of this library is a `Policy`. Policies combine:
31
+
32
+ - **facts** (called `conditions`) about the state of the world
33
+ - **judgements** about these facts (called `rules`)
34
+
35
+ This library exists to determine the truth value of statements of the form:
36
+
37
+ ```
38
+ Subject Predicate [Object]
39
+ ```
40
+
41
+ For example:
42
+
43
+ - `user :is_alive`
44
+ - `user :can_drive car`
45
+ - `user :can_sell car`
46
+
47
+ It does this by letting us associate a `Policy` (a set of rules about which
48
+ statements are true) with the objects of the sentences. A statement is
49
+ considered to hold if no rule `prevents` it, and at least one rule `enables` it.
50
+
51
+ For example, imagine we have a data model containing vehicles and users, and we
52
+ want to know if a user can drive a vehicle. We need a `VehiclePolicy`:
53
+
54
+ ```ruby
55
+ class VehiclePolicy < DeclarativePolicy::Base
56
+ # relevant facts
57
+ condition(:owns) { @subject.owner == @user }
58
+ condition(:has_access_to) { @subject.owner.trusts?(@user) }
59
+ condition(:old_enough_to_drive) { @user.age >= laws.minimum_age }
60
+ condition(:has_driving_license) { @user.driving_license&.valid? }
61
+ # expensive rules can have 'score'. Higher scores are 'more expensive' to calculate
62
+ condition(:owns, score: 0) { @subject.owner == @user }
63
+ condition(:has_access_to, score: 3) { @subject.owner.trusts?(@user) }
64
+ condition(:intoxicated, score: 5) { @user.blood_alcohol < laws.max_blood_alcohol }
65
+
66
+ # conclusions we can draw:
67
+ rule { owns }.enable :drive_vehicle
68
+ rule { has_access_to }.enable :drive_vehicle
69
+ rule { ~old_enough_to_drive }.prevent :drive_vehicle
70
+ rule { intoxicated }.prevent :drive_vehicle
71
+ rule { ~has_driving_license }.prevent :drive_vehicle
72
+
73
+ # we can use methods to abstract common logic
74
+ def laws
75
+ @subject.registration.country.driving_laws
76
+ end
77
+ end
78
+ ```
79
+
80
+ A few points to note: we could have written this as one big rule
81
+ (`(owns | has_access_to) & old_enough_to_drive & ~intoxicated & has_driving_license`)
82
+ but we can see some of the features that make declarative policies scalable for
83
+ large systems: rules can be broken up into small elements, and composed into
84
+ larger rules. New conditions and rules can be added at any time.
85
+
86
+ What is more difficult to see is that many performance optimizations are handled
87
+ for us transparently:
88
+
89
+ - more expensive conditions are called later
90
+ - we automatically get the desired groupings (evaluate all conditions that might
91
+ prevent an action, but stop once we have at least one call to enable).
92
+ - intermediate values are cached.
93
+ - policies support inheritance and delegation, meaning authorization logic
94
+ remains DRY.
95
+
96
+ In short this library aims to be declarative: we declare the rules that are
97
+ important, and the library arranges how to evaluate them.
98
+
99
+ Caching is a particularly valuable feature of policies. If we add new rules
100
+ about selling a vehicle, for example:
101
+
102
+ ```ruby
103
+ rule { owns }.enable :sell_vehicle
104
+ ```
105
+
106
+ Then the fact of ownership can be shared between different calls to the policy,
107
+ saving database calls and other expensive IO operations.
108
+
109
+ ### Evaluating a policy:
110
+
111
+ We can check the determination of a policy with:
112
+
113
+ ```ruby
114
+ cache = Session.current_session
115
+ policy = DeclarativePolicy.policy_for(user, car, cache: cache)
116
+ policy.can?(:drive_vehicle)
117
+ ```
118
+
119
+ For more usage details, see the [documentation](docs/usage.md).
120
+
121
+ ## Development
122
+
123
+ After checking out the repository, run `bin/setup` to install dependencies.
124
+ Then, run `rake spec` to run the tests. You can also run `bin/console` for an
125
+ interactive prompt that will allow you to experiment.
126
+
127
+ 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).
128
+
129
+ ## Contributing
130
+
131
+ Bug reports and pull requests are welcome on GitHub at
132
+ https://gitlab.com/gitlab-org/declarative-policy. This project is intended to be
133
+ a safe, welcoming space for collaboration, and contributors are expected to
134
+ adhere to the [GitLab code of conduct](https://about.gitlab.com/community/contribute/code-of-conduct/).
135
+
136
+ ## License
137
+
138
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
139
+
140
+ ## Code of Conduct
141
+
142
+ Everyone interacting in the `DeclarativePolicy` project's codebase, issue
143
+ trackers, chat rooms and mailing lists is expected to follow
144
+ the [code of conduct](https://github.com/[USERNAME]/declarative-policy/blob/master/CODE_OF_CONDUCT.md).