soar-registry-directory 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a4505d2bbb4a6b9d47b370ddeaf82d8a9b76231b
4
- data.tar.gz: e4de04def83d9751931f30eb49e9fcaad7acd61c
3
+ metadata.gz: 70a565fb09b0f4af26cfb869c32c41aa5809b27e
4
+ data.tar.gz: 2fb0d1201fce3c266bf570315b2524005a61776b
5
5
  SHA512:
6
- metadata.gz: 44514a249b7af19f67f784abe25868d644bfd91a70e777078a0aa613954c196bab77e915b5270be35b2146e29a9ea22fcc31860854c7eb704ef0a7688864e153
7
- data.tar.gz: 715d8a78da3f01196c2a67d61fe78bcb059fe86458cd3f6d270f318cfb2de46ba66d57731d8753972d3d1bb7b06ed6bdf32cda651a9e053d87b1102d1607330e
6
+ metadata.gz: cfbebba8afea49661752f2fe56a23f57c3874c3595af6b23f90fee6a30697258733b83836254df42e9552f1d841de4c8025ee7b7359f7be5871bd428cb72a049
7
+ data.tar.gz: 12784a7f75d25c92dabdcd1f3fa88ec779bac1dfd5173507f0a29767ffc8ac60ef3e5816e52ac9ddb05b57f92bb92a32e69320dee5a1c0616f4b191c97b66181
data/README.md CHANGED
@@ -23,7 +23,6 @@ Create an instance of the stub provider by passing in the name, primary key and
23
23
  > require 'soar/registry/directory'
24
24
  > provider = Soar::Registry::Directory::Provider::Stub.new({
25
25
  table: "mytable",
26
- primary_key: "uuid",
27
26
  index: ["uuid", "email"]
28
27
  })
29
28
  ```
@@ -36,7 +35,6 @@ Create an instance of the stub provider by passing in the name, primary key and
36
35
  },
37
36
  table: "mytable",
38
37
  index: ['uuid', 'email'],
39
- primary_key: "uuid",
40
38
  configuration: {
41
39
  region: 'us-west-2'
42
40
  endpoint: 'http://localhost:8000'
@@ -45,6 +43,23 @@ Create an instance of the stub provider by passing in the name, primary key and
45
43
 
46
44
  ```
47
45
 
46
+ ### LDAP Provider
47
+ ```ruby
48
+ > provider = Soar::Registry::Directory::Provider::Ldap.new({
49
+ base: 'dc=hetzner,dc=co,dc=za',
50
+ index: ['entryuuid', 'mail'],
51
+ config: {
52
+ host: 'localhost',
53
+ port: 389
54
+ },
55
+ attributes: ['entryuuid', 'cn', 'mail', 'sn'],
56
+ credentials: {
57
+ username: 'cn=admin,dc=hetzner,dc=co,dc=za'
58
+ password: 'secret'
59
+ }
60
+ })
61
+ ```
62
+
48
63
  ### The Model
49
64
  ```ruby
50
65
  > directory = Soar::Registry::Directory.new(provider)
@@ -70,8 +85,8 @@ exit $EXIT_CODE
70
85
 
71
86
  #### Local
72
87
  ```bash
73
- $ docker-compose --file docker-compose.dynamo_db.yml up
74
- $ CONFIG_FILE=config.dynamo_db.yml TEST_PROVIDER=DynamoDb cucumber
88
+ $ docker-compose --file docker-compose.dynamo_db.yml up --remove-orphans
89
+ $ CONFIG_FILE=config.dynamo_db.yml TEST_ORCHESTRATION_PROVIDER=DynamoDb cucumber
75
90
  ```
76
91
 
77
92
  #### CI
@@ -80,3 +95,19 @@ docker-compose --file docker-compose.ci.dynamo_db.yml up --abort-on-container-ex
80
95
  EXIT_CODE=$(docker ps -a -f "name=soar-registry-directory-test-provider-dynamo_db" -q | xargs docker inspect -f "{{ .State.ExitCode }}")
81
96
  exit $EXIT_CODE
82
97
  ```
98
+
99
+ ### LDAP provider
100
+
101
+ #### Local
102
+ ```bash
103
+ $ docker-compose --file docker-compose.ldap.yml up --remove-orphans
104
+ $ CONFIG_FILE=config.ldap.yml TEST_ORCHESTRATION_PROVIDER=Ldap cucumber
105
+ ```
106
+
107
+ #### CI
108
+ ```bash
109
+ docker-compose --file docker-compose.ci.ldap.yml up --abort-on-container-exit --remove-orphans --build --force-recreate
110
+ EXIT_CODE=$(docker ps -a -f "name=soar-registry-directory-test-provider-ldap" -q | xargs docker inspect -f "{{ .State.ExitCode }}")
111
+ exit $EXIT_CODE
112
+ ```
113
+
@@ -3,6 +3,7 @@ module Soar
3
3
  module Directory
4
4
  module Error
5
5
  class NoEntriesFound < StandardError; end;
6
+ class MultipleEntriesFound < StandardError; end;
6
7
  end
7
8
  end
8
9
  end
@@ -1,6 +1,7 @@
1
1
  require 'soar/registry/directory/error'
2
2
  require 'soar/registry/directory/provider/stub'
3
3
  require 'soar/registry/directory/provider/dynamo_db'
4
+ require 'soar/registry/directory/provider/ldap'
4
5
 
5
6
  module Soar
6
7
  module Registry
@@ -14,13 +14,12 @@ module Soar
14
14
  ##
15
15
  # @param credentials [Hash] { username: 'username', password: 'secret'}
16
16
  # @param table [String]
17
- # @param primary_key [String]
18
17
  # @param index [Array] primary key should be the first item
19
18
  # @param configuration [Hash] { region: 'us-west-2', endpoint: 'http://localhost:8000' }
20
19
  ##
21
- def initialize(credentials: nil, table: nil, primary_key: nil, index: nil, configuration: nil)
20
+ def initialize(credentials: , table: , index: , configuration: )
22
21
  @table_name = table
23
- @primary_key = primary_key
22
+ @primary_key = index[0]
24
23
  @index = index
25
24
  @credentials = Hashie.symbolize_keys(credentials)
26
25
  configuration[:credentials] = Aws::Credentials.new(@credentials[:username], @credentials[:password])
@@ -70,7 +69,7 @@ module Soar
70
69
  }
71
70
  }
72
71
 
73
- options.merge!({index_name: "#{key}_index"}) if @index.include?(key)
72
+ options.merge!({index_name: "#{key}-index"}) if @index.include?(key)
74
73
  identity = @client.query(options)
75
74
  identity.items.map { |item|
76
75
  Hashie.stringify_keys(item)
@@ -0,0 +1,103 @@
1
+ require 'soar/registry/directory/error'
2
+ require 'net/ldap'
3
+
4
+ module Soar
5
+ module Registry
6
+ module Directory
7
+ module Provider
8
+ class Ldap
9
+
10
+ ##
11
+ # @param config [Hash]
12
+ # @param base [String] ldap tree base eg 'dc=hetzner,dc=co,dc=za'
13
+ # @param attributes [Array] array of attributes to return for queries
14
+ # @param credentials [Hash]
15
+ ##
16
+ def initialize(config: , base: , attributes: , index: , credentials: )
17
+ @base = base
18
+ @index = index
19
+ @attributes = attributes
20
+ @config = {
21
+ host: config[:host],
22
+ port: config[:port],
23
+ auth: {
24
+ method: :simple,
25
+ username: credentials[:username],
26
+ password: credentials[:password]
27
+ }
28
+ }
29
+ @ldap = Net::LDAP.new(@config)
30
+ @ldap.bind
31
+ end
32
+
33
+ def put(entry)
34
+ @ldap.add({
35
+ dn: entry[:dn],
36
+ attributes: entry[:attributes]
37
+ })
38
+ end
39
+
40
+ ##
41
+ # @param [String] uuid primary key of the identity
42
+ # @return [Hash] the identity
43
+ # @raise [Soar::Registry::Directory::Error::NoEntriesFound] if primary key not found
44
+ # @raise [Soar::Registry::Directory::Error::MultipleEntriesFound] if multiple matches found
45
+ ##
46
+ def fetch(uuid)
47
+ result = @ldap.search({
48
+ base: @base,
49
+ attributes: @attributes,
50
+ filter: Net::LDAP::Filter.eq(@index[0], uuid),
51
+ return_result: true
52
+ })
53
+ raise Soar::Registry::Directory::Error::NoEntriesFound if result.empty?
54
+ raise Soar::Registry::Directory::Error::MultipleEntriesFound if result.length > 1
55
+ response = {}
56
+ @attributes.each { |attribute|
57
+ response[attribute.to_sym] = result[0][attribute.to_sym][0]
58
+ }
59
+ response
60
+ end
61
+
62
+
63
+ ##
64
+ # @param key, named index [String]
65
+ # @param value [String]
66
+ # @return [Array] list of identities
67
+ # @raise [ArgumentError] if value or named index is not specified
68
+ ##
69
+ def search(key, value)
70
+ result = []
71
+ entries = @ldap.search({
72
+ base: @base,
73
+ filter: Net::LDAP::Filter.eq(key, value),
74
+ attributes: @attributes,
75
+ return_result: true
76
+ })
77
+
78
+ entries.each { |entry|
79
+ response = {}
80
+ @attributes.each { |attribute|
81
+ response[attribute.to_sym] = entry[attribute.to_sym][0]
82
+ }
83
+ result << response
84
+ }
85
+ return result
86
+ end
87
+
88
+ ##
89
+ # @return [Array] a list of primary keys and global secondary indexes
90
+ ##
91
+ def index
92
+ @index
93
+ end
94
+
95
+ def delete(dn)
96
+ @ldap.delete(dn: dn)
97
+ end
98
+
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
@@ -16,9 +16,9 @@ module Soar
16
16
  # @param primary_key [String]
17
17
  # @param index [Array] primary key should be the first item
18
18
  ##
19
- def initialize(table: nil, primary_key: nil, index: nil)
19
+ def initialize(table: , index: )
20
20
  @table = table
21
- @primary_key = primary_key
21
+ @primary_key = index[0]
22
22
  @index = index
23
23
  @@interface.clear
24
24
  end
@@ -1,7 +1,6 @@
1
1
  [
2
2
  {
3
3
  "uuid": "identity-62936e70-1815-439b-bf89-8492855a7e6b",
4
- "entity_id": "entity-2d931510-d99f-494a-8c67-87feb05e1594",
5
4
  "email": "test+publisher@hetzner.co.za",
6
5
  "roles": {
7
6
  "staff": {
@@ -14,7 +13,6 @@
14
13
  },
15
14
  {
16
15
  "uuid": "identity-43353f18-8afe-11e6-ae22-56b6b6499611",
17
- "entity_id": "entity-2d931510-d99f-494a-8c67-87feb05e1594",
18
16
  "email": "test+consumer@hetzner.co.za",
19
17
  "roles": {
20
18
  "staff": {},
@@ -26,7 +24,6 @@
26
24
  },
27
25
  {
28
26
  "uuid": "identity-820d5660-2204-4f7d-8c04-746313439b81",
29
- "entity_id": "entity-bad85eb9-0713-4da7-8d36-07a8e4b00eab",
30
27
  "email": "admin@hetzner.co.za",
31
28
  "roles": {
32
29
  "staff": {},
@@ -48,7 +45,6 @@
48
45
  },
49
46
  {
50
47
  "uuid": "identity-1ff472a6-8df3-4f13-82c3-89fde26db3cf",
51
- "entity_id": "entity-bad85eb9-0713-4da7-8d36-07a8e4b00eab",
52
48
  "email": "none@example.com",
53
49
  "client_nr": "C123456789",
54
50
  "roles": {
@@ -11,10 +11,6 @@
11
11
  "attribute_name": "uuid",
12
12
  "attribute_type": "S"
13
13
  },
14
- {
15
- "attribute_name": "entity_id",
16
- "attribute_type": "S"
17
- },
18
14
  {
19
15
  "attribute_name": "email",
20
16
  "attribute_type": "S"
@@ -22,7 +18,7 @@
22
18
  ],
23
19
  "global_secondary_indexes": [
24
20
  {
25
- "index_name": "email_index",
21
+ "index_name": "email-index",
26
22
  "key_schema": [
27
23
  {
28
24
  "attribute_name": "email",
@@ -32,23 +28,6 @@
32
28
  "projection": {
33
29
  "projection_type": "ALL"
34
30
 
35
- },
36
- "provisioned_throughput": {
37
- "read_capacity_units": 10,
38
- "write_capacity_units": 10
39
- }
40
- },
41
- {
42
- "index_name": "entity_id_index",
43
- "key_schema": [
44
- {
45
- "attribute_name": "entity_id",
46
- "key_type": "HASH"
47
- }
48
- ],
49
- "projection": {
50
- "projection_type": "ALL"
51
-
52
31
  },
53
32
  "provisioned_throughput": {
54
33
  "read_capacity_units": 10,
@@ -1,5 +1,6 @@
1
1
  require 'soar/registry/directory/test/provider/stub'
2
2
  require 'soar/registry/directory/test/provider/dynamo_db'
3
+ require 'soar/registry/directory/test/provider/ldap'
3
4
 
4
5
  module Soar
5
6
  module Registry
@@ -19,7 +19,6 @@ module Soar
19
19
  credentials: @configuration['provider']['credentials'],
20
20
  table: @table,
21
21
  index: @index,
22
- primary_key: @index[0],
23
22
  configuration: @configuration['provider']['config']
24
23
  })
25
24
  @directory = Soar::Registry::Directory.new(provider)
@@ -0,0 +1,132 @@
1
+ require 'soar/registry/directory'
2
+
3
+ module Soar
4
+ module Registry
5
+ module Directory
6
+ module Test
7
+ module Provider
8
+ class Ldap
9
+
10
+ def initialize
11
+ @configuration = YAML.load_file("config/#{ENV['CONFIG_FILE']}")
12
+ @base = @configuration['provider']['base']
13
+ @config = {
14
+ host: @configuration['provider']['config']['host'],
15
+ port: @configuration['provider']['config']['port']
16
+ }
17
+ @credentials = {
18
+ username: @configuration['provider']['credentials']['username'],
19
+ password: @configuration['provider']['credentials']['password']
20
+ }
21
+ @index = @configuration['provider']['index']
22
+ @entries = [{
23
+ dn: "cn=John Smith,#{@base}",
24
+ attributes: {
25
+ cn: "John Smith",
26
+ mail: "test@example.com",
27
+ objectclass: ["inetOrgPerson", "top"],
28
+ sn: "Smith"
29
+ }
30
+ }, {
31
+ dn: "cn=Sarel Cilliers,#{@base}",
32
+ attributes: {
33
+ cn: "Sarel Cilliers",
34
+ mail: "sarel@example.com",
35
+ objectclass: ["inetOrgPerson", "top"],
36
+ sn: "Cilliers"
37
+ }
38
+ }]
39
+ end
40
+
41
+ def given_configured_directory
42
+ provider = Soar::Registry::Directory::Provider::Ldap.new({
43
+ base: @base,
44
+ index: @index,
45
+ config: {
46
+ host: @config[:host],
47
+ port: @config[:port]
48
+ },
49
+ attributes: ['entryuuid', 'cn', 'mail', 'sn'],
50
+ credentials: {
51
+ username: @credentials[:username],
52
+ password: @credentials[:password]
53
+ }
54
+ })
55
+ @directory = Soar::Registry::Directory.new(provider)
56
+ @entries.each { |entry|
57
+ provider.delete(entry[:dn])
58
+ }
59
+ end
60
+
61
+ ##
62
+ # Adds @entries to datastore using ldap protocol
63
+ # Adds entryuuid to @entries
64
+ ##
65
+ def given_existing_data
66
+ @entries.each{ |entry|
67
+ @directory.put(entry)
68
+ result = @directory.search("mail", entry[:attributes][:mail])
69
+ entry[:attributes][:entryuuid] = result[0][:entryuuid]
70
+ }
71
+ end
72
+
73
+ def put_entry
74
+ @directory.put(@entries[0])
75
+ result = @directory.search("mail", @entries[0][:attributes][:mail])
76
+ @entries[0][:attributes][:entryuuid] = result[0][:entryuuid]
77
+ end
78
+
79
+ def search_for_entry
80
+ @result = @directory.search("mail", @entries[0][:attributes][:mail])
81
+ end
82
+
83
+ def request_index
84
+ @result = @directory.index
85
+ end
86
+
87
+ def fetch_entry
88
+ begin
89
+ @result = @directory.fetch(@entries[0][:attributes][:entryuuid])
90
+ rescue Soar::Registry::Directory::Error::NoEntriesFound
91
+ @error = true
92
+ end
93
+ end
94
+
95
+ def persisted?
96
+ result = @directory.fetch(@entries[0][:attributes][:entryuuid])
97
+ entry = @entries[0][:attributes]
98
+ entry.delete(:objectclass)
99
+ result == entry
100
+ end
101
+
102
+ def returned?
103
+ entry = @entries[0][:attributes]
104
+ entry.delete(:objectclass)
105
+ @result == [entry]
106
+ end
107
+
108
+ def index?
109
+ @result == @index
110
+ end
111
+
112
+ def single_entry?
113
+ entry = @entries[0][:attributes]
114
+ entry.delete(:objectclass)
115
+ @result == entry
116
+ end
117
+
118
+ def no_entries_found?
119
+ @error == true
120
+ end
121
+
122
+ def no_matching_entries?
123
+ @result == []
124
+ end
125
+
126
+ end
127
+ end
128
+ end
129
+ end
130
+
131
+ end
132
+ end
@@ -12,12 +12,11 @@ module Soar
12
12
  "identifier" => SecureRandom.hex
13
13
  }
14
14
 
15
- @@index = ["identity_id", "email", "entity_id"]
15
+ @@index = ["uuid", "identifier"]
16
16
 
17
17
  def given_configured_directory
18
18
  provider = Soar::Registry::Directory::Provider::Stub.new({
19
19
  table: "identities",
20
- primary_key: "uuid",
21
20
  index: @@index
22
21
  })
23
22
  @directory = Soar::Registry::Directory.new(provider)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: soar-registry-directory
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Charles Mulder
@@ -67,7 +67,7 @@ dependencies:
67
67
  version: '2.6'
68
68
  - - ">="
69
69
  - !ruby/object:Gem::Version
70
- version: 2.6.28
70
+ version: 2.6.38
71
71
  type: :runtime
72
72
  prerelease: false
73
73
  version_requirements: !ruby/object:Gem::Requirement
@@ -77,7 +77,7 @@ dependencies:
77
77
  version: '2.6'
78
78
  - - ">="
79
79
  - !ruby/object:Gem::Version
80
- version: 2.6.28
80
+ version: 2.6.38
81
81
  - !ruby/object:Gem::Dependency
82
82
  name: hashie
83
83
  requirement: !ruby/object:Gem::Requirement
@@ -98,6 +98,20 @@ dependencies:
98
98
  - - ">="
99
99
  - !ruby/object:Gem::Version
100
100
  version: 3.4.6
101
+ - !ruby/object:Gem::Dependency
102
+ name: net-ldap
103
+ requirement: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - "~>"
106
+ - !ruby/object:Gem::Version
107
+ version: 0.15.0
108
+ type: :runtime
109
+ prerelease: false
110
+ version_requirements: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - "~>"
113
+ - !ruby/object:Gem::Version
114
+ version: 0.15.0
101
115
  description: Directories for soar registries
102
116
  email: charles.mulder@hetzner.co.za
103
117
  executables: []
@@ -109,11 +123,14 @@ files:
109
123
  - lib/soar/registry/directory/error.rb
110
124
  - lib/soar/registry/directory/model.rb
111
125
  - lib/soar/registry/directory/provider/dynamo_db.rb
126
+ - lib/soar/registry/directory/provider/ldap.rb
112
127
  - lib/soar/registry/directory/provider/stub.rb
113
128
  - lib/soar/registry/directory/test/fixtures/entries.json
129
+ - lib/soar/registry/directory/test/fixtures/entries.ldif
114
130
  - lib/soar/registry/directory/test/fixtures/table_structure.json
115
131
  - lib/soar/registry/directory/test/orchestrator.rb
116
132
  - lib/soar/registry/directory/test/provider/dynamo_db.rb
133
+ - lib/soar/registry/directory/test/provider/ldap.rb
117
134
  - lib/soar/registry/directory/test/provider/stub.rb
118
135
  homepage: https://gitlab.host-h.net/registries/directory
119
136
  licenses: