Commit 8d814a70 authored by jan.koester's avatar jan.koester
Browse files

optimize

parent 20cafd38
Loading
Loading
Loading
Loading
+38 −49
Original line number Diff line number Diff line
@@ -192,49 +192,36 @@ void App::store_session(const std::string& token, const std::string& username,
    sessions_[token] = SessionInfo{username, domain_label, group_ids, std::chrono::steady_clock::now()};
}

std::string App::get_session_username(const HttpRequest& req) const {
// Caller must hold session_mutex_.
const App::SessionInfo* App::find_session(const HttpRequest& req) const {
    auto it = req.headers.find("authorization");
    if (it == req.headers.end()) return {};
    if (it == req.headers.end()) return nullptr;
    const std::string& value = it->second;
    const std::string prefix = "Bearer ";
    if (value.size() <= prefix.size() || value.compare(0, prefix.size(), prefix) != 0) return {};
    const std::string token = value.substr(prefix.size());
    std::lock_guard<std::mutex> lk(session_mutex_);
    auto sit = sessions_.find(token);
    if (sit == sessions_.end()) return {};
    constexpr std::string_view prefix = "Bearer ";
    if (value.size() <= prefix.size() || value.compare(0, prefix.size(), prefix.data()) != 0) return nullptr;
    auto sit = sessions_.find(value.substr(prefix.size()));
    if (sit == sessions_.end()) return nullptr;
    if (std::chrono::steady_clock::now() - sit->second.created_at > std::chrono::seconds(SESSION_TTL_SECONDS))
        return {};
    return sit->second.username;
        return nullptr;
    return &sit->second;
}

std::string App::get_session_username(const HttpRequest& req) const {
    std::lock_guard<std::mutex> lk(session_mutex_);
    auto* s = find_session(req);
    return s ? s->username : std::string{};
}

std::string App::get_session_domain(const HttpRequest& req) const {
    auto it = req.headers.find("authorization");
    if (it == req.headers.end()) return {};
    const std::string& value = it->second;
    const std::string prefix = "Bearer ";
    if (value.size() <= prefix.size() || value.compare(0, prefix.size(), prefix) != 0) return {};
    const std::string token = value.substr(prefix.size());
    std::lock_guard<std::mutex> lk(session_mutex_);
    auto sit = sessions_.find(token);
    if (sit == sessions_.end()) return {};
    if (std::chrono::steady_clock::now() - sit->second.created_at > std::chrono::seconds(SESSION_TTL_SECONDS))
        return {};
    return sit->second.domain_label;
    auto* s = find_session(req);
    return s ? s->domain_label : std::string{};
}

std::vector<std::string> App::get_session_groups(const HttpRequest& req) const {
    auto it = req.headers.find("authorization");
    if (it == req.headers.end()) return {};
    const std::string& value = it->second;
    const std::string prefix = "Bearer ";
    if (value.size() <= prefix.size() || value.compare(0, prefix.size(), prefix) != 0) return {};
    const std::string token = value.substr(prefix.size());
    std::lock_guard<std::mutex> lk(session_mutex_);
    auto sit = sessions_.find(token);
    if (sit == sessions_.end()) return {};
    if (std::chrono::steady_clock::now() - sit->second.created_at > std::chrono::seconds(SESSION_TTL_SECONDS))
        return {};
    return sit->second.group_ids;
    auto* s = find_session(req);
    return s ? s->group_ids : std::vector<std::string>{};
}

std::vector<std::string> App::resolve_session_groups(authdb::client::Client& client) {
@@ -279,18 +266,8 @@ void App::repopulate_session(const HttpRequest& req) {
}

bool App::is_session_known(const HttpRequest& req) const {
    auto it = req.headers.find("authorization");
    if (it == req.headers.end()) return false;
    const std::string& value = it->second;
    const std::string prefix = "Bearer ";
    if (value.size() <= prefix.size() || value.compare(0, prefix.size(), prefix) != 0) return false;
    const std::string token = value.substr(prefix.size());
    std::lock_guard<std::mutex> lk(session_mutex_);
    auto sit = sessions_.find(token);
    if (sit == sessions_.end()) return false;
    if (std::chrono::steady_clock::now() - sit->second.created_at > std::chrono::seconds(SESSION_TTL_SECONDS))
        return false;
    return true;
    return find_session(req) != nullptr;
}

bool App::is_any_authorized(const HttpRequest& req) {
@@ -303,12 +280,18 @@ bool App::is_any_authorized(const HttpRequest& req) {
}

bool App::has_store_access(const HttpRequest& req, const std::string& store_id) const {
    const std::string domain = get_session_domain(req);
    if (domain.empty()) return true;
    std::string domain;
    std::vector<std::string> grps;
    {
        std::lock_guard<std::mutex> lk(session_mutex_);
        auto* s = find_session(req);
        if (!s || s->domain_label.empty()) return true;
        domain = s->domain_label;
        grps = s->group_ids;
    }

    auto acls = db_.list_store_acls(store_id);
    if (!acls.empty()) {
        auto grps = get_session_groups(req);
        for (const auto& acl : acls) {
            if (!acl.can_read) continue;
            for (const auto& gid : grps) {
@@ -326,12 +309,18 @@ bool App::has_store_access(const HttpRequest& req, const std::string& store_id)
}

bool App::has_store_write_access(const HttpRequest& req, const std::string& store_id) const {
    const std::string domain = get_session_domain(req);
    if (domain.empty()) return true;
    std::string domain;
    std::vector<std::string> grps;
    {
        std::lock_guard<std::mutex> lk(session_mutex_);
        auto* s = find_session(req);
        if (!s || s->domain_label.empty()) return true;
        domain = s->domain_label;
        grps = s->group_ids;
    }

    auto acls = db_.list_store_acls(store_id);
    if (!acls.empty()) {
        auto grps = get_session_groups(req);
        for (const auto& acl : acls) {
            if (!acl.can_write) continue;
            for (const auto& gid : grps) {
+1 −0
Original line number Diff line number Diff line
@@ -142,6 +142,7 @@ private:
    mutable std::mutex session_mutex_;
    std::unordered_map<std::string, SessionInfo> sessions_;
    void evict_expired_sessions();
    const SessionInfo* find_session(const HttpRequest& req) const;

    // import state
    std::mutex import_mutex_;
+14 −6
Original line number Diff line number Diff line
@@ -278,6 +278,7 @@ std::vector<AlbumRecord> BinDb::list_albums(const std::string& store_id) const {
    std::vector<AlbumRecord> out;
    auto sit = stores_.find(store_id);
    if (sit == stores_.end()) return out;
    out.reserve(sit->second.album_ids.size());
    for (const auto& aid : sit->second.album_ids) {
        auto ait = albums_.find(aid);
        if (ait != albums_.end()) out.push_back(ait->second);
@@ -400,6 +401,7 @@ std::vector<MediaRecord> BinDb::list_media(const std::string& album_id) const {
    std::vector<MediaRecord> out;
    auto ait = albums_.find(album_id);
    if (ait == albums_.end()) return out;
    out.reserve(ait->second.media_ids.size());
    for (const auto& mid : ait->second.media_ids) {
        auto mit = media_.find(mid);
        if (mit != media_.end()) out.push_back(mit->second);
@@ -512,6 +514,10 @@ bool BinDb::export_db(const std::string& path) const {
            bin_write_str(out, store.created_at);
            bin_write_u32(out, static_cast<std::uint32_t>(store.album_ids.size()));

            std::ifstream sin;
            constexpr std::size_t BUF = 1024 * 1024;
            std::vector<char> buf(BUF);

            for (const auto& aid : store.album_ids) {
                auto ait = albums_.find(aid);
                if (ait == albums_.end()) {
@@ -545,11 +551,10 @@ bool BinDb::export_db(const std::string& path) const {
                        out.write(reinterpret_cast<const char*>(m.pending_data.data()),
                                  static_cast<std::streamsize>(m.pending_data.size()));
                    } else if (m.data_offset > 0 && m.size_bytes > 0) {
                        std::ifstream sin(store_file(sid), std::ios::binary);
                        if (!sin.is_open())
                            sin.open(store_file(sid), std::ios::binary);
                        if (sin.is_open()) {
                            sin.seekg(static_cast<std::streamoff>(m.data_offset));
                            constexpr std::size_t BUF = 1024 * 1024;
                            std::vector<char> buf(BUF);
                            std::uint64_t remaining = m.size_bytes;
                            while (remaining > 0 && sin.good()) {
                                auto chunk = static_cast<std::streamsize>(
@@ -591,6 +596,10 @@ std::vector<std::uint8_t> BinDb::export_db_to_buffer() const {
        wr_str(store.created_at);
        wr_u32(static_cast<std::uint32_t>(store.album_ids.size()));

        std::ifstream sin;
        constexpr std::size_t BUF = 1024 * 1024;
        std::vector<char> buf(BUF);

        for (const auto& aid : store.album_ids) {
            auto ait = albums_.find(aid);
            if (ait == albums_.end()) {
@@ -624,11 +633,10 @@ std::vector<std::uint8_t> BinDb::export_db_to_buffer() const {
                    oss.write(reinterpret_cast<const char*>(m.pending_data.data()),
                              static_cast<std::streamsize>(m.pending_data.size()));
                } else if (m.data_offset > 0 && m.size_bytes > 0) {
                    std::ifstream sin(store_file(sid), std::ios::binary);
                    if (!sin.is_open())
                        sin.open(store_file(sid), std::ios::binary);
                    if (sin.is_open()) {
                        sin.seekg(static_cast<std::streamoff>(m.data_offset));
                        constexpr std::size_t BUF = 1024 * 1024;
                        std::vector<char> buf(BUF);
                        std::uint64_t remaining = m.size_bytes;
                        while (remaining > 0 && sin.good()) {
                            auto chunk = static_cast<std::streamsize>(
+13 −11
Original line number Diff line number Diff line
@@ -10,7 +10,7 @@
#include <algorithm>
#include <filesystem>
#include <iostream>
#include <sstream>
#include <string_view>

namespace mediadb {

@@ -340,16 +340,18 @@ std::unordered_map<std::string, std::string> MediaHttpEvent::parse_query(const s
    std::unordered_map<std::string, std::string> result;
    auto qpos = raw_url.find('?');
    if (qpos == std::string::npos) return result;
    std::string qs = raw_url.substr(qpos + 1);
    std::istringstream stream(qs);
    std::string pair;
    while (std::getline(stream, pair, '&')) {
        auto eq = pair.find('=');
        if (eq != std::string::npos) {
            result[pair.substr(0, eq)] = pair.substr(eq + 1);
        } else {
            result[pair] = "";
        }
    std::string_view qs(raw_url);
    qs.remove_prefix(qpos + 1);
    while (!qs.empty()) {
        auto amp = qs.find('&');
        auto seg = qs.substr(0, amp);
        auto eq = seg.find('=');
        if (eq != std::string_view::npos)
            result[std::string(seg.substr(0, eq))] = std::string(seg.substr(eq + 1));
        else if (!seg.empty())
            result[std::string(seg)] = "";
        if (amp == std::string_view::npos) break;
        qs.remove_prefix(amp + 1);
    }
    return result;
}