zaikio-directory 0.0.5 → 0.0.10

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: 1ee582c20c55f62a0b07e24dc51924982c4ed5fb0e8853c92042c1485ff91319
4
- data.tar.gz: 8f886aae2708711336ca2a2911beeb8a769680cd821334f7525ce9f01b544f6d
3
+ metadata.gz: 26d6a02aea4964a306cbb0dbd0a72232aa064e13a5b168b3e1a4f9eab78f4dbe
4
+ data.tar.gz: 8112dac6c53620e836c39f1c33838ef4a2d059deee71c12292c05a717f836a0e
5
5
  SHA512:
6
- metadata.gz: 0152acb74f6a20207cc649d4f7e8d0ced6c78d54480ba81411d933146bd6af0b4fb33f4e604b07107ab265c1e7822a110d05d13a947bc454a449b24da26661c4
7
- data.tar.gz: f4b338c8f5853fb6b8ef594d2d1b2ef08de1b6b8860d1e31fec189a7a847810e0a8af58f3702cf4f91265c2d31080530e30486fe62a353a42443f0e110527b97
6
+ metadata.gz: b612f4b4bac78dbed24d840ecbe3ce5eb05ddf2f7105c3a8f1c050eda076d4b793ed886c85d83466b691cebd4aee53dbe0939d31eb2c273dd1a6f8bab825ee9e
7
+ data.tar.gz: 8c38ce7c669744039a576c91ff9b8e48b90cbd6f5b3e4857d221f34004c9bb06237aaa513b0a47899cc218dc781482c3fd914f82f88bc07558dc84d63bc50ce9
data/README.md CHANGED
@@ -26,7 +26,7 @@ $ gem install zaikio-directory
26
26
  # config/initializers/zaikio_directory.rb
27
27
 
28
28
  Zaikio::Directory.configure do |config|
29
- config.host :production # sandbox or production
29
+ config.environment = :production # sandbox or production
30
30
  end
31
31
  ```
32
32
 
@@ -106,3 +106,38 @@ Zaikio::Directory.with_token(token) do
106
106
  Zaikio::Directory::RevokedAccessToken.create
107
107
  end
108
108
  ```
109
+
110
+ ### Error Handling
111
+
112
+ If an unexpected error occurs with an API call (i.e. an error that has no status code `2xx`, `404` or `422`) then a `Zaikio::ConnectionError` is thrown automatically (for `404` there will be a `Zaikio::ResourceNotFound`).
113
+
114
+ This can be easily caught using the `with_fallback` method. We recommend to always work with fallbacks.
115
+
116
+ ```rb
117
+ Zaikio::Directory.with_token(token) do
118
+ person = Zaikio::Directory::CurrentPerson
119
+ .find_with_fallback(Zaikio::Directory::CurrentPerson.new(full_name: "Hello World"))
120
+
121
+ person.organizations # Automatically uses empty array as fallback
122
+ end
123
+
124
+ Zaikio::Directory.with_token(token) do
125
+ organization = Zaikio::Directory::CurrentOrganization.new
126
+
127
+ organization.machines.with_fallback.all
128
+ organization.machines
129
+ .with_fallback(Zaikio::Directory::Machine.new(name: 'My Machine'))
130
+ .find('machine-id')
131
+
132
+
133
+ organization.machines
134
+ .with_fallback(Zaikio::Directory::Machine.new(name: 'My Machine'))
135
+ .find('machine-does-not-exist') # => raises Zaikio::ResourceNotFound
136
+
137
+ begin
138
+ organization.machines.create(name: "Machine Name")
139
+ rescue Zaikio::ConnectionError
140
+ # Do something
141
+ end
142
+ end
143
+ ```
@@ -6,13 +6,16 @@ require "zaikio/directory/authorization_middleware"
6
6
  require "zaikio/directory/basic_auth_middleware"
7
7
 
8
8
  # Models
9
+ require "zaikio/error"
9
10
  require "zaikio/directory/base"
11
+ require "zaikio/directory/asset"
10
12
  require "zaikio/directory/organization_membership"
11
13
  require "zaikio/directory/business_relationship"
12
14
  require "zaikio/directory/organization"
13
15
  require "zaikio/directory/person"
14
16
  require "zaikio/directory/machine"
15
17
  require "zaikio/directory/software"
18
+ require "zaikio/directory/specialist"
16
19
  require "zaikio/directory/site"
17
20
  require "zaikio/directory/membership"
18
21
  require "zaikio/directory/current_person"
@@ -69,14 +72,15 @@ module Zaikio
69
72
 
70
73
  private
71
74
 
72
- def create_token_data(payload)
75
+ def create_token_data(payload) # rubocop:disable Metrics/AbcSize
73
76
  subjects = payload["sub"].split(">")
74
77
 
75
78
  OpenStruct.new(
76
79
  audience: payload["aud"].first,
77
80
  on_behalf_of_id: subjects.first.split("/").last,
78
81
  subject_id: subjects.last.split("/").last,
79
- subject_type: subjects.last.split("/").first
82
+ subject_type: subjects.last.split("/").first,
83
+ scopes: payload["scope"]
80
84
  )
81
85
  end
82
86
  end
@@ -0,0 +1,55 @@
1
+ module Zaikio
2
+ module Directory
3
+ module Asset
4
+ extend ActiveSupport::Concern
5
+
6
+ included do
7
+ # Callbacks
8
+ after_create :make_organization_owner
9
+ end
10
+
11
+ def make_organization_owner
12
+ if Zaikio::Directory.current_token_data.subject_type == "Organization"
13
+ self.class.request(:post,
14
+ "#{collection_name}/#{id}/#{singular_name}_ownership")
15
+ else
16
+ org_path = "person/organizations/#{organization_id}"
17
+ self.class.request(:post,
18
+ "#{org_path}/#{collection_name}/#{id}/#{singular_name}_ownership")
19
+ end
20
+ end
21
+
22
+ def destroy
23
+ if Zaikio::Directory.current_token_data.subject_type == "Organization"
24
+ self.class.request(:delete,
25
+ "#{collection_name}/#{id}/#{singular_name}_ownership")
26
+ else
27
+ org_path = "person/organizations/#{owner_id || organization_id}"
28
+ self.class.request(:delete,
29
+ "#{org_path}/#{collection_name}/#{id}/#{singular_name}_ownership")
30
+ end
31
+ end
32
+
33
+ def specification
34
+ prefix = if Zaikio::Directory.current_token_data.subject_type == "Person"
35
+ "person/organizations/#{owner_id || organization_id}/"
36
+ else
37
+ ""
38
+ end
39
+ self.class.request(:get,
40
+ "#{prefix}#{collection_name}/#{id}/#{singular_name}_specification")
41
+ &.body&.dig("data")
42
+ end
43
+
44
+ private
45
+
46
+ def collection_name
47
+ self.class.name.demodulize.underscore.pluralize
48
+ end
49
+
50
+ def singular_name
51
+ self.class.name.demodulize.underscore
52
+ end
53
+ end
54
+ end
55
+ end
@@ -9,7 +9,7 @@ module Zaikio
9
9
  end
10
10
 
11
11
  def self.token(token = nil)
12
- @token = token || @token
12
+ @token ||= token
13
13
  end
14
14
 
15
15
  def call(request_env)
@@ -9,7 +9,7 @@ module Zaikio
9
9
  end
10
10
 
11
11
  def self.credentials(credentials = nil)
12
- @credentials = credentials || @credentials
12
+ @credentials ||= credentials
13
13
  end
14
14
 
15
15
  def call(request_env)
@@ -9,24 +9,34 @@ module Zaikio
9
9
  all.find_one
10
10
  end
11
11
 
12
+ def self.find_with_fallback(fallback)
13
+ all.with_fallback(fallback).find_one
14
+ end
15
+
12
16
  # Associations
13
17
  has_many :memberships, class_name: "Zaikio::Directory::Membership",
14
- uri: "organization/memberships"
18
+ uri: "organization/memberships(/:id)"
15
19
  has_many :business_relationships, class_name: "Zaikio::Directory::BusinessRelationship",
16
- uri: "organization/business_relationships"
20
+ uri: "organization/business_relationships(/:id)"
17
21
  has_many :software, class_name: "Zaikio::Directory::Software",
18
- uri: "software"
22
+ uri: "software(/:id)"
19
23
  has_many :machines, class_name: "Zaikio::Directory::Machine",
20
- uri: "machines"
24
+ uri: "machines(/:id)"
25
+ has_many :specialists, class_name: "Zaikio::Directory::Specialist",
26
+ uri: "specialists(/:id)"
21
27
  has_many :sites, class_name: "Zaikio::Directory::Site",
22
- uri: "sites"
28
+ uri: "sites(/:id)"
23
29
 
24
30
  def fetch
25
31
  self.attributes = get
26
32
  end
27
33
 
34
+ def reload
35
+ self.attributes = self.class.find.attributes
36
+ end
37
+
28
38
  def members
29
- memberships.map(&:person)
39
+ memberships.with_fallback.map(&:person)
30
40
  end
31
41
  end
32
42
  end
@@ -9,6 +9,10 @@ module Zaikio
9
9
  all.find_one
10
10
  end
11
11
 
12
+ def self.find_with_fallback(fallback)
13
+ all.with_fallback(fallback).find_one
14
+ end
15
+
12
16
  # Associations
13
17
  has_many :organization_memberships, class_name: "Zaikio::Directory::OrganizationMembership",
14
18
  uri: nil
@@ -18,7 +22,7 @@ module Zaikio
18
22
  end
19
23
 
20
24
  def organizations
21
- organization_memberships.map(&:organization)
25
+ organization_memberships.with_fallback.map(&:organization)
22
26
  end
23
27
 
24
28
  def admin_organizations
@@ -3,13 +3,33 @@ require "multi_json"
3
3
  module Zaikio
4
4
  module Directory
5
5
  class JSONParser < Faraday::Response::Middleware
6
- def parse(body)
6
+ def on_complete(env)
7
+ connection_error(env) unless /^(2\d\d)|422|404$/.match?(env.status.to_s)
8
+
9
+ raise Spyke::ResourceNotFound if env.status.to_s == "404"
10
+
11
+ env.body = parse_body(env.body)
12
+ end
13
+
14
+ def connection_error(env)
15
+ Zaikio::Directory.configuration.logger
16
+ .error("Zaikio::Directory Status Code #{env.status}, #{env.body}")
17
+ raise Spyke::ConnectionError, "Status Code #{env.status}, #{env.body}"
18
+ end
19
+
20
+ def parse_body(body)
7
21
  json = MultiJson.load(body, symbolize_keys: true)
8
22
  {
9
23
  data: json,
10
24
  metadata: {},
11
25
  errors: json.is_a?(Hash) ? json[:errors] : {}
12
26
  }
27
+ rescue MultiJson::ParseError
28
+ {
29
+ data: {},
30
+ metadata: {},
31
+ errors: {}
32
+ }
13
33
  end
14
34
  end
15
35
  end
@@ -1,29 +1,10 @@
1
1
  module Zaikio
2
2
  module Directory
3
3
  class Machine < Base
4
+ include Asset
5
+
4
6
  uri "machines(/:id)"
5
7
  include_root_in_json :machine
6
-
7
- # Callbacks
8
- after_create :make_organization_owner
9
-
10
- def make_organization_owner
11
- if Zaikio::Directory.current_token_data.subject_type == "Organization"
12
- self.class.request(:post, "machines/#{id}/machine_ownership")
13
- else
14
- org_path = "person/organizations/#{organization_id}"
15
- self.class.request(:post, "#{org_path}/machines/#{id}/machine_ownership")
16
- end
17
- end
18
-
19
- def destroy
20
- if Zaikio::Directory.current_token_data.subject_type == "Organization"
21
- self.class.request(:delete, "machines/#{id}/machine_ownership")
22
- else
23
- org_path = "person/organizations/#{owner_id || organization_id}"
24
- self.class.request(:delete, "#{org_path}/machines/#{id}/machine_ownership")
25
- end
26
- end
27
8
  end
28
9
  end
29
10
  end
@@ -12,6 +12,8 @@ module Zaikio
12
12
  uri: "person/organizations/:organization_id/software"
13
13
  has_many :machines, class_name: "Zaikio::Directory::Machine",
14
14
  uri: "person/organizations/:organization_id/machines"
15
+ has_many :specialists, class_name: "Zaikio::Directory::Specialist",
16
+ uri: "person/organizations/:organization_id/specialists"
15
17
  has_many :sites, class_name: "Zaikio::Directory::Site",
16
18
  uri: "person/organizations/:organization_id/sites"
17
19
  end
@@ -1,28 +1,15 @@
1
1
  module Zaikio
2
2
  module Directory
3
3
  class Software < Base
4
+ include Asset
5
+
4
6
  uri "software(/:id)"
5
7
  include_root_in_json :software
6
8
 
7
- # Callbacks
8
- after_create :make_organization_owner
9
-
10
- def make_organization_owner
11
- if Zaikio::Directory.current_token_data.subject_type == "Organization"
12
- self.class.request(:post, "software/#{id}/software_ownership")
13
- else
14
- org_path = "person/organizations/#{organization_id}"
15
- self.class.request(:post, "#{org_path}/software/#{id}/software_ownership")
16
- end
17
- end
9
+ private
18
10
 
19
- def destroy
20
- if Zaikio::Directory.current_token_data.subject_type == "Organization"
21
- self.class.request(:delete, "software/#{id}/software_ownership")
22
- else
23
- org_path = "person/organizations/#{owner_id || organization_id}"
24
- self.class.request(:delete, "#{org_path}/software/#{id}/software_ownership")
25
- end
11
+ def collection_name
12
+ "software"
26
13
  end
27
14
  end
28
15
  end
@@ -0,0 +1,10 @@
1
+ module Zaikio
2
+ module Directory
3
+ class Specialist < Base
4
+ include Asset
5
+
6
+ uri "specialists(/:id)"
7
+ include_root_in_json :specialist
8
+ end
9
+ end
10
+ end
@@ -1,5 +1,5 @@
1
1
  module Zaikio
2
2
  module Directory
3
- VERSION = "0.0.5".freeze
3
+ VERSION = "0.0.10".freeze
4
4
  end
5
5
  end
@@ -0,0 +1,16 @@
1
+ module Zaikio
2
+ class Error < StandardError; end
3
+ class ConnectionError < Zaikio::Error; end
4
+ class ResourceNotFound < Zaikio::Error; end
5
+ end
6
+
7
+ module Spyke
8
+ instance_eval do
9
+ # avoid warning: already initialized constant
10
+ remove_const("ConnectionError")
11
+ remove_const("ResourceNotFound")
12
+ end
13
+
14
+ ConnectionError = Class.new Zaikio::ConnectionError
15
+ ResourceNotFound = Class.new Zaikio::ResourceNotFound
16
+ end
metadata CHANGED
@@ -1,14 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: zaikio-directory
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.0.10
5
5
  platform: ruby
6
6
  authors:
7
- - Zaikio GmbH
7
+ - crispymtn
8
+ - Jalyna Schröder
9
+ - Martin Spickermann
8
10
  autorequire:
9
11
  bindir: bin
10
12
  cert_chain: []
11
- date: 2020-04-08 00:00:00.000000000 Z
13
+ date: 2020-06-03 00:00:00.000000000 Z
12
14
  dependencies:
13
15
  - !ruby/object:Gem::Dependency
14
16
  name: jwt
@@ -68,7 +70,9 @@ dependencies:
68
70
  version: 5.3.4
69
71
  description: Ruby API Client for Zaikio's Directory
70
72
  email:
73
+ - op@crispymtn.com
71
74
  - js@crispymtn.com
75
+ - spickermann@gmail.com
72
76
  executables: []
73
77
  extensions: []
74
78
  extra_rdoc_files: []
@@ -77,6 +81,7 @@ files:
77
81
  - README.md
78
82
  - Rakefile
79
83
  - lib/zaikio/directory.rb
84
+ - lib/zaikio/directory/asset.rb
80
85
  - lib/zaikio/directory/authorization_middleware.rb
81
86
  - lib/zaikio/directory/base.rb
82
87
  - lib/zaikio/directory/basic_auth_middleware.rb
@@ -95,7 +100,9 @@ files:
95
100
  - lib/zaikio/directory/role.rb
96
101
  - lib/zaikio/directory/site.rb
97
102
  - lib/zaikio/directory/software.rb
103
+ - lib/zaikio/directory/specialist.rb
98
104
  - lib/zaikio/directory/version.rb
105
+ - lib/zaikio/error.rb
99
106
  homepage: https://www.zaikio.com/
100
107
  licenses:
101
108
  - MIT