feat: CalDAV credential persistence in Secret Service

Move CalDAV username/password from in-memory config to Secret Service
(gnome-keyring). CalDAVSyncProvider now loads credentials at sync time
and erases them on disconnect. OAuthSecretStore extended with
store/load/erase_caldav_credential methods using a separate libsecret
schema.
This commit is contained in:
2026-07-23 20:39:16 +01:00
parent 5efcfdafb9
commit 23d95e957c
8 changed files with 230 additions and 12 deletions

View File

@@ -5,7 +5,7 @@
namespace nocal::sync {
// CalDAV account configuration.
// CalDAV account configuration (credentials loaded from Secret Service at runtime).
struct CalDAVAccountConfig {
std::string server_url;
std::string username;

View File

@@ -3,19 +3,28 @@
#include "nocal/sync/caldav_account.hpp"
#include "nocal/sync/http.hpp"
#include "nocal/sync/provider.hpp"
#include "nocal/sync/secret_store.hpp"
#include <memory>
#include <string>
namespace nocal::storage {
class SyncCache;
}
#include <string>
namespace nocal::sync {
// CalDAV server configuration (no credentials — those live in Secret Service).
struct CalDAVServerConfig {
std::string server_url;
std::string account_id;
std::string display_name;
};
class CalDAVSyncProvider final : public SyncProvider {
public:
CalDAVSyncProvider(HttpTransport& transport, storage::SyncCache& cache,
CalDAVAccountConfig config);
OAuthSecretStore& secret_store, CalDAVServerConfig config);
std::string_view provider_id() const noexcept override { return "caldav"; }
ConnectedAccount connect_account() override;
@@ -25,7 +34,8 @@ public:
private:
HttpTransport& transport_;
storage::SyncCache& cache_;
CalDAVAccountConfig config_;
OAuthSecretStore& secret_store_;
CalDAVServerConfig config_;
};
} // namespace nocal::sync

View File

@@ -9,6 +9,13 @@
namespace nocal::sync {
struct CalDAVCredential {
std::string username;
std::string password;
bool operator==(const CalDAVCredential&) const = default;
};
class SecretStoreError : public std::runtime_error {
public:
enum class Kind {
@@ -34,6 +41,13 @@ public:
[[nodiscard]] virtual std::optional<OAuthTokens> load(
std::string account_id, std::stop_token stop = {}) = 0;
virtual void erase(std::string account_id, std::stop_token stop = {}) = 0;
virtual void store_caldav_credential(std::string account_id,
const CalDAVCredential& credential, std::stop_token stop = {}) = 0;
[[nodiscard]] virtual std::optional<CalDAVCredential> load_caldav_credential(
std::string account_id, std::stop_token stop = {}) = 0;
virtual void erase_caldav_credential(std::string account_id,
std::stop_token stop = {}) = 0;
};
// Synchronous libsecret adapter. Call only from a worker thread: Secret Service
@@ -45,6 +59,13 @@ public:
[[nodiscard]] std::optional<OAuthTokens> load(
std::string account_id, std::stop_token stop = {}) override;
void erase(std::string account_id, std::stop_token stop = {}) override;
void store_caldav_credential(std::string account_id,
const CalDAVCredential& credential, std::stop_token stop = {}) override;
[[nodiscard]] std::optional<CalDAVCredential> load_caldav_credential(
std::string account_id, std::stop_token stop = {}) override;
void erase_caldav_credential(std::string account_id,
std::stop_token stop = {}) override;
};
} // namespace nocal::sync