-
Notifications
You must be signed in to change notification settings - Fork 105
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Network API: SIM Swap and Number Verification implementation (#313)
Implementing Network SIM Swap and Number Verification APIs
- Loading branch information
1 parent
a488667
commit 9327396
Showing
23 changed files
with
830 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# typed: true | ||
# frozen_string_literal: true | ||
|
||
module Vonage | ||
class NetworkAuthentication < AbstractAuthentication | ||
def update(object, data) | ||
return unless object.is_a?(Net::HTTPRequest) | ||
|
||
token = self.public_send(data[:auth_flow]).token(**data) | ||
|
||
object['Authorization'] = 'Bearer ' + token | ||
end | ||
|
||
def client_authentication | ||
@client_authentication ||= ClientAuthentication.new(@config) | ||
end | ||
|
||
def server_authentication | ||
@server_authentication ||= ServerAuthentication.new(@config) | ||
end | ||
end | ||
end |
39 changes: 39 additions & 0 deletions
39
lib/vonage/network_authentication/client_authentication.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
# typed: true | ||
# frozen_string_literal: true | ||
|
||
module Vonage | ||
class NetworkAuthentication::ClientAuthentication < Namespace | ||
extend T::Sig | ||
|
||
self.authentication = BearerToken | ||
|
||
self.host = :vonage_host | ||
|
||
self.request_headers['Content-Type'] = 'application/x-www-form-urlencoded' | ||
|
||
def token(oidc_auth_code:, redirect_uri:, **params) | ||
request( | ||
'/oauth2/token', | ||
params: { | ||
grant_type: 'authorization_code', | ||
code: oidc_auth_code, | ||
redirect_uri: redirect_uri | ||
}, | ||
type: Post | ||
).access_token | ||
end | ||
|
||
def generate_oidc_uri(purpose:, api_scope:, login_hint:, redirect_uri:, state:) | ||
scope = "openid%20dpv:#{purpose}%23#{api_scope}" | ||
uri = "https://oidc.idp.vonage.com/oauth2/auth?" + | ||
"client_id=#{@config.application_id}" + | ||
"&response_type=code" + | ||
"&scope=#{scope}" + | ||
"&login_hint=#{login_hint}" + | ||
"&redirect_uri=#{redirect_uri}" + | ||
"&state=#{state}" | ||
|
||
uri | ||
end | ||
end | ||
end |
47 changes: 47 additions & 0 deletions
47
lib/vonage/network_authentication/server_authentication.rb
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# typed: true | ||
# frozen_string_literal: true | ||
|
||
module Vonage | ||
class NetworkAuthentication::ServerAuthentication < Namespace | ||
extend T::Sig | ||
|
||
self.authentication = BearerToken | ||
|
||
self.host = :vonage_host | ||
|
||
self.request_headers['Content-Type'] = 'application/x-www-form-urlencoded' | ||
|
||
def token(purpose:, api_scope:, login_hint:, **params) | ||
auth_req_id = bc_authorize( | ||
purpose: purpose, | ||
api_scope: api_scope, | ||
login_hint: login_hint | ||
).auth_req_id | ||
|
||
request_access_token(auth_req_id: auth_req_id).access_token | ||
end | ||
|
||
def bc_authorize(purpose:, api_scope:, login_hint:) | ||
scope = "openid dpv:#{purpose}##{api_scope}" | ||
request( | ||
"/oauth2/bc-authorize", | ||
params: { | ||
scope: scope, | ||
login_hint: login_hint | ||
}, | ||
type: Post | ||
) | ||
end | ||
|
||
def request_access_token(auth_req_id:) | ||
request( | ||
"/oauth2/token", | ||
params: { | ||
grant_type: 'urn:openid:params:grant-type:ciba', | ||
auth_req_id: auth_req_id | ||
}, | ||
type: Post | ||
) | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
# typed: strict | ||
# frozen_string_literal: true | ||
require 'phonelib' | ||
|
||
module Vonage | ||
class NetworkNumberVerification < Namespace | ||
extend T::Sig | ||
include Keys | ||
|
||
self.authentication = NetworkAuthentication | ||
|
||
self.host = :vonage_host | ||
|
||
self.request_body = JSON | ||
|
||
# Verifies if the specified phone number (plain text or hashed format) matches the one that the user is currently using. | ||
# | ||
# @example | ||
# response = client.network_number_verification.verify( | ||
# phone_number: '+447900000000', | ||
# auth_data: { | ||
# oidc_auth_code: '0dadaeb4-7c79-4d39-b4b0-5a6cc08bf537', | ||
# redirect_uri: 'https://example.com/callback' | ||
# } | ||
# ) | ||
# | ||
# @param [required, String] :phone_number The phone number to check, in the E.164 format, prepended with a `+`. | ||
# | ||
# @param [required, Hash] :auth_data A hash of authentication data required for the client token request. Must contain the following keys: | ||
# @option auth_data [required, String] :oidc_auth_code The OIDC auth code. | ||
# @option auth_data [required, String] :redirect_uri The redirect URI. | ||
# @see https://developer.vonage.com/en/getting-started-network/authentication#client-authentication-flow | ||
# | ||
# @return [Response] | ||
# | ||
# @see https://developer.vonage.com/en/api/camara/number-verification#verifyNumberVerification | ||
# | ||
sig { params(phone_number: String, auth_data: Hash).returns(Vonage::Response) } | ||
def verify(phone_number:, auth_data:) | ||
raise ArgumentError.new("`phone_number` must be in E.164 format") unless Phonelib.parse(phone_number).valid? | ||
raise ArgumentError.new("`phone_number` must be prepended with a `+`") unless phone_number.start_with?('+') | ||
raise ArgumentError.new("`auth_data` must contain key `:oidc_auth_code`") unless auth_data.has_key?(:oidc_auth_code) | ||
raise ArgumentError.new("`auth_data[:oidc_auth_code]` must be a String") unless auth_data[:oidc_auth_code].is_a?(String) | ||
raise ArgumentError.new("`auth_data` must contain key `:redirect_uri`") unless auth_data.has_key?(:redirect_uri) | ||
raise ArgumentError.new("`auth_data[:redirect_uri]` must be a String") unless auth_data[:redirect_uri].is_a?(String) | ||
|
||
params = {phone_number: phone_number} | ||
|
||
request( | ||
'/camara/number-verification/v031/verify', | ||
params: camelcase(params), | ||
type: Post, | ||
auth_data: { | ||
oidc_auth_code: auth_data[:oidc_auth_code], | ||
redirect_uri: auth_data[:redirect_uri], | ||
auth_flow: :client_authentication | ||
} | ||
) | ||
end | ||
|
||
# Creates a URL for a client-side OIDC request. | ||
# | ||
# @example | ||
# response = client.network_number_verification.generate_oidc_uri( | ||
# phone_number: '+447900000000', | ||
# redirect_uri: 'https://example.com/callback' | ||
# ) | ||
# | ||
# @param [required, String] :phone_number The phone number that will be checked during the verification request. | ||
# | ||
# @param [required, String] :redirect_uri The URI that will receive the callback containing the OIDC auth code. | ||
# | ||
# @param [required, String] :state A string that you can use for tracking. | ||
# Used to set a unique identifier for each access token you generate. | ||
# | ||
# @return [String] | ||
# | ||
# @see https://developer.vonage.com/en/getting-started-network/authentication#1-make-an-oidc-request | ||
sig { params(phone_number: String, redirect_uri: String, state: String).returns(String) } | ||
def generate_oidc_uri(phone_number:, redirect_uri:, state:) | ||
params = { | ||
purpose: 'FraudPreventionAndDetection', | ||
api_scope: 'number-verification-verify-read', | ||
login_hint: phone_number, | ||
redirect_uri: redirect_uri, | ||
state: state | ||
} | ||
|
||
Vonage::NetworkAuthentication::ClientAuthentication.new(@config).generate_oidc_uri(**params) | ||
end | ||
end | ||
end |
Oops, something went wrong.