blob: 6c139d1aeca24a1f8bc82f473bd3430fcd71afa9 [file] [log] [blame]
#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_