19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
|
# File 'lib/mpp/server/verify.rb', line 19
def verify_or_challenge(authorization:, intent:, request:, realm:, secret_key:,
method: nil, description: nil, meta: nil, expires: nil)
method_name = method || "tempo"
request = Mpp::Units.transform_units(request)
new_challenge = Kernel.lambda {
create_challenge(method_name, intent.name, request, realm, secret_key, description, meta, expires)
}
return new_challenge.call if authorization.nil?
payment_scheme = (authorization)
return new_challenge.call if payment_scheme.nil?
begin
credential = Mpp::Credential.from_authorization(payment_scheme)
rescue Mpp::ParseError
return new_challenge.call
end
echo = credential.challenge
begin
echo_request = echo.request.empty? ? {} : Mpp::Parsing.b64_decode(echo.request)
echo_opaque = (echo.opaque && !T.must(echo.opaque).empty?) ? Mpp::Parsing.b64_decode(echo.opaque) : nil
rescue Mpp::ParseError
return new_challenge.call
end
expected_id = Mpp.generate_challenge_id(
secret_key: secret_key,
realm: echo.realm,
method: echo.method,
intent: echo.intent,
request: echo_request,
expires: echo.expires,
digest: echo.digest,
opaque: echo_opaque
)
return new_challenge.call unless Mpp.secure_compare(echo.id, expected_id)
return new_challenge.call unless echo.realm == realm && echo.method == method_name && echo.intent == intent.name
return new_challenge.call unless echo_request == request
return new_challenge.call unless echo_opaque == meta
if echo.expires
begin
expires_dt = Time.iso8601(T.must(echo.expires).gsub("Z", "+00:00"))
return new_challenge.call if expires_dt < Time.now.utc
rescue ArgumentError
end
end
request.each do |key, value|
return new_challenge.call unless echo_request[key] == value
end
return new_challenge.call unless echo.expires
begin
expires_dt = Time.iso8601(T.must(echo.expires).gsub("Z", "+00:00"))
rescue ArgumentError
return new_challenge.call
end
return new_challenge.call if expires_dt < Time.now.utc
receipt = intent.verify(credential, request)
[credential, receipt]
end
|