This commit is contained in:
Jabberwocky238
2026-07-17 05:55:31 -04:00
parent 67c07b3bcf
commit 68cda1972c
19 changed files with 897 additions and 897 deletions
+44 -44
View File
@@ -1,19 +1,19 @@
// Private-DB models for simplegit.
//
// This is a credential-centric access model: there is NO users table. The two
// things that can authenticate a git operation are an SSH public key or a PAT,
// and each is granted access to repos directly via the ACL table. This matches
// the Store interface (cmd/listener.go): AccessBySSHKey / AccessByToken resolve
// a credential and check it against a repo, with no user id in between.
//
// Anonymous access (no credential) is governed by Repo.IsPrivate: a public repo
// allows anonymous read; write always requires a credential. That special case
// lives in the store layer, not in ACL -- ACL only records explicit grants.
//
// xorm derives the schema from the struct tags via Sync2 (see InitEngine), so
// there is no hand-written DDL. GonicMapper is required so SSHKey -> "ssh_key"
// (the default SnakeMapper would produce "s_s_h_key"); this matches
// simpleconsole, whose raw-SQL joins rely on the same names.
package state
import (
@@ -23,8 +23,8 @@ import (
"xorm.io/xorm/names"
)
// BaseModel is the common row shape: auto-increment PK plus xorm-managed
// created/updated/deleted timestamps (soft-delete via DeletedAt).
type BaseModel struct {
ID int64 `xorm:"pk autoincr" json:"id"`
CreatedAt time.Time `xorm:"created" json:"created_at"`
@@ -32,59 +32,59 @@ type BaseModel struct {
DeletedAt *time.Time `xorm:"deleted" json:"deleted_at,omitempty"`
}
// Repo is a registered repository. The on-disk bare repo lives under the git
// root; this row is the authority for its namespace/name and visibility.
type Repo struct {
BaseModel `xorm:"extends"`
NamespaceID int64 `xorm:"notnull unique(cred)" json:"namespace_id"`
Namespace string `xorm:"varchar(255) notnull index" json:"namespace"`
NameID int64 `xorm:"notnull unique(cred)" json:"name_id"`
Name string `xorm:"varchar(255) notnull" json:"name"`
IsPrivate bool `xorm:"default false" json:"is_private"` // public repos allow anonymous read
IsPrivate bool `xorm:"default false" json:"is_private"`
}
// SSHKey is a registered public key, resolved by fingerprint in AccessBySSHKey.
type SSHKey struct {
BaseModel `xorm:"extends"`
PublicKey string `xorm:"text notnull" json:"-"`
Fingerprint string `xorm:"varchar(255) unique notnull" json:"fingerprint"` // "SHA256:..."
KeyType string `xorm:"varchar(50) notnull" json:"key_type"` // ssh-ed25519, ssh-rsa, ...
Fingerprint string `xorm:"varchar(255) unique notnull" json:"fingerprint"`
KeyType string `xorm:"varchar(50) notnull" json:"key_type"`
Comment string `xorm:"varchar(255)" json:"comment,omitempty"`
LastUsedAt *time.Time `xorm:"" json:"last_used_at,omitempty"`
}
// PAT is an opaque HTTP credential. Only its sha256 hash is stored; the
// plaintext is returned once at creation. AccessByToken hashes the presented
// token and looks it up here by token_hash.
type PAT struct {
BaseModel `xorm:"extends"`
TokenHash string `xorm:"varchar(64) unique notnull" json:"-"` // hex(sha256(plaintext))
Prefix string `xorm:"varchar(20)" json:"prefix"` // first chars, for display only
TokenHash string `xorm:"varchar(64) unique notnull" json:"-"`
Prefix string `xorm:"varchar(20)" json:"prefix"`
Name string `xorm:"varchar(255)" json:"name"`
ExpiresAt *time.Time `xorm:"" json:"expires_at,omitempty"`
LastUsedAt *time.Time `xorm:"" json:"last_used_at,omitempty"`
}
// ACL grants a credential access to a repo. CredType selects which table CredID
// points at -- the foreign key is polymorphic by design, so it is NOT
// database-enforced: deleting a credential must clean up its ACL rows in the
// store layer. The unique(cred) group means one grant per credential per repo;
// raise it by updating perm, not by inserting a duplicate.
type ACL struct {
BaseModel `xorm:"extends"`
CredType int `xorm:"notnull unique(cred) index" json:"cred_type"` // CredTypePAT or CredTypeSSH
CredID int64 `xorm:"notnull unique(cred)" json:"cred_id"` // pats.id or ssh_keys.id (per CredType)
TargetType int `xorm:"notnull unique(cred) index" json:"target_type"` // TargetType
CredType int `xorm:"notnull unique(cred) index" json:"cred_type"`
CredID int64 `xorm:"notnull unique(cred)" json:"cred_id"`
TargetType int `xorm:"notnull unique(cred) index" json:"target_type"`
TargetID int64 `xorm:"notnull unique(cred)" json:"target_id"`
Perm string `xorm:"varchar(20) default 'read'" json:"perm"` // PermRead | PermWrite | PermAdmin
Perm string `xorm:"varchar(20) default 'read'" json:"perm"`
}
type CredType int
// Credential kinds for ACL.CredType.
const (
CredTypePAT CredType = 0 // HTTP transport (PAT)
CredTypeSSH CredType = 1 // SSH transport (public key)
CredTypePAT CredType = 0
CredTypeSSH CredType = 1
)
type TargetType int
@@ -94,9 +94,9 @@ const (
TargetTypeNS TargetType = 1
)
// InitEngine opens an xorm engine on driver/dsn, applies the GonicMapper (see
// package doc), and syncs all model tables. It mirrors simpleconsole's
// models.InitEngine so the two services share table/column naming.
func InitEngine(driverName, dataSourceName string) (*xorm.Engine, error) {
engine, err := xorm.NewEngine(driverName, dataSourceName)
if err != nil {