Skip to content
quarry Artifact [c4ab64cdea]
Login

Artifact [c4ab64cdea]

Artifact c4ab64cdea5cc9c155f8e18caea4096be36b5c35719058d39267f72bc074009d:


// mirrortoken.go is the access token a Git mirror's fetches send, for
// an upstream that is not public (a private GitHub repository).
//
// It is sealed the way the uv round's password is (secret.go): every
// fetch replays it, so a one-way hash cannot hold it, and a copy of
// oltp.db alone must not yield it. MirrorGitToken is its one reader, and
// no op returns it.
package oltp

import (
	"database/sql"
	"errors"
	"fmt"
)

// SetMirrorGitToken stores the token repo's Git mirror fetches with,
// sealed; an empty token clears it, and the fetches go anonymously. The
// upstream the token belongs to is the row's URL, which a Git mirror
// never changes, and SetMirror drops the token if it ever did.
func (d *DB) SetMirrorGitToken(repo, token string) error {
	sealed := ""
	if token != "" {
		var err error
		if sealed, err = d.seal.seal(token); err != nil {
			return err
		}
	}
	res, err := d.w.Exec(`UPDATE mirror SET git_token_enc = ? WHERE repo = ? AND kind = ?`, sealed, repo, MirrorGit)
	if err != nil {
		return err
	}
	if n, _ := res.RowsAffected(); n == 0 {
		return fmt.Errorf("oltp: %s is not a Git mirror", repo)
	}
	return nil
}

// MirrorGitToken is repo's Git mirror token unsealed, "" when it holds
// none or has no mirror. Its one caller is the fetch.
func (d *DB) MirrorGitToken(repo string) (string, error) {
	var sealed string
	err := d.db.QueryRow(`SELECT git_token_enc FROM mirror WHERE repo = ?`, repo).Scan(&sealed)
	if errors.Is(err, sql.ErrNoRows) {
		return "", nil
	}
	if err != nil {
		return "", err
	}
	if sealed == "" {
		return "", nil
	}
	return d.seal.open(sealed)
}