| Age | Commit message (Collapse) | Author |
|
License the software with the GNU AGPLv3+ with the exception of the
'aquatic-prime' and 'paddle' libraries and 'aquatic-prime' binary, which
are licensed under the GNU GPLv3+.
|
|
Make it easier on users by not requiring them to pass a signature into
the method. This means they don't have to extract the `p_signature`
param and base64 decode it themselves.
Essentially, we want to move the code from `request` that removes the
`p_signature` key and base64 decodes it into the
`paddle::verify_signature()` function.
We need to make the string-like type params in `verify_signature()`
conform additionally to `PartialEq<str>` and `PartialOrd`. Doing so
allows us to find the key "p_signature".
To remove the `p_signature` param from the iterator, we partition it
into two iterators: one for the `p_signature` entry, and another for the
rest. We then extract the value of `p_signature` and base64 decode it
for verification.
Add a new error type in case no `p_signature` entry is found in the
iterator.
|
|
I think I was doing it in the wrong direction. Previously, I had added
the signature from the POST param to the verifier, and verified against
the serialized params.
Seems like I was instead supposed to add the serialized params to the
verifier, and verify against the input signature.
It works correctly now against a request from Paddle.
|
|
In the POST param, the signature is a base64 string, but when we verify
it, it needs to be decoded to bytes.
|
|
Return a `Result` from the function to pass errors through.
|
|
Use `AsRef<str>` instead of `&str` to offer a more flexible interface.
We need this because `url::form_urlencoded::parse()` gives us an
iterator of `(Cow<_, str>, Cow<_, str>)`, and we want to pass that into
`verify_signature()`.
Also change `key.len()` and `value.len()` to `.chars().count()` because
I was having a hard time getting the `len()` method from a trait (`str`
doesn't implement `ExactSizeIterator`), and I learned this:
> This length is in bytes, not chars or graphemes. In other words, it
> may not be what a human considers the length of the string.
(https://doc.rust-lang.org/std/primitive.str.html#method.len)
Also:
https://stackoverflow.com/questions/46290655/get-the-string-length-in-characters-in-rust/46290728#46290728
I assume the PHP serializer uses character count instead of byte length.
|
|
In order to properly verify the signature, dictionary entries must be
serialized in sorted order. Seems simpler to put the onus on the caller
to ensure the entries can be sorted rather than having to deal with that
myself.
|
|
Hoping this is how to set up the verifier to verify the signature.
|
|
Not sure if this works yet as I haven't tested it, but it follows most
of the examples in various languages on:
https://paddle.com/docs/reference-verifying-webhooks/
Just need to add in the comparison to the input signature.
|
|
Replace the `ExactSizeIterator` with an `IntoIterator`, as I wasn't able
to pass in a `HashMap` with `ExactSizeIterator`.
While we lose the convenience of the `len()` method, it's easy enough to
just count the length of the iterator while we're serializing the
entries within it.
|
|
The expected value was generated with the following PHP code, some of
which was reproduced from the PHP example on
https://paddle.com/docs/reference-verifying-webhooks/ :
<?php
$fields = array(
'checkout_id' => '1234asdfjkl',
'currency' => 'USD',
'customer_name' => 'Senjougahara',
);
ksort($fields);
foreach($fields as $k => $v) {
if(!in_array(gettype($v), array('object', 'array'))) {
$fields[$k] = "$v";
}
}
$data = serialize($fields);
echo "Data: ", $data;
|
|
Should verify a Paddle webhook. This ensures that the request really
does come from Paddle.
In order to verify the request, we need to sign the serialized POST
parameters. And, weirdly, Paddle requires you to serialize parameters in
PHP's serialization format.
Using this Gist by 'drewmccormack' as a reference for the format:
https://gist.github.com/drewmccormack/a51b18ffeda8f596a11a8623481344d8
|