giteaclient

package
v0.41.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 30, 2026 License: Apache-2.0 Imports: 16 Imported by: 0

Documentation

Overview

Package giteaclient is a small, focused Gitea REST client used by e2e tests and debug tools. It is intentionally not a full SDK: only the endpoints the project exercises are covered.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func NormalizeAuthorizedKey

func NormalizeAuthorizedKey(k string) string

NormalizeAuthorizedKey returns the "<type> <base64>" prefix of an authorized_keys entry, dropping any trailing comment. This matches how Gitea stores and returns keys, so it is the right shape for equality comparisons.

func PathEscape

func PathEscape(v string) string

PathEscape percent-encodes a single URL path segment.

func TruncateBody

func TruncateBody(s string) string

TruncateBody clips a response body for safe inclusion in error messages.

Types

type AccessToken

type AccessToken struct {
	ID   int64  `json:"id"`
	Name string `json:"name"`
	SHA1 string `json:"sha1"`
}

AccessToken is the subset of the Gitea token payload used by the e2e harness.

type Client

type Client struct {
	BaseURL    string
	Username   string
	Password   string
	HTTPClient *http.Client
}

Client talks to a Gitea instance using basic auth. Username/Password are used for every request; for flows that require acting as a specific user (e.g. key verification), construct a second Client with that user's credentials.

func New

func New(baseURL, username, password string) *Client

New returns a Client with sensible defaults. baseURL must be the /api/v1 root.

func (*Client) CreateAccessToken

func (c *Client) CreateAccessToken(ctx context.Context, login, name string, scopes []string) (string, error)

CreateAccessToken creates a token on the named user and returns the secret value.

func (*Client) CreateGiteaWebhook

func (c *Client) CreateGiteaWebhook(
	ctx context.Context,
	owner,
	repo,
	callbackURL,
	secret string,
	events []string,
) (*RepoHook, error)

CreateGiteaWebhook creates a repository webhook of type "gitea".

func (*Client) CreateUser

func (c *Client) CreateUser(ctx context.Context, login, email string) (*User, string, error)

CreateUser creates a Gitea user via the admin API. Returns the created user plus the generated password. Returns ErrUserExists (wrapped) if the user already exists with a different email.

func (*Client) CreateUserRepo

func (c *Client) CreateUserRepo(
	ctx context.Context,
	owner, name string,
	autoInit bool,
	trustModel string,
) (*Repository, error)

CreateUserRepo creates a repository owned by the named user via the admin API. If the repo already exists, it is returned as-is.

trustModel must be one of: "default", "collaborator", "committer", "collaboratorcommitter", or "" to let Gitea pick the instance default. For verifying user-signed commits, "committer" is the relevant value.

func (*Client) DeleteRepo

func (c *Client) DeleteRepo(ctx context.Context, owner, name string) error

DeleteRepo removes a repository. Missing repos are treated as success.

func (*Client) DeleteRepoHook

func (c *Client) DeleteRepoHook(ctx context.Context, owner, repo string, hookID int64) error

DeleteRepoHook removes a single repository webhook. Missing hooks are treated as success.

func (*Client) DeleteUserKeyAsAdmin

func (c *Client) DeleteUserKeyAsAdmin(ctx context.Context, login string, keyID int64) error

DeleteUserKeyAsAdmin removes a single public key from the named user.

func (*Client) Do

func (c *Client) Do(ctx context.Context, method, path string, in, out any) (int, []byte, error)

Do issues an authenticated JSON request. If out is non-nil and the response is 2xx with a body, the body is unmarshalled into out. The raw body is always returned so callers can report unexpected responses.

func (*Client) EnsureCollaborator

func (c *Client) EnsureCollaborator(ctx context.Context, owner, repo, user string) error

EnsureCollaborator grants the named user write access on owner/repo.

func (*Client) EnsureOrg

func (c *Client) EnsureOrg(ctx context.Context, name, fullName, description string) (*Organization, error)

EnsureOrg creates an organization when missing.

func (*Client) EnsureOrgRepo

func (c *Client) EnsureOrgRepo(
	ctx context.Context,
	org,
	name,
	description string,
	private,
	autoInit bool,
) (*Repository, error)

EnsureOrgRepo creates an organization-owned repository when missing.

func (*Client) EnsureUser

func (c *Client) EnsureUser(ctx context.Context, login, email string) (*TestUser, error)

EnsureUser creates the user if missing and always returns a TestUser with a known password (rotating it on reuse so callers can always re-authenticate).

func (*Client) EnsureUserKeyAsAdmin

func (c *Client) EnsureUserKeyAsAdmin(ctx context.Context, login, title, publicKey string) (*PublicKey, error)

EnsureUserKeyAsAdmin ensures the named user has exactly the requested key material for the given title. If the title already exists with different material, the stale key is removed before the new key is created.

func (*Client) FindUserKey

func (c *Client) FindUserKey(ctx context.Context, login, publicKey string) (*PublicKey, bool, error)

FindUserKey looks up a public key on the named user by key material, ignoring the trailing comment.

func (*Client) FindUserKeyByTitle

func (c *Client) FindUserKeyByTitle(ctx context.Context, login, title string) (*PublicKey, bool, error)

FindUserKeyByTitle looks up a public key on the named user by title.

func (*Client) GetCommitVerification

func (c *Client) GetCommitVerification(ctx context.Context, owner, repo, sha string) (*CommitVerification, error)

GetCommitVerification returns the verification block for a commit.

func (*Client) GetKeyRaw

func (c *Client) GetKeyRaw(ctx context.Context, keyID int64) ([]byte, error)

GetKeyRaw fetches a single key by ID and returns the raw JSON body, so callers can inspect fields the typed struct may not decode (e.g. internal columns Gitea might expose in newer versions).

func (*Client) GetOrg

func (c *Client) GetOrg(ctx context.Context, name string) (*Organization, error)

GetOrg fetches an organization by name.

func (*Client) GetRepo

func (c *Client) GetRepo(ctx context.Context, owner, name string) (*Repository, error)

GetRepo fetches a repository by owner and name.

func (*Client) GetUser

func (c *Client) GetUser(ctx context.Context, login string) (*User, bool, error)

GetUser returns the Gitea user with the given login, or (nil, false, nil) if it does not exist.

func (*Client) GetVerificationToken

func (c *Client) GetVerificationToken(ctx context.Context) (string, error)

GetVerificationToken returns the per-user verification token. The same token is used by the GPG and SSH verification flows; Gitea's web form accepts an SSH signature over it (namespace "gitea") to flip public_key.verified=1. Requires the Client to be authenticated as the target user.

func (*Client) ListRepoHooks

func (c *Client) ListRepoHooks(ctx context.Context, owner, repo string) ([]RepoHook, error)

ListRepoHooks returns every webhook configured on owner/repo, following pagination.

func (*Client) ListUserKeys

func (c *Client) ListUserKeys(ctx context.Context, login string) ([]PublicKey, error)

ListUserKeys returns EVERY public key on the named user, following pagination.

The pagination is load-bearing, not tidiness. Gitea's default page size is 30, and this listing backs FindUserKeyByTitle, which EnsureUserKeyAsAdmin uses to decide whether a title is already taken. An unpaginated listing therefore stops seeing keys once a user holds more than one page of them, and "ensure" starts failing with `422 Key title has been used` for a key that demonstrably exists — the caller cannot see it to replace it. The e2e suite hits this reliably: it registers ~24 seeded transport keys per full run against a long-lived Gitea, so the second run onward exceeds one page and the stable-titled `playground` key becomes unreachable.

func (*Client) RegisterUserKeyAsAdmin

func (c *Client) RegisterUserKeyAsAdmin(ctx context.Context, login, title, publicKey string) (*PublicKey, error)

RegisterUserKeyAsAdmin idempotently registers a public key on the named user using the admin endpoint POST /admin/users/{username}/keys.

func (*Client) RegisterUserKeyAsUser

func (c *Client) RegisterUserKeyAsUser(ctx context.Context, title, publicKey string) (*PublicKey, error)

RegisterUserKeyAsUser registers a public key via POST /user/keys using the currently authenticated user. Use this when comparing whether admin-upload vs user-upload lands the key with a different key_type in Gitea's classification.

func (*Client) SetUserPassword

func (c *Client) SetUserPassword(ctx context.Context, login, password string) error

SetUserPassword resets a user's password via the admin API so tooling can authenticate as that user after the fact.

func (*Client) VerifySSHKey

func (c *Client) VerifySSHKey(
	ctx context.Context,
	user *TestUser,
	opts SSHKeyVerificationOptions,
) (*SSHKeyVerificationResult, error)

VerifySSHKey performs the full user-scoped SSH key verification flow: fetch token, sign it in process, log into the web UI, and submit the verify_ssh form for the given public key fingerprint.

func (*Client) WebBaseURL

func (c *Client) WebBaseURL() string

WebBaseURL derives the Gitea web root from the client's /api/v1 base URL.

type CommitResponse

type CommitResponse struct {
	SHA    string `json:"sha"`
	Commit struct {
		Verification CommitVerification `json:"verification"`
	} `json:"commit"`
}

CommitResponse wraps the verification block returned by the commit API.

type CommitVerification

type CommitVerification struct {
	Verified  bool   `json:"verified"`
	Reason    string `json:"reason"`
	Signature string `json:"signature"`
	Payload   string `json:"payload"`
	Signer    *User  `json:"signer,omitempty"`
}

CommitVerification is the verification block of the commit API.

type Organization

type Organization struct {
	ID       int64  `json:"id"`
	UserName string `json:"username"`
	FullName string `json:"full_name"`
}

Organization is the subset of the Gitea org payload we care about.

type PublicKey

type PublicKey struct {
	ID          int64  `json:"id"`
	Title       string `json:"title"`
	Key         string `json:"key"`
	Fingerprint string `json:"fingerprint"`
	KeyType     string `json:"key_type"`
	ReadOnly    bool   `json:"read_only"`
	CreatedAt   string `json:"created_at"`
	LastUsedAt  string `json:"last_used_at"`
}

PublicKey mirrors Gitea's public key shape. Note: Gitea's API does NOT expose the internal `public_key.verified` DB column; KeyType is what distinguishes auth keys ("user") from deploy/principal keys.

type RepoHook

type RepoHook struct {
	ID     int64          `json:"id"`
	Type   string         `json:"type"`
	Active bool           `json:"active"`
	Config RepoHookConfig `json:"config"`
}

RepoHook is the subset of the repository webhook payload we use.

type RepoHookConfig

type RepoHookConfig struct {
	URL         string `json:"url"`
	ContentType string `json:"content_type"`
}

RepoHookConfig is the subset of the repository webhook config payload we use.

type Repository

type Repository struct {
	ID       int64  `json:"id"`
	Name     string `json:"name"`
	FullName string `json:"full_name"`
	CloneURL string `json:"clone_url"`
	SSHURL   string `json:"ssh_url"`
	Private  bool   `json:"private"`
	Owner    User   `json:"owner"`
}

Repository is the subset of the Gitea repo payload we use.

type SSHKeyVerificationOptions

type SSHKeyVerificationOptions struct {
	PublicKey      string
	Fingerprint    string
	PrivateKeyPEM  []byte
	PrivateKeyPath string
	Debug          bool
}

SSHKeyVerificationOptions controls the shared SSH-key verification flow that signs Gitea's verification token and submits the web form.

type SSHKeyVerificationResult

type SSHKeyVerificationResult struct {
	Token     string
	Signature string
	Session   *WebSession
}

SSHKeyVerificationResult contains the main artifacts from a verification run.

type TestUser

type TestUser struct {
	Login    string
	Email    string
	Password string
	ID       int64
}

TestUser is a local Gitea identity with a password we captured at creation time, so tooling can re-authenticate as that user (required for per-user endpoints like key verification).

type User

type User struct {
	ID    int64  `json:"id"`
	Login string `json:"login"`
	Email string `json:"email"`
}

User is the subset of the Gitea user payload we care about.

type WebSession

type WebSession struct {
	BaseURL    string
	HTTPClient *http.Client
	// Debug, when true, prints each HTTP request/response so we can see
	// exactly what Gitea says on login and verify.
	Debug bool
}

WebSession drives Gitea's web UI for flows the REST API does not expose (most importantly: SSH key verification, which lives at POST /user/settings/keys?type=verify_ssh).

BaseURL must be the Gitea host root WITHOUT /api/v1 (e.g. "http://gitea-http.gitea-e2e.svc.cluster.local:13000").

func NewWebSession

func NewWebSession(ctx context.Context, baseURL, username, password string, debug bool) (*WebSession, error)

NewWebSession logs the given user into Gitea and returns a session whose cookie jar carries the login cookies required for subsequent form POSTs.

func (*WebSession) VerifySSHKey

func (s *WebSession) VerifySSHKey(ctx context.Context, publicKey, fingerprint, signature string) error

VerifySSHKey drives the web form at POST /user/settings/keys?type=verify_ssh to flip `public_key.verified = 1` for the uploaded key matching fingerprint. publicKey is the authorized_keys-form public key ("ssh-ed25519 AAAA..."), which Gitea requires in the `content` form field even though it already has the key stored. signature is the armored `-----BEGIN SSH SIGNATURE-----` block produced by `ssh-keygen -Y sign -n gitea` over the token from /user/gpg_key_token.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL