| // Copyright 2025 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/glic/glic_user_status_request.h" |
| |
| #include "base/json/json_reader.h" |
| #include "base/logging.h" |
| #include "base/strings/string_util.h" |
| #include "chrome/browser/glic/glic_user_status_code.h" |
| #include "google_apis/common/api_error_codes.h" |
| |
| namespace { |
| // The server response would be first converted to JSON. The JSON object would |
| // be converted to this struct. |
| struct GlicUserStatusResponse { |
| bool is_glic_enabled = true; |
| bool is_access_denied_by_admin = false; |
| bool is_enterprise_account_data_protected = false; |
| static void RegisterJSONConverter( |
| base::JSONValueConverter<GlicUserStatusResponse>* converter) { |
| converter->RegisterBoolField(glic::kIsGlicEnabled, |
| &GlicUserStatusResponse::is_glic_enabled); |
| converter->RegisterBoolField( |
| glic::kIsAccessDeniedByAdmin, |
| &GlicUserStatusResponse::is_access_denied_by_admin); |
| converter->RegisterBoolField( |
| glic::kIsEnterpriseAccountDataProtected, |
| &GlicUserStatusResponse::is_enterprise_account_data_protected); |
| } |
| }; |
| } // namespace |
| |
| namespace glic { |
| GlicUserStatusRequest::GlicUserStatusRequest( |
| google_apis::RequestSender* sender, |
| GURL url, |
| base::OnceCallback<void(const CachedUserStatus&)> process_response_callback) |
| : UrlFetchRequestBase(sender, |
| google_apis::ProgressCallback(), |
| google_apis::ProgressCallback()), |
| url_(url), |
| process_response_callback_(std::move(process_response_callback)) {} |
| |
| GlicUserStatusRequest::~GlicUserStatusRequest() = default; |
| |
| GURL GlicUserStatusRequest::GetURL() const { |
| return url_; |
| } |
| |
| google_apis::ApiErrorCode GlicUserStatusRequest::MapReasonToError( |
| google_apis::ApiErrorCode code, |
| const std::string& reason) { |
| // This method is to map error reason parsed from response body to |
| // ApiErrorCode. we assume for now that result is to be sent as |
| // ApiErrorCode. |
| return code; |
| } |
| |
| bool GlicUserStatusRequest::IsSuccessfulErrorCode( |
| google_apis::ApiErrorCode error) { |
| return error == google_apis::HTTP_SUCCESS; |
| } |
| |
| void GlicUserStatusRequest::ProcessURLFetchResults( |
| const network::mojom::URLResponseHead* response_head, |
| base::FilePath response_file, |
| std::string response_body) { |
| auto cached_user_status = |
| MapApiErrorCodeAndResponseBodyToUserStatus(GetErrorCode(), response_body); |
| |
| std::move(process_response_callback_).Run(cached_user_status); |
| |
| OnProcessURLFetchResultsComplete(); |
| } |
| |
| // called when request is canceled or auth is failed. |
| void GlicUserStatusRequest::RunCallbackOnPrematureFailure( |
| google_apis::ApiErrorCode error) { |
| auto cached_user_status = |
| MapApiErrorCodeAndResponseBodyToUserStatus(error, ""); |
| std::move(process_response_callback_).Run(cached_user_status); |
| } |
| |
| CachedUserStatus |
| GlicUserStatusRequest::MapApiErrorCodeAndResponseBodyToUserStatus( |
| google_apis::ApiErrorCode api_error_code, |
| std::string_view response_body_as_string) { |
| // Currently, the is_enterprise_account_data_protected is not used for any |
| // Chrome behavir. Its sole use is to tell the user if their data is logged. |
| // It is worse to tell the user that their data when in fact it is, than to |
| // tell the user that their data is logged when in fact it is not. (And that |
| // messaging is the only thing this boolean controls). Therefore, we default |
| // the field to false. If the field is to be used in other ways later, the |
| // default value may need to change too. |
| CachedUserStatus user_status = { |
| .user_status_code = UserStatusCode::SERVER_UNAVAILABLE, |
| .is_enterprise_account_data_protected = false, |
| .last_updated = base::Time::Now()}; |
| |
| if (api_error_code != google_apis::HTTP_SUCCESS) { |
| return user_status; |
| } |
| |
| // Parse response body to JSON in the form of |
| // { |
| // is_glic_enabled: true/false |
| // is_access_denied_by_admin: true/false |
| // is_enterprise_account_data_protected: true/false |
| // } |
| std::optional<base::Value::Dict> parsed_json = |
| base::JSONReader::ReadDict(response_body_as_string); |
| |
| if (!parsed_json.has_value()) { |
| DVLOG(1) << "Failed reading response body: " << response_body_as_string; |
| return user_status; |
| } |
| |
| // Convert response body in JSON format to the GlicUserStatusResponse |
| // struct. |
| GlicUserStatusResponse response; |
| base::JSONValueConverter<GlicUserStatusResponse> converter; |
| |
| if (!converter.Convert(parsed_json.value(), &response)) { |
| return user_status; |
| } |
| |
| user_status.is_enterprise_account_data_protected = |
| response.is_enterprise_account_data_protected; |
| |
| if (response.is_glic_enabled) { |
| // The feature is enabled (if the response fails to mention it, we assume it |
| // is). |
| user_status.user_status_code = UserStatusCode::ENABLED; |
| } else { |
| // The feature is disabled (find the reason, if given). |
| user_status.user_status_code = response.is_access_denied_by_admin |
| ? UserStatusCode::DISABLED_BY_ADMIN |
| : UserStatusCode::DISABLED_OTHER; |
| } |
| |
| return user_status; |
| } |
| } // namespace glic |