1
#include "source/extensions/grpc_credentials/example/config.h"
2

            
3
#include "envoy/config/core/v3/grpc_service.pb.h"
4
#include "envoy/grpc/google_grpc_creds.h"
5
#include "envoy/registry/registry.h"
6

            
7
#include "source/common/grpc/google_grpc_creds_impl.h"
8

            
9
namespace Envoy {
10
namespace Extensions {
11
namespace GrpcCredentials {
12
namespace Example {
13

            
14
std::shared_ptr<grpc::ChannelCredentials>
15
AccessTokenExampleGrpcCredentialsFactory::getChannelCredentials(
16
    const envoy::config::core::v3::GrpcService& grpc_service_config,
17
5
    Server::Configuration::CommonFactoryContext& context) {
18
5
  const auto& google_grpc = grpc_service_config.google_grpc();
19
5
  std::shared_ptr<grpc::ChannelCredentials> creds =
20
5
      Grpc::CredsUtility::defaultSslChannelCredentials(grpc_service_config, context.api());
21
5
  std::shared_ptr<grpc::CallCredentials> call_creds = nullptr;
22
7
  for (const auto& credential : google_grpc.call_credentials()) {
23
7
    switch (credential.credential_specifier_case()) {
24
6
    case envoy::config::core::v3::GrpcService::GoogleGrpc::CallCredentials::
25
6
        CredentialSpecifierCase::kAccessToken: {
26
6
      if (!credential.access_token().empty()) {
27
5
        std::shared_ptr<grpc::CallCredentials> new_call_creds = grpc::MetadataCredentialsFromPlugin(
28
5
            std::make_unique<StaticHeaderAuthenticator>(credential.access_token()));
29
5
        if (call_creds == nullptr) {
30
4
          call_creds = new_call_creds;
31
4
        } else {
32
1
          call_creds = grpc::CompositeCallCredentials(call_creds, new_call_creds);
33
1
        }
34
5
      }
35
6
      break;
36
    }
37
1
    default:
38
      // unused credential types
39
1
      continue;
40
7
    }
41
7
  }
42
5
  if (call_creds != nullptr) {
43
4
    return grpc::CompositeChannelCredentials(creds, call_creds);
44
4
  }
45
1
  return creds;
46
5
}
47

            
48
grpc::Status
49
StaticHeaderAuthenticator::GetMetadata(grpc::string_ref, grpc::string_ref, const grpc::AuthContext&,
50
5
                                       std::multimap<grpc::string, grpc::string>* metadata) {
51
  // this function is run on a separate thread by the gRPC client library (independent of Envoy
52
  // threading), so it can perform actions such as refreshing an access token without blocking
53
  // the main thread. see:
54
  // https://grpc.io/grpc/cpp/classgrpc_1_1_metadata_credentials_plugin.html#a6faf44f7c08d0311a38a868fdb8cbaf0
55
5
  metadata->insert(std::make_pair("authorization", "Bearer " + ticket_));
56
5
  return grpc::Status::OK;
57
5
}
58

            
59
/**
60
 * Static registration for the static header Google gRPC credentials factory. @see RegisterFactory.
61
 */
62
REGISTER_FACTORY(AccessTokenExampleGrpcCredentialsFactory, Grpc::GoogleGrpcCredentialsFactory);
63

            
64
} // namespace Example
65
} // namespace GrpcCredentials
66
} // namespace Extensions
67
} // namespace Envoy