Files
simplegit/state/ssh.go
T
2026-07-17 05:55:31 -04:00

114 lines
1.7 KiB
Go

package state
import (
"context"
"errors"
"fmt"
"time"
"golang.org/x/crypto/ssh"
"simplegit/common"
)
func (s *LocalState) AccessBySSHKey(ctx context.Context, key ssh.PublicKey, owner, name string, perm common.Perm) (bool, error) {
r, err := s.findRepo(owner, name)
if err != nil {
if errors.Is(err, ErrRepoNotFound) {
return false, ErrDenied
}
return false, err
}
var sk SSHKey
has, err := s.engine.Where("fingerprint = ?", fingerprint(key)).Get(&sk)
if err != nil {
return false, fmt.Errorf("lookup ssh key: %w", err)
}
if !has {
return false, ErrDenied
}
now := time.Now()
if _, err := s.engine.ID(sk.ID).Cols("last_used_at").Update(&SSHKey{LastUsedAt: &now}); err == nil {
sk.LastUsedAt = &now
}
if perm == common.PermRead && !r.IsPrivate {
return true, nil
}
ok, err := s.hasAccess(CredTypeSSH, sk.ID, r.ID, r.NamespaceID, perm)
if err != nil {
return false, err
}
if !ok {
return false, ErrDenied
}
return true, nil
}
func (s *LocalState) KnownSSHKey(key ssh.PublicKey) (bool, error) {
var sk SSHKey
has, err := s.engine.Where("fingerprint = ?", fingerprint(key)).Get(&sk)
if err != nil {
return false, fmt.Errorf("lookup ssh key: %w", err)
}
if !has {
return false, ErrDenied
}
hasGrant, err := s.keyHasGrant(sk.ID)
if err != nil {
return false, err
}
if !hasGrant {
return false, ErrDenied
}
return true, nil
}
func (s *LocalState) keyHasGrant(credID int64) (bool, error) {
count, err := s.engine.Where("cred_type = ? AND cred_id = ?", CredTypeSSH, credID).Count(&ACL{})
if err != nil {
return false, fmt.Errorf("count ssh key grants: %w", err)
}
return count > 0, nil
}