Skip to content

Commit 37a80d6

Browse files
committed
Make DecodeAuthorization return a Result rather than throw
1 parent 67d93f6 commit 37a80d6

File tree

5 files changed

+57
-24
lines changed

5 files changed

+57
-24
lines changed

SecretTestValues.h.enc

192 Bytes
Binary file not shown.

psicash.cpp

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -793,6 +793,17 @@ Result<PsiCash::NewExpiringPurchaseResponse> PsiCash::NewExpiringPurchase(
793793
}
794794
// Not checking authorization, as it doesn't apply to all expiring purchases
795795

796+
optional<Authorization> authOptional = nullopt;
797+
if (!authorization_encoded.empty()) {
798+
auto decodeAuthResult = DecodeAuthorization(authorization_encoded);
799+
if (!decodeAuthResult) {
800+
// Authorization can be optional, but inability to decode suggests
801+
// something is very wrong.
802+
return WrapError(decodeAuthResult.error(), "failed to decode Purchase Authorization");
803+
}
804+
authOptional = *decodeAuthResult;
805+
}
806+
796807
Purchase purchase = {
797808
transaction_id,
798809
transaction_class,
@@ -801,7 +812,7 @@ Result<PsiCash::NewExpiringPurchaseResponse> PsiCash::NewExpiringPurchase(
801812
server_expiry),
802813
server_expiry.IsZero() ? nullopt : make_optional(
803814
server_expiry),
804-
authorization_encoded.empty() ? nullopt : make_optional(DecodeAuthorization(authorization_encoded))
815+
authOptional
805816
};
806817

807818
user_data_->UpdatePurchaseLocalTimeExpiry(purchase);
@@ -950,12 +961,18 @@ void from_json(const json& j, Authorization& v) {
950961
v.encoded = j.value("Encoded", ""s);
951962
}
952963

953-
Authorization DecodeAuthorization(const string& encoded) {
954-
auto decoded = base64::B64Decode(encoded);
955-
auto json =json::parse(decoded);
956-
auto auth = json.at("Authorization").get<Authorization>();
957-
auth.encoded = encoded;
958-
return auth;
964+
Result<Authorization> DecodeAuthorization(const string& encoded) {
965+
try {
966+
auto decoded = base64::B64Decode(encoded);
967+
auto json = json::parse(decoded);
968+
auto auth = json.at("Authorization").get<Authorization>();
969+
auth.encoded = encoded;
970+
return auth;
971+
}
972+
catch (json::exception& e) {
973+
return MakeCriticalError(
974+
utils::Stringer("json parse failed: ", e.what(), "; id:", e.id).c_str());
975+
}
959976
}
960977

961978
} // namespace psicash

psicash.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ struct Authorization {
122122
using Authorizations = std::vector<Authorization>;
123123

124124
// May be used for for decoding non-PsiCash authorizations.
125-
Authorization DecodeAuthorization(const std::string& encoded);
125+
error::Result<Authorization> DecodeAuthorization(const std::string& encoded);
126126

127127
using TransactionID = std::string;
128128
extern const char* const kTransactionIDZero; // The "zero value" for a TransactionID

psicash_test.cpp

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -284,10 +284,11 @@ TEST_F(TestPsiCash, GetPurchases) {
284284
auto v = pc.GetPurchases();
285285
ASSERT_EQ(v.size(), 0);
286286

287-
auto auth = DecodeAuthorization("eyJBdXRob3JpemF0aW9uIjp7IklEIjoiMFYzRXhUdmlBdFNxTGZOd2FpQXlHNHpaRUJJOGpIYnp5bFdNeU5FZ1JEZz0iLCJBY2Nlc3NUeXBlIjoic3BlZWQtYm9vc3QtdGVzdCIsIkV4cGlyZXMiOiIyMDE5LTAxLTE0VDE3OjIyOjIzLjE2ODc2NDEyOVoifSwiU2lnbmluZ0tleUlEIjoiUUNZTzV2clIvZGhjRDZ6M2FMQlVNeWRuZlJyZFNRL1RWYW1IUFhYeTd0TT0iLCJTaWduYXR1cmUiOiJQL2NrenloVUJoSk5RQ24zMnluM1VTdGpLencxU04xNW9MclVhTU9XaW9scXBOTTBzNVFSNURHVEVDT1FzQk13ODdQdTc1TGE1OGtJTHRIcW1BVzhDQT09In0=");
287+
auto auth_res = DecodeAuthorization("eyJBdXRob3JpemF0aW9uIjp7IklEIjoiMFYzRXhUdmlBdFNxTGZOd2FpQXlHNHpaRUJJOGpIYnp5bFdNeU5FZ1JEZz0iLCJBY2Nlc3NUeXBlIjoic3BlZWQtYm9vc3QtdGVzdCIsIkV4cGlyZXMiOiIyMDE5LTAxLTE0VDE3OjIyOjIzLjE2ODc2NDEyOVoifSwiU2lnbmluZ0tleUlEIjoiUUNZTzV2clIvZGhjRDZ6M2FMQlVNeWRuZlJyZFNRL1RWYW1IUFhYeTd0TT0iLCJTaWduYXR1cmUiOiJQL2NrenloVUJoSk5RQ24zMnluM1VTdGpLencxU04xNW9MclVhTU9XaW9scXBOTTBzNVFSNURHVEVDT1FzQk13ODdQdTc1TGE1OGtJTHRIcW1BVzhDQT09In0=");
288+
ASSERT_TRUE(auth_res);
288289

289290
Purchases ps = {
290-
{"id1", "tc1", "d1", datetime::DateTime::Now(), datetime::DateTime::Now(), nonstd::make_optional(auth)},
291+
{"id1", "tc1", "d1", datetime::DateTime::Now(), datetime::DateTime::Now(), *auth_res},
291292
{"id2", "tc2", "d2", nonstd::nullopt, nonstd::nullopt, nonstd::nullopt}};
292293

293294
err = pc.user_data().SetPurchases(ps);
@@ -347,26 +348,34 @@ TEST_F(TestPsiCash, DecodeAuthorization) {
347348
const auto encoded1 = "eyJBdXRob3JpemF0aW9uIjp7IklEIjoiMFYzRXhUdmlBdFNxTGZOd2FpQXlHNHpaRUJJOGpIYnp5bFdNeU5FZ1JEZz0iLCJBY2Nlc3NUeXBlIjoic3BlZWQtYm9vc3QtdGVzdCIsIkV4cGlyZXMiOiIyMDE5LTAxLTE0VDE3OjIyOjIzLjE2ODc2NDEyOVoifSwiU2lnbmluZ0tleUlEIjoiUUNZTzV2clIvZGhjRDZ6M2FMQlVNeWRuZlJyZFNRL1RWYW1IUFhYeTd0TT0iLCJTaWduYXR1cmUiOiJQL2NrenloVUJoSk5RQ24zMnluM1VTdGpLencxU04xNW9MclVhTU9XaW9scXBOTTBzNVFSNURHVEVDT1FzQk13ODdQdTc1TGE1OGtJTHRIcW1BVzhDQT09In0=";
348349
const auto encoded2 = "eyJBdXRob3JpemF0aW9uIjp7IklEIjoibFRSWnBXK1d3TFJqYkpzOGxBUFVaQS8zWnhmcGdwNDFQY0dkdlI5a0RVST0iLCJBY2Nlc3NUeXBlIjoic3BlZWQtYm9vc3QtdGVzdCIsIkV4cGlyZXMiOiIyMDE5LTAxLTE0VDIxOjQ2OjMwLjcxNzI2NTkyNFoifSwiU2lnbmluZ0tleUlEIjoiUUNZTzV2clIvZGhjRDZ6M2FMQlVNeWRuZlJyZFNRL1RWYW1IUFhYeTd0TT0iLCJTaWduYXR1cmUiOiJtV1Z5Tm9ZU0pFRDNXU3I3bG1OeEtReEZza1M5ZWlXWG1lcDVvVWZBSHkwVmYrSjZaQW9WajZrN3ZVTDNrakIreHZQSTZyaVhQc3FzWENRNkx0eFdBQT09In0=";
349350

350-
auto auth1 = psicash::DecodeAuthorization(encoded1);
351-
auto auth2 = psicash::DecodeAuthorization(encoded2);
351+
auto auth_res1 = psicash::DecodeAuthorization(encoded1);
352+
auto auth_res2 = psicash::DecodeAuthorization(encoded2);
352353

353-
ASSERT_TRUE(auth1 == auth1);
354-
ASSERT_FALSE(auth1 == auth2);
355-
ASSERT_EQ(auth1.id, "0V3ExTviAtSqLfNwaiAyG4zZEBI8jHbzylWMyNEgRDg=");
356-
ASSERT_EQ(auth1.access_type, "speed-boost-test");
354+
ASSERT_TRUE(auth_res1);
355+
ASSERT_TRUE(auth_res2);
356+
ASSERT_TRUE(*auth_res1 == *auth_res1);
357+
ASSERT_FALSE(*auth_res1 == *auth_res2);
358+
ASSERT_EQ(auth_res1->id, "0V3ExTviAtSqLfNwaiAyG4zZEBI8jHbzylWMyNEgRDg=");
359+
ASSERT_EQ(auth_res1->access_type, "speed-boost-test");
357360

358361
psicash::datetime::DateTime want_date;
359362
ASSERT_TRUE(want_date.FromISO8601("2019-01-14T17:22:23.168764129Z"));
360-
ASSERT_EQ(auth1.expires, want_date) << auth1.expires.ToISO8601();
363+
ASSERT_EQ(auth_res1->expires, want_date) << auth_res1->expires.ToISO8601();
361364

362365
auto invalid_base64 = "BAD-BASE64-$^#&*(@===============";
363-
ASSERT_THROW(psicash::DecodeAuthorization(invalid_base64), json::exception);
366+
auto auth_res_fail = psicash::DecodeAuthorization(invalid_base64);
367+
ASSERT_FALSE(auth_res_fail);
368+
ASSERT_TRUE(auth_res_fail.error().Critical());
364369

365370
auto invalid_json = "dGhpcyBpcyBub3QgdmFsaWQgSlNPTg==";
366-
ASSERT_THROW(psicash::DecodeAuthorization(invalid_json), json::exception);
371+
auth_res_fail = psicash::DecodeAuthorization(invalid_json);
372+
ASSERT_FALSE(auth_res_fail);
373+
ASSERT_TRUE(auth_res_fail.error().Critical());
367374

368375
auto incorrect_json = "eyJ2YWxpZCI6ICJqc29uIiwgImJ1dCI6ICJub3QgYSB2YWxpZCBhdXRob3JpemF0aW9uIn0=";
369-
ASSERT_THROW(psicash::DecodeAuthorization(incorrect_json), json::exception);
376+
auth_res_fail = psicash::DecodeAuthorization(incorrect_json);
377+
ASSERT_FALSE(auth_res_fail);
378+
ASSERT_TRUE(auth_res_fail.error().Critical());
370379
}
371380

372381
TEST_F(TestPsiCash, ActiveAuthorizations) {
@@ -389,9 +398,14 @@ TEST_F(TestPsiCash, ActiveAuthorizations) {
389398
const auto encoded1 = "eyJBdXRob3JpemF0aW9uIjp7IklEIjoiMFYzRXhUdmlBdFNxTGZOd2FpQXlHNHpaRUJJOGpIYnp5bFdNeU5FZ1JEZz0iLCJBY2Nlc3NUeXBlIjoic3BlZWQtYm9vc3QtdGVzdCIsIkV4cGlyZXMiOiIyMDE5LTAxLTE0VDE3OjIyOjIzLjE2ODc2NDEyOVoifSwiU2lnbmluZ0tleUlEIjoiUUNZTzV2clIvZGhjRDZ6M2FMQlVNeWRuZlJyZFNRL1RWYW1IUFhYeTd0TT0iLCJTaWduYXR1cmUiOiJQL2NrenloVUJoSk5RQ24zMnluM1VTdGpLencxU04xNW9MclVhTU9XaW9scXBOTTBzNVFSNURHVEVDT1FzQk13ODdQdTc1TGE1OGtJTHRIcW1BVzhDQT09In0=";
390399
const auto encoded2 = "eyJBdXRob3JpemF0aW9uIjp7IklEIjoibFRSWnBXK1d3TFJqYkpzOGxBUFVaQS8zWnhmcGdwNDFQY0dkdlI5a0RVST0iLCJBY2Nlc3NUeXBlIjoic3BlZWQtYm9vc3QtdGVzdCIsIkV4cGlyZXMiOiIyMDE5LTAxLTE0VDIxOjQ2OjMwLjcxNzI2NTkyNFoifSwiU2lnbmluZ0tleUlEIjoiUUNZTzV2clIvZGhjRDZ6M2FMQlVNeWRuZlJyZFNRL1RWYW1IUFhYeTd0TT0iLCJTaWduYXR1cmUiOiJtV1Z5Tm9ZU0pFRDNXU3I3bG1OeEtReEZza1M5ZWlXWG1lcDVvVWZBSHkwVmYrSjZaQW9WajZrN3ZVTDNrakIreHZQSTZyaVhQc3FzWENRNkx0eFdBQT09In0=";
391400

401+
auto auth_res1 = psicash::DecodeAuthorization(encoded1);
402+
auto auth_res2 = psicash::DecodeAuthorization(encoded2);
403+
ASSERT_TRUE(auth_res1);
404+
ASSERT_TRUE(auth_res2);
405+
392406
purchases = {{"future_no_auth", "tc1", "d1", after_now, nonstd::nullopt, nonstd::nullopt},
393-
{"past_auth", "tc2", "d2", before_now, nonstd::nullopt, nonstd::make_optional(psicash::DecodeAuthorization(encoded1))},
394-
{"future_auth", "tc3", "d3", after_now, nonstd::nullopt, nonstd::make_optional(psicash::DecodeAuthorization(encoded2))}};
407+
{"past_auth", "tc2", "d2", before_now, nonstd::nullopt, *auth_res1},
408+
{"future_auth", "tc3", "d3", after_now, nonstd::nullopt, *auth_res2}};
395409

396410
err = pc.user_data().SetPurchases(purchases);
397411
ASSERT_FALSE(err);

userdata_test.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,9 +261,11 @@ TEST_F(TestUserData, Purchases)
261261
// Set then get
262262
auto dt1 = datetime::DateTime::Now().Add(datetime::Duration(1));
263263
auto dt2 = datetime::DateTime::Now().Add(datetime::Duration(2));
264-
auto auth1 = psicash::DecodeAuthorization("eyJBdXRob3JpemF0aW9uIjp7IklEIjoibFRSWnBXK1d3TFJqYkpzOGxBUFVaQS8zWnhmcGdwNDFQY0dkdlI5a0RVST0iLCJBY2Nlc3NUeXBlIjoic3BlZWQtYm9vc3QtdGVzdCIsIkV4cGlyZXMiOiIyMDE5LTAxLTE0VDIxOjQ2OjMwLjcxNzI2NTkyNFoifSwiU2lnbmluZ0tleUlEIjoiUUNZTzV2clIvZGhjRDZ6M2FMQlVNeWRuZlJyZFNRL1RWYW1IUFhYeTd0TT0iLCJTaWduYXR1cmUiOiJtV1Z5Tm9ZU0pFRDNXU3I3bG1OeEtReEZza1M5ZWlXWG1lcDVvVWZBSHkwVmYrSjZaQW9WajZrN3ZVTDNrakIreHZQSTZyaVhQc3FzWENRNkx0eFdBQT09In0=");
264+
auto auth_res1 = psicash::DecodeAuthorization("eyJBdXRob3JpemF0aW9uIjp7IklEIjoibFRSWnBXK1d3TFJqYkpzOGxBUFVaQS8zWnhmcGdwNDFQY0dkdlI5a0RVST0iLCJBY2Nlc3NUeXBlIjoic3BlZWQtYm9vc3QtdGVzdCIsIkV4cGlyZXMiOiIyMDE5LTAxLTE0VDIxOjQ2OjMwLjcxNzI2NTkyNFoifSwiU2lnbmluZ0tleUlEIjoiUUNZTzV2clIvZGhjRDZ6M2FMQlVNeWRuZlJyZFNRL1RWYW1IUFhYeTd0TT0iLCJTaWduYXR1cmUiOiJtV1Z5Tm9ZU0pFRDNXU3I3bG1OeEtReEZza1M5ZWlXWG1lcDVvVWZBSHkwVmYrSjZaQW9WajZrN3ZVTDNrakIreHZQSTZyaVhQc3FzWENRNkx0eFdBQT09In0=");
265+
ASSERT_TRUE(auth_res1);
266+
265267
Purchases want = {
266-
{"id1", "tc1", "d1", dt1, dt2, auth1},
268+
{"id1", "tc1", "d1", dt1, dt2, *auth_res1},
267269
{"id2", "tc2", "d2", nullopt, nullopt, nullopt}};
268270

269271
err = ud.SetPurchases(want);

0 commit comments

Comments
 (0)