feat: add Linux OAuth adapters
Add a bounded libcurl transport with verified TLS, no redirects or retries, sanitized failures, binary-safe requests, and resolved-address enforcement for cleartext loopback traffic. Add shell-free xdg-open launching and a one-shot IPv4 loopback callback receiver with strict HTTP/query parsing, deadlines, fixed callback path, and RAII cleanup. Token parsing, Secret Service, and Graph remain follow-up phases.
This commit is contained in:
45
include/nocal/sync/curl_http.hpp
Normal file
45
include/nocal/sync/curl_http.hpp
Normal file
@@ -0,0 +1,45 @@
|
||||
#pragma once
|
||||
|
||||
#include "nocal/sync/http.hpp"
|
||||
|
||||
#include <cstddef>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace nocal::sync {
|
||||
|
||||
class CurlHttpError : public std::runtime_error {
|
||||
public:
|
||||
enum class Kind {
|
||||
invalid_request,
|
||||
initialization_failed,
|
||||
transport_failed,
|
||||
response_too_large,
|
||||
};
|
||||
|
||||
CurlHttpError(Kind kind, std::string message);
|
||||
|
||||
[[nodiscard]] Kind kind() const noexcept;
|
||||
|
||||
private:
|
||||
Kind kind_;
|
||||
};
|
||||
|
||||
struct CurlHttpOptions {
|
||||
long connect_timeout_milliseconds{10'000};
|
||||
long total_timeout_milliseconds{30'000};
|
||||
std::size_t maximum_response_bytes{8U * 1024U * 1024U};
|
||||
std::string user_agent{"nocal/0.1"};
|
||||
};
|
||||
|
||||
class CurlHttpTransport final : public HttpTransport {
|
||||
public:
|
||||
explicit CurlHttpTransport(CurlHttpOptions options = {});
|
||||
|
||||
[[nodiscard]] HttpResponse send(const HttpRequest& request) override;
|
||||
|
||||
private:
|
||||
CurlHttpOptions options_;
|
||||
};
|
||||
|
||||
} // namespace nocal::sync
|
||||
40
include/nocal/sync/desktop_oauth.hpp
Normal file
40
include/nocal/sync/desktop_oauth.hpp
Normal file
@@ -0,0 +1,40 @@
|
||||
#pragma once
|
||||
|
||||
#include "nocal/sync/oauth.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace nocal::sync {
|
||||
|
||||
class XdgBrowserLauncher final : public BrowserLauncher {
|
||||
public:
|
||||
explicit XdgBrowserLauncher(std::string executable = "xdg-open");
|
||||
|
||||
void open(const std::string& url) override;
|
||||
|
||||
private:
|
||||
std::string executable_;
|
||||
};
|
||||
|
||||
class LoopbackCallbackReceiver final : public AuthorizationCallbackReceiver {
|
||||
public:
|
||||
explicit LoopbackCallbackReceiver(
|
||||
std::chrono::milliseconds timeout = std::chrono::minutes{5});
|
||||
~LoopbackCallbackReceiver();
|
||||
|
||||
LoopbackCallbackReceiver(const LoopbackCallbackReceiver&) = delete;
|
||||
LoopbackCallbackReceiver& operator=(const LoopbackCallbackReceiver&) = delete;
|
||||
LoopbackCallbackReceiver(LoopbackCallbackReceiver&&) noexcept;
|
||||
LoopbackCallbackReceiver& operator=(LoopbackCallbackReceiver&&) noexcept;
|
||||
|
||||
[[nodiscard]] std::string redirect_uri() const override;
|
||||
AuthorizationCallback receive() override;
|
||||
|
||||
private:
|
||||
struct Impl;
|
||||
std::unique_ptr<Impl> impl_;
|
||||
};
|
||||
|
||||
} // namespace nocal::sync
|
||||
Reference in New Issue
Block a user