20#ifndef ORES_COMMS_NET_CLIENT_SESSION_HPP
21#define ORES_COMMS_NET_CLIENT_SESSION_HPP
27#include <boost/uuid/uuid.hpp>
28#include "ores.utility/log/make_logger.hpp"
29#include "ores.comms/messaging/message_types.hpp"
30#include "ores.comms/messaging/frame.hpp"
31#include "ores.comms/messaging/error_protocol.hpp"
32#include "ores.comms/net/client.hpp"
33#include "ores.comms/net/client_options.hpp"
41 boost::uuids::uuid account_id;
55 deserialization_failed,
59template<
typename Request>
60concept Serializable =
requires(Request req) {
61 { req.serialize() } -> std::convertible_to<std::vector<std::byte>>;
64template<
typename Response>
65concept Deserializable =
requires(std::span<const std::byte> data) {
67 Response::deserialize(data)
68 } -> std::same_as<std::expected<Response, messaging::error_code>>;
83 inline static std::string_view logger_name =
84 "ores.comms.net.client_session";
88 static auto instance = make_logger(logger_name);
128 return session_info_.has_value();
139 session_info_ = std::move(info);
148 session_info_.reset();
155 return session_info_.has_value() && session_info_->is_admin;
161 [[nodiscard]]
const std::optional<client_session_info>&
session_info() const noexcept {
162 return session_info_;
176 template <Serializable RequestType,
177 Deserializable ResponseType,
178 messaging::message_type RequestMsgType>
179 std::expected<ResponseType, client_session_error>
183 if (!client_ || !client_->is_connected()) {
184 BOOST_LOG_SEV(lg(), error) <<
"Not connected to server";
185 return std::unexpected(client_session_error::not_connected);
188 BOOST_LOG_SEV(lg(), debug) <<
"Processing request type: "
191 auto payload = request.serialize();
194 auto response_result = client_->send_request_sync(std::move(request_frame));
196 if (!response_result) {
197 BOOST_LOG_SEV(lg(), error) <<
"Request failed with error code: "
198 <<
static_cast<int>(response_result.error());
199 return std::unexpected(client_session_error::request_failed);
202 auto decompressed = response_result->decompressed_payload();
204 BOOST_LOG_SEV(lg(), error) <<
"Failed to decompress response payload";
205 return std::unexpected(client_session_error::deserialization_failed);
209 if (response_result->header().type == messaging::message_type::error_response) {
212 BOOST_LOG_SEV(lg(), error) <<
"Server returned error: "
213 << err_resp->message;
215 return std::unexpected(client_session_error::server_error);
218 auto response = ResponseType::deserialize(*decompressed);
220 BOOST_LOG_SEV(lg(), error) <<
"Failed to deserialize response";
221 return std::unexpected(client_session_error::deserialization_failed);
224 BOOST_LOG_SEV(lg(), debug) <<
"Successfully processed request";
225 return std::move(*response);
239 template <Serializable RequestType,
240 Deserializable ResponseType,
241 messaging::message_type RequestMsgType>
242 std::expected<ResponseType, client_session_error>
246 BOOST_LOG_SEV(lg(), warn) <<
"Attempted authenticated request while "
248 return std::unexpected(client_session_error::not_logged_in);
250 return process_request<RequestType, ResponseType, RequestMsgType>(
266 template <Serializable RequestType,
267 Deserializable ResponseType,
268 messaging::message_type RequestMsgType>
269 std::expected<ResponseType, client_session_error>
273 BOOST_LOG_SEV(lg(), warn) <<
"Attempted admin request while "
275 return std::unexpected(client_session_error::not_logged_in);
278 BOOST_LOG_SEV(lg(), warn) <<
"Attempted admin request without "
279 <<
"admin privileges";
280 return std::unexpected(client_session_error::admin_required);
282 return process_request<RequestType, ResponseType, RequestMsgType>(
287 std::shared_ptr<client> client_;
288 std::optional<client_session_info> session_info_;
Contains the networking elements of the comms library.
Definition client.hpp:42
std::string to_string(client_session_error error)
Convert client_session_error to string for display.
Definition client_session.cpp:79
client_session_error
Error codes specific to client session operations.
Definition client_session.hpp:49
Implements logging for ORE Studio.
Definition lifecycle_manager.hpp:30
static std::expected< error_response, error_code > deserialize(std::span< const std::byte > data)
Deserialize from frame payload.
Definition handshake.cpp:112
Complete frame with header and payload.
Definition frame.hpp:77
Configuration for the client.
Definition client_options.hpp:78
Information about the client's authenticated session.
Definition client_session.hpp:40
Client-side session manager providing auth-aware request handling.
Definition client_session.hpp:81
std::expected< void, client_session_error > connect(client_options options)
Connect to the server.
Definition client_session.cpp:33
bool is_connected() const noexcept
Check if connected to server.
Definition client_session.cpp:75
const std::optional< client_session_info > & session_info() const noexcept
Get current session info if logged in.
Definition client_session.hpp:161
std::expected< ResponseType, client_session_error > process_request(RequestType request)
Process a request that does not require authentication.
Definition client_session.hpp:180
std::expected< ResponseType, client_session_error > process_authenticated_request(RequestType request)
Process a request that requires authentication.
Definition client_session.hpp:243
bool is_admin() const noexcept
Check if logged in as admin.
Definition client_session.hpp:154
bool is_logged_in() const noexcept
Check if logged in.
Definition client_session.hpp:127
void clear_session_info() noexcept
Clear session info on logout.
Definition client_session.hpp:147
void disconnect()
Disconnect from the server.
Definition client_session.cpp:56
void set_session_info(client_session_info info)
Set session info after successful login.
Definition client_session.hpp:138
std::expected< ResponseType, client_session_error > process_admin_request(RequestType request)
Process a request that requires admin privileges.
Definition client_session.hpp:270