| #ifndef THIRD_PARTY_MILOTIC_INTERNAL_CC_PROXY_REDFISH_SESSION_AUTH_H_ |
| #define THIRD_PARTY_MILOTIC_INTERNAL_CC_PROXY_REDFISH_SESSION_AUTH_H_ |
| |
| #include <memory> |
| #include <optional> |
| #include <string> |
| |
| #include "absl/base/no_destructor.h" |
| #include "absl/base/thread_annotations.h" |
| #include "absl/status/status.h" |
| #include "absl/status/statusor.h" |
| #include "absl/strings/str_cat.h" |
| #include "absl/strings/string_view.h" |
| #include "absl/synchronization/mutex.h" |
| #include "absl/time/clock.h" |
| #include "absl/time/time.h" |
| #include <source_location> |
| #include "proxy.h" |
| #include "proxy_config.pb.h" |
| #include "redfish_plugin.h" |
| #include "remote_credentials.h" |
| #include "request_response.h" |
| |
| namespace milotic { |
| |
| class RedfishSessionAuthPlugin : public RedfishPlugin { |
| public: |
| struct SessionState { |
| static constexpr absl::string_view kUninit = "plugin_uninitialized"; |
| static constexpr absl::string_view kOk = "ok"; |
| static constexpr absl::string_view kAbsent = "absent"; |
| static constexpr absl::string_view kLost = "lost"; |
| static constexpr absl::string_view kFailed = "failed"; |
| static constexpr absl::string_view kNoCredentials = "no_credentials"; |
| static constexpr absl::string_view kDisabled = "disabled"; |
| }; |
| |
| explicit RedfishSessionAuthPlugin( |
| const milotic_grpc_proxy::Plugin::RedfishSessionAuth& config) |
| : credentials_{.username = config.username().empty() |
| ? std::nullopt |
| : std::make_optional(config.username()), |
| .password = config.password()}, |
| credentials_file_manager_(CredentialsFileReader(), |
| CredentialsFileWriter()), |
| only_use_basic_auth_(config.only_use_basic_auth()) { |
| if (config.session_check_interval_sec() > 0) { |
| session_check_interval_ = |
| absl::Seconds(config.session_check_interval_sec()); |
| } |
| credentials_file_manager_.AddSourceFiles( |
| config.credentials_file().path().begin(), |
| config.credentials_file().path().end()); |
| if (!config.credentials_file().private_cache_path().empty()) { |
| credentials_file_manager_.SetPrivateCachePath( |
| config.credentials_file().private_cache_path()); |
| } |
| } |
| |
| RequestAction PreprocessRequest(RedfishPlugin::RequestVerb verb, |
| ProxyRequest& request) override; |
| |
| absl::StatusOr<ProxyResponse> HandleRequest( |
| RedfishPlugin::RequestVerb verb, |
| std::unique_ptr<ProxyRequest> request) override; |
| |
| absl::Status Subscribe(std::unique_ptr<ProxyRequest> /*request*/, |
| EventHandler* /*handler*/) override { |
| return absl::UnknownError("Function should never be called"); |
| } |
| |
| absl::Status Initialize(Proxy* proxy) override; |
| |
| static milotic::CredentialsFileReader& CredentialsFileReader() { |
| static absl::NoDestructor<milotic::CredentialsFileReader> reader( |
| UnimplementedCredentialsFileReader); |
| return *reader; |
| } |
| |
| static milotic::CredentialsFileWriter& CredentialsFileWriter() { |
| static absl::NoDestructor<milotic::CredentialsFileWriter> writer( |
| UnimplementedCredentialsFileWriter); |
| return *writer; |
| } |
| |
| static std::string SessionStateResourcePath(absl::string_view plugin_name) { |
| return absl::StrCat("/", plugin_name, "/session_state"); |
| } |
| |
| std::string SessionStateResourcePath() const { |
| return SessionStateResourcePath(Name()); |
| } |
| |
| protected: |
| virtual absl::Time Now() { return absl::Now(); } |
| |
| private: |
| std::optional<absl::string_view> MaybeGetNewToken(bool force) |
| ABSL_LOCKS_EXCLUDED(token_state_mutex_); |
| absl::Status GetSessionService() |
| ABSL_EXCLUSIVE_LOCKS_REQUIRED(token_state_mutex_); |
| absl::Status GetToken() ABSL_EXCLUSIVE_LOCKS_REQUIRED(token_state_mutex_); |
| absl::Status LoadCredentials( |
| const absl::StatusOr<RemoteCredentials>& credentials) |
| ABSL_EXCLUSIVE_LOCKS_REQUIRED(token_state_mutex_); |
| absl::Status DeleteSession() |
| ABSL_EXCLUSIVE_LOCKS_REQUIRED(token_state_mutex_); |
| void InsertAuth(std::optional<absl::string_view> token, |
| ProxyRequest* request); |
| absl::Status CheckSession(std::optional<absl::Time> after = std::nullopt) |
| ABSL_LOCKS_EXCLUDED(token_state_mutex_); |
| void SetState(absl::string_view state, |
| const std::source_location& source_location = |
| std::source_location::current()) |
| ABSL_EXCLUSIVE_LOCKS_REQUIRED(token_state_mutex_); |
| |
| Proxy* proxy_; |
| RemoteCredentials credentials_; |
| CredentialsFileManager credentials_file_manager_; |
| absl::Duration session_check_interval_ = absl::Minutes(10); |
| absl::Mutex token_state_mutex_; |
| std::optional<std::string> token_ ABSL_GUARDED_BY(token_state_mutex_); |
| absl::Time token_timeout_ ABSL_GUARDED_BY(token_state_mutex_) = |
| absl::InfinitePast(); |
| absl::Duration session_timeout_ ABSL_GUARDED_BY(token_state_mutex_) = |
| absl::ZeroDuration(); |
| std::optional<std::string> session_ ABSL_GUARDED_BY(token_state_mutex_); |
| bool only_use_basic_auth_; |
| absl::string_view session_state_ ABSL_GUARDED_BY(token_state_mutex_) = |
| SessionState::kUninit; |
| }; |
| |
| } // namespace milotic |
| |
| #endif // THIRD_PARTY_MILOTIC_INTERNAL_CC_PROXY_REDFISH_SESSION_AUTH_H_ |