view connectors/connector.h @ 281:c57149ad216e default tip

Copilot-Session: f68442b1-fa8f-46a0-9689-81710613bbd4
author MrJuneJune <me@mrjunejune.com>
date Tue, 18 Aug 2026 22:18:15 -0700
parents b3b547563ec7
children
line wrap: on
line source

#ifndef ZENBU_CONNECTOR_H
#define ZENBU_CONNECTOR_H

#include "deita/deita.h"
#include "dowa/dowa.h"
#include "seobeo/seobeo.h"

#include <stddef.h>

#define CONNECTOR_MAX_JSON_BYTES (1024 * 1024)
#define CONNECTOR_ID_MAX 128

typedef enum {
  CONNECTOR_OK = 0,
  CONNECTOR_ERROR,
  CONNECTOR_INVALID,
  CONNECTOR_NOT_FOUND,
  CONNECTOR_FORBIDDEN,
  CONNECTOR_CONFIRMATION_REQUIRED,
  CONNECTOR_CONFLICT,
  CONNECTOR_PROVIDER_ERROR
} Connector_Status;

typedef enum {
  CONNECTOR_CONFIRM_NEVER = 0,
  CONNECTOR_CONFIRM_ALWAYS = 1
} Connector_Confirmation_Policy;

typedef enum {
  CONNECTOR_OP_DRIVE_LIST,
  CONNECTOR_OP_DRIVE_GET,
  CONNECTOR_OP_DRIVE_DOWNLOAD,
  CONNECTOR_OP_DRIVE_CHANGES,
  CONNECTOR_OP_DRIVE_CREATE,
  CONNECTOR_OP_DRIVE_UPLOAD,
  CONNECTOR_OP_DRIVE_UPDATE,
  CONNECTOR_OP_GMAIL_LIST,
  CONNECTOR_OP_GMAIL_GET,
  CONNECTOR_OP_GMAIL_ATTACHMENT,
  CONNECTOR_OP_GMAIL_HISTORY,
  CONNECTOR_OP_GMAIL_DRAFT_CREATE,
  CONNECTOR_OP_GMAIL_SEND
} Connector_Operation;

typedef struct {
  uint32 version;
  uint8 key[32];
} Connector_Master_Key;

typedef struct {
  char account_id[CONNECTOR_ID_MAX];
  char user_id[CONNECTOR_ID_MAX];
  char provider[32];
  char provider_subject[CONNECTOR_ID_MAX];
  char email[256];
  char access_token[2048];
  char refresh_token[2048];
  int64 expires_at;
  char scopes[1024];
} Connector_Account;

typedef struct {
  char account_id[CONNECTOR_ID_MAX];
  char provider[32];
  char email[256];
  int64 expires_at;
  char scopes[1024];
} Connector_Account_Summary;

typedef struct {
  char state[128];
  char code_verifier[128];
  char code_challenge[128];
} Connector_OAuth_Start;

typedef struct {
  const char *method;
  const char *url;
  const char *content_type;
  const char *body;
  size_t body_length;
  const char *download_path;
} Connector_HTTP_Request;

typedef struct {
  int32 status_code;
  char *body;
  size_t body_length;
} Connector_HTTP_Response;

typedef struct {
  int32 http_status;
  char code[64];
  char description[256];
} Connector_Provider_Error;

typedef Connector_Status (*Connector_HTTP_Transport)(
    const Connector_HTTP_Request *request,
    const char *access_token,
    Connector_HTTP_Response *response,
    Dowa_Arena *arena,
    void *context);

typedef struct {
  const char *client_id;
  const char *client_secret;
  const char *redirect_uri;
  const char *oauth_authorize_url;
  const char *oauth_token_url;
  const char *oauth_revoke_url;
  const char *identity_url;
  const char *drive_api_url;
  const char *drive_upload_url;
  const char *gmail_api_url;
  Connector_HTTP_Transport transport;
  void *transport_context;
} Connector_Google_Config;

typedef struct {
  const char *method;
  const char *path;
  const char *query;
  const char *content_type;
  const char *body;
  size_t body_length;
  const char *download_path;
  boolean overwrite;
} Connector_Provider_Request;

typedef struct {
  Connector_Status status;
  int32 provider_status;
  char *body;
  size_t body_length;
} Connector_Provider_Response;

typedef struct Connector_Store {
  Deita_Connection *connection;
  Connector_Master_Key master_key;
} Connector_Store;

typedef const char *(*Connector_Auth_Resolve_User)(
    Seobeo_Request_Entry *request,
    boolean require_csrf,
    Dowa_Arena *arena,
    void *context);

typedef struct {
  char user_id[CONNECTOR_ID_MAX];
  char username[64];
  char role[16];
  char csrf_token[128];
} Connector_Auth_Session;

typedef boolean (*Connector_Auth_Resolve_Session)(
    Seobeo_Request_Entry *request,
    Connector_Auth_Session *session,
    void *context);

typedef struct {
  Connector_Auth_Resolve_User resolve_user;
  Connector_Auth_Resolve_Session resolve_session;
  void *context;
} Connector_Auth_Adapter;

boolean Connector_Base64Url_Encode(
    const uint8 *input, size_t input_length, char *output, size_t output_size);
boolean Connector_Base64Url_Decode(
    const char *input, uint8 *output, size_t output_size, size_t *output_length);
boolean Connector_Encrypt(
    const Connector_Master_Key *key, const char *plaintext,
    char *encoded, size_t encoded_size);
boolean Connector_Decrypt(
    const Connector_Master_Key *key, const char *encoded,
    char *plaintext, size_t plaintext_size);
boolean Connector_Form_Encode(
    const char *input, char *output, size_t output_size);
boolean Connector_Request_Digest(
    const char *user_id, const char *account_id, Connector_Operation operation,
    const Connector_Provider_Request *request, char output[65]);
boolean Connector_OAuth_PKCE_Start(Connector_OAuth_Start *start);
const char *Connector_Operation_Name(Connector_Operation operation);
boolean Connector_Operation_Is_Mutation(Connector_Operation operation);
boolean Connector_Operation_Is_Allowed(Connector_Operation operation);

boolean Connector_Store_Open(
    Connector_Store *store, const char *database_path,
    const Connector_Master_Key *master_key);
void Connector_Store_Close(Connector_Store *store);
boolean Connector_Store_Migrate(Connector_Store *store);
boolean Connector_Store_Create_State(
    Connector_Store *store, const char *user_id, const Connector_OAuth_Start *start,
    int64 expires_at);
boolean Connector_Store_Consume_State(
    Connector_Store *store, const char *user_id, const char *state, int64 now,
    char *verifier, size_t verifier_size);
boolean Connector_Store_Save_Account(
    Connector_Store *store, const Connector_Account *account);
boolean Connector_Store_Get_Account(
    Connector_Store *store, const char *user_id, const char *account_id,
    Connector_Account *account);
boolean Connector_Store_List_Accounts(
    Connector_Store *store, const char *user_id,
    Connector_Account_Summary **accounts, Dowa_Arena *arena);
boolean Connector_Store_Delete_Account(
    Connector_Store *store, const char *user_id, const char *account_id);
boolean Connector_Store_Set_Policy(
    Connector_Store *store, const char *user_id, const char *action,
    Connector_Confirmation_Policy policy);
Connector_Confirmation_Policy Connector_Store_Get_Policy(
    Connector_Store *store, const char *user_id, const char *action);
boolean Connector_Store_Create_Confirmation(
    Connector_Store *store, const char *user_id, const char *digest,
    const char *token, int64 expires_at);
boolean Connector_Store_Consume_Confirmation(
    Connector_Store *store, const char *user_id, const char *digest,
    const char *token, int64 now);
boolean Connector_Store_Get_Idempotent(
    Connector_Store *store, const char *user_id, const char *key,
    const char *digest, int32 *status, char *body, size_t body_size);
boolean Connector_Store_Idempotency_Conflict(
    Connector_Store *store, const char *user_id, const char *key,
    const char *digest);
boolean Connector_Store_Put_Idempotent(
    Connector_Store *store, const char *user_id, const char *key,
    const char *digest, int32 status, const char *body);
boolean Connector_Store_Audit(
    Connector_Store *store, const char *user_id, const char *account_id,
    const char *operation, const char *digest, int32 status);

char *Connector_Google_Authorization_URL(
    const Connector_Google_Config *config, const Connector_OAuth_Start *start,
    Dowa_Arena *arena);
Connector_Status Connector_Google_Exchange_Code(
    const Connector_Google_Config *config, const char *code,
    const char *verifier, Connector_Account *account,
    Connector_Provider_Error *error, Dowa_Arena *arena);
Connector_Status Connector_Google_Refresh(
    const Connector_Google_Config *config, Connector_Account *account,
    Dowa_Arena *arena);
Connector_Status Connector_Google_Revoke(
    const Connector_Google_Config *config, const char *token, Dowa_Arena *arena);
Connector_Status Connector_Google_Execute(
    const Connector_Google_Config *config, Connector_Operation operation,
    const Connector_Provider_Request *request, const char *access_token,
    Connector_Provider_Response *response, Dowa_Arena *arena);

void Connector_Service_Configure(
    Connector_Store *store, const Connector_Google_Config *google,
    Connector_Auth_Adapter auth);
void Connector_Service_Register_Routes(void);

#endif