Files
flvx/go-backend/internal/store/repo/repository_relay_auth.go
T

68 lines
2.3 KiB
Go

package repo
import (
"errors"
"strconv"
"go-backend/internal/relaysecurity"
"go-backend/internal/store/model"
"gorm.io/gorm"
"gorm.io/gorm/clause"
)
// RelayEndpointCredentials loads existing state, creating only when explicitly
// requested by a new endpoint operation. Reconnects must never recreate a secret.
func (r *Repository) RelayEndpointCredentials(tx *gorm.DB, tunnelID, nodeID int64, role int, create bool) (*relaysecurity.Credentials, error) {
db := tx
if db == nil {
db = r.db
}
var row model.RelayEndpointAuth
find := func() error {
return db.Where("tunnel_id = ? AND node_id = ? AND chain_type = ?", tunnelID, nodeID, role).First(&row).Error
}
err := find()
if errors.Is(err, gorm.ErrRecordNotFound) && create {
var existing int64
// chain_tunnel stores roles as text; relay_endpoint_auth uses integers.
if e := db.Model(&model.ChainTunnel{}).Where("tunnel_id = ? AND node_id = ? AND chain_type = ?", tunnelID, nodeID, strconv.Itoa(role)).Count(&existing).Error; e != nil {
return nil, e
}
if existing > 0 {
var tunnel model.Tunnel
if e := db.First(&tunnel, tunnelID).Error; e != nil {
return nil, e
}
if tunnel.Type == 2 || tunnel.RelayAuthMode == relaysecurity.Required {
return nil, errors.New("required relay endpoint credentials unavailable; refusing regeneration")
}
}
c, e := relaysecurity.New()
if e != nil {
return nil, e
}
row = model.RelayEndpointAuth{TunnelID: tunnelID, NodeID: nodeID, ChainType: role, Version: c.Version, Username: c.Username, Password: c.Password}
if e = db.Clauses(clause.OnConflict{DoNothing: true}).Create(&row).Error; e != nil {
return nil, e
}
row = model.RelayEndpointAuth{}
err = find()
}
if err != nil {
return nil, errors.New("required relay endpoint credentials unavailable")
}
c := &relaysecurity.Credentials{Version: row.Version, Username: row.Username, Password: row.Password}
if err := c.Validate(); err != nil {
return nil, err
}
return c, nil
}
func (r *Repository) SetTunnelRelayAuthModeTx(tx *gorm.DB, tunnelID int64, mode string) error {
if mode != relaysecurity.Required && mode != relaysecurity.Legacy {
return errors.New("invalid relay authentication mode")
}
return tx.Model(&model.Tunnel{}).Where("id = ?", tunnelID).Update("relay_auth_mode", mode).Error
}