Skip to content

Commit 4486914

Browse files
committed
Moves promotions to new endpoint structure
Resolves brave/brave-browser#11203
1 parent 91dd812 commit 4486914

File tree

16 files changed

+794
-237
lines changed

16 files changed

+794
-237
lines changed

components/brave_rewards/test/BUILD.gn

+2
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ source_set("brave_rewards_unit_tests") {
4949
"//brave/vendor/bat-native-ledger/src/bat/ledger/internal/publisher/publisher_unittest.cc",
5050
"//brave/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/api/api_util_unittest.cc",
5151
"//brave/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/api/get_parameters/get_parameters_unittest.cc",
52+
"//brave/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/promotion/promotions_util_unittest.cc",
53+
"//brave/vendor/bat-native-ledger/src/bat/ledger/internal/endpoint/promotion/get_available/get_available_unittest.cc",
5254
"//brave/vendor/bat-native-ledger/src/bat/ledger/internal/uphold/uphold_unittest.cc",
5355
"//brave/vendor/bat-native-ledger/src/bat/ledger/internal/uphold/uphold_util_unittest.cc",
5456
"//brave/vendor/bat-native-ledger/src/bat/ledger/internal/wallet/wallet_util_unittest.cc",

vendor/bat-native-ledger/BUILD.gn

+6
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,12 @@ source_set("ledger") {
330330
"src/bat/ledger/internal/endpoint/api/api_util.h",
331331
"src/bat/ledger/internal/endpoint/api/get_parameters/get_parameters.cc",
332332
"src/bat/ledger/internal/endpoint/api/get_parameters/get_parameters.h",
333+
"src/bat/ledger/internal/endpoint/promotion/promotion_server.cc",
334+
"src/bat/ledger/internal/endpoint/promotion/promotion_server.h",
335+
"src/bat/ledger/internal/endpoint/promotion/promotions_util.cc",
336+
"src/bat/ledger/internal/endpoint/promotion/promotions_util.h",
337+
"src/bat/ledger/internal/endpoint/promotion/get_available/get_available.cc",
338+
"src/bat/ledger/internal/endpoint/promotion/get_available/get_available.h",
333339
"src/bat/ledger/internal/sku/sku.h",
334340
"src/bat/ledger/internal/sku/sku_brave.cc",
335341
"src/bat/ledger/internal/sku/sku_brave.h",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,250 @@
1+
/* Copyright (c) 2020 The Brave Authors. All rights reserved.
2+
* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this
4+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5+
6+
#include <utility>
7+
8+
#include "base/json/json_reader.h"
9+
#include "base/json/json_writer.h"
10+
#include "base/strings/string_number_conversions.h"
11+
#include "base/strings/stringprintf.h"
12+
#include "bat/ledger/internal/endpoint/promotion/get_available/get_available.h"
13+
#include "bat/ledger/internal/endpoint/promotion/promotions_util.h"
14+
#include "bat/ledger/internal/ledger_impl.h"
15+
#include "bat/ledger/internal/promotion/promotion_util.h"
16+
#include "net/http/http_status_code.h"
17+
18+
using std::placeholders::_1;
19+
20+
// GET /v1/promotions?migrate=true&paymentId={payment_id}&platform={platform}
21+
//
22+
// Success:
23+
// HTTP_OK (200)
24+
//
25+
// Error codes:
26+
// HTTP_BAD_REQUEST (400)
27+
// HTTP_NOT_FOUND (404)
28+
// HTTP_INTERNAL_SERVER_ERROR (500)
29+
//
30+
// Response body:
31+
// {
32+
// "promotions": [
33+
// {
34+
// "id": "83b3b77b-e7c3-455b-adda-e476fa0656d2",
35+
// "createdAt": "2020-06-08T15:04:45.352584Z",
36+
// "expiresAt": "2020-10-08T15:04:45.352584Z",
37+
// "version": 5,
38+
// "suggestionsPerGrant": 120,
39+
// "approximateValue": "30",
40+
// "type": "ugp",
41+
// "available": true,
42+
// "platform": "desktop",
43+
// "publicKeys": [
44+
// "dvpysTSiJdZUPihius7pvGOfngRWfDiIbrowykgMi1I="
45+
// ],
46+
// "legacyClaimed": false
47+
// }
48+
// ]
49+
// }
50+
51+
namespace ledger {
52+
namespace endpoint {
53+
namespace promotion {
54+
55+
GetAvailable::GetAvailable(bat_ledger::LedgerImpl* ledger):
56+
ledger_(ledger) {
57+
DCHECK(ledger_);
58+
}
59+
60+
GetAvailable::~GetAvailable() = default;
61+
62+
std::string GetAvailable::GetUrl(const std::string& platform) {
63+
const std::string payment_id = ledger_->state()->GetPaymentId();
64+
const std::string& arguments = base::StringPrintf(
65+
"migrate=true&paymentId=%s&platform=%s",
66+
payment_id.c_str(),
67+
platform.c_str());
68+
69+
const std::string& path = base::StringPrintf(
70+
"/v1/promotions?%s",
71+
arguments.c_str());
72+
73+
return GetServerUrl(path);
74+
}
75+
76+
ledger::Result GetAvailable::CheckStatusCode(const int status_code) {
77+
if (status_code == net::HTTP_BAD_REQUEST) {
78+
BLOG(0, "Invalid paymentId or platform in request");
79+
return ledger::Result::LEDGER_ERROR;
80+
}
81+
82+
if (status_code == net::HTTP_NOT_FOUND) {
83+
BLOG(0, "Unrecognized paymentId/promotion combination");
84+
return ledger::Result::NOT_FOUND;
85+
}
86+
87+
if (status_code == net::HTTP_INTERNAL_SERVER_ERROR) {
88+
BLOG(0, "Internal server error");
89+
return ledger::Result::LEDGER_ERROR;
90+
}
91+
92+
if (status_code != net::HTTP_OK) {
93+
return ledger::Result::LEDGER_ERROR;
94+
}
95+
96+
return ledger::Result::LEDGER_OK;
97+
}
98+
99+
ledger::Result GetAvailable::ParseBody(
100+
const std::string& body,
101+
ledger::PromotionList* list,
102+
std::vector<std::string>* corrupted_promotions) {
103+
104+
DCHECK(list && corrupted_promotions);
105+
106+
base::Optional<base::Value> value = base::JSONReader::Read(body);
107+
if (!value || !value->is_dict()) {
108+
BLOG(0, "Invalid JSON");
109+
return ledger::Result::LEDGER_ERROR;
110+
}
111+
112+
base::DictionaryValue* dictionary = nullptr;
113+
if (!value->GetAsDictionary(&dictionary)) {
114+
BLOG(0, "Invalid JSON");
115+
return ledger::Result::LEDGER_ERROR;
116+
}
117+
118+
auto* promotions = dictionary->FindListKey("promotions");
119+
if (!promotions) {
120+
return ledger::Result::LEDGER_OK;
121+
}
122+
123+
const auto promotion_size = promotions->GetList().size();
124+
for (auto& item : promotions->GetList()) {
125+
ledger::PromotionPtr promotion = ledger::Promotion::New();
126+
127+
const auto* id = item.FindStringKey("id");
128+
if (!id) {
129+
continue;
130+
}
131+
promotion->id = *id;
132+
133+
const auto version = item.FindIntKey("version");
134+
if (!version) {
135+
corrupted_promotions->push_back(promotion->id);
136+
continue;
137+
}
138+
promotion->version = *version;
139+
140+
const auto* type = item.FindStringKey("type");
141+
if (!type) {
142+
corrupted_promotions->push_back(promotion->id);
143+
continue;
144+
}
145+
promotion->type =
146+
braveledger_promotion::ConvertStringToPromotionType(*type);
147+
148+
const auto suggestions = item.FindIntKey("suggestionsPerGrant");
149+
if (!suggestions) {
150+
corrupted_promotions->push_back(promotion->id);
151+
continue;
152+
}
153+
promotion->suggestions = *suggestions;
154+
155+
const auto* approximate_value = item.FindStringKey("approximateValue");
156+
if (!approximate_value) {
157+
corrupted_promotions->push_back(promotion->id);
158+
continue;
159+
}
160+
161+
const bool success_conversion =
162+
base::StringToDouble(*approximate_value, &promotion->approximate_value);
163+
if (!success_conversion) {
164+
promotion->approximate_value = 0.0;
165+
}
166+
167+
const auto available = item.FindBoolKey("available");
168+
if (!available) {
169+
corrupted_promotions->push_back(promotion->id);
170+
continue;
171+
}
172+
173+
if (*available) {
174+
promotion->status = ledger::PromotionStatus::ACTIVE;
175+
} else {
176+
promotion->status = ledger::PromotionStatus::OVER;
177+
}
178+
179+
auto* expires_at = item.FindStringKey("expiresAt");
180+
if (!expires_at) {
181+
corrupted_promotions->push_back(promotion->id);
182+
continue;
183+
}
184+
185+
base::Time time;
186+
bool success = base::Time::FromUTCString((*expires_at).c_str(), &time);
187+
if (success) {
188+
promotion->expires_at = time.ToDoubleT();
189+
}
190+
191+
auto* public_keys = item.FindListKey("publicKeys");
192+
if (!public_keys || public_keys->GetList().empty()) {
193+
corrupted_promotions->push_back(promotion->id);
194+
continue;
195+
}
196+
197+
std::string keys_json;
198+
base::JSONWriter::Write(*public_keys, &keys_json);
199+
promotion->public_keys = keys_json;
200+
201+
auto legacy_claimed = item.FindBoolKey("legacyClaimed");
202+
promotion->legacy_claimed = legacy_claimed.value_or(false);
203+
204+
list->push_back(std::move(promotion));
205+
}
206+
207+
if (promotion_size != list->size()) {
208+
return ledger::Result::CORRUPTED_DATA;
209+
}
210+
211+
return ledger::Result::LEDGER_OK;
212+
}
213+
214+
void GetAvailable::Request(
215+
const std::string& platform,
216+
GetAvailableCallback callback) {
217+
auto url_callback = std::bind(&GetAvailable::OnRequest,
218+
this,
219+
_1,
220+
callback);
221+
ledger_->LoadURL(
222+
GetUrl(platform),
223+
{},
224+
"",
225+
"",
226+
ledger::UrlMethod::GET,
227+
url_callback);
228+
}
229+
230+
void GetAvailable::OnRequest(
231+
const ledger::UrlResponse& response,
232+
GetAvailableCallback callback) {
233+
ledger::LogUrlResponse(__func__, response);
234+
235+
ledger::PromotionList list;
236+
std::vector<std::string> corrupted_promotions;
237+
ledger::Result result = CheckStatusCode(response.status_code);
238+
239+
if (result != ledger::Result::LEDGER_OK) {
240+
callback(result, std::move(list), corrupted_promotions);
241+
return;
242+
}
243+
244+
result = ParseBody(response.body, &list, &corrupted_promotions);
245+
callback(result, std::move(list), corrupted_promotions);
246+
}
247+
248+
} // namespace promotion
249+
} // namespace endpoint
250+
} // namespace ledger
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/* Copyright (c) 2020 The Brave Authors. All rights reserved.
2+
* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this
4+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5+
6+
#ifndef BRAVELEDGER_ENDPOINT_PROMOTION_GET_AVAILABLE_GET_AVAILABLE_H_
7+
#define BRAVELEDGER_ENDPOINT_PROMOTION_GET_AVAILABLE_GET_AVAILABLE_H_
8+
9+
#include <string>
10+
#include <vector>
11+
12+
#include "bat/ledger/ledger.h"
13+
14+
namespace bat_ledger {
15+
class LedgerImpl;
16+
}
17+
18+
namespace ledger {
19+
namespace endpoint {
20+
namespace promotion {
21+
22+
using GetAvailableCallback = std::function<void(
23+
const ledger::Result result,
24+
ledger::PromotionList list,
25+
const std::vector<std::string>& corrupted_promotions)>;
26+
27+
class GetAvailable {
28+
public:
29+
explicit GetAvailable(bat_ledger::LedgerImpl* ledger);
30+
~GetAvailable();
31+
32+
void Request(
33+
const std::string& platform,
34+
GetAvailableCallback callback);
35+
36+
private:
37+
std::string GetUrl(const std::string& platform);
38+
39+
ledger::Result CheckStatusCode(const int status_code);
40+
41+
ledger::Result ParseBody(
42+
const std::string& body,
43+
ledger::PromotionList* list,
44+
std::vector<std::string>* corrupted_promotions);
45+
46+
void OnRequest(
47+
const ledger::UrlResponse& response,
48+
GetAvailableCallback callback);
49+
50+
bat_ledger::LedgerImpl* ledger_; // NOT OWNED
51+
};
52+
53+
} // namespace promotion
54+
} // namespace endpoint
55+
} // namespace ledger
56+
57+
#endif // BRAVELEDGER_ENDPOINT_PROMOTION_GET_AVAILABLE_GET_AVAILABLE_H_

0 commit comments

Comments
 (0)