114 lines
3.0 KiB
C++
114 lines
3.0 KiB
C++
#pragma once
|
|||
|
|
|
||
|
|
// Data layer skeletons: sessions, basic auth, dual-backend ORM stub with
|
||
|
|
// self-healing demo, upload store, and WebDAV store.
|
||
|
|
// Gap: real 04-data.md owns the Postgres wire client, SQLite handling,
|
||
|
|
// pooling, transactions, and production self-healing; real password hashing
|
||
|
|
// (Argon2id) and encryption live in 03-security.md.
|
||
|
|
|
||
|
|
#include <map>
|
||
|
|
#include <mutex>
|
||
|
|
#include <string>
|
||
|
|
#include <vector>
|
||
|
|
|
||
|
|
namespace molo::example::fw {
|
||
|
|
|
||
|
|
class SessionStore {
|
||
|
|
public:
|
||
|
|
std::string create();
|
||
|
|
bool get(const std::string& id, std::map<std::string, std::string>& out);
|
||
|
|
void put(const std::string& id, const std::string& key,
|
||
|
|
const std::string& value);
|
||
|
|
void rotate(const std::string& old_id, std::string& new_id);
|
||
|
|
|
||
|
|
private:
|
||
|
|
mutable std::mutex mu_;
|
||
|
|
std::map<std::string, std::map<std::string, std::string>> sessions_;
|
||
|
|
unsigned long next_id_ = 1;
|
||
|
|
};
|
||
|
|
|
||
|
|
struct BasicUser {
|
||
|
|
std::string username;
|
||
|
|
std::string password_hash;
|
||
|
|
};
|
||
|
|
|
||
|
|
std::string demo_hash_password(const std::string& password);
|
||
|
|
bool parse_basic_auth(const std::string& header, std::string& user,
|
||
|
|
std::string& password);
|
||
|
|
|
||
|
|
class Auth {
|
||
|
|
public:
|
||
|
|
void add_user(const std::string& username, const std::string& password);
|
||
|
|
bool check(const std::string& username, const std::string& password) const;
|
||
|
|
|
||
|
|
private:
|
||
|
|
mutable std::mutex mu_;
|
||
|
|
std::map<std::string, std::string> users_;
|
||
|
|
};
|
||
|
|
|
||
|
|
enum class OrmBackend { Sqlite, Postgres };
|
||
|
|
|
||
|
|
std::string backend_name(OrmBackend backend);
|
||
|
|
OrmBackend parse_backend(const std::string& name);
|
||
|
|
|
||
|
|
struct OrmRow {
|
||
|
|
std::map<std::string, std::string> columns;
|
||
|
|
};
|
||
|
|
|
||
|
|
struct OrmResult {
|
||
|
|
bool ok = true;
|
||
|
|
bool healed = false;
|
||
|
|
std::string healed_note;
|
||
|
|
std::vector<OrmRow> rows;
|
||
|
|
};
|
||
|
|
|
||
|
|
class OrmDb {
|
||
|
|
public:
|
||
|
|
explicit OrmDb(OrmBackend backend);
|
||
|
|
|
||
|
|
OrmBackend backend() const;
|
||
|
|
OrmResult insert(const std::string& table,
|
||
|
|
const std::map<std::string, std::string>& values);
|
||
|
|
OrmResult select_all(const std::string& table);
|
||
|
|
OrmResult ensure_column(const std::string& table, const std::string& column);
|
||
|
|
std::vector<std::string> tables() const;
|
||
|
|
std::vector<std::string> columns(const std::string& table) const;
|
||
|
|
|
||
|
|
private:
|
||
|
|
OrmBackend backend_;
|
||
|
|
mutable std::mutex mu_;
|
||
|
|
std::map<std::string, std::vector<std::string>> schema_;
|
||
|
|
std::map<std::string, std::vector<OrmRow>> rows_;
|
||
|
|
};
|
||
|
|
|
||
|
|
struct UploadInfo {
|
||
|
|
std::string filename;
|
||
|
|
std::string content_type;
|
||
|
|
std::size_t size = 0;
|
||
|
|
};
|
||
|
|
|
||
|
|
class UploadStore {
|
||
|
|
public:
|
||
|
|
bool store(const std::string& filename, const std::string& content_type,
|
||
|
|
const std::string& data, UploadInfo& out, std::string& error);
|
||
|
|
std::vector<UploadInfo> list() const;
|
||
|
|
|
||
|
|
private:
|
||
|
|
mutable std::mutex mu_;
|
||
|
|
std::vector<UploadInfo> uploads_;
|
||
|
|
};
|
||
|
|
|
||
|
|
class WebdavStore {
|
||
|
|
public:
|
||
|
|
void put(const std::string& path, const std::string& content);
|
||
|
|
bool get(const std::string& path, std::string& out) const;
|
||
|
|
bool remove(const std::string& path);
|
||
|
|
std::string propfind_xml(const std::string& root) const;
|
||
|
|
|
||
|
|
private:
|
||
|
|
mutable std::mutex mu_;
|
||
|
|
std::map<std::string, std::string> files_;
|
||
|
|
};
|
||
|
|
|
||
|
|
} // namespace molo::example::fw
|