| /* |
| * |
| * Copyright 2015 gRPC authors. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| |
| #include "test/core/security/oauth2_utils.h" |
| |
| #include <string.h> |
| |
| #include <grpc/grpc.h> |
| #include <grpc/grpc_security.h> |
| #include <grpc/slice.h> |
| #include <grpc/support/alloc.h> |
| #include <grpc/support/log.h> |
| #include <grpc/support/sync.h> |
| |
| #include "src/core/lib/security/credentials/credentials.h" |
| |
| typedef struct { |
| gpr_mu* mu; |
| grpc_polling_entity pops; |
| bool is_done; |
| char* token; |
| |
| grpc_credentials_mdelem_array md_array; |
| grpc_closure closure; |
| } oauth2_request; |
| |
| static void on_oauth2_response(void* arg, grpc_error* error) { |
| oauth2_request* request = (oauth2_request*)arg; |
| char* token = nullptr; |
| grpc_slice token_slice; |
| if (error != GRPC_ERROR_NONE) { |
| gpr_log(GPR_ERROR, "Fetching token failed: %s", grpc_error_string(error)); |
| } else { |
| GPR_ASSERT(request->md_array.size == 1); |
| token_slice = GRPC_MDVALUE(request->md_array.md[0]); |
| token = (char*)gpr_malloc(GRPC_SLICE_LENGTH(token_slice) + 1); |
| memcpy(token, GRPC_SLICE_START_PTR(token_slice), |
| GRPC_SLICE_LENGTH(token_slice)); |
| token[GRPC_SLICE_LENGTH(token_slice)] = '\0'; |
| } |
| grpc_credentials_mdelem_array_destroy(&request->md_array); |
| gpr_mu_lock(request->mu); |
| request->is_done = true; |
| request->token = token; |
| GRPC_LOG_IF_ERROR( |
| "pollset_kick", |
| grpc_pollset_kick(grpc_polling_entity_pollset(&request->pops), nullptr)); |
| gpr_mu_unlock(request->mu); |
| } |
| |
| static void do_nothing(void* unused, grpc_error* error) {} |
| |
| char* grpc_test_fetch_oauth2_token_with_credentials( |
| grpc_call_credentials* creds) { |
| oauth2_request request; |
| memset(&request, 0, sizeof(request)); |
| grpc_core::ExecCtx exec_ctx; |
| grpc_closure do_nothing_closure; |
| grpc_auth_metadata_context null_ctx = {"", "", nullptr, nullptr}; |
| |
| grpc_pollset* pollset = (grpc_pollset*)gpr_zalloc(grpc_pollset_size()); |
| grpc_pollset_init(pollset, &request.mu); |
| request.pops = grpc_polling_entity_create_from_pollset(pollset); |
| request.is_done = false; |
| |
| GRPC_CLOSURE_INIT(&do_nothing_closure, do_nothing, nullptr, |
| grpc_schedule_on_exec_ctx); |
| |
| GRPC_CLOSURE_INIT(&request.closure, on_oauth2_response, &request, |
| grpc_schedule_on_exec_ctx); |
| |
| grpc_error* error = GRPC_ERROR_NONE; |
| if (grpc_call_credentials_get_request_metadata(creds, &request.pops, null_ctx, |
| &request.md_array, |
| &request.closure, &error)) { |
| // Synchronous result; invoke callback directly. |
| on_oauth2_response(&request, error); |
| GRPC_ERROR_UNREF(error); |
| } |
| grpc_core::ExecCtx::Get()->Flush(); |
| |
| gpr_mu_lock(request.mu); |
| while (!request.is_done) { |
| grpc_pollset_worker* worker = nullptr; |
| if (!GRPC_LOG_IF_ERROR( |
| "pollset_work", |
| grpc_pollset_work(grpc_polling_entity_pollset(&request.pops), |
| &worker, GRPC_MILLIS_INF_FUTURE))) { |
| request.is_done = true; |
| } |
| } |
| gpr_mu_unlock(request.mu); |
| |
| grpc_pollset_shutdown(grpc_polling_entity_pollset(&request.pops), |
| &do_nothing_closure); |
| |
| gpr_free(grpc_polling_entity_pollset(&request.pops)); |
| return request.token; |
| } |