Coverage Report

Created: 2023-11-12 09:30

/proc/self/cwd/source/extensions/filters/network/ext_authz/ext_authz.h
Line
Count
Source (jump to first uncovered line)
1
#pragma once
2
3
#include <cstdint>
4
#include <memory>
5
#include <string>
6
#include <vector>
7
8
#include "envoy/extensions/filters/network/ext_authz/v3/ext_authz.pb.h"
9
#include "envoy/network/connection.h"
10
#include "envoy/network/filter.h"
11
#include "envoy/runtime/runtime.h"
12
#include "envoy/service/auth/v3/external_auth.pb.h"
13
#include "envoy/stats/scope.h"
14
#include "envoy/stats/stats_macros.h"
15
#include "envoy/upstream/cluster_manager.h"
16
17
#include "source/common/common/matchers.h"
18
#include "source/extensions/filters/common/ext_authz/ext_authz.h"
19
#include "source/extensions/filters/common/ext_authz/ext_authz_grpc_impl.h"
20
21
namespace Envoy {
22
namespace Extensions {
23
namespace NetworkFilters {
24
namespace ExtAuthz {
25
26
/**
27
 * All tcp external authorization stats. @see stats_macros.h
28
 */
29
#define ALL_TCP_EXT_AUTHZ_STATS(COUNTER, GAUGE)                                                    \
30
9
  COUNTER(cx_closed)                                                                               \
31
9
  COUNTER(denied)                                                                                  \
32
9
  COUNTER(error)                                                                                   \
33
9
  COUNTER(failure_mode_allowed)                                                                    \
34
9
  COUNTER(ok)                                                                                      \
35
9
  COUNTER(total)                                                                                   \
36
9
  COUNTER(disabled)                                                                                \
37
9
  GAUGE(active, Accumulate)
38
39
/**
40
 * Struct definition for all external authorization stats. @see stats_macros.h
41
 */
42
struct InstanceStats {
43
  ALL_TCP_EXT_AUTHZ_STATS(GENERATE_COUNTER_STRUCT, GENERATE_GAUGE_STRUCT)
44
};
45
46
/**
47
 * Global configuration for ExtAuthz filter.
48
 */
49
class Config {
50
  using LabelsMap = Protobuf::Map<std::string, std::string>;
51
52
public:
53
  Config(const envoy::extensions::filters::network::ext_authz::v3::ExtAuthz& config,
54
         Stats::Scope& scope, envoy::config::bootstrap::v3::Bootstrap& bootstrap)
55
      : stats_(generateStats(config.stat_prefix(), scope)),
56
        failure_mode_allow_(config.failure_mode_allow()),
57
        include_peer_certificate_(config.include_peer_certificate()),
58
        filter_enabled_metadata_(
59
            config.has_filter_enabled_metadata()
60
                ? absl::optional<Matchers::MetadataMatcher>(config.filter_enabled_metadata())
61
9
                : absl::nullopt) {
62
9
    auto labels_key_it =
63
9
        bootstrap.node().metadata().fields().find(config.bootstrap_metadata_labels_key());
64
9
    if (labels_key_it != bootstrap.node().metadata().fields().end()) {
65
0
      for (const auto& labels_it : labels_key_it->second.struct_value().fields()) {
66
0
        destination_labels_[labels_it.first] = labels_it.second.string_value();
67
0
      }
68
0
    }
69
9
  }
70
71
72
  const InstanceStats& stats() { return stats_; }
72
0
  bool failureModeAllow() const { return failure_mode_allow_; }
73
0
  void setFailModeAllow(bool value) { failure_mode_allow_ = value; }
74
3
  bool includePeerCertificate() const { return include_peer_certificate_; }
75
3
  const LabelsMap& destinationLabels() const { return destination_labels_; }
76
243
  bool filterEnabledMetadata(const envoy::config::core::v3::Metadata& metadata) const {
77
243
    return filter_enabled_metadata_.has_value() ? filter_enabled_metadata_->match(metadata) : true;
78
243
  }
79
80
private:
81
  static InstanceStats generateStats(const std::string& name, Stats::Scope& scope);
82
  const InstanceStats stats_;
83
  bool failure_mode_allow_;
84
  LabelsMap destination_labels_;
85
  const bool include_peer_certificate_;
86
  const absl::optional<Matchers::MetadataMatcher> filter_enabled_metadata_;
87
};
88
89
using ConfigSharedPtr = std::shared_ptr<Config>;
90
91
/**
92
 * ExtAuthz filter instance. This filter will call the Authorization service with the given
93
 * configuration parameters. If the authorization service returns an error or a deny the
94
 * connection will be closed without any further filters being called. Otherwise all buffered
95
 * data will be released to further filters.
96
 */
97
class Filter : public Network::ReadFilter,
98
               public Network::ConnectionCallbacks,
99
               public Filters::Common::ExtAuthz::RequestCallbacks {
100
  using LabelsMap = std::map<std::string, std::string>;
101
102
public:
103
  Filter(ConfigSharedPtr config, Filters::Common::ExtAuthz::ClientPtr&& client)
104
6
      : config_(config), client_(std::move(client)) {}
105
6
  ~Filter() override = default;
106
107
  // Network::ReadFilter
108
  Network::FilterStatus onData(Buffer::Instance& data, bool end_stream) override;
109
  Network::FilterStatus onNewConnection() override;
110
6
  void initializeReadFilterCallbacks(Network::ReadFilterCallbacks& callbacks) override {
111
6
    filter_callbacks_ = &callbacks;
112
6
    filter_callbacks_->connection().addConnectionCallbacks(*this);
113
6
  }
114
115
  // Network::ConnectionCallbacks
116
  void onEvent(Network::ConnectionEvent event) override;
117
0
  void onAboveWriteBufferHighWatermark() override {}
118
0
  void onBelowWriteBufferLowWatermark() override {}
119
120
  // ExtAuthz::RequestCallbacks
121
  void onComplete(Filters::Common::ExtAuthz::ResponsePtr&&) override;
122
123
private:
124
  // State of this filter's communication with the external authorization service.
125
  // The filter has either not started calling the external service, in the middle of calling
126
  // it or has completed.
127
  enum class Status { NotStarted, Calling, Complete };
128
  // FilterReturn is used to capture what the return code should be to the filter chain.
129
  // if this filter is either in the middle of calling the external service or the result is denied
130
  // then the filter chain should stop. Otherwise the filter chain can continue to the next filter.
131
  enum class FilterReturn { Stop, Continue };
132
  void callCheck();
133
134
243
  bool filterEnabled(const envoy::config::core::v3::Metadata& metadata) {
135
243
    return config_->filterEnabledMetadata(metadata);
136
243
  }
137
  absl::optional<MonotonicTime> start_time_;
138
139
  ConfigSharedPtr config_;
140
  Filters::Common::ExtAuthz::ClientPtr client_;
141
  Network::ReadFilterCallbacks* filter_callbacks_{};
142
  Status status_{Status::NotStarted};
143
  FilterReturn filter_return_{FilterReturn::Stop};
144
  // Used to identify if the callback to onComplete() is synchronous (on the stack) or asynchronous.
145
  bool calling_check_{};
146
  envoy::service::auth::v3::CheckRequest check_request_{};
147
};
148
} // namespace ExtAuthz
149
} // namespace NetworkFilters
150
} // namespace Extensions
151
} // namespace Envoy