cerbos 0.11.0 → 0.12.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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +8 -1
  3. data/README.md +30 -2
  4. data/cerbos.gemspec +1 -0
  5. data/lib/cerbos/abstract_class.rb +10 -0
  6. data/lib/cerbos/client.rb +24 -41
  7. data/lib/cerbos/error.rb +79 -10
  8. data/lib/cerbos/hub/access_token.rb +137 -0
  9. data/lib/cerbos/hub/circuit_breaker.rb +185 -0
  10. data/lib/cerbos/hub/service.rb +18 -0
  11. data/lib/cerbos/hub/stores/client.rb +162 -0
  12. data/lib/cerbos/hub/stores/error.rb +108 -0
  13. data/lib/cerbos/hub/stores/file.rb +28 -0
  14. data/lib/cerbos/hub/stores/input/change_details/origin.rb +144 -0
  15. data/lib/cerbos/hub/stores/input/change_details/uploader.rb +38 -0
  16. data/lib/cerbos/hub/stores/input/change_details.rb +52 -0
  17. data/lib/cerbos/hub/stores/input/file_filter.rb +30 -0
  18. data/lib/cerbos/hub/stores/input/file_modification_condition.rb +34 -0
  19. data/lib/cerbos/hub/stores/input/file_operation.rb +66 -0
  20. data/lib/cerbos/hub/stores/input/string_match.rb +88 -0
  21. data/lib/cerbos/hub/stores/input.rb +17 -0
  22. data/lib/cerbos/hub/stores/output/get_files.rb +31 -0
  23. data/lib/cerbos/hub/stores/output/list_files.rb +31 -0
  24. data/lib/cerbos/hub/stores/output/modify_files.rb +35 -0
  25. data/lib/cerbos/hub/stores/output/replace_files.rb +43 -0
  26. data/lib/cerbos/hub/stores/output.rb +16 -0
  27. data/lib/cerbos/hub/stores.rb +15 -0
  28. data/lib/cerbos/hub.rb +12 -0
  29. data/lib/cerbos/input.rb +2 -1
  30. data/lib/cerbos/protobuf/buf/validate/validate_pb.rb +6 -6
  31. data/lib/cerbos/protobuf/cerbos/cloud/apikey/v1/apikey_pb.rb +26 -0
  32. data/lib/cerbos/protobuf/cerbos/cloud/apikey/v1/apikey_services_pb.rb +32 -0
  33. data/lib/cerbos/protobuf/cerbos/cloud/store/v1/store_pb.rb +52 -0
  34. data/lib/cerbos/protobuf/cerbos/cloud/store/v1/store_services_pb.rb +35 -0
  35. data/lib/cerbos/protobuf/cerbos/effect/v1/effect_pb.rb +1 -1
  36. data/lib/cerbos/protobuf/cerbos/engine/v1/engine_pb.rb +2 -2
  37. data/lib/cerbos/protobuf/cerbos/request/v1/request_pb.rb +2 -2
  38. data/lib/cerbos/protobuf/cerbos/response/v1/response_pb.rb +2 -2
  39. data/lib/cerbos/protobuf/cerbos/schema/v1/schema_pb.rb +1 -1
  40. data/lib/cerbos/protobuf/cerbos/svc/v1/svc_pb.rb +1 -1
  41. data/lib/cerbos/protobuf/google/api/annotations_pb.rb +1 -1
  42. data/lib/cerbos/protobuf/google/api/field_behavior_pb.rb +1 -1
  43. data/lib/cerbos/protobuf/google/api/http_pb.rb +2 -2
  44. data/lib/cerbos/protobuf/google/api/visibility_pb.rb +19 -0
  45. data/lib/cerbos/protobuf/grpc/health/v1/health_pb.rb +1 -1
  46. data/lib/cerbos/protobuf/protoc-gen-openapiv2/options/annotations_pb.rb +1 -1
  47. data/lib/cerbos/protobuf/protoc-gen-openapiv2/options/openapiv2_pb.rb +1 -1
  48. data/lib/cerbos/protobuf.rb +2 -0
  49. data/lib/cerbos/service.rb +33 -0
  50. data/lib/cerbos/version.rb +1 -1
  51. data/lib/cerbos.rb +7 -1
  52. data/yard_extensions.rb +8 -1
  53. metadata +45 -3
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cerbos
4
+ module Hub
5
+ module Stores
6
+ module Input
7
+ # Metadata describing a change that was made to a store.
8
+ class ChangeDetails
9
+ # Description of the change.
10
+ #
11
+ # @return [String]
12
+ attr_reader :description
13
+
14
+ # Origin of the change.
15
+ #
16
+ # @return [Origin]
17
+ # @return [nil] if not provided
18
+ attr_reader :origin
19
+
20
+ # Metadata describing the uploader who made the change.
21
+ #
22
+ # @return [Uploader]
23
+ # @return [nil] if not provided
24
+ attr_reader :uploader
25
+
26
+ # Specify metadata describing a change that was made to a store.
27
+ #
28
+ # @param description [String] description of the change.
29
+ # @param origin [Origin, Hash, nil] origin of the change.
30
+ # @param uploader [Uploader, Hash, nil] metadata describing the uploader who made the change.
31
+ def initialize(description: "", origin: nil, uploader: nil)
32
+ @description = description
33
+ @origin = Cerbos::Input.coerce_optional(origin, Origin)
34
+ @uploader = Cerbos::Input.coerce_optional(uploader, Uploader)
35
+ end
36
+
37
+ # @private
38
+ def to_protobuf
39
+ Protobuf::Cerbos::Cloud::Store::V1::ChangeDetails.new(
40
+ description:,
41
+ origin: origin&.to_protobuf,
42
+ uploader: uploader&.to_protobuf
43
+ )
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ require_relative "change_details/origin"
52
+ require_relative "change_details/uploader"
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cerbos
4
+ module Hub
5
+ module Stores
6
+ module Input
7
+ # A filter to match files when listing store contents.
8
+ class FileFilter
9
+ # Match files by path.
10
+ #
11
+ # @return [StringMatch]
12
+ # @return [nil] if not provided
13
+ attr_reader :path
14
+
15
+ # Specify a filter to match files when listing store contents.
16
+ #
17
+ # @param path [StringMatch, Hash, nil] match files by path.
18
+ def initialize(path: nil)
19
+ @path = Cerbos::Input.coerce_optional(path, StringMatch)
20
+ end
21
+
22
+ # @private
23
+ def to_protobuf
24
+ Protobuf::Cerbos::Cloud::Store::V1::FileFilter.new(path: path&.to_protobuf)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cerbos
4
+ module Hub
5
+ module Stores
6
+ module Input
7
+ # A condition that must be met to make a file modification.
8
+ class FileModificationCondition
9
+ # Only modify files if the store version is equal to the provided value.
10
+ #
11
+ # @return [Integer]
12
+ attr_reader :store_version_must_equal
13
+
14
+ # Specify a condition that must be met to make a file modification.
15
+ #
16
+ # @param store_version_must_equal [Integer] only modify files if the store version is equal to the provided value.
17
+ def initialize(store_version_must_equal:)
18
+ @store_version_must_equal = store_version_must_equal
19
+ end
20
+
21
+ # @private
22
+ def to_protobuf_modify_files
23
+ Protobuf::Cerbos::Cloud::Store::V1::ModifyFilesRequest::Condition.new(store_version_must_equal:)
24
+ end
25
+
26
+ # @private
27
+ def to_protobuf_replace_files
28
+ Protobuf::Cerbos::Cloud::Store::V1::ReplaceFilesRequest::Condition.new(store_version_must_equal:)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cerbos
4
+ module Hub
5
+ module Stores
6
+ module Input
7
+ # An operation modifying a file in a store.
8
+ #
9
+ # @abstract
10
+ class FileOperation
11
+ include AbstractClass
12
+
13
+ # Add or update a file.
14
+ class AddOrUpdate < FileOperation
15
+ # The file to add or update.
16
+ #
17
+ # @return [File]
18
+ attr_reader :file
19
+
20
+ # Specify a file to add or update.
21
+ #
22
+ # @param file [File, Hash] the file to add or update.
23
+ def initialize(file:)
24
+ @file = Cerbos::Input.coerce_required(file, File)
25
+ end
26
+
27
+ # @private
28
+ def to_protobuf
29
+ Protobuf::Cerbos::Cloud::Store::V1::FileOp.new(add_or_update: file.to_protobuf)
30
+ end
31
+ end
32
+
33
+ # Delete a file.
34
+ class Delete < FileOperation
35
+ # Path of the file to delete.
36
+ #
37
+ # @return [String]
38
+ attr_reader :path
39
+
40
+ # Specify a file to delete.
41
+ #
42
+ # @param path [String] path of the file to delete.
43
+ def initialize(path:)
44
+ @path = path
45
+ end
46
+
47
+ # @private
48
+ def to_protobuf
49
+ Protobuf::Cerbos::Cloud::Store::V1::FileOp.new(delete: path)
50
+ end
51
+ end
52
+
53
+ # @private
54
+ def self.from_h(**file_operation)
55
+ case file_operation
56
+ in add_or_update: file, **nil
57
+ AddOrUpdate.new(file:)
58
+ in delete: path, **nil
59
+ Delete.new(path:)
60
+ end
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cerbos
4
+ module Hub
5
+ module Stores
6
+ module Input
7
+ # Filter to match a string.
8
+ #
9
+ # @abstract
10
+ class StringMatch
11
+ include AbstractClass
12
+
13
+ # Filter to match a string exactly.
14
+ class Equals < StringMatch
15
+ # The string to match.
16
+ #
17
+ # @return [String]
18
+ attr_reader :value
19
+
20
+ # Specify a filter to match a string exactly.
21
+ #
22
+ # @param value [String] the string to match.
23
+ def initialize(value:)
24
+ @value = value
25
+ end
26
+
27
+ # @private
28
+ def to_protobuf
29
+ Protobuf::Cerbos::Cloud::Store::V1::StringMatch.new(equals: value)
30
+ end
31
+ end
32
+
33
+ # Filter to match a string by a substring.
34
+ class Contains < StringMatch
35
+ # The substring to match.
36
+ #
37
+ # @return [String]
38
+ attr_reader :value
39
+
40
+ # Specify a filter to match a string by a substring.
41
+ #
42
+ # @param value [String] the substring to match.
43
+ def initialize(value:)
44
+ @value = value
45
+ end
46
+
47
+ # @private
48
+ def to_protobuf
49
+ Protobuf::Cerbos::Cloud::Store::V1::StringMatch.new(contains: value)
50
+ end
51
+ end
52
+
53
+ # Filter to match a string from a list.
54
+ class In < StringMatch
55
+ # The strings to match.
56
+ #
57
+ # @return [Array<String>]
58
+ attr_reader :values
59
+
60
+ # Specify a filter to match a string from a list.
61
+ #
62
+ # @param values [Array<String>] the strings to match.
63
+ def initialize(values:)
64
+ @values = values
65
+ end
66
+
67
+ # @private
68
+ def to_protobuf
69
+ Protobuf::Cerbos::Cloud::Store::V1::StringMatch.new(in: Protobuf::Cerbos::Cloud::Store::V1::StringMatch::InList.new(values:))
70
+ end
71
+ end
72
+
73
+ # @private
74
+ def self.from_h(**string_match)
75
+ case string_match
76
+ in equals: value, **nil
77
+ Equals.new(value:)
78
+ in contains: value, **nil
79
+ Contains.new(value:)
80
+ in in: values, **nil
81
+ In.new(values:)
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cerbos
4
+ module Hub
5
+ module Stores
6
+ # Namespace for objects passed to {Client} methods.
7
+ module Input
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+ require_relative "input/change_details"
14
+ require_relative "input/file_filter"
15
+ require_relative "input/file_modification_condition"
16
+ require_relative "input/file_operation"
17
+ require_relative "input/string_match"
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cerbos
4
+ module Hub
5
+ module Stores
6
+ module Output
7
+ # The outcome of getting files from a store.
8
+ #
9
+ # @see Client#get_files
10
+ GetFiles = Cerbos::Output.new_class(:store_version, :files) do
11
+ # @!attribute [r] store_version
12
+ # The current version of the store.
13
+ #
14
+ # @return [Integer]
15
+
16
+ # @!attribute [r] files
17
+ # Paths of the files that were found in the store.
18
+ #
19
+ # @return [Array<File>]
20
+
21
+ def self.from_protobuf(get_files)
22
+ new(
23
+ store_version: get_files.store_version,
24
+ files: get_files.files.map { |file| File.from_protobuf(file) }
25
+ )
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cerbos
4
+ module Hub
5
+ module Stores
6
+ module Output
7
+ # The outcome of listing files in a store.
8
+ #
9
+ # @see Client#list_files
10
+ ListFiles = Cerbos::Output.new_class(:store_version, :files) do
11
+ # @!attribute [r] store_version
12
+ # The current version of the store.
13
+ #
14
+ # @return [Integer]
15
+
16
+ # @!attribute [r] files
17
+ # Paths of the files that were found in the store.
18
+ #
19
+ # @return [Array<String>]
20
+
21
+ def self.from_protobuf(list_files)
22
+ new(
23
+ store_version: list_files.store_version,
24
+ files: list_files.files
25
+ )
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cerbos
4
+ module Hub
5
+ module Stores
6
+ module Output
7
+ # The outcome of modifying files in a store.
8
+ #
9
+ # @see Client#modify_files
10
+ ModifyFiles = Cerbos::Output.new_class(:new_store_version, :changed) do
11
+ # @!attribute [r] new_store_version
12
+ # The new version of the store after the files were replaced.
13
+ #
14
+ # If `allow_unchanged` was `true`, this will be the existing store version if no changes were made.
15
+ #
16
+ # @return [Integer]
17
+
18
+ # @!attribute [r] changed
19
+ # Whether any changes were made to the store contents.
20
+ #
21
+ # This can only be `false` if `allow_unchanged` was `true`.
22
+ #
23
+ # @return [Boolean]
24
+
25
+ def self.from_protobuf(modify_files)
26
+ new(
27
+ new_store_version: modify_files.new_store_version,
28
+ changed: true
29
+ )
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cerbos
4
+ module Hub
5
+ module Stores
6
+ module Output
7
+ # The outcome of replacing files in a store.
8
+ #
9
+ # @see Client#replace_files
10
+ ReplaceFiles = Cerbos::Output.new_class(:new_store_version, :ignored_files, :changed) do
11
+ # @!attribute [r] new_store_version
12
+ # The new version of the store after the files were replaced.
13
+ #
14
+ # If `allow_unchanged` was `true`, this will be the existing store version if no changes were made.
15
+ #
16
+ # @return [Integer]
17
+
18
+ # @!attribute [r] ignored_files
19
+ # Paths of files that were provided in the request but were ignored.
20
+ #
21
+ # Files with unexpected paths, for example hidden files, will be ignored.
22
+ #
23
+ # @return [Array<String>]
24
+
25
+ # @!attribute [r] changed
26
+ # Whether any changes were made to the store contents.
27
+ #
28
+ # This can only be `false` if `allow_unchanged` was `true`.
29
+ #
30
+ # @return [Boolean]
31
+
32
+ def self.from_protobuf(replace_files)
33
+ new(
34
+ new_store_version: replace_files.new_store_version,
35
+ ignored_files: replace_files.ignored_files,
36
+ changed: true
37
+ )
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cerbos
4
+ module Hub
5
+ module Stores
6
+ # Namespace for objects returned by {Client} methods.
7
+ module Output
8
+ end
9
+ end
10
+ end
11
+ end
12
+
13
+ require_relative "output/get_files"
14
+ require_relative "output/list_files"
15
+ require_relative "output/modify_files"
16
+ require_relative "output/replace_files"
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cerbos
4
+ module Hub
5
+ # Namespace for interacting with {https://docs.cerbos.dev/cerbos-hub/policy-stores policy stores}.
6
+ module Stores
7
+ end
8
+ end
9
+ end
10
+
11
+ require_relative "stores/client"
12
+ require_relative "stores/error"
13
+ require_relative "stores/file"
14
+ require_relative "stores/input"
15
+ require_relative "stores/output"
data/lib/cerbos/hub.rb ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cerbos
4
+ # Namespace for clients for interacting with {https://www.cerbos.dev/product-cerbos-hub Cerbos Hub}.
5
+ module Hub
6
+ end
7
+ end
8
+
9
+ require_relative "hub/access_token"
10
+ require_relative "hub/circuit_breaker"
11
+ require_relative "hub/service"
12
+ require_relative "hub/stores"
data/lib/cerbos/input.rb CHANGED
@@ -7,9 +7,10 @@ module Cerbos
7
7
  def self.coerce_required(value, to_class)
8
8
  raise ArgumentError, "Value is required" if value.nil?
9
9
  return value if value.is_a?(to_class)
10
+ return to_class.from_h(**value) if to_class.respond_to?(:from_h)
10
11
 
11
12
  to_class.new(**value)
12
- rescue ArgumentError, TypeError => error
13
+ rescue ArgumentError, NoMatchingPatternError, TypeError => error
13
14
  raise Error::InvalidArgument.new(details: "Failed to create #{to_class.name} from #{value.inspect}: #{error}")
14
15
  end
15
16