Chromium Code Reviews| Index: content/common/origin_trials/trial_token.cc |
| diff --git a/content/common/origin_trials/trial_token.cc b/content/common/origin_trials/trial_token.cc |
| index 0a137edc68b43e780e572c1d083379c864921fc8..b96436b76f95befcc6c45da91a68130c202bcb3b 100644 |
| --- a/content/common/origin_trials/trial_token.cc |
| +++ b/content/common/origin_trials/trial_token.cc |
| @@ -43,49 +43,65 @@ const uint8_t kVersion2 = 2; |
| TrialToken::~TrialToken() {} |
| -// static |
| +// Static |
|
Marijn Kruisselbrink
2016/04/22 21:51:06
the lowercase version of this comment is vastly mo
chasej
2016/04/25 20:32:52
Done.
|
| std::unique_ptr<TrialToken> TrialToken::From(const std::string& token_text, |
| - base::StringPiece public_key) { |
| - std::unique_ptr<std::string> token_payload = Extract(token_text, public_key); |
| - if (!token_payload) { |
| + base::StringPiece public_key, |
| + TrialTokenStatus* out_status) { |
| + DCHECK(out_status); |
| + std::string token_payload; |
| + *out_status = Extract(token_text, public_key, &token_payload); |
| + if (*out_status != TRIAL_TOKEN_STATUS_SUCCESS) { |
| return nullptr; |
| } |
| - return Parse(*token_payload); |
| + std::unique_ptr<TrialToken> token = Parse(token_payload); |
| + *out_status = |
| + token ? TRIAL_TOKEN_STATUS_SUCCESS : TRIAL_TOKEN_STATUS_MALFORMED; |
| + return token; |
| } |
| -bool TrialToken::IsValidForFeature(const url::Origin& origin, |
| - base::StringPiece feature_name, |
| - const base::Time& now) const { |
| - return ValidateOrigin(origin) && ValidateFeatureName(feature_name) && |
| - ValidateDate(now); |
| +TrialTokenStatus TrialToken::IsValidForFeature(const url::Origin& origin, |
| + base::StringPiece feature_name, |
| + const base::Time& now) const { |
| + // The order of these checks is intentional. For example, will only report a |
| + // token as expired if it is valid for the origin + feature combination. |
| + if (!ValidateOrigin(origin)) { |
| + return TRIAL_TOKEN_STATUS_WRONG_ORIGIN; |
| + } |
| + if (!ValidateFeatureName(feature_name)) { |
| + return TRIAL_TOKEN_STATUS_WRONG_FEATURE; |
| + } |
| + if (!ValidateDate(now)) { |
| + return TRIAL_TOKEN_STATUS_EXPIRED; |
| + } |
| + return TRIAL_TOKEN_STATUS_SUCCESS; |
| } |
| -std::unique_ptr<std::string> TrialToken::Extract( |
| - const std::string& token_payload, |
| - base::StringPiece public_key) { |
| +TrialTokenStatus TrialToken::Extract(const std::string& token_payload, |
| + base::StringPiece public_key, |
| + std::string* out_token_json) { |
| if (token_payload.empty()) { |
| - return nullptr; |
| + return TRIAL_TOKEN_STATUS_MALFORMED; |
| } |
| // Token is base64-encoded; decode first. |
| std::string token_contents; |
| if (!base::Base64Decode(token_payload, &token_contents)) { |
| - return nullptr; |
| + return TRIAL_TOKEN_STATUS_MALFORMED; |
| } |
| // Only version 2 currently supported. |
| if (token_contents.length() < (kVersionOffset + kVersionSize)) { |
| - return nullptr; |
| + return TRIAL_TOKEN_STATUS_MALFORMED; |
| } |
| uint8_t version = token_contents[kVersionOffset]; |
| if (version != kVersion2) { |
| - return nullptr; |
| + return TRIAL_TOKEN_STATUS_MALFORMED; |
| } |
| // Token must be large enough to contain a version, signature, and payload |
| // length. |
| if (token_contents.length() < (kPayloadLengthOffset + kPayloadLengthSize)) { |
| - return nullptr; |
| + return TRIAL_TOKEN_STATUS_MALFORMED; |
| } |
| // Extract the length of the signed data (Big-endian). |
| @@ -94,7 +110,7 @@ std::unique_ptr<std::string> TrialToken::Extract( |
| // Validate that the stated length matches the actual payload length. |
| if (payload_length != token_contents.length() - kPayloadOffset) { |
| - return nullptr; |
| + return TRIAL_TOKEN_STATUS_MALFORMED; |
| } |
| // Extract the version-specific contents of the token. |
| @@ -110,12 +126,12 @@ std::unique_ptr<std::string> TrialToken::Extract( |
| // Validate the signature on the data before proceeding. |
| if (!TrialToken::ValidateSignature(signature, signed_data, public_key)) { |
| - return nullptr; |
| + return TRIAL_TOKEN_STATUS_INVALID_SIGNATURE; |
| } |
| // Return just the payload, as a new string. |
| - return base::WrapUnique( |
| - new std::string(token_contents, kPayloadOffset, payload_length)); |
| + *out_token_json = token_contents.substr(kPayloadOffset, payload_length); |
| + return TRIAL_TOKEN_STATUS_SUCCESS; |
| } |
| std::unique_ptr<TrialToken> TrialToken::Parse(const std::string& token_json) { |