1
#pragma once
2

            
3
#include <string>
4

            
5
#include "envoy/extensions/http/injected_credentials/oauth2/v3/oauth2.pb.h"
6
#include "envoy/extensions/http/injected_credentials/oauth2/v3/oauth2.pb.validate.h"
7
#include "envoy/stats/stats_macros.h"
8

            
9
#include "source/extensions/http/injected_credentials/common/credential.h"
10
#include "source/extensions/http/injected_credentials/common/secret_reader.h"
11
#include "source/extensions/http/injected_credentials/oauth2/oauth_client.h"
12

            
13
#include "oauth.h"
14

            
15
namespace Envoy {
16
namespace Extensions {
17
namespace Http {
18
namespace InjectedCredentials {
19
namespace OAuth2 {
20

            
21
/**
22
 * All Oauth2 access token provider stats. @see stats_macros.h
23
 */
24
#define ALL_OAUTH2_CLIENT_CREDENTIAL_TOKEN_PROVIDER_STATS(COUNTER)                                 \
25
25
  COUNTER(token_fetch_failed_on_client_secret)                                                     \
26
25
  COUNTER(token_fetch_failed_on_cluster_not_found)                                                 \
27
25
  COUNTER(token_fetch_failed_on_stream_reset)                                                      \
28
25
  COUNTER(token_fetch_failed_on_bad_token)                                                         \
29
25
  COUNTER(token_fetch_failed_on_bad_response_code)                                                 \
30
25
  COUNTER(token_requested)                                                                         \
31
25
  COUNTER(token_fetched)
32

            
33
/**
34
 * Struct definition for Oauth2 access token provider stats. @see stats_macros.h
35
 */
36
struct TokenProviderStats {
37
  ALL_OAUTH2_CLIENT_CREDENTIAL_TOKEN_PROVIDER_STATS(GENERATE_COUNTER_STRUCT)
38
};
39

            
40
using envoy::extensions::http::injected_credentials::oauth2::v3::OAuth2;
41

            
42
class ThreadLocalOauth2ClientCredentialsToken : public ThreadLocal::ThreadLocalObject {
43
public:
44
46
  ThreadLocalOauth2ClientCredentialsToken(absl::string_view token) : token_(token) {}
45

            
46
16
  const std::string& token() const { return token_; };
47

            
48
private:
49
  std::string token_;
50
};
51

            
52
using ThreadLocalOauth2ClientCredentialsTokenSharedPtr =
53
    std::shared_ptr<ThreadLocalOauth2ClientCredentialsToken>;
54

            
55
class TokenProvider : public Common::SecretReader,
56
                      public FilterCallbacks,
57
                      public Logger::Loggable<Logger::Id::credential_injector> {
58
public:
59
  TokenProvider(Common::SecretReaderConstSharedPtr secret_reader, ThreadLocal::SlotAllocator& tls,
60
                Upstream::ClusterManager& cm, const OAuth2& proto_config,
61
                Event::Dispatcher& dispatcher, const std::string& stats_prefix,
62
                Stats::Scope& scope);
63
  void asyncGetAccessToken();
64

            
65
16
  const ThreadLocalOauth2ClientCredentialsToken& threadLocal() const {
66
16
    return tls_->getTyped<ThreadLocalOauth2ClientCredentialsToken>();
67
16
  }
68

            
69
  // Common::SecretReader
70
  const std::string& credential() const override;
71

            
72
  // FilterCallbacks
73
  void onGetAccessTokenSuccess(const std::string& access_code, std::chrono::seconds) override;
74
  void onGetAccessTokenFailure(FilterCallbacks::FailureReason) override;
75

            
76
private:
77
25
  static TokenProviderStats generateStats(const std::string& prefix, Stats::Scope& scope) {
78
25
    return TokenProviderStats{
79
25
        ALL_OAUTH2_CLIENT_CREDENTIAL_TOKEN_PROVIDER_STATS(POOL_COUNTER_PREFIX(scope, prefix))};
80
25
  }
81

            
82
  std::string token_;
83
  const Common::SecretReaderConstSharedPtr secret_reader_;
84
  ThreadLocal::SlotPtr tls_;
85
  std::unique_ptr<OAuth2Client> oauth2_client_;
86
  std::string client_id_;
87
  const std::string oauth_scopes_;
88
  const std::map<std::string, std::string> endpoint_params_;
89
  Event::Dispatcher* dispatcher_;
90
  Event::TimerPtr timer_;
91
  TokenProviderStats stats_;
92
  // retry interval for fetching the token
93
  const std::chrono::seconds retry_interval_{2};
94
};
95

            
96
} // namespace OAuth2
97
} // namespace InjectedCredentials
98
} // namespace Http
99
} // namespace Extensions
100
} // namespace Envoy