soar-registry-staff 0.0.3 → 0.0.4
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/README.md +30 -37
- data/lib/soar/registry/staff/directory/dynamo_db.rb +151 -0
- data/lib/soar/registry/staff/directory/stub.rb +107 -0
- data/lib/soar/registry/staff/identity/base.rb +84 -0
- data/lib/soar/registry/staff/identity/email.rb +22 -0
- data/lib/soar/registry/staff/identity/id.rb +22 -0
- data/lib/soar/registry/staff/test/directory/orchestrator.rb +81 -0
- data/lib/soar/registry/staff/test/directory/provider/base.rb +50 -0
- data/lib/soar/registry/staff/test/directory/provider/dynamo_db.rb +84 -0
- data/lib/soar/registry/staff/test/directory/provider/stub.rb +68 -0
- data/lib/soar/registry/staff/test/fixtures/identity_data.json +60 -0
- data/lib/soar/registry/staff/test/fixtures/identity_table.json +63 -0
- metadata +40 -7
- data/lib/soar/registry/staff/directory/dynamo_db/base.rb +0 -90
- data/lib/soar/registry/staff/directory/dynamo_db/identity.rb +0 -83
- data/lib/soar/registry/staff/identifier/factory.rb +0 -40
- data/lib/soar/registry/staff/identifier/hash.rb +0 -24
- data/lib/soar/registry/staff/identifier/id.rb +0 -18
- data/lib/soar/registry/staff/identity.rb +0 -95
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: soar-registry-staff
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Charles Mulder
|
@@ -10,6 +10,34 @@ bindir: bin
|
|
10
10
|
cert_chain: []
|
11
11
|
date: 2016-10-19 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: hashy_db
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.1'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: mince
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.3'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '2.3'
|
13
41
|
- !ruby/object:Gem::Dependency
|
14
42
|
name: soar_idm
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -91,13 +119,18 @@ extensions: []
|
|
91
119
|
extra_rdoc_files: []
|
92
120
|
files:
|
93
121
|
- README.md
|
94
|
-
- lib/soar/registry/staff/directory/dynamo_db
|
95
|
-
- lib/soar/registry/staff/directory/dynamo_db/identity.rb
|
122
|
+
- lib/soar/registry/staff/directory/dynamo_db.rb
|
96
123
|
- lib/soar/registry/staff/directory/error.rb
|
97
|
-
- lib/soar/registry/staff/
|
98
|
-
- lib/soar/registry/staff/
|
99
|
-
- lib/soar/registry/staff/
|
100
|
-
- lib/soar/registry/staff/identity.rb
|
124
|
+
- lib/soar/registry/staff/directory/stub.rb
|
125
|
+
- lib/soar/registry/staff/identity/base.rb
|
126
|
+
- lib/soar/registry/staff/identity/email.rb
|
127
|
+
- lib/soar/registry/staff/identity/id.rb
|
128
|
+
- lib/soar/registry/staff/test/directory/orchestrator.rb
|
129
|
+
- lib/soar/registry/staff/test/directory/provider/base.rb
|
130
|
+
- lib/soar/registry/staff/test/directory/provider/dynamo_db.rb
|
131
|
+
- lib/soar/registry/staff/test/directory/provider/stub.rb
|
132
|
+
- lib/soar/registry/staff/test/fixtures/identity_data.json
|
133
|
+
- lib/soar/registry/staff/test/fixtures/identity_table.json
|
101
134
|
- lib/soar/registry/staff/translator/dynamo_db.rb
|
102
135
|
homepage: https://gitlab.host-h.net/registries/staff
|
103
136
|
licenses:
|
@@ -1,90 +0,0 @@
|
|
1
|
-
require 'soar_idm/directory_provider'
|
2
|
-
require 'aws-sdk'
|
3
|
-
require 'hashie'
|
4
|
-
require 'soar/registry/staff/directory/error'
|
5
|
-
|
6
|
-
module Soar
|
7
|
-
module Registry
|
8
|
-
module Staff
|
9
|
-
module Directory
|
10
|
-
module DynamoDb
|
11
|
-
class Base < SoarIdm::DirectoryProvider
|
12
|
-
|
13
|
-
attr_reader :configuration, :credentials, :client
|
14
|
-
|
15
|
-
##
|
16
|
-
# @param [Hash] configuration for the directory provider
|
17
|
-
# @return [Nil]
|
18
|
-
# @raise [Soar::Registry::Staff::Directory::Error::BootstrapError] if required configuration is missing
|
19
|
-
##
|
20
|
-
def bootstrap(configuration)
|
21
|
-
@configuration = Hashie.stringify_keys(configuration)
|
22
|
-
raise Soar::Registry::Staff::Directory::Error::BootstrapError, 'Missing region' if not @configuration.has_key?('region')
|
23
|
-
raise Soar::Registry::Staff::Directory::Error::BootstrapError, 'Missing endpoint' if not @configuration.has_key?('endpoint')
|
24
|
-
@table_name = @configuration.delete('table')
|
25
|
-
raise Soar::Registry::Staff::Directory::Error::BootstrapError, 'Missing table name' if not @table_name
|
26
|
-
end
|
27
|
-
|
28
|
-
##
|
29
|
-
# @return [Bool] whether directory provider received minimum required configuration
|
30
|
-
##
|
31
|
-
def bootstrapped?
|
32
|
-
@configuration.has_key?('region') and @configuration.has_key?('endpoint')
|
33
|
-
end
|
34
|
-
|
35
|
-
def uri
|
36
|
-
@configuration['endpoint']
|
37
|
-
end
|
38
|
-
|
39
|
-
def authenticate(credentials)
|
40
|
-
raise Soar::Registry::Staff::Directory::Error::AuthenticationError, 'missing username' if not credentials.key?('username')
|
41
|
-
raise Soar::Registry::Staff::Directory::Error::AuthenticationError, 'missing password' if not credentials.key?('password')
|
42
|
-
@credentials = {
|
43
|
-
"access_key_id" => credentials['username'],
|
44
|
-
"secret_access_key" => credentials['password']
|
45
|
-
}
|
46
|
-
end
|
47
|
-
|
48
|
-
def connect
|
49
|
-
begin
|
50
|
-
options = @configuration.dup
|
51
|
-
options['credentials'] = Aws::Credentials.new(@credentials['access_key_id'], @credentials['secret_access_key'])
|
52
|
-
@client = Aws::DynamoDB::Client.new(Hashie.symbolize_keys(options))
|
53
|
-
@client
|
54
|
-
rescue ArgumentError => e
|
55
|
-
raise Soar::Registry::Staff::Directory::Error::ConnectionError, e.message
|
56
|
-
rescue
|
57
|
-
raise Soar::Registry::Staff::Directory::Error::ConnectionError, 'error creating client'
|
58
|
-
end
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
def connected?
|
63
|
-
return @client.class.name == 'Aws::DynamoDB::Client'
|
64
|
-
end
|
65
|
-
|
66
|
-
def ready?
|
67
|
-
begin
|
68
|
-
#return @client.list_tables.table_names.class.name == 'Array'
|
69
|
-
resp = @client.describe_table({
|
70
|
-
table_name: @table_name
|
71
|
-
})
|
72
|
-
return resp.table.table_name == @table_name
|
73
|
-
rescue Seahorse::Client::NetworkingError
|
74
|
-
return false
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
def put_identity(entity)
|
79
|
-
@client.put_item({
|
80
|
-
table_name: @table_name,
|
81
|
-
item: Hashie.symbolize_keys(entity)
|
82
|
-
})
|
83
|
-
end
|
84
|
-
|
85
|
-
end
|
86
|
-
end
|
87
|
-
end
|
88
|
-
end
|
89
|
-
end
|
90
|
-
end
|
@@ -1,83 +0,0 @@
|
|
1
|
-
require 'soar_idm/directory_provider'
|
2
|
-
require 'soar/registry/staff/directory/dynamo_db/base'
|
3
|
-
require 'aws-sdk'
|
4
|
-
require 'hashie'
|
5
|
-
|
6
|
-
module Soar
|
7
|
-
module Registry
|
8
|
-
module Staff
|
9
|
-
module Directory
|
10
|
-
module DynamoDb
|
11
|
-
class Identity < Base
|
12
|
-
|
13
|
-
LIMIT = 10
|
14
|
-
INDEXED_ATTRIBUTES = ['email', 'entity_id']
|
15
|
-
|
16
|
-
##
|
17
|
-
# @param [String] identity_id primary key of the identity
|
18
|
-
# @return [Hash] the identity
|
19
|
-
# @raise [Soar::Registry::Staff::Directory::DynamoDb::Error::UniqueIdentifierNotFoundError] if primary key not found
|
20
|
-
##
|
21
|
-
def fetch_identity(identifier)
|
22
|
-
options = {
|
23
|
-
table_name: @table_name,
|
24
|
-
key: {
|
25
|
-
identity_id: identifier
|
26
|
-
}
|
27
|
-
}
|
28
|
-
identity = @client.get_item(options)
|
29
|
-
raise Soar::Registry::Staff::Directory::Error::UniqueIdentifierNotFoundError, 'Unable to find identity' if identity.item.nil?
|
30
|
-
identity.item
|
31
|
-
end
|
32
|
-
|
33
|
-
##
|
34
|
-
# @param [String] identifier_attribute
|
35
|
-
# @param [String] identifier_value
|
36
|
-
# @return [Array] list of identities
|
37
|
-
# @raise [ArgumentError] if query or index is not specified
|
38
|
-
##
|
39
|
-
def search_identities(identifier_attribute, identifier_value)
|
40
|
-
raise ArgumentError, "Attribute is required" if identifier_attribute.nil?
|
41
|
-
raise ArgumentError, 'Value is required' if identifier_value.nil?
|
42
|
-
options = {
|
43
|
-
table_name: @table_name,
|
44
|
-
select: 'ALL_ATTRIBUTES',
|
45
|
-
limit: LIMIT,
|
46
|
-
key_condition_expression: "#{identifier_attribute} = :value",
|
47
|
-
expression_attribute_values: {
|
48
|
-
":value": identifier_value
|
49
|
-
}
|
50
|
-
}
|
51
|
-
|
52
|
-
options.merge!({index_name: "#{identifier_attribute}_index"}) if INDEXED_ATTRIBUTES.include?(identifier_attribute)
|
53
|
-
identity = @client.query(options)
|
54
|
-
identity.items.map { |item|
|
55
|
-
Hashie.stringify_keys(item)
|
56
|
-
}
|
57
|
-
end
|
58
|
-
|
59
|
-
##
|
60
|
-
# @return [Array] a list of primary keys and global secondary indexes
|
61
|
-
##
|
62
|
-
def indexed_attributes
|
63
|
-
resp = @client.describe_table({
|
64
|
-
table_name: @table_name
|
65
|
-
})
|
66
|
-
indexed_attributes = []
|
67
|
-
resp['table']['key_schema'].each { |key_schema|
|
68
|
-
indexed_attributes << key_schema['attribute_name']
|
69
|
-
}
|
70
|
-
resp['table']['global_secondary_indexes'].each { |index|
|
71
|
-
index['key_schema'].each { |key_schema|
|
72
|
-
indexed_attributes << key_schema['attribute_name']
|
73
|
-
}
|
74
|
-
}
|
75
|
-
indexed_attributes
|
76
|
-
end
|
77
|
-
|
78
|
-
end
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
require 'soar/registry/staff/identifier/id'
|
2
|
-
require 'soar/registry/staff/identifier/hash'
|
3
|
-
|
4
|
-
module Soar
|
5
|
-
module Registry
|
6
|
-
module Staff
|
7
|
-
module Identifier
|
8
|
-
class Factory
|
9
|
-
|
10
|
-
##
|
11
|
-
# @param [String] identifier_id or a json serialized hash with length 1 eg. '{"email":"test@example.com"}'
|
12
|
-
# @return [Soar::Registry::Staff::Identifier::Id|Soar::Registry::Staff::Identifier::Hash] identifier
|
13
|
-
##
|
14
|
-
def get_identifier(identifier)
|
15
|
-
if is_json?(identifier)
|
16
|
-
return Soar::Registry::Staff::Identifier::Hash.new(identifier)
|
17
|
-
else
|
18
|
-
return Soar::Registry::Staff::Identifier::Id.new(identifier)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
private
|
23
|
-
|
24
|
-
def is_json?(identifier)
|
25
|
-
begin
|
26
|
-
return JSON.parse(identifier)
|
27
|
-
return true
|
28
|
-
rescue JSON::ParserError => e
|
29
|
-
return false
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
end
|
34
|
-
|
35
|
-
end
|
36
|
-
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
@@ -1,24 +0,0 @@
|
|
1
|
-
module Soar
|
2
|
-
module Registry
|
3
|
-
module Staff
|
4
|
-
module Identifier
|
5
|
-
class Hash
|
6
|
-
|
7
|
-
class MultipleIdentifierTypesError < StandardError; end;
|
8
|
-
|
9
|
-
attr_reader :type
|
10
|
-
attr_reader :value
|
11
|
-
|
12
|
-
def initialize(identifier)
|
13
|
-
identifier = JSON.parse(identifier)
|
14
|
-
raise MultipleIdentifierTypesError, 'Multiple identifier types are not allowed' if identifier.length > 1
|
15
|
-
@type = identifier.keys[0]
|
16
|
-
@value = identifier[identifier.keys[0]]
|
17
|
-
end
|
18
|
-
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
@@ -1,95 +0,0 @@
|
|
1
|
-
require 'soar_idm/soar_idm'
|
2
|
-
require 'soar/registry/staff/translator/dynamo_db'
|
3
|
-
require 'soar/registry/staff/directory/dynamo_db/identity'
|
4
|
-
require 'soar/registry/staff/identifier/factory'
|
5
|
-
|
6
|
-
module Soar
|
7
|
-
module Registry
|
8
|
-
module Staff
|
9
|
-
|
10
|
-
class Identity < SoarIdm::IdmApi
|
11
|
-
|
12
|
-
attr_reader :directory
|
13
|
-
attr_reader :translator
|
14
|
-
attr_reader :client
|
15
|
-
|
16
|
-
##
|
17
|
-
# @param [Hash] configuration
|
18
|
-
# for example see config/config.yml
|
19
|
-
##
|
20
|
-
def initialize(configuration)
|
21
|
-
@translator = Object.const_get(configuration['rule_set']['adaptor']).new
|
22
|
-
@directory = Object::const_get(configuration['provider']['adaptor']).new
|
23
|
-
@directory.bootstrap(configuration['provider']['config'])
|
24
|
-
@directory.authenticate(configuration['provider']['credentials'])
|
25
|
-
@client = @directory.connect
|
26
|
-
raise Soar::Registry::Staff::Directory::Error::BootstrapError if not @directory.bootstrapped?
|
27
|
-
raise Soar::Registry::Staff::Directory::Error::ConnectionError if not @directory.connected?
|
28
|
-
raise Soar::Registry::Staff::Directory::Error::NotReadyError if not @directory.ready?
|
29
|
-
end
|
30
|
-
|
31
|
-
##
|
32
|
-
# @param [String] identity_id
|
33
|
-
# @return [Array] list of roles
|
34
|
-
def calculate_roles(identity)
|
35
|
-
entry = @directory.fetch_identity(identity['identity_id'])
|
36
|
-
return nil if not entry
|
37
|
-
identity = @translator.get_identity(entry)
|
38
|
-
roles = []
|
39
|
-
identity['roles'].each do |role, attributes|
|
40
|
-
roles << role
|
41
|
-
end
|
42
|
-
roles
|
43
|
-
end
|
44
|
-
|
45
|
-
##
|
46
|
-
# @param [String] identity_id
|
47
|
-
# @return [Array] list of identifiers
|
48
|
-
##
|
49
|
-
def calculate_identifiers(identity)
|
50
|
-
indexes = @directory.indexed_attributes
|
51
|
-
entry = @directory.fetch_identity(identity['identity_id'])
|
52
|
-
identity = @translator.get_identity(entry)
|
53
|
-
identifiers = []
|
54
|
-
indexes.each { |index|
|
55
|
-
identifiers << identity[index]
|
56
|
-
}
|
57
|
-
identifiers
|
58
|
-
end
|
59
|
-
|
60
|
-
##
|
61
|
-
# @param [String] identity_id
|
62
|
-
# @param [String] role
|
63
|
-
# @return [Hash] A hash of attributes
|
64
|
-
def calculate_attributes(identity, role)
|
65
|
-
entry = @directory.fetch_identity(identity['identity_id'])
|
66
|
-
return nil if not entry
|
67
|
-
identity = @translator.get_identity(entry)
|
68
|
-
{ role => identity['roles'][role] }
|
69
|
-
end
|
70
|
-
|
71
|
-
##
|
72
|
-
# @param [String] identity_id
|
73
|
-
# @return [Hash] Hash of attributes keyed by role
|
74
|
-
def calculate_all_attributes(identity)
|
75
|
-
entry = @directory.fetch_identity(identity['identity_id'])
|
76
|
-
@translator.get_identity(entry)
|
77
|
-
end
|
78
|
-
|
79
|
-
##
|
80
|
-
# @param [String] identifier primary key (identity_id) or a json serialized hash with length 1 eg. '{"email":"test@example.com"}'
|
81
|
-
# @return [Hash] an identity
|
82
|
-
def calculate_identities(identifier)
|
83
|
-
identifier_factory = Soar::Registry::Staff::Identifier::Factory.new
|
84
|
-
identifier = identifier_factory.get_identifier(identifier)
|
85
|
-
if identifier.is_a?(Soar::Registry::Staff::Identifier::Id)
|
86
|
-
return [@translator.get_identity(@directory.fetch_identity(identifier.value))]
|
87
|
-
end
|
88
|
-
entries = @directory.search_identities(identifier.type, identifier.value )
|
89
|
-
return [@translator.get_identity(entries)[0]]
|
90
|
-
end
|
91
|
-
|
92
|
-
end
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|