Skip to content

Commit

Permalink
Fix #17901 - Claim endpoint for gemini needs a deposit address
Browse files Browse the repository at this point in the history
  • Loading branch information
jumde committed Jul 23, 2021
1 parent 70186e2 commit a4be47a
Show file tree
Hide file tree
Showing 16 changed files with 419 additions and 53 deletions.
2 changes: 2 additions & 0 deletions vendor/bat-native-ledger/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,8 @@ source_set("ledger") {
"src/bat/ledger/internal/endpoint/gemini/post_balance/post_balance_gemini.h",
"src/bat/ledger/internal/endpoint/gemini/post_oauth/post_oauth_gemini.cc",
"src/bat/ledger/internal/endpoint/gemini/post_oauth/post_oauth_gemini.h",
"src/bat/ledger/internal/endpoint/gemini/post_recipient_id/post_recipient_id_gemini.cc",
"src/bat/ledger/internal/endpoint/gemini/post_recipient_id/post_recipient_id_gemini.h",
"src/bat/ledger/internal/endpoint/gemini/post_transaction/post_transaction_gemini.cc",
"src/bat/ledger/internal/endpoint/gemini/post_transaction/post_transaction_gemini.h",
"src/bat/ledger/internal/endpoint/payment/get_credentials/get_credentials.cc",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ GeminiServer::GeminiServer(LedgerImpl* ledger)
: post_account_(std::make_unique<gemini::PostAccount>(ledger)),
post_balance_(std::make_unique<gemini::PostBalance>(ledger)),
post_oauth_(std::make_unique<gemini::PostOauth>(ledger)),
post_recipient_id_(std::make_unique<gemini::PostRecipientId>(ledger)),
post_transaction_(std::make_unique<gemini::PostTransaction>(ledger)) {}

GeminiServer::~GeminiServer() = default;
Expand All @@ -30,6 +31,10 @@ gemini::PostOauth* GeminiServer::post_oauth() const {
return post_oauth_.get();
}

gemini::PostRecipientId* GeminiServer::post_recipient_id() const {
return post_recipient_id_.get();
}

gemini::PostTransaction* GeminiServer::post_transaction() const {
return post_transaction_.get();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include "bat/ledger/internal/endpoint/gemini/post_account/post_account_gemini.h"
#include "bat/ledger/internal/endpoint/gemini/post_balance/post_balance_gemini.h"
#include "bat/ledger/internal/endpoint/gemini/post_oauth/post_oauth_gemini.h"
#include "bat/ledger/internal/endpoint/gemini/post_recipient_id/post_recipient_id_gemini.h"
#include "bat/ledger/internal/endpoint/gemini/post_transaction/post_transaction_gemini.h"
#include "bat/ledger/ledger.h"

Expand All @@ -30,12 +31,15 @@ class GeminiServer {

gemini::PostOauth* post_oauth() const;

gemini::PostRecipientId* post_recipient_id() const;

gemini::PostTransaction* post_transaction() const;

private:
std::unique_ptr<gemini::PostAccount> post_account_;
std::unique_ptr<gemini::PostBalance> post_balance_;
std::unique_ptr<gemini::PostOauth> post_oauth_;
std::unique_ptr<gemini::PostRecipientId> post_recipient_id_;
std::unique_ptr<gemini::PostTransaction> post_transaction_;
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,9 @@ std::string PostAccount::GetUrl() {
}

type::Result PostAccount::ParseBody(const std::string& body,
std::string* address,
std::string* linking_info,
std::string* user_name,
bool* verified) {
DCHECK(address);
DCHECK(linking_info);
DCHECK(user_name);
DCHECK(verified);
Expand All @@ -59,12 +57,6 @@ type::Result PostAccount::ParseBody(const std::string& body,
return type::Result::LEDGER_ERROR;
}

const auto* account_name = account->FindStringKey("accountName");
if (!account_name) {
BLOG(0, "Missing account name");
return type::Result::LEDGER_ERROR;
}

const auto* linking_information = account->FindStringKey("verificationToken");
if (!linking_info) {
BLOG(0, "Missing linking info");
Expand Down Expand Up @@ -95,7 +87,6 @@ type::Result PostAccount::ParseBody(const std::string& body,
return type::Result::LEDGER_ERROR;
}

*address = *account_name;
*linking_info = *linking_information;
*user_name = *name;
*verified = *is_verified;
Expand All @@ -120,18 +111,16 @@ void PostAccount::OnRequest(const type::UrlResponse& response,
type::Result result = CheckStatusCode(response.status_code);

if (result != type::Result::LEDGER_OK) {
callback(result, "", "", "", false);
callback(result, "", "", false);
return;
}

std::string linking_info;
std::string address;
std::string user_name;
bool verified;

result =
ParseBody(response.body, &address, &linking_info, &user_name, &verified);
callback(result, address, linking_info, user_name, verified);
result = ParseBody(response.body, &linking_info, &user_name, &verified);
callback(result, linking_info, user_name, verified);
}

} // namespace gemini
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ namespace endpoint {
namespace gemini {

using PostAccountCallback = std::function<void(const type::Result result,
const std::string address,
const std::string linking_info,
const std::string user_name,
const bool verified)>;
Expand All @@ -60,7 +59,6 @@ class PostAccount {
std::string GetUrl();

type::Result ParseBody(const std::string& body,
std::string* address,
std::string* linking_info,
std::string* user_name,
bool* verified);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,9 @@ TEST_F(GeminiPostAccountTest, ServerOK) {

post_account_->Request(
"4c2b665ca060d912fec5c735c734859a06118cc8",
[](const type::Result result, const std::string& address,
const std::string& linking_info, const std::string& user_name,
const bool verified) {
[](const type::Result result, const std::string& linking_info,
const std::string& user_name, const bool verified) {
EXPECT_EQ(result, type::Result::LEDGER_OK);
EXPECT_EQ(address, "Primary");
EXPECT_EQ(linking_info, "mocktoken");
EXPECT_EQ(user_name, "Test");
EXPECT_TRUE(verified);
Expand All @@ -93,11 +91,9 @@ TEST_F(GeminiPostAccountTest, ServerError401) {

post_account_->Request(
"4c2b665ca060d912fec5c735c734859a06118cc8",
[](const type::Result result, const std::string& address,
const std::string& linking_info, const std::string& user_name,
const bool verified) {
[](const type::Result result, const std::string& linking_info,
const std::string& user_name, const bool verified) {
EXPECT_EQ(result, type::Result::EXPIRED_TOKEN);
EXPECT_EQ(address, "");
EXPECT_EQ(linking_info, "");
EXPECT_EQ(user_name, "");
EXPECT_FALSE(verified);
Expand All @@ -117,11 +113,9 @@ TEST_F(GeminiPostAccountTest, ServerError403) {

post_account_->Request(
"4c2b665ca060d912fec5c735c734859a06118cc8",
[](const type::Result result, const std::string& address,
const std::string& linking_info, const std::string& user_name,
const bool verified) {
[](const type::Result result, const std::string& linking_info,
const std::string& user_name, const bool verified) {
EXPECT_EQ(result, type::Result::EXPIRED_TOKEN);
EXPECT_EQ(address, "");
EXPECT_EQ(linking_info, "");
EXPECT_EQ(user_name, "");
EXPECT_FALSE(verified);
Expand All @@ -141,11 +135,9 @@ TEST_F(GeminiPostAccountTest, ServerError404) {

post_account_->Request(
"4c2b665ca060d912fec5c735c734859a06118cc8",
[](const type::Result result, const std::string& address,
const std::string& linking_info, const std::string& user_name,
const bool verified) {
[](const type::Result result, const std::string& linking_info,
const std::string& user_name, const bool verified) {
EXPECT_EQ(result, type::Result::NOT_FOUND);
EXPECT_EQ(address, "");
EXPECT_EQ(linking_info, "");
EXPECT_EQ(user_name, "");
EXPECT_FALSE(verified);
Expand All @@ -165,11 +157,9 @@ TEST_F(GeminiPostAccountTest, ServerErrorRandom) {

post_account_->Request(
"4c2b665ca060d912fec5c735c734859a06118cc8",
[](const type::Result result, const std::string& address,
const std::string& linking_info, const std::string& user_name,
const bool verified) {
[](const type::Result result, const std::string& linking_info,
const std::string& user_name, const bool verified) {
EXPECT_EQ(result, type::Result::LEDGER_ERROR);
EXPECT_EQ(address, "");
EXPECT_EQ(linking_info, "");
EXPECT_EQ(user_name, "");
EXPECT_FALSE(verified);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
/* Copyright (c) 2021 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "bat/ledger/internal/endpoint/gemini/post_recipient_id/post_recipient_id_gemini.h"

#include <utility>

#include "base/base64.h"
#include "base/guid.h"
#include "base/json/json_reader.h"
#include "base/json/json_writer.h"
#include "bat/ledger/internal/endpoint/gemini/gemini_utils.h"
#include "bat/ledger/internal/ledger_impl.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

using std::placeholders::_1;

namespace ledger {
namespace endpoint {
namespace gemini {

PostRecipientId::PostRecipientId(LedgerImpl* ledger) : ledger_(ledger) {
DCHECK(ledger_);
}

PostRecipientId::~PostRecipientId() = default;

std::string PostRecipientId::GetUrl() {
return GetApiServerUrl("/v1/payments/recipientIds");
}

type::Result PostRecipientId::ParseBody(const std::string& body,
std::string* recipient_id) {
DCHECK(recipient_id);

absl::optional<base::Value> value = base::JSONReader::Read(body);
if (!value || !value->is_dict()) {
BLOG(0, "Invalid JSON");
return type::Result::LEDGER_ERROR;
}

base::DictionaryValue* dictionary = nullptr;
if (!value->GetAsDictionary(&dictionary)) {
BLOG(0, "Invalid JSON");
return type::Result::LEDGER_ERROR;
}

const auto* result = dictionary->FindStringKey("result");
if (!result || *result != "OK") {
BLOG(0, "Failed creating recipient_id");
return type::Result::LEDGER_ERROR;
}

const auto* id = dictionary->FindStringKey("recipient_id");
if (!id) {
BLOG(0, "Response missing a recipient_id");
return type::Result::LEDGER_ERROR;
}

*recipient_id = *id;
return type::Result::LEDGER_OK;
}

std::string PostRecipientId::GeneratePayload() {
base::Value payload(base::Value::Type::DICTIONARY);
payload.SetStringKey("label", base::GenerateGUID());

std::string json;
base::JSONWriter::Write(payload, &json);

std::string base64;
base::Base64Encode(base::StringPiece(json), &base64);
return base64;
}

void PostRecipientId::Request(const std::string& token,
PostRecipientIdCallback callback) {
auto url_callback =
std::bind(&PostRecipientId::OnRequest, this, _1, token, callback);

auto request = type::UrlRequest::New();
auto payload = GeneratePayload();

request->url = GetUrl();
request->method = type::UrlMethod::POST;
request->headers = RequestAuthorization(token);
request->headers.push_back("X-GEMINI-PAYLOAD: " + payload);

ledger_->LoadURL(std::move(request), url_callback);
}

void PostRecipientId::OnRequest(const type::UrlResponse& response,
const std::string& token,
PostRecipientIdCallback callback) {
ledger::LogUrlResponse(__func__, response);

type::Result result = CheckStatusCode(response.status_code);

if (result != type::Result::LEDGER_OK) {
callback(result, "", "");
return;
}

std::string recipient_id;
result = ParseBody(response.body, &recipient_id);
callback(result, recipient_id, token);
}

} // namespace gemini
} // namespace endpoint
} // namespace ledger
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/* Copyright (c) 2021 The Brave Authors. All rights reserved.
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef BRAVE_VENDOR_BAT_NATIVE_LEDGER_SRC_BAT_LEDGER_INTERNAL_ENDPOINT_GEMINI_POST_RECIPIENT_ID_POST_RECIPIENT_ID_GEMINI_H_
#define BRAVE_VENDOR_BAT_NATIVE_LEDGER_SRC_BAT_LEDGER_INTERNAL_ENDPOINT_GEMINI_POST_RECIPIENT_ID_POST_RECIPIENT_ID_GEMINI_H_

#include <string>

#include "bat/ledger/ledger.h"

// POST https://api.gemini.com/v1/payments/recipientIds
// Payload:
// {
// "label": <uuid>
// }
//
// Headers:
// Authorization: Bearer <token>
// X-GEMINI-PAYLOAD: base64-payload
//
// Request body:
// {}
//
// Success code:
// HTTP_OK (200)
//
// Error codes:
// HTTP_UNAUTHORIZED (401)
// HTTP_NOT_FOUND (404)
//
// Response body:
// {
// "result": "OK",
// "recipient_id": "60f9be89-ada7-486d-9cef-f6d3a10886d7",
// "label": <uuid>
// }

namespace ledger {
class LedgerImpl;

namespace endpoint {
namespace gemini {

using PostRecipientIdCallback =
std::function<void(const type::Result result,
const std::string recipient_id,
const std::string token)>;

class PostRecipientId {
public:
explicit PostRecipientId(LedgerImpl* ledger);
~PostRecipientId();

void Request(const std::string& token, PostRecipientIdCallback callback);

private:
std::string GetUrl();

type::Result ParseBody(const std::string& body, std::string* recipient_id);

void OnRequest(const type::UrlResponse& response,
const std::string& token,
PostRecipientIdCallback callback);
std::string GeneratePayload();

LedgerImpl* ledger_; // NOT OWNED
};

} // namespace gemini
} // namespace endpoint
} // namespace ledger

#endif // BRAVE_VENDOR_BAT_NATIVE_LEDGER_SRC_BAT_LEDGER_INTERNAL_ENDPOINT_GEMINI_POST_RECIPIENT_ID_POST_RECIPIENT_ID_GEMINI_H_
Loading

0 comments on commit a4be47a

Please sign in to comment.