incognia_api 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Ruby](https://github.com/inloco/incognia-ruby/actions/workflows/main.yml/badge.svg)](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 [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](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: []
|