op_connect 0.1.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 +7 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +31 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/workflows/coverage.yml +27 -0
- data/.github/workflows/publish.yml +42 -0
- data/.github/workflows/test.yml +27 -0
- data/.gitignore +11 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +16 -0
- data/Guardfile +23 -0
- data/LICENSE.txt +21 -0
- data/README.md +322 -0
- data/Rakefile +12 -0
- data/bin/console +17 -0
- data/bin/setup +8 -0
- data/docker-compose.yml +20 -0
- data/lib/op_connect/api_request/actor.rb +15 -0
- data/lib/op_connect/api_request/resource.rb +14 -0
- data/lib/op_connect/api_request.rb +17 -0
- data/lib/op_connect/client/files.rb +20 -0
- data/lib/op_connect/client/items.rb +34 -0
- data/lib/op_connect/client/vaults.rb +15 -0
- data/lib/op_connect/client.rb +45 -0
- data/lib/op_connect/configurable.rb +45 -0
- data/lib/op_connect/connection.rb +103 -0
- data/lib/op_connect/default.rb +57 -0
- data/lib/op_connect/error.rb +60 -0
- data/lib/op_connect/item/field.rb +18 -0
- data/lib/op_connect/item/file.rb +16 -0
- data/lib/op_connect/item/generator_recipe.rb +12 -0
- data/lib/op_connect/item/section.rb +12 -0
- data/lib/op_connect/item/url.rb +14 -0
- data/lib/op_connect/item.rb +31 -0
- data/lib/op_connect/object.rb +21 -0
- data/lib/op_connect/response/raise_error.rb +16 -0
- data/lib/op_connect/response.rb +5 -0
- data/lib/op_connect/server_health/dependency.rb +13 -0
- data/lib/op_connect/server_health.rb +13 -0
- data/lib/op_connect/vault.rb +16 -0
- data/lib/op_connect/version.rb +5 -0
- data/lib/op_connect.rb +47 -0
- data/op_connect.gemspec +34 -0
- metadata +116 -0
data/docker-compose.yml
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
version: '3.8'
|
|
2
|
+
|
|
3
|
+
services:
|
|
4
|
+
op-connect-api:
|
|
5
|
+
image: 1password/connect-api:latest
|
|
6
|
+
ports:
|
|
7
|
+
- 8080:8080
|
|
8
|
+
volumes:
|
|
9
|
+
- ./1password-credentials.json:/home/opuser/.op/1password-credentials.json
|
|
10
|
+
- op-connect-data:/home/opuser/.op/data
|
|
11
|
+
op-connect-sync:
|
|
12
|
+
image: 1password/connect-sync:latest
|
|
13
|
+
ports:
|
|
14
|
+
- 8081:8080
|
|
15
|
+
volumes:
|
|
16
|
+
- ./1password-credentials.json:/home/opuser/.op/1password-credentials.json
|
|
17
|
+
- op-connect-data:/home/opuser/.op/data
|
|
18
|
+
|
|
19
|
+
volumes:
|
|
20
|
+
op-connect-data:
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module OpConnect
|
|
2
|
+
class APIRequest
|
|
3
|
+
class Actor
|
|
4
|
+
attr_reader :id, :account, :jti, :user_agent, :ip
|
|
5
|
+
|
|
6
|
+
def initialize(options = {})
|
|
7
|
+
@id = options["id"]
|
|
8
|
+
@account = options["account"]
|
|
9
|
+
@jti = options["jti"]
|
|
10
|
+
@user_agent = options["user_agent"]
|
|
11
|
+
@ip = options["ip"]
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
module OpConnect
|
|
2
|
+
class APIRequest
|
|
3
|
+
class Resource
|
|
4
|
+
attr_reader :type, :vault, :item, :item_version
|
|
5
|
+
|
|
6
|
+
def initialize(options = {})
|
|
7
|
+
@type = options["type"]
|
|
8
|
+
@vault = Object.new(options["vault"])
|
|
9
|
+
@item = Object.new(options["item"])
|
|
10
|
+
@item_version = options["item_version"]
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module OpConnect
|
|
2
|
+
class APIRequest
|
|
3
|
+
autoload :Actor, "op_connect/api_request/actor"
|
|
4
|
+
autoload :Resource, "op_connect/api_request/resource"
|
|
5
|
+
|
|
6
|
+
attr_reader :request_id, :timestamp, :action, :result, :actor, :resource
|
|
7
|
+
|
|
8
|
+
def initialize(options = {})
|
|
9
|
+
@request_id = options["request_id"]
|
|
10
|
+
@timestamp = options["timestamp"]
|
|
11
|
+
@action = options["action"]
|
|
12
|
+
@result = options["result"]
|
|
13
|
+
@actor = Actor.new(options["actor"])
|
|
14
|
+
@resource = Resource.new(options["resource"])
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
module OpConnect
|
|
2
|
+
class Client
|
|
3
|
+
module Files
|
|
4
|
+
def list_files(vault_id:, item_id:, **params)
|
|
5
|
+
get("vaults/#{vault_id}/items/#{item_id}/files", params: params).body.map { |file| Item::File.new(file) }
|
|
6
|
+
end
|
|
7
|
+
alias_method :files, :list_files
|
|
8
|
+
|
|
9
|
+
def get_file(vault_id:, item_id:, id:, **params)
|
|
10
|
+
Item::File.new get("vaults/#{vault_id}/items/#{item_id}/files/#{id}", params: params).body
|
|
11
|
+
end
|
|
12
|
+
alias_method :file, :get_file
|
|
13
|
+
|
|
14
|
+
def get_file_content(vault_id:, item_id:, id:)
|
|
15
|
+
get("vaults/#{vault_id}/items/#{item_id}/files/#{id}/content").body
|
|
16
|
+
end
|
|
17
|
+
alias_method :file_content, :get_file_content
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module OpConnect
|
|
2
|
+
class Client
|
|
3
|
+
module Items
|
|
4
|
+
def list_items(vault_id:, **params)
|
|
5
|
+
get("vaults/#{vault_id}/items", params: params).body.map { |item| Item.new(item) }
|
|
6
|
+
end
|
|
7
|
+
alias_method :items, :list_items
|
|
8
|
+
|
|
9
|
+
def get_item(vault_id:, id:)
|
|
10
|
+
Item.new get("vaults/#{vault_id}/items/#{id}").body
|
|
11
|
+
end
|
|
12
|
+
alias_method :item, :get_item
|
|
13
|
+
|
|
14
|
+
def create_item(vault_id:, **attributes)
|
|
15
|
+
Item.new post("vaults/#{vault_id}/items", body: attributes).body
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def replace_item(vault_id:, id:, **attributes)
|
|
19
|
+
Item.new put("vaults/#{vault_id}/items/#{id}", body: attributes).body
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def delete_item(vault_id:, id:)
|
|
23
|
+
return true if delete("vaults/#{vault_id}/items/#{id}").status == 204
|
|
24
|
+
false
|
|
25
|
+
rescue OpConnect::Error
|
|
26
|
+
false
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def update_item(vault_id:, id:, **attributes)
|
|
30
|
+
Item.new patch("vaults/#{vault_id}/items/#{id}", body: attributes, headers: {"Content-Type": "applicatoin/json-patch+json"}).body
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
module OpConnect
|
|
2
|
+
class Client
|
|
3
|
+
module Vaults
|
|
4
|
+
def list_vaults(**params)
|
|
5
|
+
get("vaults", params: params).body.map { |vault| Vault.new(vault) }
|
|
6
|
+
end
|
|
7
|
+
alias_method :vaults, :list_vaults
|
|
8
|
+
|
|
9
|
+
def get_vault(id:)
|
|
10
|
+
Vault.new get("vaults/#{id}").body
|
|
11
|
+
end
|
|
12
|
+
alias_method :vault, :get_vault
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module OpConnect
|
|
2
|
+
class Client
|
|
3
|
+
autoload :Vaults, "op_connect/client/vaults"
|
|
4
|
+
autoload :Items, "op_connect/client/items"
|
|
5
|
+
autoload :Files, "op_connect/client/files"
|
|
6
|
+
|
|
7
|
+
include OpConnect::Configurable
|
|
8
|
+
include OpConnect::Connection
|
|
9
|
+
include OpConnect::Client::Vaults
|
|
10
|
+
include OpConnect::Client::Items
|
|
11
|
+
include OpConnect::Client::Files
|
|
12
|
+
|
|
13
|
+
def initialize(options = {})
|
|
14
|
+
OpConnect::Configurable.keys.each do |key|
|
|
15
|
+
value = options.key?(key) ? options[key] : OpConnect.instance_variable_get(:"@#{key}")
|
|
16
|
+
instance_variable_set(:"@#{key}", value)
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def inspect
|
|
21
|
+
inspected = super
|
|
22
|
+
inspected.gsub!(@access_token, ("*" * 24).to_s) if @access_token
|
|
23
|
+
inspected
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def activity(**params)
|
|
27
|
+
get("activity", params: params).body.map { |a| APIRequest.new(a) }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def heartbeat
|
|
31
|
+
return true if get("/heartbeat").status == 200
|
|
32
|
+
false
|
|
33
|
+
rescue OpConnect::Error
|
|
34
|
+
false
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def health
|
|
38
|
+
ServerHealth.new get("/health").body
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def metrics
|
|
42
|
+
get("/metrics").body
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module OpConnect
|
|
2
|
+
module Configurable
|
|
3
|
+
attr_accessor :access_token, :adapter, :stubs, :user_agent
|
|
4
|
+
attr_writer :api_endpoint
|
|
5
|
+
|
|
6
|
+
class << self
|
|
7
|
+
def keys
|
|
8
|
+
@keys ||= [
|
|
9
|
+
:access_token,
|
|
10
|
+
:adapter,
|
|
11
|
+
:api_endpoint,
|
|
12
|
+
:stubs,
|
|
13
|
+
:user_agent
|
|
14
|
+
]
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def configure
|
|
19
|
+
yield self
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def reset!
|
|
23
|
+
OpConnect::Configurable.keys.each do |key|
|
|
24
|
+
instance_variable_set(:"@#{key}", OpConnect::Default.options[key])
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
self
|
|
28
|
+
end
|
|
29
|
+
alias_method :setup, :reset!
|
|
30
|
+
|
|
31
|
+
def same_options?(opts)
|
|
32
|
+
opts.hash == options.hash
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def api_endpoint
|
|
36
|
+
::File.join(@api_endpoint, "")
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def options
|
|
42
|
+
OpConnect::Configurable.keys.map { |key| [key, instance_variable_get(:"@#{key}")] }.to_h
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
module OpConnect
|
|
2
|
+
# Network layer for API clients.
|
|
3
|
+
#
|
|
4
|
+
module Connection
|
|
5
|
+
# Make an HTTP GET request.
|
|
6
|
+
#
|
|
7
|
+
# @param url [String] The path, relative to {#api_endpoint}.
|
|
8
|
+
# @param params [Hash] Query parameters for the request.
|
|
9
|
+
# @param headers [Hash] Header params for the request.
|
|
10
|
+
#
|
|
11
|
+
# @return [Faraday::Response]
|
|
12
|
+
#
|
|
13
|
+
def get(url, params: {}, headers: {})
|
|
14
|
+
request :get, url, params, headers
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Make an HTTP POST request.
|
|
18
|
+
#
|
|
19
|
+
# @param url [String] The path, relative to {#api_endpoint}.
|
|
20
|
+
# @param body [Hash] Body params for the request.
|
|
21
|
+
# @param headers [Hash] Header params for the request.
|
|
22
|
+
#
|
|
23
|
+
# @return [Faraday::Response]
|
|
24
|
+
#
|
|
25
|
+
def post(url, body:, headers: {})
|
|
26
|
+
request :post, url, body, headers
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Make an HTTP PUT request.
|
|
30
|
+
#
|
|
31
|
+
# @param url [String] The path, relative to {#api_endpoint}.
|
|
32
|
+
# @param body [Hash] Body params for the request.
|
|
33
|
+
# @param headers [Hash] Header params for the request.
|
|
34
|
+
#
|
|
35
|
+
# @return [Faraday::Response]
|
|
36
|
+
#
|
|
37
|
+
def put(url, body:, headers: {})
|
|
38
|
+
request :put, url, body, headers
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Make an HTTP PATCH request.
|
|
42
|
+
#
|
|
43
|
+
# @param url [String] The path, relative to {#api_endpoint}.
|
|
44
|
+
# @param body [Hash] Body params for the request.
|
|
45
|
+
# @param headers [Hash] Header params for the request.
|
|
46
|
+
#
|
|
47
|
+
# @return [Faraday::Response]
|
|
48
|
+
#
|
|
49
|
+
def patch(url, body:, headers: {})
|
|
50
|
+
request :patch, url, body, headers
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Make an HTTP DELETE request.
|
|
54
|
+
#
|
|
55
|
+
# @param url [String] The path, relative to {#api_endpoint}.
|
|
56
|
+
# @param params [Hash] Query params for the request.
|
|
57
|
+
# @param headers [Hash] Header params for the request.
|
|
58
|
+
#
|
|
59
|
+
# @return [Faraday::Response]
|
|
60
|
+
#
|
|
61
|
+
def delete(url, params: {}, headers: {})
|
|
62
|
+
request :delete, url, params, headers
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Connection object for the 1Password Connect API.
|
|
66
|
+
#
|
|
67
|
+
# @return [Faraday::Client]
|
|
68
|
+
#
|
|
69
|
+
def connection
|
|
70
|
+
@connection ||= Faraday.new(api_endpoint) do |http|
|
|
71
|
+
http.headers[:user_agent] = user_agent
|
|
72
|
+
|
|
73
|
+
http.request :authorization, :Bearer, access_token
|
|
74
|
+
http.request :json
|
|
75
|
+
|
|
76
|
+
http.use OpConnect::Response::RaiseError
|
|
77
|
+
|
|
78
|
+
http.response :dates
|
|
79
|
+
http.response :json, content_type: "application/json"
|
|
80
|
+
|
|
81
|
+
http.adapter adapter, @stubs
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Response for the last HTTP request.
|
|
86
|
+
#
|
|
87
|
+
# @return [Faraday::Response]
|
|
88
|
+
#
|
|
89
|
+
def last_response
|
|
90
|
+
@last_response if defined? @last_response
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
private
|
|
94
|
+
|
|
95
|
+
def request(method, path, data, headers = {})
|
|
96
|
+
@last_response = response = connection.send(method, path, data, headers)
|
|
97
|
+
response
|
|
98
|
+
rescue OpConnect::Error => error
|
|
99
|
+
@last_response = nil
|
|
100
|
+
raise error
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "op_connect/version"
|
|
4
|
+
|
|
5
|
+
module OpConnect
|
|
6
|
+
# Default configuration options for {Client}
|
|
7
|
+
#
|
|
8
|
+
module Default
|
|
9
|
+
API_ENDPOINT = "http://localhost:8080/v1"
|
|
10
|
+
USER_AGENT = "1Password Connect Ruby SDK #{OpConnect::VERSION}"
|
|
11
|
+
|
|
12
|
+
class << self
|
|
13
|
+
# Configuration options
|
|
14
|
+
#
|
|
15
|
+
# @return [Hash]
|
|
16
|
+
#
|
|
17
|
+
def options
|
|
18
|
+
OpConnect::Configurable.keys.map { |key| [key, send(key)] }.to_h
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# Default access token from ENV
|
|
22
|
+
#
|
|
23
|
+
# @return [String]
|
|
24
|
+
#
|
|
25
|
+
def access_token
|
|
26
|
+
ENV["OP_CONNECT_ACCESS_TOKEN"]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Default network adapter for Faraday (defaults to :net_http)
|
|
30
|
+
#
|
|
31
|
+
# @return [Symbol]
|
|
32
|
+
#
|
|
33
|
+
def adapter
|
|
34
|
+
Faraday.default_adapter
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Default API endpoint from ENV or {API_ENDPOINT}
|
|
38
|
+
#
|
|
39
|
+
# @return [<Type>] <description>
|
|
40
|
+
#
|
|
41
|
+
def api_endpoint
|
|
42
|
+
ENV["OP_CONNECT_API_ENDPOINT"] || API_ENDPOINT
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def stubs
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Default user agent from ENV or {USER_AGENT}
|
|
49
|
+
#
|
|
50
|
+
# @return [<Type>] <description>
|
|
51
|
+
#
|
|
52
|
+
def user_agent
|
|
53
|
+
ENV["OP_CONNECT_USER_AGENT"] || USER_AGENT
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
module OpConnect
|
|
2
|
+
class Error < StandardError
|
|
3
|
+
class << self
|
|
4
|
+
def from_response(response)
|
|
5
|
+
status = response.status
|
|
6
|
+
|
|
7
|
+
if (klass = case status
|
|
8
|
+
when 400 then OpConnect::BadRequest
|
|
9
|
+
when 401 then OpConnect::Unauthorized
|
|
10
|
+
when 403 then OpConnect::Forbidden
|
|
11
|
+
when 404 then OpConnect::NotFound
|
|
12
|
+
when 413 then OpConnect::PayloadTooLarge
|
|
13
|
+
when 400..499 then OpConnect::ClientError
|
|
14
|
+
when 500 then OpConnect::InternalServerError
|
|
15
|
+
when 503 then OpConnect::ServiceUnavailable
|
|
16
|
+
when 500..599 then OpConnect::ServerError
|
|
17
|
+
end)
|
|
18
|
+
klass.new(response)
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def initialize(response = nil)
|
|
24
|
+
@response = response
|
|
25
|
+
super(build_error_message)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def build_error_message
|
|
31
|
+
return nil if @response.nil?
|
|
32
|
+
|
|
33
|
+
message = "#{@response.method.to_s.upcase} "
|
|
34
|
+
message << "#{@response.url}: "
|
|
35
|
+
message << "#{@response.status} - "
|
|
36
|
+
message << @response.body["message"].to_s if @response.body["message"]
|
|
37
|
+
message << "\n\n#{@response.body}\n\n"
|
|
38
|
+
|
|
39
|
+
message
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
class ClientError < Error; end
|
|
44
|
+
|
|
45
|
+
class BadRequest < ClientError; end
|
|
46
|
+
|
|
47
|
+
class Unauthorized < ClientError; end
|
|
48
|
+
|
|
49
|
+
class Forbidden < ClientError; end
|
|
50
|
+
|
|
51
|
+
class NotFound < ClientError; end
|
|
52
|
+
|
|
53
|
+
class PayloadTooLarge < ClientError; end
|
|
54
|
+
|
|
55
|
+
class ServerError < Error; end
|
|
56
|
+
|
|
57
|
+
class InternalServerError < ServerError; end
|
|
58
|
+
|
|
59
|
+
class ServiceUnavailable < ServerError; end
|
|
60
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module OpConnect
|
|
2
|
+
class Item
|
|
3
|
+
class Field
|
|
4
|
+
attr_reader :purpose, :type, :value, :should_generate, :recipe, :section
|
|
5
|
+
|
|
6
|
+
alias_method :generate?, :should_generate
|
|
7
|
+
|
|
8
|
+
def initialize(options = {})
|
|
9
|
+
@purpose = options["purpose"] if options["purpose"]
|
|
10
|
+
@type = options["type"] if options["type"]
|
|
11
|
+
@value = options["value"]
|
|
12
|
+
@should_generate = options["generate"] || false
|
|
13
|
+
@recipe = GeneratorRecipe.new(options["recipe"])
|
|
14
|
+
@section = Object.new(options["section"])
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module OpConnect
|
|
2
|
+
class Item
|
|
3
|
+
class File
|
|
4
|
+
attr_reader :id, :name, :size, :content_path, :content, :section
|
|
5
|
+
|
|
6
|
+
def initialize(options = {})
|
|
7
|
+
@id = options["id"]
|
|
8
|
+
@name = options["name"]
|
|
9
|
+
@size = options["size"]
|
|
10
|
+
@content_path = options["content_path"]
|
|
11
|
+
@content = options["content"]
|
|
12
|
+
@section = Object.new(options["section"])
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
module OpConnect
|
|
2
|
+
class Item
|
|
3
|
+
class GeneratorRecipe
|
|
4
|
+
attr_reader :length, :character_sets
|
|
5
|
+
|
|
6
|
+
def initialize(options = {})
|
|
7
|
+
@length = options["length"] if options & ["length"]
|
|
8
|
+
@character_sets = options["characterSets"] if options & ["characterSets"]
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module OpConnect
|
|
2
|
+
class Item
|
|
3
|
+
autoload :Field, "op_connect/item/field"
|
|
4
|
+
autoload :File, "op_connect/item/file"
|
|
5
|
+
autoload :GeneratorRecipe, "op_connect/item/generator_recipe"
|
|
6
|
+
autoload :Section, "op_connect/item/section"
|
|
7
|
+
autoload :URL, "op_connect/item/url"
|
|
8
|
+
|
|
9
|
+
attr_reader :id, :title, :vault, :category, :urls, :is_favorite, :tags, :version, :state, :sections, :fields, :files, :created_at, :updated_at, :last_edited_by
|
|
10
|
+
|
|
11
|
+
alias_method :favorite?, :is_favorite
|
|
12
|
+
|
|
13
|
+
def initialize(options = {})
|
|
14
|
+
@id = options["id"]
|
|
15
|
+
@title = options["title"]
|
|
16
|
+
@vault = Object.new(options["vault"])
|
|
17
|
+
@category = options["category"]
|
|
18
|
+
@urls = options["urls"]&.collect! { |url| URL.new(url) }
|
|
19
|
+
@is_favorite = options["favorite"] || false
|
|
20
|
+
@tags = options["tags"]
|
|
21
|
+
@version = options["version"]
|
|
22
|
+
@state = options["state"]
|
|
23
|
+
@sections = options["sections"]&.collect! { |section| Section.new(section) } || []
|
|
24
|
+
@fields = options["fields"]&.collect! { |field| Field.new(field) } || []
|
|
25
|
+
@files = options["files"]&.collect! { |file| File.new(file) } || []
|
|
26
|
+
@created_at = options["createdAt"]
|
|
27
|
+
@updated_at = options["updatedAt"]
|
|
28
|
+
@last_edited_by = options["lastEditedBy"]
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require "ostruct"
|
|
2
|
+
|
|
3
|
+
module OpConnect
|
|
4
|
+
class Object < SimpleDelegator
|
|
5
|
+
def initialize(attributes)
|
|
6
|
+
super to_ostruct(attributes)
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
def to_ostruct(obj)
|
|
12
|
+
if obj.is_a?(Hash)
|
|
13
|
+
OpenStruct.new(obj.map { |key, value| [key, to_ostruct(value)] }.to_h)
|
|
14
|
+
elsif obj.is_a?(Array)
|
|
15
|
+
obj.map { |o| to_ostruct(o) }
|
|
16
|
+
else
|
|
17
|
+
obj
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module OpConnect
|
|
2
|
+
# Faraday response middleware
|
|
3
|
+
#
|
|
4
|
+
module Response
|
|
5
|
+
# This class raises an OpConnect-flavored exception based on HTTP status
|
|
6
|
+
# codes returned by the API.
|
|
7
|
+
#
|
|
8
|
+
class RaiseError < Faraday::Middleware
|
|
9
|
+
def on_complete(response)
|
|
10
|
+
if (error = OpConnect::Error.from_response(response))
|
|
11
|
+
raise error
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module OpConnect
|
|
2
|
+
class ServerHealth
|
|
3
|
+
autoload :Dependency, "op_connect/server_health/dependency"
|
|
4
|
+
|
|
5
|
+
attr_reader :name, :version, :dependencies
|
|
6
|
+
|
|
7
|
+
def initialize(options = {})
|
|
8
|
+
@name = options["name"]
|
|
9
|
+
@version = options["version"]
|
|
10
|
+
@dependencies = options["dependencies"]&.collect! { |dependency| Dependency.new(dependency) } || []
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module OpConnect
|
|
2
|
+
class Vault
|
|
3
|
+
attr_reader :id, :name, :attribute_version, :content_version, :items, :type, :created_at, :updated_at
|
|
4
|
+
|
|
5
|
+
def initialize(options = {})
|
|
6
|
+
@id = options["id"]
|
|
7
|
+
@name = options["name"]
|
|
8
|
+
@attribute_version = options["attributeVersion"]
|
|
9
|
+
@content_version = options["contentVersion"]
|
|
10
|
+
@items = options["items"]
|
|
11
|
+
@type = options["type"]
|
|
12
|
+
@created_at = options["createdAt"]
|
|
13
|
+
@updated_at = options["updatedAt"]
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|