incognia_api 0.1.0
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/CODEOWNERS +1 -0
- data/.github/workflows/main.yml +18 -0
- data/.gitignore +11 -0
- data/.rspec +3 -0
- data/CHANGELOG.md +5 -0
- data/Gemfile +15 -0
- data/Gemfile.lock +68 -0
- data/README.md +98 -0
- data/Rakefile +8 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/fixtures/vcr_cassettes/token.yml +101 -0
- data/incognia.gemspec +36 -0
- data/lib/incognia/address.rb +108 -0
- data/lib/incognia/api.rb +39 -0
- data/lib/incognia/client.rb +74 -0
- data/lib/incognia/resources/api_resource.rb +13 -0
- data/lib/incognia/resources/credentials.rb +11 -0
- data/lib/incognia/resources/signup_assessment.rb +5 -0
- data/lib/incognia/util.rb +19 -0
- data/lib/incognia/version.rb +5 -0
- data/lib/incognia.rb +39 -0
- metadata +95 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 5eb3f0cd63a0319c016e88eea0d86fd5892271befa4a28b8c5d8870c21cd27bb
|
4
|
+
data.tar.gz: 8439dfd8d7cefe7ee1b7d0c91687d8f062b8809afb7a76798e52de2c792c520a
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 88e070f8841a1410117cd527139be05ee19b8e73aea4d1190642f107f97dc181a086b56cbe1c0bfab2bc833d7a0000500b66fc2ce6a3c57b9b0d9e9d58979640
|
7
|
+
data.tar.gz: e7d396d6623a7b2f0965e6b430faa5d5aa28d22b137949a2b24c6956840f85787906d6739f342004381cb593f614af8ec5596443e64277a71e6aaf84a994df00
|
data/.github/CODEOWNERS
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
* @guiocavalcanti
|
@@ -0,0 +1,18 @@
|
|
1
|
+
name: Ruby
|
2
|
+
|
3
|
+
on: [push,pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
build:
|
7
|
+
runs-on: ubuntu-latest
|
8
|
+
steps:
|
9
|
+
- uses: actions/checkout@v2
|
10
|
+
- name: Set up Ruby
|
11
|
+
uses: ruby/setup-ruby@v1
|
12
|
+
with:
|
13
|
+
ruby-version: 3.0.1
|
14
|
+
- name: Run the default task
|
15
|
+
run: |
|
16
|
+
gem install bundler -v 2.2.15
|
17
|
+
bundle install
|
18
|
+
bundle exec rake
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/CHANGELOG.md
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,68 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
incognia_api (0.1.0)
|
5
|
+
faraday
|
6
|
+
faraday_middleware
|
7
|
+
|
8
|
+
GEM
|
9
|
+
remote: https://rubygems.org/
|
10
|
+
specs:
|
11
|
+
addressable (2.8.0)
|
12
|
+
public_suffix (>= 2.0.2, < 5.0)
|
13
|
+
crack (0.4.5)
|
14
|
+
rexml
|
15
|
+
diff-lcs (1.4.4)
|
16
|
+
faraday (1.4.2)
|
17
|
+
faraday-em_http (~> 1.0)
|
18
|
+
faraday-em_synchrony (~> 1.0)
|
19
|
+
faraday-excon (~> 1.1)
|
20
|
+
faraday-net_http (~> 1.0)
|
21
|
+
faraday-net_http_persistent (~> 1.1)
|
22
|
+
multipart-post (>= 1.2, < 3)
|
23
|
+
ruby2_keywords (>= 0.0.4)
|
24
|
+
faraday-em_http (1.0.0)
|
25
|
+
faraday-em_synchrony (1.0.0)
|
26
|
+
faraday-excon (1.1.0)
|
27
|
+
faraday-net_http (1.0.1)
|
28
|
+
faraday-net_http_persistent (1.1.0)
|
29
|
+
faraday_middleware (1.0.0)
|
30
|
+
faraday (~> 1.0)
|
31
|
+
hashdiff (1.0.1)
|
32
|
+
multipart-post (2.1.1)
|
33
|
+
public_suffix (4.0.6)
|
34
|
+
rake (13.0.3)
|
35
|
+
rexml (3.2.5)
|
36
|
+
rspec (3.10.0)
|
37
|
+
rspec-core (~> 3.10.0)
|
38
|
+
rspec-expectations (~> 3.10.0)
|
39
|
+
rspec-mocks (~> 3.10.0)
|
40
|
+
rspec-core (3.10.1)
|
41
|
+
rspec-support (~> 3.10.0)
|
42
|
+
rspec-expectations (3.10.1)
|
43
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
44
|
+
rspec-support (~> 3.10.0)
|
45
|
+
rspec-mocks (3.10.2)
|
46
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
47
|
+
rspec-support (~> 3.10.0)
|
48
|
+
rspec-support (3.10.2)
|
49
|
+
ruby2_keywords (0.0.4)
|
50
|
+
timecop (0.9.4)
|
51
|
+
webmock (3.14.0)
|
52
|
+
addressable (>= 2.8.0)
|
53
|
+
crack (>= 0.3.2)
|
54
|
+
hashdiff (>= 0.4.0, < 2.0.0)
|
55
|
+
|
56
|
+
PLATFORMS
|
57
|
+
ruby
|
58
|
+
x86_64-darwin-20
|
59
|
+
|
60
|
+
DEPENDENCIES
|
61
|
+
incognia_api!
|
62
|
+
rake (~> 13.0)
|
63
|
+
rspec (~> 3.0)
|
64
|
+
timecop
|
65
|
+
webmock
|
66
|
+
|
67
|
+
BUNDLED WITH
|
68
|
+
2.3.7
|
data/README.md
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
# Incognia Ruby Library
|
2
|
+
|
3
|
+
[](https://github.com/inloco/incognia-ruby/actions/workflows/main.yml)
|
4
|
+
|
5
|
+
Incognia Ruby library provides easy access to the Incogia API from Ruby
|
6
|
+
applications. It includes:
|
7
|
+
|
8
|
+
- Basic Access Token management (with transparent token refresh)
|
9
|
+
- API resounces dinamically built from API responses
|
10
|
+
|
11
|
+
For more information on how to integrate Incognia APIs, refer to one of the
|
12
|
+
following guides:
|
13
|
+
|
14
|
+
- Address verification on user onboarding
|
15
|
+
- Protecting app logins
|
16
|
+
- Secure and frictionless device change
|
17
|
+
|
18
|
+
## Installation
|
19
|
+
|
20
|
+
Add this line to your application's Gemfile:
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
gem 'incognia_api'
|
24
|
+
```
|
25
|
+
|
26
|
+
And then execute:
|
27
|
+
|
28
|
+
$ bundle install
|
29
|
+
|
30
|
+
Or install it yourself as:
|
31
|
+
|
32
|
+
$ gem install incognia_api
|
33
|
+
|
34
|
+
## Usage
|
35
|
+
|
36
|
+
### Configuration
|
37
|
+
|
38
|
+
Before using the API client, you must initialize it using credentials obtained
|
39
|
+
from the [Incognia dashboard]():
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
api = Incognia::Api.new(client_id: "your-client-id", client_secret:
|
43
|
+
"your-client-secret")
|
44
|
+
|
45
|
+
```
|
46
|
+
|
47
|
+
For sandbox credentials, refer to the [API testing guide]().
|
48
|
+
|
49
|
+
|
50
|
+
### Registering a Signup
|
51
|
+
|
52
|
+
This method registers a new signup for the given installation and address, returning a signup assessment, containing the risk assessment and supporting evidence:
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
address = Incognia::Address.new(line: "West 34th Street, New York City, NY 10001")
|
56
|
+
installation_id = "WlMksW+jh5GPhqWBorsV8yDihoSHHpmt+DpjJ7eYxpHhuO/5tuHTuA..."
|
57
|
+
|
58
|
+
assessment = api.register_signup(
|
59
|
+
installation_id: installation_id,
|
60
|
+
address: address
|
61
|
+
)
|
62
|
+
|
63
|
+
# => #<OpenStruct id="...", request_id="...", device_id="...", risk_assessment="..", evidence=...>
|
64
|
+
|
65
|
+
```
|
66
|
+
|
67
|
+
### Getting a Signup
|
68
|
+
|
69
|
+
This method allows you to query the latest assessment for a given signup event, returning signup assessment, containing the risk assessment and supporting evidence:
|
70
|
+
|
71
|
+
```ruby
|
72
|
+
assessment = api.get_signup_assessment(signup_id: "95a9fc56-f65e-436b-a87f-a1338043678f")
|
73
|
+
|
74
|
+
# => #<OpenStruct id="...", request_id="...", device_id="...", risk_assessment="..", evidence=...>
|
75
|
+
|
76
|
+
```
|
77
|
+
|
78
|
+
## Exception handling
|
79
|
+
|
80
|
+
Every method call can throw `APIError` and `APIAuthenticationError`.
|
81
|
+
|
82
|
+
`APIError` is thrown when the API returned an unexpected http status code or if something goes wrong with the request (network failure, for example). You can retrieve it by calling the `status` method in the exception, along with the `errors` method, which returns the api response payload, which might include additional details. As any subclass of `StandardError` it also responds to `message`.
|
83
|
+
|
84
|
+
`APIAuthenticationError` indicates that the credentials used to authenticate were considered invalid by the API.
|
85
|
+
|
86
|
+
## How to Contribute
|
87
|
+
|
88
|
+
If you have found a bug or if you have a feature request, please report them at this repository issues section.
|
89
|
+
|
90
|
+
### Development
|
91
|
+
|
92
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
93
|
+
|
94
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
95
|
+
|
96
|
+
## License
|
97
|
+
|
98
|
+
The gem is available as open source under the terms of the [](https://opensource.org/licenses/MIT)
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/setup"
|
5
|
+
require "incognia"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require "irb"
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://incognia.inloco.com.br/api/v2/token
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers:
|
10
|
+
User-Agent:
|
11
|
+
- Faraday v1.4.2
|
12
|
+
Authorization:
|
13
|
+
- Basic R1BXSzFMQ1paSW8xRkxPQ0NuTExNcU44UWkxSHYzazQ6RUxHOV8yazU5T0hkMUdiVXhIaGRTdGtqZUI3TXlQZ21vRjhlR2YxM0xBMU1scmZRZ1Q1bkhFMmFIaVNobVc0WA==
|
14
|
+
Content-Type:
|
15
|
+
- application/x-www-form-urlencoded
|
16
|
+
response:
|
17
|
+
status:
|
18
|
+
code: 200
|
19
|
+
message: OK
|
20
|
+
headers:
|
21
|
+
date:
|
22
|
+
- Fri, 28 May 2021 18:35:32 GMT
|
23
|
+
content-type:
|
24
|
+
- application/json
|
25
|
+
transfer-encoding:
|
26
|
+
- chunked
|
27
|
+
connection:
|
28
|
+
- keep-alive
|
29
|
+
cf-cache-status:
|
30
|
+
- DYNAMIC
|
31
|
+
cf-request-id:
|
32
|
+
- 0a55dba85a0000db787b9d4000000001
|
33
|
+
expect-ct:
|
34
|
+
- max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
|
35
|
+
report-to:
|
36
|
+
- '{"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v2?s=TNlC7ygzRcV1NVUH05toX7rM1LCh0iEmsEwDAp%2Bmruqc6hMLyH%2Bb4cUreSYsSI96oTX%2FVfOnOzWPNZ5eYZwGww6giYqd97ZXMHfLpU7A%2BuiFoCyVeeqTCIRgsmZ1O787%2F2rN"}],"group":"cf-nel","max_age":604800}'
|
37
|
+
nel:
|
38
|
+
- '{"report_to":"cf-nel","max_age":604800}'
|
39
|
+
strict-transport-security:
|
40
|
+
- max-age=15552000; includeSubDomains; preload
|
41
|
+
x-content-type-options:
|
42
|
+
- nosniff
|
43
|
+
server:
|
44
|
+
- cloudflare
|
45
|
+
cf-ray:
|
46
|
+
- 65699553cdf2db78-GIG
|
47
|
+
alt-svc:
|
48
|
+
- h3-27=":443"; ma=86400, h3-28=":443"; ma=86400, h3-29=":443"; ma=86400
|
49
|
+
body:
|
50
|
+
encoding: ASCII-8BIT
|
51
|
+
string: '{"access_token":"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsImtpZCI6IlJFVkNPVGMwTkVaRk9EVTFNekUzTlVRMFEwSTNNekZDTVVFeE5ESkdSREJHUWpkQlFVSTVNUSJ9.eyJodHRwczovL2FjY291bnRzL29yZ2FuaXphdGlvbl9pZCI6IjQ5MSIsImlzcyI6Imh0dHBzOi8vaW5sb2NvLXByb2R1Y3Rpb24uYXV0aDAuY29tLyIsInN1YiI6IkdQV0sxTENaWklvMUZMT0NDbkxMTXFOOFFpMUh2M2s0QGNsaWVudHMiLCJhdWQiOiJodHRwczovL2luY29nbmlhLmlubG9jby5jb20uYnIiLCJpYXQiOjE2MjIyMjY5MzIsImV4cCI6MTYyMjIyODEzMiwiYXpwIjoiR1BXSzFMQ1paSW8xRkxPQ0NuTExNcU44UWkxSHYzazQiLCJndHkiOiJjbGllbnQtY3JlZGVudGlhbHMifQ.Csc3cJ4eqzqR4s-aLh5Qvdl41LrTyD2DnBe3iNv4gtwzAVqRD6rdTxZAfKzWwOdYZ91bw0o1aCVN7MA3fGj6dUqkgtylvCFdWVTU5xWlW6ugaZ6VMRuPmJkD0DkZuctjXkFl_Um9mw-_M-84CqSvrVqFHDK_AJrdymztcsc_aoFKVMDLFgn-gHBNT9TchLatePHFeRKa6S3IaevcR900DiAmeU4_BKvVYc_TlhS4iIJGwIXUNX4V2x-76CxSs6aFFJD3t76x1GehGdrjmxzis-ciWZrhflSWSFq_2M4kWFiCIiCgiFe0pln0JUG-u9Hm5yu5S3dPJ46Br3kg8MOZJQ","expires_in":"1200","token_type":"Bearer"}'
|
52
|
+
recorded_at: Fri, 28 May 2021 18:35:30 GMT
|
53
|
+
- request:
|
54
|
+
method: post
|
55
|
+
uri: https://incognia.inloco.com.br/api/onboarding/signups
|
56
|
+
body:
|
57
|
+
encoding: UTF-8
|
58
|
+
string: '{"installation_id":"xyz"}'
|
59
|
+
headers:
|
60
|
+
User-Agent:
|
61
|
+
- Faraday v1.4.2
|
62
|
+
Authorization:
|
63
|
+
- Bearer access_token
|
64
|
+
Content-Type:
|
65
|
+
- application/json
|
66
|
+
response:
|
67
|
+
status:
|
68
|
+
code: 401
|
69
|
+
message: Unauthorized
|
70
|
+
headers:
|
71
|
+
date:
|
72
|
+
- Fri, 28 May 2021 18:35:33 GMT
|
73
|
+
transfer-encoding:
|
74
|
+
- chunked
|
75
|
+
connection:
|
76
|
+
- keep-alive
|
77
|
+
cf-cache-status:
|
78
|
+
- DYNAMIC
|
79
|
+
cf-request-id:
|
80
|
+
- 0a55dbadde000009d0c5074000000001
|
81
|
+
expect-ct:
|
82
|
+
- max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
|
83
|
+
report-to:
|
84
|
+
- '{"endpoints":[{"url":"https:\/\/a.nel.cloudflare.com\/report\/v2?s=wRYcemb6TiPJlpWuANxj0o5Qq05jbH3gynAJX%2FNI8ErLVVffL65N7zUFJfOhFs1U9bUZqEUCkKOgJaD%2B%2FKYe%2FjeL4oPo%2FGyc3Ax1vvz4TCIOTEVMpRd%2FcCO1J11ulga8bve0"}],"group":"cf-nel","max_age":604800}'
|
85
|
+
nel:
|
86
|
+
- '{"report_to":"cf-nel","max_age":604800}'
|
87
|
+
strict-transport-security:
|
88
|
+
- max-age=15552000; includeSubDomains; preload
|
89
|
+
x-content-type-options:
|
90
|
+
- nosniff
|
91
|
+
server:
|
92
|
+
- cloudflare
|
93
|
+
cf-ray:
|
94
|
+
- 6569955c9fcd09d0-GIG
|
95
|
+
alt-svc:
|
96
|
+
- h3-27=":443"; ma=86400, h3-28=":443"; ma=86400, h3-29=":443"; ma=86400
|
97
|
+
body:
|
98
|
+
encoding: UTF-8
|
99
|
+
string: ''
|
100
|
+
recorded_at: Fri, 28 May 2021 18:35:31 GMT
|
101
|
+
recorded_with: VCR 6.0.0
|
data/incognia.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "lib/incognia/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = "incognia_api"
|
7
|
+
spec.version = Incognia::VERSION
|
8
|
+
spec.authors = ["Guilherme Cavalcanti"]
|
9
|
+
spec.email = ["guiocavalcanti@gmail.com"]
|
10
|
+
|
11
|
+
spec.summary = "Official Ruby lib for communicating with Incognia API"
|
12
|
+
spec.description = "Official Ruby lib for communicating with Incognia API"
|
13
|
+
spec.homepage = "https://github.com/inloco/incognia-api-ruby"
|
14
|
+
spec.required_ruby_version = Gem::Requirement.new(">= 2.4.0")
|
15
|
+
|
16
|
+
spec.metadata["homepage_uri"] = spec.homepage
|
17
|
+
spec.metadata["source_code_uri"] = "https://github.com/inloco/incognia-api-ruby"
|
18
|
+
spec.metadata["changelog_uri"] = "https://github.com/inloco/incognia-api-ruby/blob/master/"
|
19
|
+
|
20
|
+
# Specify which files should be added to the gem when it is released.
|
21
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
22
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
23
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{\A(?:test|spec|features)/}) }
|
24
|
+
end
|
25
|
+
spec.bindir = "exe"
|
26
|
+
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
|
27
|
+
spec.require_paths = ["lib"]
|
28
|
+
|
29
|
+
# Uncomment to register a new dependency of your gem
|
30
|
+
# spec.add_dependency "example-gem", "~> 1.0"
|
31
|
+
spec.add_dependency('faraday')
|
32
|
+
spec.add_dependency('faraday_middleware')
|
33
|
+
|
34
|
+
# For more information and examples about making a new gem, checkout our
|
35
|
+
# guide at: https://bundler.io/guides/creating_gem.html
|
36
|
+
end
|
@@ -0,0 +1,108 @@
|
|
1
|
+
require "ostruct"
|
2
|
+
|
3
|
+
module Incognia
|
4
|
+
class Address
|
5
|
+
attr_reader :line, :coordinates, :structured
|
6
|
+
|
7
|
+
class Line
|
8
|
+
def initialize(address)
|
9
|
+
@address = address
|
10
|
+
end
|
11
|
+
|
12
|
+
def to_hash
|
13
|
+
{ address_line: @address }
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Coordinates
|
18
|
+
def initialize(lat:, lng:)
|
19
|
+
@lat, @lng = lat, lng
|
20
|
+
end
|
21
|
+
|
22
|
+
def to_hash
|
23
|
+
{ address_coordinates: { lat: @lat, lng: @lng } }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class Structured
|
28
|
+
attr_reader :locale, :country_name, :country_code, :state, :city, :borough,
|
29
|
+
:neighborhood, :state, :city, :borough, :neighborhood, :postal_code,
|
30
|
+
:street, :number, :complements
|
31
|
+
|
32
|
+
def initialize(locale: nil, country_name: nil, country_code: nil, \
|
33
|
+
state: nil, city: nil, borough: nil, neighborhood: nil, \
|
34
|
+
postal_code: nil, street: nil, number: nil, complements: nil)
|
35
|
+
|
36
|
+
@locale = locale
|
37
|
+
@country_name = country_name
|
38
|
+
@country_code = country_code
|
39
|
+
@state = state
|
40
|
+
@city = city
|
41
|
+
@borough = borough
|
42
|
+
@neighborhood = neighborhood
|
43
|
+
@postal_code = postal_code
|
44
|
+
@street = street
|
45
|
+
@number = number
|
46
|
+
@complements = complements
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_hash
|
50
|
+
{
|
51
|
+
structured_address: {
|
52
|
+
locale: locale,
|
53
|
+
country_name: country_name,
|
54
|
+
country_code: country_code,
|
55
|
+
state: state,
|
56
|
+
city: city,
|
57
|
+
borough: borough,
|
58
|
+
neighborhood: neighborhood,
|
59
|
+
street: street,
|
60
|
+
number: number,
|
61
|
+
complements: complements,
|
62
|
+
postal_code: postal_code
|
63
|
+
}.select { |_,v| !v.nil? }
|
64
|
+
}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
FORMATS = [:line, :coordinates, :structured].freeze
|
69
|
+
|
70
|
+
def initialize(line: nil, coordinates: {}, structured: {})
|
71
|
+
coordinates = Util.symbolize_names(coordinates)
|
72
|
+
structured = Util.symbolize_names(structured)
|
73
|
+
|
74
|
+
if line.nil? && coordinates.empty? && structured.empty?
|
75
|
+
raise ArgumentError.new(
|
76
|
+
"missing keyword: should be one of #{FORMATS.join(', ')}"
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
80
|
+
@line = build_line(line)
|
81
|
+
@coordinates = build_coordinates(coordinates)
|
82
|
+
@structured = build_structured(structured)
|
83
|
+
end
|
84
|
+
|
85
|
+
def to_hash
|
86
|
+
hash = {}
|
87
|
+
hash.merge!(@line.to_hash)
|
88
|
+
hash.merge!(@coordinates.to_hash)
|
89
|
+
hash.merge!(@structured.to_hash)
|
90
|
+
hash
|
91
|
+
end
|
92
|
+
|
93
|
+
protected
|
94
|
+
|
95
|
+
def build_coordinates(hash)
|
96
|
+
hash.empty? ? hash : Coordinates.new(**hash)
|
97
|
+
end
|
98
|
+
|
99
|
+
def build_line(raw_line = nil)
|
100
|
+
raw_line ? Line.new(raw_line) : {}
|
101
|
+
end
|
102
|
+
|
103
|
+
def build_structured(hash)
|
104
|
+
hash.empty? ? hash : Structured.new(**hash)
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
end
|
data/lib/incognia/api.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
require "faraday"
|
2
|
+
require "json"
|
3
|
+
require "logger"
|
4
|
+
require 'faraday_middleware'
|
5
|
+
|
6
|
+
module Incognia
|
7
|
+
class Api
|
8
|
+
# business layer: uses the Client to build domain objects
|
9
|
+
# raises missing parameters errors
|
10
|
+
attr_accessor :connection
|
11
|
+
|
12
|
+
def initialize(client_id:, client_secret:)
|
13
|
+
@connection = Client.new(client_id: client_id,
|
14
|
+
client_secret: client_secret,
|
15
|
+
host: "https://api.incognia.com/api")
|
16
|
+
end
|
17
|
+
|
18
|
+
def register_signup(installation_id:, address: )
|
19
|
+
response = connection.request(
|
20
|
+
:post,
|
21
|
+
'v2/onboarding/signups',
|
22
|
+
installation_id: installation_id,
|
23
|
+
**address.to_hash
|
24
|
+
)
|
25
|
+
|
26
|
+
SignupAssessment.from_hash(response.body) if response.success?
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_signup_assessment(signup_id:)
|
30
|
+
response = connection.request(
|
31
|
+
:get,
|
32
|
+
"v2/onboarding/signups/#{signup_id}"
|
33
|
+
)
|
34
|
+
|
35
|
+
SignupAssessment.from_hash(response.body) if response.success?
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require "time"
|
2
|
+
|
3
|
+
module Incognia
|
4
|
+
class Client
|
5
|
+
# TODO:
|
6
|
+
# (ok) http/adapter specific code
|
7
|
+
# (ok) raises network/authentication errors
|
8
|
+
# (ok) handles token refreshing ok
|
9
|
+
# future: handles retrying
|
10
|
+
attr_reader :connection
|
11
|
+
|
12
|
+
def initialize(client_id:, client_secret:, host:)
|
13
|
+
@client_id = client_id
|
14
|
+
@client_secret = client_secret
|
15
|
+
@host = host
|
16
|
+
|
17
|
+
@connection = Faraday.new(host) do |faraday|
|
18
|
+
faraday.adapter Faraday.default_adapter
|
19
|
+
faraday.request :json
|
20
|
+
faraday.response :json, content_type: /\bjson$/
|
21
|
+
# faraday.response :logger, nil, { headers: true, bodies: true }
|
22
|
+
faraday.response :raise_error
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def request(method, endpoint = nil, data = nil, headers = {})
|
27
|
+
connection.send(method, endpoint, data, headers) do |r|
|
28
|
+
r.headers[Faraday::Request::Authorization::KEY] ||= Faraday::Request
|
29
|
+
.lookup_middleware(:authorization)
|
30
|
+
.header(:Bearer, credentials.access_token)
|
31
|
+
end
|
32
|
+
rescue Faraday::ClientError, Faraday::ServerError => e
|
33
|
+
raise APIError.new(e.to_s, e.response)
|
34
|
+
rescue Faraday::Error => e
|
35
|
+
raise APIError.new(e.to_s)
|
36
|
+
end
|
37
|
+
|
38
|
+
def credentials
|
39
|
+
@credentials = request_credentials if @credentials.nil? || @credentials.stale?
|
40
|
+
|
41
|
+
@credentials
|
42
|
+
end
|
43
|
+
|
44
|
+
protected
|
45
|
+
|
46
|
+
def request_credentials
|
47
|
+
basic_auth = Faraday::Request
|
48
|
+
.lookup_middleware(:basic_auth)
|
49
|
+
.header(@client_id, @client_secret)
|
50
|
+
|
51
|
+
response = connection.send(:post, 'v2/token') do |r|
|
52
|
+
r.headers[Faraday::Request::Authorization::KEY] = basic_auth
|
53
|
+
end
|
54
|
+
|
55
|
+
response.success? ? build_credentials(response) : nil
|
56
|
+
rescue Faraday::UnauthorizedError => e
|
57
|
+
raise APIAuthenticationError
|
58
|
+
rescue Faraday::Error => e
|
59
|
+
raise APIError.new(e.to_s)
|
60
|
+
end
|
61
|
+
|
62
|
+
def build_credentials(raw_response)
|
63
|
+
body = raw_response.body
|
64
|
+
response_date = raw_response.headers['Date']
|
65
|
+
|
66
|
+
properties = body.merge(
|
67
|
+
generated_at: response_date ? Time.parse(response_date) : Time.now
|
68
|
+
)
|
69
|
+
|
70
|
+
Credentials.from_hash(properties)
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Incognia
|
2
|
+
module Util
|
3
|
+
def self.symbolize_names(object)
|
4
|
+
case object
|
5
|
+
when Hash
|
6
|
+
new_hash = {}
|
7
|
+
object.each do |key, value|
|
8
|
+
key = (begin key.to_sym; rescue StandardError; key end) || key
|
9
|
+
new_hash[key] = symbolize_names(value)
|
10
|
+
end
|
11
|
+
new_hash
|
12
|
+
when Array
|
13
|
+
object.map { |value| symbolize_names(value) }
|
14
|
+
else
|
15
|
+
object
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/incognia.rb
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "incognia/version"
|
4
|
+
require_relative "incognia/client"
|
5
|
+
require_relative "incognia/util"
|
6
|
+
require_relative "incognia/address"
|
7
|
+
require_relative "incognia/api"
|
8
|
+
|
9
|
+
require_relative "incognia/resources/api_resource"
|
10
|
+
require_relative "incognia/resources/signup_assessment"
|
11
|
+
require_relative "incognia/resources/credentials"
|
12
|
+
|
13
|
+
module Incognia
|
14
|
+
class APIError < StandardError
|
15
|
+
attr_reader :message, :errors, :status
|
16
|
+
|
17
|
+
def initialize(message, response_info = {})
|
18
|
+
@status = response_info[:status]
|
19
|
+
@errors = response_info[:body]
|
20
|
+
@message = format_message(message)
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_s
|
24
|
+
message
|
25
|
+
end
|
26
|
+
|
27
|
+
def format_message(initial_message)
|
28
|
+
message = "[HTTP #{status}]: #{initial_message}"
|
29
|
+
message += "\n#{errors}" if errors
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class APIAuthenticationError < StandardError
|
34
|
+
def to_s
|
35
|
+
"Informed credentials failed"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
# Your code goes here...
|
39
|
+
end
|
metadata
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: incognia_api
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Guilherme Cavalcanti
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2022-04-22 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: faraday
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: faraday_middleware
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: Official Ruby lib for communicating with Incognia API
|
42
|
+
email:
|
43
|
+
- guiocavalcanti@gmail.com
|
44
|
+
executables: []
|
45
|
+
extensions: []
|
46
|
+
extra_rdoc_files: []
|
47
|
+
files:
|
48
|
+
- ".github/CODEOWNERS"
|
49
|
+
- ".github/workflows/main.yml"
|
50
|
+
- ".gitignore"
|
51
|
+
- ".rspec"
|
52
|
+
- CHANGELOG.md
|
53
|
+
- Gemfile
|
54
|
+
- Gemfile.lock
|
55
|
+
- README.md
|
56
|
+
- Rakefile
|
57
|
+
- bin/console
|
58
|
+
- bin/setup
|
59
|
+
- fixtures/vcr_cassettes/token.yml
|
60
|
+
- incognia.gemspec
|
61
|
+
- lib/incognia.rb
|
62
|
+
- lib/incognia/address.rb
|
63
|
+
- lib/incognia/api.rb
|
64
|
+
- lib/incognia/client.rb
|
65
|
+
- lib/incognia/resources/api_resource.rb
|
66
|
+
- lib/incognia/resources/credentials.rb
|
67
|
+
- lib/incognia/resources/signup_assessment.rb
|
68
|
+
- lib/incognia/util.rb
|
69
|
+
- lib/incognia/version.rb
|
70
|
+
homepage: https://github.com/inloco/incognia-api-ruby
|
71
|
+
licenses: []
|
72
|
+
metadata:
|
73
|
+
homepage_uri: https://github.com/inloco/incognia-api-ruby
|
74
|
+
source_code_uri: https://github.com/inloco/incognia-api-ruby
|
75
|
+
changelog_uri: https://github.com/inloco/incognia-api-ruby/blob/master/
|
76
|
+
post_install_message:
|
77
|
+
rdoc_options: []
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: 2.4.0
|
85
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
requirements: []
|
91
|
+
rubygems_version: 3.2.3
|
92
|
+
signing_key:
|
93
|
+
specification_version: 4
|
94
|
+
summary: Official Ruby lib for communicating with Incognia API
|
95
|
+
test_files: []
|