Skip to content
Open
421 changes: 360 additions & 61 deletions MLE.md

Large diffs are not rendered by default.

8 changes: 6 additions & 2 deletions generator/cybersource-ruby-template/api.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -180,18 +180,22 @@ module {{moduleName}}
sdk_tracker = SdkTracker.new
post_body = sdk_tracker.insert_developer_id_tracker(post_body, '{{dataType}}', @api_client.config.host, @api_client.merchantconfig.defaultDeveloperId)
{{/bodyParam}}
inbound_mle_status = "{{#vendorExtensions.x-devcenter-metaData.mleForRequest}}{{vendorExtensions.x-devcenter-metaData.mleForRequest}}{{/vendorExtensions.x-devcenter-metaData.mleForRequest}}{{^vendorExtensions.x-devcenter-metaData.mleForRequest}}false{{/vendorExtensions.x-devcenter-metaData.mleForRequest}}"
inbound_mle_status = "{{#vendorExtensions.x-devcenter-metaData.mleForRequest}}{{vendorExtensions.x-devcenter-metaData.mleForRequest}}{{/vendorExtensions.x-devcenter-metaData.mleForRequest}}{{^vendorExtensions.x-devcenter-metaData.mleForRequest}}false{{/vendorExtensions.x-devcenter-metaData.mleForRequest}}"
if MLEUtility.check_is_mle_for_API(@api_client.merchantconfig, inbound_mle_status, ["{{operationId}}","{{operationId}}_with_http_info"])
post_body = MLEUtility.encrypt_request_payload(@api_client.merchantconfig, post_body)
end

is_response_mle_for_api = MLEUtility.check_is_response_mle_for_api(@api_client.merchantconfig, ["{{operationId}}","{{operationId}}_with_http_info"])

auth_names = [{{#authMethods}}'{{name}}'{{#hasMore}}, {{/hasMore}}{{/authMethods}}]
data, status_code, headers = @api_client.call_api(:{{httpMethod}}, local_var_path,
:header_params => header_params,
:query_params => query_params,
:form_params => form_params,
:body => post_body,
:auth_names => auth_names{{#returnType}},
:return_type => '{{{returnType}}}'{{/returnType}})
:return_type => '{{{returnType}}}'{{/returnType}},
:isResponseMLEForApi => is_response_mle_for_api)
if @api_client.config.debugging
begin
raise
Expand Down
23 changes: 20 additions & 3 deletions generator/cybersource-ruby-template/api_client.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,19 @@ module {{moduleName}}
end
end

# Check the response body first if it is mle encrypted then do deserialize
if MLEUtility.check_is_mle_encrypted_response(response.body)
begin
body = MLEUtility.decrypt_mle_response_payload(@merchantconfig, response.body)
response = Typhoeus::Response.new(:code => response.code, :headers => response.headers.to_hash, :body => body)
rescue => e
raise ApiError.new(:message => "MLE Encrypted Response Decryption Error Occurred. Error: #{e.message}",
:code => response.code,
:response_headers => response.headers,
:body => response.body)
end
end

if opts[:return_type]
data = deserialize(response, opts[:return_type])
else
Expand All @@ -110,9 +123,11 @@ module {{moduleName}}
query_params = Addressable::URI.form_encode(query_params)
end

isResponseMLEForApi = opts[:isResponseMLEForApi] || false

headers = opts[:header_params]
if @merchantconfig.authenticationType.upcase != Constants::AUTH_TYPE_MUTUAL_AUTH
headers = CallAuthenticationHeader(http_method, path, body_params, headers, query_params)
headers = CallAuthenticationHeader(http_method, path, body_params, headers, query_params, isResponseMLEForApi)
end
http_method = http_method.to_sym.downcase
header_params = headers.merge(@default_headers)
Expand Down Expand Up @@ -184,7 +199,7 @@ module {{moduleName}}
end
end
# Calling Authentication
def CallAuthenticationHeader(http_method, path, body_params, header_params, query_params)
def CallAuthenticationHeader(http_method, path, body_params, header_params, query_params, isResponseMLEForApi)
require_relative '../AuthenticationSDK/core/Authorization.rb'
require_relative '../AuthenticationSDK/authentication/payloadDigest/digest.rb'
request_target = get_query_param(path, query_params)
Expand All @@ -203,7 +218,7 @@ module {{moduleName}}
@merchantconfig.requestUrl = url
# Calling APISDK, Apisdk.controller.
gmtDateTime = DateTime.now.httpdate
token = Authorization.new.getToken(@merchantconfig, gmtDateTime)
token = Authorization.new.getToken(@merchantconfig, gmtDateTime, isResponseMLEForApi)

# Adding client ID header
header_params['v-c-client-id'] = @client_id
Expand Down Expand Up @@ -263,6 +278,8 @@ module {{moduleName}}
# @param [Response] response HTTP response
# @param [String] return_type some examples: "User", "Array[User]", "Hash[String,Integer]"
def deserialize(response, return_type)
require_relative '../AuthenticationSDK/util/MLEUtility.rb'

body = response.body

# handle file downloading - return the File instance processed in request callbacks
Expand Down
20 changes: 14 additions & 6 deletions lib/AuthenticationSDK/authentication/jwt/JwtToken.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,19 @@ class GenerateJwtToken
@log_obj

#JWT Token-generated based on the Request type
def getToken(merchantconfig_obj,gmtDatetime)
def getToken(merchantconfig_obj, gmtDatetime, isResponseMLEForApi)
@log_obj = Log.new merchantconfig_obj.log_config, "JwtToken"

jwtBody = ''
request_type = merchantconfig_obj.requestType.upcase

jwtBody=getJwtBody(request_type, gmtDatetime, merchantconfig_obj)
jwtBody = getJwtBody(request_type, gmtDatetime, merchantconfig_obj, isResponseMLEForApi)
claimSet = JSON.parse(jwtBody)

cache_value = Cache.new.fetchCachedP12Certificate(merchantconfig_obj)
privateKey = cache_value.private_key
jwt_cert_obj = cache_value.cert
jwt_cert_in_der= Base64.strict_encode64(jwt_cert_obj.to_der)
jwt_cert_in_der = Base64.strict_encode64(jwt_cert_obj.to_der)


# JWT token-Generates using RS256 algorithm only
Expand All @@ -51,18 +51,26 @@ def getToken(merchantconfig_obj,gmtDatetime)
raise err
end

def getJwtBody(request_type, gmtDatetime, merchantconfig_obj)
def getJwtBody(request_type, gmtDatetime, merchantconfig_obj, isResponseMLEForApi=false)
jwtBody = "{\n "

if request_type == Constants::POST_REQUEST_TYPE || request_type == Constants::PUT_REQUEST_TYPE || request_type == Constants::PATCH_REQUEST_TYPE
payload = merchantconfig_obj.requestJsonData

# Note: Digest is not passed for GET calls
digest = DigestGeneration.new.generateDigest(payload)
jwtBody = "{\n \"digest\":\"" + digest + "\", \"digestAlgorithm\":\"SHA-256\", \"iat\":" + Time.parse(gmtDatetime).to_i.to_s + "}"
jwtBody = jwtBody + "\"digest\":\"" + digest + "\", \"digestAlgorithm\":\"SHA-256\", \"iat\":" + Time.parse(gmtDatetime).to_i.to_s
elsif request_type == Constants::GET_REQUEST_TYPE || request_type == Constants::DELETE_REQUEST_TYPE
jwtBody = "{\n \"iat\":" + Time.parse(gmtDatetime).to_i.to_s + "\n} \n\n"
jwtBody = jwtBody + "\"iat\":" + Time.parse(gmtDatetime).to_i.to_s
else
raise StandardError.new(Constants::ERROR_PREFIX + Constants::INVALID_REQUEST_TYPE_METHOD)
end

if isResponseMLEForApi
jwtBody = jwtBody + ", \"v-c-response-mle-kid\":\"" + merchantconfig_obj.responseMleKID + "\""
end

jwtBody = jwtBody + "\n}"
end
implements TokenInterface
end
4 changes: 2 additions & 2 deletions lib/AuthenticationSDK/core/Authorization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
# This function calls for the generation of Signature message depending on the authentication type.
class Authorization
@log_obj
def getToken(merchantconfig_obj, gmtdatetime)
def getToken(merchantconfig_obj, gmtdatetime, isResponseMLEForApi)
@log_obj = Log.new merchantconfig_obj.log_config, "Authorization"

authenticationType = merchantconfig_obj.authenticationType.upcase
Expand All @@ -21,7 +21,7 @@ def getToken(merchantconfig_obj, gmtdatetime)
if authenticationType == Constants::AUTH_TYPE_HTTP
token = GenerateHttpSignature.new.getToken(merchantconfig_obj, gmtdatetime)
elsif authenticationType == Constants::AUTH_TYPE_JWT
token = GenerateJwtToken.new.getToken(merchantconfig_obj, gmtdatetime)
token = GenerateJwtToken.new.getToken(merchantconfig_obj, gmtdatetime, isResponseMLEForApi)
elsif authenticationType == Constants::AUTH_TYPE_OAUTH
token = GenerateOAuthToken.new.getToken(merchantconfig_obj, gmtdatetime)
else
Expand Down
Loading