| 856 | } |
| 857 | |
| 858 | PocoHTTPClientGCPOAuth::BearerToken PocoHTTPClientGCPOAuth::requestBearerToken() const |
| 859 | { |
| 860 | if (!google_adc_client_id.empty() && !google_adc_client_secret.empty() && !google_adc_refresh_token.empty()) |
| 861 | return requestBearerTokenFromADC(); |
| 862 | |
| 863 | chassert(!request_token_path.empty()); |
| 864 | chassert(!metadata_service.empty()); |
| 865 | chassert(!service_account.empty()); |
| 866 | |
| 867 | Poco::URI url; |
| 868 | url.setScheme("http"); |
| 869 | url.setHost(metadata_service); |
| 870 | url.setPath(fmt::format("{}/{}/token", request_token_path, service_account)); |
| 871 | |
| 872 | Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_GET, url.toString(), Poco::Net::HTTPRequest::HTTP_1_1); |
| 873 | request.add("metadata-flavor", "Google"); |
| 874 | |
| 875 | auto log = getLogger("PocoHTTPClientGCPOAuth"); |
| 876 | if (enable_s3_requests_logging) |
| 877 | LOG_TEST(log, "Make request to: {}", url.toString()); |
| 878 | |
| 879 | auto group = for_disk_s3 ? HTTPConnectionGroupType::DISK : HTTPConnectionGroupType::STORAGE; |
| 880 | auto session = makeHTTPSession(group, url, timeouts); |
| 881 | session->sendRequest(request); |
| 882 | |
| 883 | Poco::Net::HTTPResponse response; |
| 884 | auto & in = session->receiveResponse(response); |
| 885 | |
| 886 | if (response.getStatus() != Poco::Net::HTTPResponse::HTTP_OK) |
| 887 | throw Exception(ErrorCodes::AUTHENTICATION_FAILED, "Failed to request bearer token: {}", response.getReason()); |
| 888 | |
| 889 | String token_json_raw; |
| 890 | Poco::StreamCopier::copyToString(in, token_json_raw); |
| 891 | |
| 892 | if (enable_s3_requests_logging) |
| 893 | LOG_TEST(log, "Received token in response: {}", token_json_raw); |
| 894 | |
| 895 | Poco::JSON::Parser parser; |
| 896 | auto object = parser.parse(token_json_raw).extract<Poco::JSON::Object::Ptr>(); |
| 897 | |
| 898 | if (!object->has("access_token") || !object->has("expires_in") || !object->has("token_type")) |
| 899 | throw Exception(ErrorCodes::AUTHENTICATION_FAILED, |
| 900 | "Unexpected structure of response. Response should have fields: 'access_token', 'expires_in', 'token_type'"); |
| 901 | |
| 902 | auto token_type = object->getValue<String>("token_type"); |
| 903 | if (token_type != "Bearer") |
| 904 | throw Exception(ErrorCodes::AUTHENTICATION_FAILED, |
| 905 | "Unexpected structure of response. Expected Bearer token, got {}", token_type); |
| 906 | |
| 907 | return |
| 908 | { |
| 909 | .token = object->getValue<String>("access_token"), |
| 910 | .is_valid_to = std::chrono::system_clock::now() + std::chrono::seconds(object->getValue<Int64>("expires_in")) |
| 911 | }; |
| 912 | } |
| 913 | |
| 914 | PocoHTTPClientGCPOAuth::BearerToken PocoHTTPClientGCPOAuth::requestBearerTokenFromADC() const |
| 915 | { |
nothing calls this directly
no test coverage detected