matrix-coro

A WIP highlevel matrix c++ SDK with a MAS first approach
git clone git://archive.git.mtrnord.blog/MTRNord/matrix-coro.git
Log | Files | Refs | README | LICENSE

matrix_coro.hpp (5875B)


      1 #pragma once
      2 #include "json.hpp"
      3 #include "utils.hpp"
      4 
      5 #include "cppcoro/task.hpp"
      6 #include <cthash/sha2/sha256.hpp>
      7 #include <spdlog/spdlog.h>
      8 
      9 
     10 class BaseClient {
     11 public:
     12     std::string user_agent = "MatrixCoro SDK/0.1.0";
     13 };
     14 
     15 class LoggedInClient : public BaseClient {
     16     TokenResponse token_data;
     17     WellKnownResponse well_known;
     18 
     19     [[nodiscard]] cppcoro::task<Json::Value> get(const std::string &url) const;
     20 
     21 public:
     22     LoggedInClient(TokenResponse token_data, WellKnownResponse well_known): token_data(std::move(token_data)),
     23                                                                             well_known(std::move(well_known)) {
     24     }
     25 
     26     [[nodiscard]] cppcoro::task<WhoamiResponse> whoami() const;
     27 };
     28 
     29 class Client : public BaseClient {
     30     friend class ClientTest; // Declare the test class as a friend
     31 
     32 public:
     33     [[nodiscard]] cppcoro::task<std::string> get_auth_url(std::string homeserver, std::string redirect_url,
     34                                                           std::string state, std::string code_verifier,
     35                                                           const ClientRegistrationData &registration_data);
     36 
     37     [[nodiscard]] cppcoro::task<LoggedInClient> exchange_token(const std::string &code,
     38                                                                const std::string &redirect_url) const;
     39 
     40 private:
     41     WellKnownResponse well_known;
     42     AuthIssuerResponse auth_issuer;
     43     ClientRegistrationResponse client_registration;
     44     OpenIDConfiguration openid_configuration;
     45     std::string state;
     46     std::string code_verifier;
     47 
     48     [[nodiscard]] cppcoro::task<Json::Value> get(const std::string &url) const;
     49 
     50     [[nodiscard]] cppcoro::task<Json::Value> post(const std::string &url, const std::string &data,
     51                                                   bool form_data = false) const;
     52 
     53     /**
     54      * \brief Fetches the well-known configuration from the specified homeserver.
     55      *
     56      * This function sends a request to the given homeserver to retrieve the well-known configuration.
     57      *
     58      * \param homeserver The URL of the homeserver from which to fetch the well-known configuration.
     59      * \return A cppcoro::task that resolves to a WellKnownResponse containing the well-known configuration.
     60      */
     61     [[nodiscard]] cppcoro::task<WellKnownResponse> fetch_wellknown(std::string homeserver);
     62 
     63     /**
     64      * \brief Fetches the authentication issuer information from the specified client-server endpoint.
     65      *
     66      * This function sends a request to the given client-server endpoint to retrieve the authentication issuer information.
     67      *
     68      * \param cs_endpoint The URL of the client-server endpoint from which to fetch the authentication issuer information.
     69      * \return A cppcoro::task that resolves to an AuthIssuerResponse containing the authentication issuer information.
     70      */
     71     [[nodiscard]] cppcoro::task<AuthIssuerResponse> fetch_auth_issuer(std::string cs_endpoint);
     72 
     73     /**
     74      * \brief Registers a client with the specified authentication endpoint (MSC2966).
     75      *
     76      * This function sends a registration request to the given authentication endpoint using the provided registration data.
     77      * It allows the client to be registered as an OAuth2 client on the OIDC server side, enabling the client to let people log in.
     78      *
     79      * \param registration_endpoint The URL of the registration endpoint to register the client which can be optained from the openid-configuration.
     80      * \param registration_data The data required for client registration.
     81      * \return A cppcoro::task that resolves to a ClientRegistrationResponse containing the registration result.
     82      */
     83     [[nodiscard]] cppcoro::task<ClientRegistrationResponse> register_client(std::string registration_endpoint,
     84                                                                             const ClientRegistrationData &
     85                                                                             registration_data);
     86 
     87 
     88     // ReSharper disable once CppMemberFunctionMayBeStatic
     89     // NOLINTNEXTLINE(*-convert-member-functions-to-static)
     90     [[nodiscard]] constexpr std::string generate_authorize_url(const std::string &auth_endpoint,
     91                                                                const ClientRegistrationResponse &auth_data,
     92                                                                const std::string &redirect_url,
     93                                                                const std::string &state,
     94                                                                const std::string &code_verifier) const {
     95         spdlog::debug("Code verifier: {}", code_verifier);
     96         // URL encode the redirect URL
     97         const auto url_encoded_redirect_url = url_encode(redirect_url);
     98 
     99         // Calculate the code challenge from the code_verifier by doing `BASE64URL(SHA256(code_verifier))`
    100         const auto sha256_code_verifier = cthash::simple<cthash::sha256>(code_verifier);
    101         const auto code_challenge = cthash::base64url_encode(sha256_code_verifier).to_string();
    102 
    103         return auth_endpoint + "?response_type=code&response_mode=fragment&client_id=" +
    104                auth_data.client_id + "&redirect_uri=" + url_encoded_redirect_url +
    105                "&scope=urn%3Amatrix%3Aorg.matrix.msc2967.client%3Aapi%3A*%20urn%3Amatrix%3Aorg.matrix.msc2967.client%3Adevice%3AABCDEFGHIJKL&state="
    106                + state + "&code_challenge_method=S256" + "&code_challenge=" + code_challenge;
    107     }
    108 
    109     [[nodiscard]] cppcoro::task<TokenResponse> exchange_code_for_token(
    110         std::string token_endpoint,
    111         const std::string &code,
    112         const std::string &code_verifier,
    113         const std::string &client_id,
    114         const std::string &redirect_url) const;
    115 
    116     [[nodiscard]] cppcoro::task<OpenIDConfiguration> fetch_openid_configuration(
    117         std::string auth_endpoint);
    118 };