view connectors/connector.h @ 279:b3b547563ec7

Add Google connector service and agent wiki Implement the C/Seobeo Google Drive and Gmail connector with encrypted OAuth storage, Zenbu authentication, browser testing, AI tool discovery, chunked HTTP decoding, and Bazel coverage. Consolidate repository guidance into progressive wiki documentation and enforce arena-first allocation for new first-party C code. Co-authored-by: Copilot <[email protected]> Copilot-Session: 84c338fd-0939-4bb3-b7f3-1062eb213e5d
author MrJuneJune <me@mrjunejune.com>
date Mon, 17 Aug 2026 22:22:36 -0700
parents
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