aserto 0.20.6 → 0.30.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dc8ec9b57f67226df562850ca0188c27b310de08b2ac716d30143c2c603b84fd
4
- data.tar.gz: 845f1cdf67e54411d004b2a91b0a37ba02d709c949512110a8158552c67f48a3
3
+ metadata.gz: ddb26b2da994a8a4f72162f227590060a990a31d16639994b5cd2e4bd9ce538f
4
+ data.tar.gz: e6969585d13f94a6e410d8763647cbc3dca69402969a194db2674239514adeeb
5
5
  SHA512:
6
- metadata.gz: dda8391014951485e822508b064667ff3bfd649b412df436fe019fb3c351fc891bed770093bf9a4c8db6e1bf791a14ed3dd6e23f9bcb6def14e5c26b69f49745
7
- data.tar.gz: 675b6dbcc2c38a8d094a3baa59de6c786a5ddd07ad0f8ab91975b70645f279df28bcfd856c5ec33a68664afe365d4852fcfc7599c91fbdd881b0ff50be3346c5
6
+ metadata.gz: c0202011d8ce67f9fc48e361fdbd00b9239e291aa7bc60e5773eed58252dec41fdbac16e28ea25f0ff54d4652a0eee247ec048f59e6df5b1ae1bc5d254638244
7
+ data.tar.gz: a2c5e23bcb6e18ee1babb1c13d0e39912c32aa70595c5ce8dae69e24e0f10c6c37e7251f6dad0d5059fbe801dc8bf3d5ddde3ba806c071ae96b52afd1ba84f49
data/README.md CHANGED
@@ -23,7 +23,7 @@ gem install aserto
23
23
 
24
24
  ## Directory
25
25
 
26
- The Directory APIs can be used to get or set object instances and relation instances. They can also be used to check whether a user has a permission or relation on an object instance.
26
+ The Directory APIs can be used to get or set object instances and relation instances. They can also be used to check whether a user has permission or relation on an object instance.
27
27
 
28
28
  ### Directory Client
29
29
 
@@ -32,7 +32,7 @@ You can initialize a directory client as follows:
32
32
  ```ruby
33
33
  require 'aserto/directory/client'
34
34
 
35
- directory_client = Aserto::Directory::Client.new(
35
+ directory_client = Aserto::Directory::V3::Client.new(
36
36
  url: "directory.eng.aserto.com:8443",
37
37
  tenant_id: "aserto-tenant-id",
38
38
  api_key: "basic directory api key",
@@ -42,87 +42,9 @@ directory_client = Aserto::Directory::Client.new(
42
42
  - `url`: hostname:port of directory service (_required_)
43
43
  - `api_key`: API key for directory service (_required_ if using hosted directory)
44
44
  - `tenant_id`: Aserto tenant ID (_required_ if using hosted directory)
45
- - `cert_path`: Path to the grpc service certificate when connecting to local topaz instance.
45
+ - `cert_path`: Path to the grpc service certificate when connecting to the local topaz instance.
46
46
 
47
- ### Getting objects and relations
48
- Get an object instance with the type `type-name` and the key `object-key`. For example:
49
-
50
- ```ruby
51
- user = directory_client.object(type: 'user', key: 'euang@acmecorp.com')
52
- ```
53
-
54
- Get an array of relations of a certain type for an object instance. For example:
55
-
56
- ```ruby
57
- identity = 'euang@acmecorp.com';
58
- relations = directory_client.relation(
59
- {
60
- subject: {
61
- type: 'user',
62
- },
63
- object: {
64
- type: 'identity',
65
- key: identity
66
- },
67
- relation: {
68
- name: 'identifier',
69
- objectType: 'identity'
70
- }
71
- }
72
- )
73
- ```
74
-
75
- ### Setting objects and relations
76
-
77
- Create a new object
78
- ```ruby
79
- user = directory_client.set_object(object: { type: "user", key: "test-object", display_name: "test object" })
80
- identity = directory_client.set_object(object: { type: "identity", key: "test-identity" })
81
- ```
82
-
83
- Update an existing object
84
- ```ruby
85
- user = directory_client.set_object(object: { type: "user", key: "test-object", display_name: "test object" })
86
- user.display_name = 'test object edit'
87
- updated_user = directory_client.set_object(object: user)
88
- ```
89
-
90
- Create a new relation
91
- ```ruby
92
- directory_client.set_relation(
93
- subject: { type: "user", "test-object" },
94
- relation: "identifier",
95
- object: { type: "identity", key: "test-identity" }
96
- )
97
- ```
98
-
99
- Delete a relation
100
- ```ruby
101
- pp client.delete_relation(
102
- subject: { type: "user", key: "test-object" },
103
- relation: { name: "identifier", object_type: "identity" },
104
- object: { type: "identity", key: "test-identity" }
105
- )
106
- ```
107
-
108
- ### Checking permissions and relations
109
- Check permission
110
- ```ruby
111
- directory_client.check_permission(
112
- subject: { type: "user", key: "011a88bc-7df9-4d92-ba1f-2ff319e101e1" },
113
- permission: { name: "read" },
114
- object: { type: "group", key: "executive" }
115
- )
116
- ```
117
-
118
- Check relation
119
- ```ruby
120
- directory_client.check_relation(
121
- subject: { type: "user", key: "dfdadc39-7335-404d-af66-c77cf13a15f8" },
122
- relation: { name: "identifier", object_type: "identity" },
123
- object: { type: "identity", key: "euang@acmecorp.com" }
124
- )
125
- ```
47
+ See [Aserto::Directory::V3::Client](https://rubydoc.info/gems/aserto/Aserto/Directory/V3/Client) for full documentation
126
48
 
127
49
  ## Authorizer
128
50
  `Aserto::Authorization` is a middleware that allows Ruby applications to use Aserto as the Authorization provider.
@@ -150,7 +72,7 @@ The middleware accepts the following optional parameters:
150
72
  | cert_path | `""` | Path to the grpc service certificate when connecting to local topaz instance. |
151
73
  | decision | `"allowed"` | The decision that will be used by the middleware when creating an authorizer request. |
152
74
  | logger | `STDOUT` | The logger to be used by the middleware. |
153
- | identity_mapping | `{ type: :none }` | The strategy for retrieving the identity, possible values: `:jwt, :sub, :none` |
75
+ | identity_mapping | `{ type: :none }` | The strategy for retrieving the identity, possible values: `:jwt, :sub, :manual, :none` |
154
76
  | disabled_for | `[{}]` | Which path and actions to skip the authorization for. |
155
77
  | on_unauthorized | `-> { return [403, {}, ["Forbidden"]] }`| A lambda that is executed when the authorization fails. |
156
78
 
@@ -172,6 +94,14 @@ config.identity_mapping = {
172
94
  }
173
95
  ```
174
96
 
97
+ ```ruby
98
+ # configure the middleware to use a manual identity.
99
+ config.identity_mapping = {
100
+ type: :manual,
101
+ value: "my-identity",
102
+ }
103
+ ```
104
+
175
105
  The whole identity resolution can be overwritten by providing a custom function.
176
106
  ```ruby
177
107
  # config/initializers/aserto.rb
@@ -190,7 +120,7 @@ end
190
120
  By default, when computing the policy path, the middleware:
191
121
  * converts all slashes to dots
192
122
  * converts any character that is not alpha, digit, dot or underscore to underscore
193
- * converts uppercase characters in the URL path to lowercases
123
+ * converts uppercase characters in the URL path to lowercase
194
124
 
195
125
  This behaviour can be overwritten by providing a custom function:
196
126
 
@@ -206,7 +136,7 @@ end
206
136
  ```
207
137
 
208
138
  ### Resource
209
- A resource can be any structured data that the authorization policy uses to evaluate decisions. By default, middleware does not include a resource in authorization calls.
139
+ A resource can be any structured data the authorization policy uses to evaluate decisions. By default, middleware does not include a resource in authorization calls.
210
140
 
211
141
  This behaviour can be overwritten by providing a custom function:
212
142
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.20.6
1
+ 0.30.1
@@ -13,6 +13,7 @@ module Aserto
13
13
  INTERNAL_MAPPING = {
14
14
  unknown: Aserto::Authorizer::V2::Api::IdentityType::IDENTITY_TYPE_UNKNOWN,
15
15
  none: Aserto::Authorizer::V2::Api::IdentityType::IDENTITY_TYPE_NONE,
16
+ manual: Aserto::Authorizer::V2::Api::IdentityType::IDENTITY_TYPE_MANUAL,
16
17
  sub: Aserto::Authorizer::V2::Api::IdentityType::IDENTITY_TYPE_SUB,
17
18
  jwt: Aserto::Authorizer::V2::Api::IdentityType::IDENTITY_TYPE_JWT
18
19
  }.freeze
@@ -1,14 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "aserto/directory"
4
- require_relative "interceptors/headers"
5
- require_relative "requests"
3
+ require_relative "v2/client"
6
4
 
7
5
  module Aserto
8
6
  module Directory
9
7
  class Client
10
- include Requests
11
-
12
8
  # Creates a new Directory Client
13
9
  #
14
10
  # @param url [String] the gRpc url of the directory server
@@ -17,127 +13,28 @@ module Aserto
17
13
  # @param cert_path [String] the path to the certificates folder
18
14
  #
19
15
  # @return [Aserto::Directory::Client] the new Directory Client
20
- def initialize(url: "directory.prod.aserto.com:8443", api_key: nil, tenant_id: nil, cert_path: nil)
21
- @reader_client = ::Aserto::Directory::Reader::V2::Reader::Stub.new(
22
- url,
23
- load_creds(cert_path),
24
- interceptors: [Interceptors::Headers.new(api_key, tenant_id)]
25
- )
26
- @writer_client = ::Aserto::Directory::Writer::V2::Writer::Stub.new(
27
- url,
28
- load_creds(cert_path),
29
- interceptors: [Interceptors::Headers.new(api_key, tenant_id)]
30
- )
31
- end
32
-
33
- # Check permissions
34
- #
35
- # @param subject [::Aserto::Directory::Common::V2::ObjectIdentifier]
36
- # @param permission [String] permission name to be checked
37
- # @param object [::Aserto::Directory::Common::V2::ObjectIdentifier]
38
- # @param trace [Boolean] whether to enable tracing
39
- #
40
- # @return [Boolean]
41
- def check_permission(subject:, permission:, object:, trace: false)
42
- reader_client.check_permission(check_permission_request(subject, permission, object, trace))
43
- end
44
-
45
- # Check relation
46
- #
47
- # @param subject [::Aserto::Directory::Common::V2::ObjectIdentifier]
48
- # @param relation [::Aserto::Directory::Common::V2::RelationTypeIdentifier] relation name to be checked
49
- # @param object [::Aserto::Directory::Common::V2::ObjectIdentifier]
50
- # @param trace [Boolean] whether to enable tracing
51
- #
52
- # @return [Boolean]
53
- def check_relation(subject:, relation:, object:, trace: false)
54
- reader_client.check_relation(check_relation_request(subject, relation, object, trace))
55
- end
56
-
57
- # Get an object by type and key
58
- #
59
- # @param type [String] the type of object
60
- # @param key [String] the key of the object
61
- #
62
- # @return [::Aserto::Directory::Common::V2::Object]
63
- def object(type:, key:)
64
- reader_client.get_object(object_request(key, type)).result
65
- end
66
-
67
- # Set an object
68
- #
69
- # @param object [::Aserto::Directory::Common::V2::Object]
70
- #
71
- # @return [::Aserto::Directory::Common::V2::Object] the created/updated object
72
- def set_object(object:)
73
- writer_client.set_object(new_object_request(object)).result
74
- end
75
-
76
- # Get a list of objects by type
77
- #
78
- # @param type [String] the type of objects
79
- # @param page [::Aserto::Directory::Common::V2::PaginationRequest]
80
- #
81
- # @return [Array<::Aserto::Directory::Common::V2::Object>]
82
- def objects(type:, page: nil)
83
- reader_client.get_objects(objects_request(type, page)).results
84
- end
85
16
 
86
- # Get a relation
87
- #
88
- # @param subject [::Aserto::Directory::Common::V2::ObjectIdentifier]
89
- # @param relation [::Aserto::Directory::Common::V2::RelationTypeIdentifier]
90
- # @param object [::Aserto::Directory::Common::V2::ObjectIdentifier]
91
- #
92
- # @return [::Aserto::Directory::Common::V2::Relation]
93
- def relation(subject: nil, relation: nil, object: nil)
94
- reader_client.get_relation(relation_request(subject, relation, object)).results
95
- end
17
+ def initialize(url: "directory.prod.aserto.com:8443", api_key: nil, tenant_id: nil, cert_path: nil)
18
+ warn WARN_MESSAGE
96
19
 
97
- # Get a list of relations
98
- #
99
- # @param subject [::Aserto::Directory::Common::V2::ObjectIdentifier]
100
- # @param relation [::Aserto::Directory::Common::V2::RelationTypeIdentifier]
101
- # @param object [::Aserto::Directory::Common::V2::ObjectIdentifier]
102
- #
103
- # @return [Array<::Aserto::Directory::Common::V2::Relation>]
104
- def relations(subject: nil, relation: nil, object: nil, page: nil)
105
- reader_client.get_relations(relations_request(subject, relation, object, page)).results
20
+ @v2_client = Aserto::Directory::V2::Client.new(
21
+ url: url, api_key: api_key, tenant_id: tenant_id, cert_path: cert_path
22
+ )
106
23
  end
107
24
 
108
- # Set a relation
109
- # @param subject [::Aserto::Directory::Common::V2::ObjectIdentifier]
110
- # @param relation [String] name of the relation
111
- # @param object [::Aserto::Directory::Common::V2::ObjectIdentifier]
112
- # @param hash [String] hash of the relation(required for updating a relation)
113
- #
114
- # @return [::Aserto::Directory::Common::V2::Relation] the created/updated relation
115
- def set_relation(subject:, relation:, object:, hash: nil)
116
- writer_client.set_relation(new_relation_request(subject, relation, object, hash)).result
25
+ def method_missing(method, args)
26
+ @v2_client.send(method, **args)
117
27
  end
118
28
 
119
- # Delete a relation
120
- #
121
- # @param subject [::Aserto::Directory::Common::V2::ObjectIdentifier]
122
- # @param relation [::Aserto::Directory::Common::V2::RelationTypeIdentifier]
123
- # @param object [::Aserto::Directory::Common::V2::ObjectIdentifier]
124
- #
125
- # @return nil
126
- def delete_relation(subject:, relation:, object:)
127
- writer_client.delete_relation(delete_relation_request(subject, relation, object))
29
+ def respond_to_missing?(_name, _include_private)
30
+ true
128
31
  end
129
32
 
130
- private
131
-
132
- attr_reader :reader_client, :writer_client
133
-
134
- def load_creds(cert_path)
135
- if cert_path && File.file?(cert_path)
136
- GRPC::Core::ChannelCredentials.new(File.read(cert_path))
137
- else
138
- GRPC::Core::ChannelCredentials.new
139
- end
140
- end
33
+ WARN_MESSAGE = <<~TEXT
34
+ Aserto::Directory::Client is deprecated and will be removed.
35
+ Use Aserto::Directory::V3::Client for the latest Directory Client.
36
+ If you need Directory V2, use Aserto::Directory::V2::Client
37
+ TEXT
141
38
  end
142
39
  end
143
40
  end
@@ -10,11 +10,31 @@ module Aserto
10
10
  super()
11
11
  end
12
12
 
13
- def request_response(method:, request:, call:, metadata:)
13
+ def request_response(request: nil, call: nil, method: nil, metadata: nil)
14
+ update_metadata(metadata)
15
+ yield(request, call, method, metadata)
16
+ end
17
+
18
+ def bidi_streamer(requests: nil, call: nil, method: nil, metadata: nil)
19
+ update_metadata(metadata)
20
+ yield(requests, call, method, metadata)
21
+ end
22
+
23
+ def client_streamer(requests: nil, call: nil, method: nil, metadata: nil)
24
+ update_metadata(metadata)
25
+ yield(requests, call, method, metadata)
26
+ end
27
+
28
+ def server_streamer(request: nil, call: nil, method: nil, metadata: nil)
29
+ update_metadata(metadata)
30
+ yield(request, call, method, metadata)
31
+ end
32
+
33
+ private
34
+
35
+ def update_metadata(metadata)
14
36
  metadata["aserto-tenant-id"] = @tenant_id
15
37
  metadata["authorization"] = @api_key
16
-
17
- yield(method, request, call, metadata)
18
38
  end
19
39
  end
20
40
  end
@@ -0,0 +1,145 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "aserto/directory"
4
+ require_relative "../interceptors/headers"
5
+ require_relative "requests"
6
+
7
+ module Aserto
8
+ module Directory
9
+ module V2
10
+ class Client
11
+ include Requests
12
+
13
+ # Creates a new Directory V2 Client
14
+ #
15
+ # @param url [String] the gRpc url of the directory server
16
+ # @param api_key [String] the api key of the directory server(for hosted directory)
17
+ # @param tenant_id [String] the tenant id of the directory server(for hosted directory)
18
+ # @param cert_path [String] the path to the certificates folder
19
+ #
20
+ # @return [Aserto::Directory::V2::Client] the new Directory Client
21
+ def initialize(url: "directory.prod.aserto.com:8443", api_key: nil, tenant_id: nil, cert_path: nil)
22
+ @reader_client = ::Aserto::Directory::Reader::V2::Reader::Stub.new(
23
+ url,
24
+ load_creds(cert_path),
25
+ interceptors: [Interceptors::Headers.new(api_key, tenant_id)]
26
+ )
27
+ @writer_client = ::Aserto::Directory::Writer::V2::Writer::Stub.new(
28
+ url,
29
+ load_creds(cert_path),
30
+ interceptors: [Interceptors::Headers.new(api_key, tenant_id)]
31
+ )
32
+ end
33
+
34
+ # Check permissions
35
+ #
36
+ # @param subject [::Aserto::Directory::Common::V2::ObjectIdentifier]
37
+ # @param permission [String] permission name to be checked
38
+ # @param object [::Aserto::Directory::Common::V2::ObjectIdentifier]
39
+ # @param trace [Boolean] whether to enable tracing
40
+ #
41
+ # @return [Boolean]
42
+ def check_permission(subject:, permission:, object:, trace: false)
43
+ reader_client.check_permission(check_permission_request(subject, permission, object, trace))
44
+ end
45
+
46
+ # Check relation
47
+ #
48
+ # @param subject [::Aserto::Directory::Common::V2::ObjectIdentifier]
49
+ # @param relation [::Aserto::Directory::Common::V2::RelationTypeIdentifier] relation name to be checked
50
+ # @param object [::Aserto::Directory::Common::V2::ObjectIdentifier]
51
+ # @param trace [Boolean] whether to enable tracing
52
+ #
53
+ # @return [Boolean]
54
+ def check_relation(subject:, relation:, object:, trace: false)
55
+ reader_client.check_relation(check_relation_request(subject, relation, object, trace))
56
+ end
57
+
58
+ # Get an object by type and key
59
+ #
60
+ # @param type [String] the type of object
61
+ # @param key [String] the key of the object
62
+ #
63
+ # @return [::Aserto::Directory::Common::V2::Object]
64
+ def object(type:, key:)
65
+ reader_client.get_object(object_request(key, type)).result
66
+ end
67
+
68
+ # Set an object
69
+ #
70
+ # @param object [::Aserto::Directory::Common::V2::Object]
71
+ #
72
+ # @return [::Aserto::Directory::Common::V2::Object] the created/updated object
73
+ def set_object(object:)
74
+ writer_client.set_object(new_object_request(object)).result
75
+ end
76
+
77
+ # Get a list of objects by type
78
+ #
79
+ # @param type [String] the type of objects
80
+ # @param page [::Aserto::Directory::Common::V2::PaginationRequest]
81
+ #
82
+ # @return [Array<::Aserto::Directory::Common::V2::Object>]
83
+ def objects(type:, page: nil)
84
+ reader_client.get_objects(objects_request(type, page)).results
85
+ end
86
+
87
+ # Get a relation
88
+ #
89
+ # @param subject [::Aserto::Directory::Common::V2::ObjectIdentifier]
90
+ # @param relation [::Aserto::Directory::Common::V2::RelationTypeIdentifier]
91
+ # @param object [::Aserto::Directory::Common::V2::ObjectIdentifier]
92
+ #
93
+ # @return [::Aserto::Directory::Common::V2::Relation]
94
+ def relation(subject: nil, relation: nil, object: nil)
95
+ reader_client.get_relation(relation_request(subject, relation, object)).results
96
+ end
97
+
98
+ # Get a list of relations
99
+ #
100
+ # @param subject [::Aserto::Directory::Common::V2::ObjectIdentifier]
101
+ # @param relation [::Aserto::Directory::Common::V2::RelationTypeIdentifier]
102
+ # @param object [::Aserto::Directory::Common::V2::ObjectIdentifier]
103
+ #
104
+ # @return [Array<::Aserto::Directory::Common::V2::Relation>]
105
+ def relations(subject: nil, relation: nil, object: nil, page: nil)
106
+ reader_client.get_relations(relations_request(subject, relation, object, page)).results
107
+ end
108
+
109
+ # Set a relation
110
+ # @param subject [::Aserto::Directory::Common::V2::ObjectIdentifier]
111
+ # @param relation [String] name of the relation
112
+ # @param object [::Aserto::Directory::Common::V2::ObjectIdentifier]
113
+ # @param hash [String] hash of the relation(required for updating a relation)
114
+ #
115
+ # @return [::Aserto::Directory::Common::V2::Relation] the created/updated relation
116
+ def set_relation(subject:, relation:, object:, hash: nil)
117
+ writer_client.set_relation(new_relation_request(subject, relation, object, hash)).result
118
+ end
119
+
120
+ # Delete a relation
121
+ #
122
+ # @param subject [::Aserto::Directory::Common::V2::ObjectIdentifier]
123
+ # @param relation [::Aserto::Directory::Common::V2::RelationTypeIdentifier]
124
+ # @param object [::Aserto::Directory::Common::V2::ObjectIdentifier]
125
+ #
126
+ # @return nil
127
+ def delete_relation(subject:, relation:, object:)
128
+ writer_client.delete_relation(delete_relation_request(subject, relation, object))
129
+ end
130
+
131
+ private
132
+
133
+ attr_reader :reader_client, :writer_client
134
+
135
+ def load_creds(cert_path)
136
+ if cert_path && File.file?(cert_path)
137
+ GRPC::Core::ChannelCredentials.new(File.read(cert_path))
138
+ else
139
+ GRPC::Core::ChannelCredentials.new
140
+ end
141
+ end
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "aserto/directory"
4
+ require_relative "../interceptors/headers"
5
+ require_relative "config"
6
+ require_relative "reader"
7
+ require_relative "writer"
8
+ require_relative "model"
9
+ require_relative "importer"
10
+ require_relative "exporter"
11
+
12
+ module Aserto
13
+ module Directory
14
+ module V3
15
+ class Client
16
+ extend Forwardable
17
+ include ::Aserto::Directory::V3::Reader
18
+ # @!parse include ::Aserto::Directory::V3::Reader
19
+
20
+ include ::Aserto::Directory::V3::Writer
21
+ # @!parse include ::Aserto::Directory::V3::Writer
22
+
23
+ include ::Aserto::Directory::V3::Model
24
+ # @!parse include ::Aserto::Directory::V3::Model
25
+
26
+ include ::Aserto::Directory::V3::Importer
27
+ # @!parse include ::Aserto::Directory::V3::Importer
28
+
29
+ include ::Aserto::Directory::V3::Exporter
30
+ # @!parse include ::Aserto::Directory::V3::Exporter
31
+
32
+ # Creates a new Directory V3 Client
33
+ #
34
+ # @param config [Aserto::Directory::V3::Config] the service configuration
35
+ # Base configuration
36
+ # If non-nil, this configuration is used for any client that doesn't have its own configuration.
37
+ # If nil, only clients that have their own configuration will be created.
38
+ #
39
+ # @example Create a new Directory V3 Client with all the services
40
+ # client = Aserto::Directory::V3::Client.new(
41
+ # {
42
+ # url: "directory.eng.aserto.com:8443",
43
+ # tenant_id: "tenant-id",
44
+ # api_key: "basic api-key",
45
+ # }
46
+ # )
47
+ #
48
+ # @example Create a new Directory V3 Client with reader only
49
+ # client = Aserto::Directory::V3::Client.new(
50
+ # {
51
+ # reader: {
52
+ # url: "directory.eng.aserto.com:8443",
53
+ # tenant_id: "tenant-id",
54
+ # api_key: "basic api-key",
55
+ # }
56
+ # }
57
+ # )
58
+ #
59
+ # @return [Aserto::Directory::V3::Client] the new Directory V3 Client
60
+ def initialize(config)
61
+ base_config = ::Aserto::Directory::V3::Config.new(config)
62
+
63
+ @reader = create_client(:reader, base_config.reader)
64
+ @writer = create_client(:writer, base_config.writer)
65
+ @importer = create_client(:importer, base_config.importer)
66
+ @exporter = create_client(:exporter, base_config.exporter)
67
+ @model = create_client(:model, base_config.model)
68
+ end
69
+
70
+ private
71
+
72
+ attr_reader :reader, :writer, :model, :importer, :exporter
73
+
74
+ class NullClient
75
+ def initialize(name)
76
+ @name = name
77
+ end
78
+
79
+ def method_missing(method, *_args)
80
+ puts "Cannot call '#{method}': '#{@name.to_s.capitalize}' client is not initialized."
81
+ end
82
+
83
+ def respond_to_missing?(_name, _include_private)
84
+ true
85
+ end
86
+ end
87
+
88
+ SERVICE_MAP = {
89
+ reader: ::Aserto::Directory::Reader::V3::Reader::Stub,
90
+ writer: ::Aserto::Directory::Writer::V3::Writer::Stub,
91
+ importer: ::Aserto::Directory::Importer::V3::Importer::Stub,
92
+ exporter: ::Aserto::Directory::Exporter::V3::Exporter::Stub,
93
+ model: ::Aserto::Directory::Model::V3::Model::Stub
94
+ }.freeze
95
+
96
+ def create_client(type, config)
97
+ return NullClient.new(type) unless config
98
+
99
+ SERVICE_MAP[type].new(
100
+ config.url,
101
+ config.credentials,
102
+ interceptors: config.interceptors
103
+ )
104
+ end
105
+ end
106
+
107
+ remove_const(:Reader)
108
+ remove_const(:Writer)
109
+ remove_const(:Model)
110
+ remove_const(:Importer)
111
+ remove_const(:Exporter)
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../interceptors/headers"
4
+
5
+ module Aserto
6
+ module Directory
7
+ module V3
8
+ class Config
9
+ attr_reader :reader, :writer, :importer, :exporter, :model
10
+
11
+ def initialize(config)
12
+ @base = {
13
+ url: config[:url] || "directory.prod.aserto.com:8443",
14
+ api_key: config[:api_key],
15
+ tenant_id: config[:tenant_id],
16
+ cert_path: config[:cert_path]
17
+ }
18
+
19
+ @reader = build(**(config[:reader] || {}))
20
+ @writer = build(**(config[:writer] || {}))
21
+ @importer = build(**(config[:importer] || {}))
22
+ @exporter = build(**(config[:exporter] || {}))
23
+ @model = build(**(config[:model] || {}))
24
+ end
25
+
26
+ private
27
+
28
+ class BaseConfig
29
+ attr_reader :url, :credentials, :interceptors
30
+
31
+ def initialize(url, credentials, interceptors)
32
+ @url = url
33
+ @credentials = credentials
34
+ @interceptors = interceptors
35
+ end
36
+ end
37
+
38
+ def build(
39
+ url: @base[:url],
40
+ api_key: @base[:api_key],
41
+ tenant_id: @base[:tenant_id],
42
+ cert_path: @base[:cert_path]
43
+ )
44
+
45
+ interceptors = []
46
+ interceptors = [Interceptors::Headers.new(api_key, tenant_id)] if !api_key.nil? && !tenant_id.nil?
47
+ BaseConfig.new(url, load_creds(cert_path), interceptors)
48
+ end
49
+
50
+ def load_creds(cert_path)
51
+ if cert_path && File.file?(cert_path)
52
+ GRPC::Core::ChannelCredentials.new(File.read(cert_path))
53
+ else
54
+ GRPC::Core::ChannelCredentials.new
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aserto
4
+ module Directory
5
+ module V3
6
+ module Exporter
7
+ DATA_TYPE = {
8
+ unknown: ::Aserto::Directory::Exporter::V3::Option::OPTION_UNKNOWN,
9
+ objects: ::Aserto::Directory::Exporter::V3::Option::OPTION_DATA_OBJECTS,
10
+ relations: ::Aserto::Directory::Exporter::V3::Option::OPTION_DATA_RELATIONS,
11
+ all: ::Aserto::Directory::Exporter::V3::Option::OPTION_DATA
12
+ }.freeze
13
+
14
+ #
15
+ # Exports directory data
16
+ #
17
+ # @param [String] data_type one of [:unknown, :objects, :relations, :all]
18
+ #
19
+ def export(data_type: :unknown)
20
+ data = []
21
+ operation = exporter.export(
22
+ Aserto::Directory::Exporter::V3::ExportRequest.new(options: DATA_TYPE[data_type]),
23
+ return_op: true
24
+ )
25
+
26
+ response = operation.execute
27
+ response.each { |r| data.push(r) }
28
+ operation.wait
29
+
30
+ data
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aserto
4
+ module Directory
5
+ module V3
6
+ module Importer
7
+ #
8
+ # Imports objects and relations
9
+ #
10
+ # @param Array[Hash] data to be imported
11
+ #
12
+ # @example
13
+ # directory.import(
14
+ # [
15
+ # { object: { id: "import-user", type: "user" } },
16
+ # { object: { id: "import-group", type: "group" } },
17
+ # {
18
+ # relation: {
19
+ # object_id: "import-user",
20
+ # object_type: "user",
21
+ # relation: "member",
22
+ # subject_id: "import-group",
23
+ # subject_type: "group"
24
+ # }
25
+ # }
26
+ # ]
27
+ # )
28
+ def import(data)
29
+ data.map! do |value|
30
+ Aserto::Directory::Importer::V3::ImportRequest.new(value)
31
+ end
32
+ operation = importer.import(data, return_op: true)
33
+ response = operation.execute
34
+ response.each { |r| } # ensures that the server sends trailing data
35
+ operation.wait
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aserto
4
+ module Directory
5
+ module V3
6
+ module Model
7
+ # rubocop:disable Naming/AccessorMethodName
8
+
9
+ # Get the content of a manifest
10
+ # @return [Hash] { body: String, updated_at: Timestap, etag: String }
11
+ def get_manifest
12
+ response = {}
13
+ manifest_enum = @model.get_manifest(Aserto::Directory::Model::V3::GetManifestRequest.new)
14
+ manifest_enum.each do |resp|
15
+ response[:body] = resp.body.data if resp.respond_to?(:body) && !resp.body.nil?
16
+ if resp.respond_to?(:metadata)
17
+ response[:updated_at] ||= resp.metadata&.updated_at&.to_time
18
+ response[:etag] ||= resp.metadata&.etag
19
+ end
20
+ end
21
+
22
+ response
23
+ end
24
+
25
+ # Set the content of a manifest
26
+ # @param body [String]
27
+ # @return [Aserto::Directory::Model::V3::SetManifestResponse]
28
+ def set_manifest(body)
29
+ @model.set_manifest([Aserto::Directory::Model::V3::SetManifestRequest.new(body: { data: body })])
30
+ end
31
+
32
+ # rubocop:enable Naming/AccessorMethodName
33
+ end
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,266 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aserto
4
+ module Directory
5
+ module V3
6
+ module Reader
7
+ #
8
+ # find an object by id and type
9
+ #
10
+ # @param object_id [String]
11
+ # @param object_type [String]
12
+ #
13
+ # @return [Aserto::Directory::Reader::V3::GetObjectResponse]
14
+ #
15
+ # @example
16
+ # client.get_object(
17
+ # object_type: "user",
18
+ # object_id: "rick@the-citadel.com"
19
+ # )
20
+ def get_object(object_id:, object_type:)
21
+ reader.get_object(
22
+ Aserto::Directory::Reader::V3::GetObjectRequest.new(
23
+ object_id: object_id,
24
+ object_type: object_type
25
+ )
26
+ )
27
+ end
28
+
29
+ #
30
+ # list objects by type
31
+ #
32
+ # @param object_type [String]
33
+ # @param page [Hash]
34
+ # @option page [Integer] :size
35
+ # @option page [String] :token
36
+ #
37
+ # @return [Aserto::Directory::V3::GetObjectsResponse]
38
+ #
39
+ # @example
40
+ # client.get_objects(
41
+ # object_type: "user",
42
+ # page: { size: 2 }
43
+ # )
44
+ def get_objects(object_type:, page: { size: 100 })
45
+ reader.get_objects(
46
+ Aserto::Directory::Reader::V3::GetObjectsRequest.new(
47
+ object_type: object_type,
48
+ page: Aserto::Directory::Common::V3::PaginationRequest.new(page)
49
+ )
50
+ )
51
+ end
52
+
53
+ #
54
+ # find a relation between two objects
55
+ #
56
+ # @param [String] object_type
57
+ # @param [String] object_id
58
+ # @param [String] relation
59
+ # @param [String] subject_type
60
+ # @param [String] subject_id
61
+ # @param [String] subject_relation
62
+ # @param [Boolean] with_objects
63
+ #
64
+ # @return [Aserto::Directory::Reader::V3::GetRelationResponse]
65
+ #
66
+ # @example
67
+ # client.get_relation(
68
+ # object_type: "user",
69
+ # object_id: "rick@the-citadel.com",
70
+ # relation: "member",
71
+ # object_type: "group",
72
+ # object_id: "evil_genius"
73
+ # )
74
+ def get_relation(object_type:, object_id:, relation:, subject_type:, subject_id:, subject_relation: "",
75
+ with_objects: false)
76
+ reader.get_relation(
77
+ Aserto::Directory::Reader::V3::GetRelationRequest.new(
78
+ object_type: object_type,
79
+ object_id: object_id,
80
+ relation: relation,
81
+ subject_type: subject_type,
82
+ subject_id: subject_id,
83
+ subject_relation: subject_relation,
84
+ with_objects: with_objects
85
+ )
86
+ )
87
+ end
88
+
89
+ #
90
+ # List relations between two objects
91
+ #
92
+ # @param [String] object_type
93
+ # @param [String] object_id
94
+ # @param [String] relation
95
+ # @param [String] subject_type
96
+ # @param [String] subject_id
97
+ # @param [String] subject_relation
98
+ # @param [Boolean] with_objects
99
+ # @param page [Hash]
100
+ # @option page [Integer] :size
101
+ # @option page [String] :token
102
+ #
103
+ # @return [Aserto::Directory::Reader::V3::GetRelationsResponse]
104
+ #
105
+ # @example
106
+ # client.get_relations(
107
+ # object_type: "user",
108
+ # object_id: "rick@the-citadel.com",
109
+ # relation: "member",
110
+ # page: { size: 10 }
111
+ # )
112
+ def get_relations(object_type: "", object_id: "", relation: "", subject_type: "", subject_id: "",
113
+ subject_relation: "", with_objects: false, page: { size: 100 })
114
+ reader.get_relations(
115
+ Aserto::Directory::Reader::V3::GetRelationsRequest.new(
116
+ object_type: object_type,
117
+ object_id: object_id,
118
+ relation: relation,
119
+ subject_type: subject_type,
120
+ subject_id: subject_id,
121
+ subject_relation: subject_relation,
122
+ with_objects: with_objects,
123
+ page: Aserto::Directory::Common::V3::PaginationRequest.new(page)
124
+ )
125
+ )
126
+ end
127
+
128
+ #
129
+ # Check relation between two objects
130
+ #
131
+ # @param [String] object_type
132
+ # @param [String] object_id
133
+ # @param [String] relation
134
+ # @param [String] subject_type
135
+ # @param [String] subject_id
136
+ # @param [Boolean] trace
137
+ #
138
+ # @return [Aserto::Directory::Reader::V3::CheckRelationResponse]
139
+ #
140
+ # @example
141
+ # client.check_relation(
142
+ # object_type: "user",
143
+ # object_id: "rick@the-citadel.com",
144
+ # relation: "member",
145
+ # object_type: "group",
146
+ # object_id: "evil_genius"
147
+ # )
148
+ def check_relation(object_type:, object_id:, relation:, subject_type:, subject_id:, trace: false)
149
+ reader.check_relation(
150
+ Aserto::Directory::Reader::V3::CheckRelationRequest.new(
151
+ object_type: object_type,
152
+ object_id: object_id,
153
+ relation: relation,
154
+ subject_type: subject_type,
155
+ subject_id: subject_id,
156
+ trace: trace
157
+ )
158
+ )
159
+ end
160
+
161
+ #
162
+ # Check relation between two objects
163
+ #
164
+ # @param [String] object_type
165
+ # @param [String] object_id
166
+ # @param [String] relation
167
+ # @param [String] subject_type
168
+ # @param [String] subject_id
169
+ # @param [Boolean] trace
170
+ #
171
+ # @return [Aserto::Directory::Reader::V3::CheckResponse]
172
+ #
173
+ # @example
174
+ # client.check(
175
+ # object_type: "user",
176
+ # object_id: "rick@the-citadel.com",
177
+ # relation: "member",
178
+ # object_type: "group",
179
+ # object_id: "evil_genius"
180
+ # )
181
+ def check(object_type:, object_id:, relation:, subject_type:, subject_id:, trace: false)
182
+ reader.check(
183
+ Aserto::Directory::Reader::V3::CheckRequest.new(
184
+ object_type: object_type,
185
+ object_id: object_id,
186
+ relation: relation,
187
+ subject_type: subject_type,
188
+ subject_id: subject_id,
189
+ trace: trace
190
+ )
191
+ )
192
+ end
193
+
194
+ #
195
+ # Check permission between two objects
196
+ #
197
+ # @param [String] object_type
198
+ # @param [String] object_id
199
+ # @param [String] permission
200
+ # @param [String] subject_type
201
+ # @param [String] subject_id
202
+ # @param [Boolean] trace
203
+ #
204
+ # @return [Aserto::Directory::Reader::V3::CheckPermissionResponse]
205
+ #
206
+ # @example
207
+ # client.check_permission(
208
+ # object_type: "user",
209
+ # object_id: "rick@the-citadel.com",
210
+ # permission: "read",
211
+ # object_type: "group",
212
+ # object_id: "evil_genius"
213
+ # )
214
+ def check_permission(object_type:, object_id:, permission:, subject_type:, subject_id:, trace: false)
215
+ reader.check_permission(
216
+ Aserto::Directory::Reader::V3::CheckPermissionRequest.new(
217
+ object_type: object_type,
218
+ object_id: object_id,
219
+ permission: permission,
220
+ subject_type: subject_type,
221
+ subject_id: subject_id,
222
+ trace: trace
223
+ )
224
+ )
225
+ end
226
+
227
+ #
228
+ # Returns object graph from anchor to subject or object.
229
+ #
230
+ # @param [String] anchor_type <description>
231
+ # @param [String] anchor_id <description>
232
+ # @param [String] object_type <description>
233
+ # @param [String] object_id <description>
234
+ # @param [String] relation <description>
235
+ # @param [String] subject_type <description>
236
+ # @param [String] <description>
237
+ #
238
+ # @return [Aserto::Directory::Reader::V3::GetGraphResponse]
239
+ #
240
+ # @example
241
+ # directory.get_graph(
242
+ # anchor_type: "user",
243
+ # anchor_id: "rick@the-citadel.com",
244
+ # subject_id: "rick@the-citadel.com",
245
+ # subject_type: "user",
246
+ # relation: "member"
247
+ # )
248
+ def get_graph(anchor_type:, anchor_id:, object_type: "", object_id: "", relation: "", subject_type: "",
249
+ subject_id: "", subject_relation: "")
250
+ reader.get_graph(
251
+ Aserto::Directory::Reader::V3::GetGraphRequest.new(
252
+ anchor_type: anchor_type,
253
+ anchor_id: anchor_id,
254
+ object_type: object_type,
255
+ object_id: object_id,
256
+ relation: relation,
257
+ subject_type: subject_type,
258
+ subject_id: subject_id,
259
+ subject_relation: subject_relation
260
+ )
261
+ )
262
+ end
263
+ end
264
+ end
265
+ end
266
+ end
@@ -0,0 +1,125 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aserto
4
+ module Directory
5
+ module V3
6
+ module Writer
7
+ require "google/protobuf/well_known_types"
8
+
9
+ #
10
+ # Create a new object
11
+ #
12
+ # @param [String] object_id
13
+ # @param [String] object_type
14
+ # @param [String] display_name
15
+ # @param [Hash] properties
16
+ # @param [String] etag
17
+ #
18
+ # @return [Aserto::Directory::Writer::V3::SetObjectResponse]
19
+ #
20
+ # @example
21
+ # client.set_object(object_id: "1234", object_type: "user", properties: { email: "test" })
22
+ def set_object(object_id:, object_type:, display_name: "", properties: {}, etag: nil)
23
+ writer.set_object(
24
+ Aserto::Directory::Writer::V3::SetObjectRequest.new(
25
+ object: {
26
+ id: object_id,
27
+ type: object_type,
28
+ display_name: display_name,
29
+ properties: Google::Protobuf::Struct.from_hash(properties.transform_keys!(&:to_s)),
30
+ etag: etag
31
+ }
32
+ )
33
+ )
34
+ end
35
+
36
+ #
37
+ # Delete an object
38
+ #
39
+ # @param [String] object_id
40
+ # @param [String] object_type
41
+ # @param [Boolean] with_relations
42
+ #
43
+ # @return [ Aserto::Directory::Writer::V3::DeleteObjectResponse]
44
+ #
45
+ # @example
46
+ # client.delete_object(object_id: "1234", object_type: "user")
47
+ def delete_object(object_id:, object_type:, with_relations: false)
48
+ writer.delete_object(
49
+ Aserto::Directory::Writer::V3::DeleteObjectRequest.new(
50
+ object_id: object_id,
51
+ object_type: object_type,
52
+ with_relations: with_relations
53
+ )
54
+ )
55
+ end
56
+
57
+ #
58
+ # Creates a relation between two objects
59
+ #
60
+ # @param [String] object_type
61
+ # @param [String] object_id
62
+ # @param [String] relation
63
+ # @param [String] subject_type
64
+ # @param [String] subject_id
65
+ #
66
+ # @return [Aserto::Directory::Writer::V3::SetRelationResponse]
67
+ #
68
+ # @example
69
+ # client.set_relation(
70
+ # object_type: "user",
71
+ # object_id: "rick@the-citadel.com",
72
+ # relation: "member",
73
+ # object_type: "group",
74
+ # object_id: "evil_genius"
75
+ # )
76
+ def set_relation(object_type:, object_id:, relation:, subject_type:, subject_id:)
77
+ writer.set_relation(
78
+ Aserto::Directory::Writer::V3::SetRelationRequest.new(
79
+ relation: {
80
+ object_type: object_type,
81
+ object_id: object_id,
82
+ relation: relation,
83
+ subject_type: subject_type,
84
+ subject_id: subject_id
85
+ }
86
+ )
87
+ )
88
+ end
89
+
90
+ #
91
+ # Delete a relation between two objects
92
+ #
93
+ # @param [String] object_type
94
+ # @param [String] object_id
95
+ # @param [String] relation
96
+ # @param [String] subject_type
97
+ # @param [String] subject_id
98
+ # @param [String] subject_relation
99
+ #
100
+ # @return [Aserto::Directory::Writer::V3::DeleteRelationRequest]
101
+ #
102
+ # @example
103
+ # client.get_relation(
104
+ # object_type: "user",
105
+ # object_id: "rick@the-citadel.com",
106
+ # relation: "member",
107
+ # object_type: "group",
108
+ # object_id: "evil_genius"
109
+ # )
110
+ def delete_relation(object_type:, object_id:, relation:, subject_type:, subject_id:, subject_relation: "")
111
+ writer.delete_relation(
112
+ Aserto::Directory::Writer::V3::DeleteRelationRequest.new(
113
+ object_type: object_type,
114
+ object_id: object_id,
115
+ relation: relation,
116
+ subject_type: subject_type,
117
+ subject_id: subject_id,
118
+ subject_relation: subject_relation
119
+ )
120
+ )
121
+ end
122
+ end
123
+ end
124
+ end
125
+ end
data/lib/aserto/errors.rb CHANGED
@@ -3,6 +3,7 @@
3
3
  module Aserto
4
4
  class Error < StandardError; end
5
5
  class InvalidResourceMapping < Error; end
6
+ class InvalidIdentityType < Error; end
6
7
 
7
8
  class AccessDenied < Error
8
9
  attr_reader :action, :conditions
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Aserto
4
+ module IdentityMapper
5
+ module Manual
6
+ class << self
7
+ def execute(_request)
8
+ {
9
+ type: :manual,
10
+ identity: ::Aserto.config.identity_mapping[:value].to_s
11
+ }
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
@@ -4,20 +4,23 @@ require_relative "identity_mapper/base"
4
4
  require_relative "identity_mapper/none"
5
5
  require_relative "identity_mapper/sub"
6
6
  require_relative "identity_mapper/jwt"
7
+ require_relative "identity_mapper/manual"
7
8
 
8
9
  module Aserto
9
10
  module IdentityMapper
10
11
  STRATEGY = {
11
12
  none: Aserto::IdentityMapper::None,
13
+ manual: Aserto::IdentityMapper::Manual,
12
14
  sub: Aserto::IdentityMapper::Sub,
13
15
  jwt: Aserto::IdentityMapper::Jwt
14
16
  }.freeze
15
17
 
16
18
  class << self
17
19
  def execute(request)
18
- STRATEGY[
19
- Aserto.config.identity_mapping[:type].to_sym || :none
20
- ].execute(request)
20
+ STRATEGY.fetch(
21
+ Aserto.config.identity_mapping[:type].to_sym || :none,
22
+ Aserto::IdentityMapper::None
23
+ ).execute(request)
21
24
  end
22
25
  end
23
26
  end
data/lib/aserto.rb CHANGED
@@ -12,6 +12,7 @@ require_relative "aserto/resource_mapper"
12
12
  require_relative "aserto/auth_client"
13
13
  require_relative "aserto/errors"
14
14
  require_relative "aserto/directory/client"
15
+ require_relative "aserto/directory/v3/client"
15
16
 
16
17
  module Aserto
17
18
  class << self
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: aserto
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.20.6
4
+ version: 0.30.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aserto
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-24 00:00:00.000000000 Z
11
+ date: 2023-11-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: aserto-authorizer
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: 0.30.0
33
+ version: 0.30.1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: 0.30.0
40
+ version: 0.30.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: jwt
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -82,11 +82,20 @@ files:
82
82
  - lib/aserto/config.rb
83
83
  - lib/aserto/directory/client.rb
84
84
  - lib/aserto/directory/interceptors/headers.rb
85
- - lib/aserto/directory/requests.rb
85
+ - lib/aserto/directory/v2/client.rb
86
+ - lib/aserto/directory/v2/requests.rb
87
+ - lib/aserto/directory/v3/client.rb
88
+ - lib/aserto/directory/v3/config.rb
89
+ - lib/aserto/directory/v3/exporter.rb
90
+ - lib/aserto/directory/v3/importer.rb
91
+ - lib/aserto/directory/v3/model.rb
92
+ - lib/aserto/directory/v3/reader.rb
93
+ - lib/aserto/directory/v3/writer.rb
86
94
  - lib/aserto/errors.rb
87
95
  - lib/aserto/identity_mapper.rb
88
96
  - lib/aserto/identity_mapper/base.rb
89
97
  - lib/aserto/identity_mapper/jwt.rb
98
+ - lib/aserto/identity_mapper/manual.rb
90
99
  - lib/aserto/identity_mapper/none.rb
91
100
  - lib/aserto/identity_mapper/sub.rb
92
101
  - lib/aserto/policy_path_mapper.rb