law 0.1.3 → 0.1.8
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.
- checksums.yaml +4 -4
- data/lib/generators/law/USAGE +9 -0
- data/lib/generators/law/law_generator.rb +15 -0
- data/lib/generators/law/regulation/USAGE +9 -0
- data/lib/generators/law/regulation/regulation_generator.rb +15 -0
- data/lib/generators/law/regulation/templates/regulation.rb.erb +4 -0
- data/lib/generators/law/statute/USAGE +9 -0
- data/lib/generators/law/statute/statute_generator.rb +15 -0
- data/lib/generators/law/statute/templates/statute.rb.erb +4 -0
- data/lib/generators/law/templates/law.rb.erb +4 -0
- data/lib/generators/rspec/law/USAGE +9 -0
- data/lib/generators/rspec/law/law_generator.rb +13 -0
- data/lib/generators/rspec/law/templates/law_spec.rb.erb +7 -0
- data/lib/generators/rspec/regulation/USAGE +9 -0
- data/lib/generators/rspec/regulation/regulation_generator.rb +13 -0
- data/lib/generators/rspec/regulation/templates/regulation_spec.rb.erb +7 -0
- data/lib/generators/rspec/statute/USAGE +9 -0
- data/lib/generators/rspec/statute/statute_generator.rb +13 -0
- data/lib/generators/rspec/statute/templates/statute_spec.rb.erb +7 -0
- data/lib/law.rb +2 -0
- data/lib/law/judgement.rb +16 -6
- data/lib/law/laws/actions.rb +11 -1
- data/lib/law/laws/petitions.rb +2 -0
- data/lib/law/legalize.rb +1 -1
- data/lib/law/petition.rb +6 -0
- data/lib/law/rspec/custom_matchers.rb +1 -0
- data/lib/law/rspec/custom_matchers/revoke_action.rb +35 -0
- data/lib/law/statute_base.rb +2 -0
- data/lib/law/statutes/compliance.rb +27 -0
- data/lib/law/version.rb +1 -1
- metadata +33 -11
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2e2ac1483d7b8253bb52289a1c81727bbfc15f47a60f0f03ab7f7f9c78e38d69
|
|
4
|
+
data.tar.gz: ab18b48276b107552e3335cd8dfc17e98d04a764aef9655ca369d40b5c6fae10
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 259728e11d27c2c78829433b4dcd6e6d6f869533c7637002b6823c498523e5bc8353a2ffcd307556d09b94095ea435cf963bf4ae6fe88234ae1e6fe90fecc437
|
|
7
|
+
data.tar.gz: 6383a6bd485a6ea5ad111095bc8df0e961c570ef54206f5139eb7c8ad2b742501d427656e79a26e2838b3a0ccef224401a9e8c564ceb9eadb55b14d78600f152
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Law
|
|
4
|
+
module Generators
|
|
5
|
+
class LawGenerator < Rails::Generators::NamedBase
|
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
|
7
|
+
|
|
8
|
+
hook_for :test_framework
|
|
9
|
+
|
|
10
|
+
def create_law
|
|
11
|
+
template "law.rb.erb", File.join("app/laws/", class_path, "#{file_name}_law.rb")
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Law
|
|
4
|
+
module Generators
|
|
5
|
+
class RegulationGenerator < Rails::Generators::NamedBase
|
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
|
7
|
+
|
|
8
|
+
hook_for :test_framework
|
|
9
|
+
|
|
10
|
+
def create_regulation
|
|
11
|
+
template "regulation.rb.erb", File.join("app/regulations/", class_path, "#{file_name}_regulation.rb")
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Law
|
|
4
|
+
module Generators
|
|
5
|
+
class StatuteGenerator < Rails::Generators::NamedBase
|
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
|
7
|
+
|
|
8
|
+
hook_for :test_framework
|
|
9
|
+
|
|
10
|
+
def create_statute
|
|
11
|
+
template "statute.rb.erb", File.join("app/statutes/", class_path, "#{file_name}_statute.rb")
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rspec
|
|
4
|
+
module Generators
|
|
5
|
+
class LawGenerator < Rails::Generators::NamedBase
|
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
|
7
|
+
|
|
8
|
+
def create_spec_file
|
|
9
|
+
template "law_spec.rb.erb", File.join("spec/laws/", class_path, "#{file_name}_law_spec.rb")
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rspec
|
|
4
|
+
module Generators
|
|
5
|
+
class RegulationGenerator < Rails::Generators::NamedBase
|
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
|
7
|
+
|
|
8
|
+
def create_spec_file
|
|
9
|
+
template "regulation_spec.rb.erb", File.join("spec/regulations/", class_path, "#{file_name}_regulation_spec.rb")
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Rspec
|
|
4
|
+
module Generators
|
|
5
|
+
class StatuteGenerator < Rails::Generators::NamedBase
|
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
|
7
|
+
|
|
8
|
+
def create_spec_file
|
|
9
|
+
template "statute_spec.rb.erb", File.join("spec/statutes/", class_path, "#{file_name}_statute_spec.rb")
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
data/lib/law.rb
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
require "active_support"
|
|
4
4
|
require "active_support/core_ext/enumerable"
|
|
5
|
+
require "active_support/hash_with_indifferent_access"
|
|
5
6
|
|
|
6
7
|
require "spicery"
|
|
7
8
|
|
|
@@ -27,4 +28,5 @@ module Law
|
|
|
27
28
|
|
|
28
29
|
class NotAuthorizedError < Error; end
|
|
29
30
|
class InjunctionError < NotAuthorizedError; end
|
|
31
|
+
class ComplianceError < NotAuthorizedError; end
|
|
30
32
|
end
|
data/lib/law/judgement.rb
CHANGED
|
@@ -15,7 +15,7 @@ module Law
|
|
|
15
15
|
|
|
16
16
|
attr_reader :petition, :violations, :applied_regulations
|
|
17
17
|
|
|
18
|
-
delegate :statute, :applicable_regulations, to: :petition
|
|
18
|
+
delegate :statute, :applicable_regulations, :compliant?, to: :petition, allow_nil: true
|
|
19
19
|
|
|
20
20
|
def initialize(petition)
|
|
21
21
|
@petition = petition
|
|
@@ -39,20 +39,30 @@ module Law
|
|
|
39
39
|
end
|
|
40
40
|
|
|
41
41
|
def judge!
|
|
42
|
-
if
|
|
42
|
+
raise AlreadyJudgedError if adjudicated?
|
|
43
|
+
|
|
44
|
+
if statute&.unregulated?
|
|
43
45
|
@applied_regulations = [ nil ]
|
|
44
46
|
return true
|
|
45
47
|
end
|
|
46
48
|
|
|
49
|
+
ensure_jurisdiction
|
|
50
|
+
reckon!
|
|
51
|
+
|
|
52
|
+
true
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
private
|
|
56
|
+
|
|
57
|
+
def ensure_jurisdiction
|
|
47
58
|
raise InjunctionError if applicable_regulations.blank?
|
|
48
|
-
raise
|
|
59
|
+
raise ComplianceError unless compliant?
|
|
60
|
+
end
|
|
49
61
|
|
|
62
|
+
def reckon!
|
|
50
63
|
@applied_regulations = applicable_regulations.map { |regulation| regulation.new(petition: petition) }
|
|
51
64
|
@violations = applied_regulations.reject(&:valid?)
|
|
52
|
-
|
|
53
65
|
raise NotAuthorizedError unless authorized?
|
|
54
|
-
|
|
55
|
-
true
|
|
56
66
|
end
|
|
57
67
|
end
|
|
58
68
|
end
|
data/lib/law/laws/actions.rb
CHANGED
|
@@ -8,22 +8,32 @@ module Law
|
|
|
8
8
|
|
|
9
9
|
included do
|
|
10
10
|
class_attribute :actions, instance_writer: false, default: HashWithIndifferentAccess.new
|
|
11
|
+
class_attribute :revoked_actions, instance_writer: false, default: HashWithIndifferentAccess.new
|
|
11
12
|
|
|
12
|
-
delegate :statute_for_action?, to: :class
|
|
13
|
+
delegate :statute_for_action?, :revoked_action?, to: :class
|
|
13
14
|
end
|
|
14
15
|
|
|
15
16
|
class_methods do
|
|
16
17
|
def inherited(base)
|
|
17
18
|
base.actions = actions.dup
|
|
19
|
+
base.revoked_actions = revoked_actions.dup
|
|
18
20
|
super
|
|
19
21
|
end
|
|
20
22
|
|
|
23
|
+
def revoked_action?(action)
|
|
24
|
+
revoked_actions[action].present?
|
|
25
|
+
end
|
|
26
|
+
|
|
21
27
|
def statute_for_action?(action)
|
|
22
28
|
actions[action].present?
|
|
23
29
|
end
|
|
24
30
|
|
|
25
31
|
private
|
|
26
32
|
|
|
33
|
+
def revoke_action(*input_actions)
|
|
34
|
+
input_actions.each { |action| revoked_actions[action] = true }
|
|
35
|
+
end
|
|
36
|
+
|
|
27
37
|
def define_action(*input_actions, enforces: nil)
|
|
28
38
|
raise ArgumentError, "invalid statute: #{enforces}" unless enforceable?(enforces)
|
|
29
39
|
|
data/lib/law/laws/petitions.rb
CHANGED
data/lib/law/legalize.rb
CHANGED
|
@@ -23,7 +23,7 @@ module Law
|
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
def law(object = nil, petitioner = nil, permissions: nil, parameters: nil, law_class: nil)
|
|
26
|
-
object ||= try(:controller_name)&.singularize&.camelize&.safe_constantize
|
|
26
|
+
object ||= @record || try(:controller_name)&.singularize&.camelize&.safe_constantize
|
|
27
27
|
petitioner ||= try(:current_user)
|
|
28
28
|
permissions ||= petitioner.try(:permissions)
|
|
29
29
|
law_class ||= object.try(:conjugate, Law::LawBase)
|
data/lib/law/petition.rb
CHANGED
|
@@ -18,5 +18,11 @@ module Law
|
|
|
18
18
|
statute.regulations.select { |regulation| permission_list.include? regulation.key }
|
|
19
19
|
end
|
|
20
20
|
memoize :applicable_regulations
|
|
21
|
+
|
|
22
|
+
def compliant?
|
|
23
|
+
return applicable_regulations.any? unless statute.full_compliance_required?
|
|
24
|
+
|
|
25
|
+
statute.regulations == applicable_regulations
|
|
26
|
+
end
|
|
21
27
|
end
|
|
22
28
|
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# RSpec matcher that tests revoking of statutes in laws.
|
|
4
|
+
#
|
|
5
|
+
# class ExampleStatute < ApplicationStatute
|
|
6
|
+
# end
|
|
7
|
+
#
|
|
8
|
+
# class CommonLaw < ApplicationStatute
|
|
9
|
+
# define_action :new, enforces: ExampleRegulation
|
|
10
|
+
# define_action :create, enforces: ExampleRegulation
|
|
11
|
+
# define_action :edit
|
|
12
|
+
# end
|
|
13
|
+
#
|
|
14
|
+
# class ExampleLaw < CommonLaw
|
|
15
|
+
# revoke_action :new, :edit
|
|
16
|
+
# end
|
|
17
|
+
#
|
|
18
|
+
# RSpec.describe ExampleLaw, type: :law do
|
|
19
|
+
# it { is_expected.to revoke_action :new, :edit }
|
|
20
|
+
# end
|
|
21
|
+
|
|
22
|
+
RSpec::Matchers.define :revoke_action do |*actions|
|
|
23
|
+
match do
|
|
24
|
+
actions.each { |action| expect(test_subject.revoked_action?(action)).to eq true }
|
|
25
|
+
end
|
|
26
|
+
description { "revoke #{"action".pluralize(actions.length)} #{actions.join(", ")}" }
|
|
27
|
+
failure_message { "expected #{test_subject} to revoke #{"action".pluralize(actions.length)} #{actions.join(", ")}" }
|
|
28
|
+
failure_message_when_negated do
|
|
29
|
+
"expected #{test_subject} not to revoke #{"action".pluralize(actions.length)} #{actions.join(", ")}"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def test_subject
|
|
33
|
+
subject.is_a?(Class) ? subject : subject.class
|
|
34
|
+
end
|
|
35
|
+
end
|
data/lib/law/statute_base.rb
CHANGED
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
require_relative "statutes/regulations"
|
|
4
4
|
require_relative "statutes/laws"
|
|
5
|
+
require_relative "statutes/compliance"
|
|
5
6
|
|
|
6
7
|
# A **Statute** restricts actions to **Actors** by enforcing a collection of **Permissions**.
|
|
7
8
|
module Law
|
|
8
9
|
class StatuteBase < Spicerack::RootObject
|
|
9
10
|
include Law::Statutes::Regulations
|
|
10
11
|
include Law::Statutes::Laws
|
|
12
|
+
include Law::Statutes::Compliance
|
|
11
13
|
end
|
|
12
14
|
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# A **Statute** is a collection of imposed **Regulations** with some **Compliance** rules.
|
|
4
|
+
module Law
|
|
5
|
+
module Statutes
|
|
6
|
+
module Compliance
|
|
7
|
+
extend ActiveSupport::Concern
|
|
8
|
+
|
|
9
|
+
class_methods do
|
|
10
|
+
def full_compliance_required?
|
|
11
|
+
@require_full_compliance.present?
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def inherited(base)
|
|
15
|
+
base.require_full_compliance if full_compliance_required?
|
|
16
|
+
super
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
protected
|
|
20
|
+
|
|
21
|
+
def require_full_compliance
|
|
22
|
+
@require_full_compliance = true
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
data/lib/law/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: law
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.8
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Eric Garside
|
|
8
|
+
- Brandon Trumpold
|
|
8
9
|
autorequire:
|
|
9
10
|
bindir: bin
|
|
10
11
|
cert_chain: []
|
|
11
|
-
date:
|
|
12
|
+
date: 2021-06-09 00:00:00.000000000 Z
|
|
12
13
|
dependencies:
|
|
13
14
|
- !ruby/object:Gem::Dependency
|
|
14
15
|
name: activesupport
|
|
@@ -16,21 +17,21 @@ dependencies:
|
|
|
16
17
|
requirements:
|
|
17
18
|
- - ">="
|
|
18
19
|
- !ruby/object:Gem::Version
|
|
19
|
-
version:
|
|
20
|
+
version: 6.0.3.7
|
|
20
21
|
type: :runtime
|
|
21
22
|
prerelease: false
|
|
22
23
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
24
|
requirements:
|
|
24
25
|
- - ">="
|
|
25
26
|
- !ruby/object:Gem::Version
|
|
26
|
-
version:
|
|
27
|
+
version: 6.0.3.7
|
|
27
28
|
- !ruby/object:Gem::Dependency
|
|
28
29
|
name: spicery
|
|
29
30
|
requirement: !ruby/object:Gem::Requirement
|
|
30
31
|
requirements:
|
|
31
32
|
- - ">="
|
|
32
33
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: 0.
|
|
34
|
+
version: 0.26.0.4
|
|
34
35
|
- - "<"
|
|
35
36
|
- !ruby/object:Gem::Version
|
|
36
37
|
version: '1.0'
|
|
@@ -40,7 +41,7 @@ dependencies:
|
|
|
40
41
|
requirements:
|
|
41
42
|
- - ">="
|
|
42
43
|
- !ruby/object:Gem::Version
|
|
43
|
-
version: 0.
|
|
44
|
+
version: 0.26.0.4
|
|
44
45
|
- - "<"
|
|
45
46
|
- !ruby/object:Gem::Version
|
|
46
47
|
version: '1.0'
|
|
@@ -134,7 +135,7 @@ dependencies:
|
|
|
134
135
|
requirements:
|
|
135
136
|
- - ">="
|
|
136
137
|
- !ruby/object:Gem::Version
|
|
137
|
-
version: 0.
|
|
138
|
+
version: 0.26.0.4
|
|
138
139
|
- - "<"
|
|
139
140
|
- !ruby/object:Gem::Version
|
|
140
141
|
version: '1.0'
|
|
@@ -144,7 +145,7 @@ dependencies:
|
|
|
144
145
|
requirements:
|
|
145
146
|
- - ">="
|
|
146
147
|
- !ruby/object:Gem::Version
|
|
147
|
-
version: 0.
|
|
148
|
+
version: 0.26.0.4
|
|
148
149
|
- - "<"
|
|
149
150
|
- !ruby/object:Gem::Version
|
|
150
151
|
version: '1.0'
|
|
@@ -154,7 +155,7 @@ dependencies:
|
|
|
154
155
|
requirements:
|
|
155
156
|
- - ">="
|
|
156
157
|
- !ruby/object:Gem::Version
|
|
157
|
-
version: 0.
|
|
158
|
+
version: 0.26.0.4
|
|
158
159
|
- - "<"
|
|
159
160
|
- !ruby/object:Gem::Version
|
|
160
161
|
version: '1.0'
|
|
@@ -164,7 +165,7 @@ dependencies:
|
|
|
164
165
|
requirements:
|
|
165
166
|
- - ">="
|
|
166
167
|
- !ruby/object:Gem::Version
|
|
167
|
-
version: 0.
|
|
168
|
+
version: 0.26.0.4
|
|
168
169
|
- - "<"
|
|
169
170
|
- !ruby/object:Gem::Version
|
|
170
171
|
version: '1.0'
|
|
@@ -172,12 +173,31 @@ description: Enforce the laws of your Rails application with highly extensible a
|
|
|
172
173
|
policies
|
|
173
174
|
email:
|
|
174
175
|
- garside@gmail.com
|
|
176
|
+
- brandon.trumpold@gmail.com
|
|
175
177
|
executables: []
|
|
176
178
|
extensions: []
|
|
177
179
|
extra_rdoc_files: []
|
|
178
180
|
files:
|
|
179
181
|
- LICENSE.txt
|
|
180
182
|
- README.md
|
|
183
|
+
- lib/generators/law/USAGE
|
|
184
|
+
- lib/generators/law/law_generator.rb
|
|
185
|
+
- lib/generators/law/regulation/USAGE
|
|
186
|
+
- lib/generators/law/regulation/regulation_generator.rb
|
|
187
|
+
- lib/generators/law/regulation/templates/regulation.rb.erb
|
|
188
|
+
- lib/generators/law/statute/USAGE
|
|
189
|
+
- lib/generators/law/statute/statute_generator.rb
|
|
190
|
+
- lib/generators/law/statute/templates/statute.rb.erb
|
|
191
|
+
- lib/generators/law/templates/law.rb.erb
|
|
192
|
+
- lib/generators/rspec/law/USAGE
|
|
193
|
+
- lib/generators/rspec/law/law_generator.rb
|
|
194
|
+
- lib/generators/rspec/law/templates/law_spec.rb.erb
|
|
195
|
+
- lib/generators/rspec/regulation/USAGE
|
|
196
|
+
- lib/generators/rspec/regulation/regulation_generator.rb
|
|
197
|
+
- lib/generators/rspec/regulation/templates/regulation_spec.rb.erb
|
|
198
|
+
- lib/generators/rspec/statute/USAGE
|
|
199
|
+
- lib/generators/rspec/statute/statute_generator.rb
|
|
200
|
+
- lib/generators/rspec/statute/templates/statute_spec.rb.erb
|
|
181
201
|
- lib/law.rb
|
|
182
202
|
- lib/law/judgement.rb
|
|
183
203
|
- lib/law/law_base.rb
|
|
@@ -198,9 +218,11 @@ files:
|
|
|
198
218
|
- lib/law/rspec/custom_matchers/define_action.rb
|
|
199
219
|
- lib/law/rspec/custom_matchers/have_default_statute.rb
|
|
200
220
|
- lib/law/rspec/custom_matchers/impose_regulations.rb
|
|
221
|
+
- lib/law/rspec/custom_matchers/revoke_action.rb
|
|
201
222
|
- lib/law/rspec/shoulda_matcher_helper.rb
|
|
202
223
|
- lib/law/spec_helper.rb
|
|
203
224
|
- lib/law/statute_base.rb
|
|
225
|
+
- lib/law/statutes/compliance.rb
|
|
204
226
|
- lib/law/statutes/laws.rb
|
|
205
227
|
- lib/law/statutes/regulations.rb
|
|
206
228
|
- lib/law/version.rb
|
|
@@ -226,7 +248,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
226
248
|
- !ruby/object:Gem::Version
|
|
227
249
|
version: '0'
|
|
228
250
|
requirements: []
|
|
229
|
-
rubygems_version: 3.
|
|
251
|
+
rubygems_version: 3.1.4
|
|
230
252
|
signing_key:
|
|
231
253
|
specification_version: 4
|
|
232
254
|
summary: Give illegal operations a whole new meaning with this policy enforcement
|