package state import ( "context" "crypto/sha256" "encoding/hex" "errors" "fmt" "time" "simplegit/common" ) const patPrefix = "sgp_" func (s *LocalState) AccessByPAT(ctx context.Context, pat, 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 } if perm == common.PermRead && !r.IsPrivate { return true, nil } if pat == "" { return false, ErrDenied } p, err := s.lookupPAT(pat) if err != nil { return false, err } ok, err := s.hasAccess(CredTypePAT, p.ID, r.ID, r.NamespaceID, perm) if err != nil { return false, err } if !ok { return false, ErrDenied } return true, nil } func (s *LocalState) lookupPAT(token string) (*PAT, error) { sum := sha256.Sum256([]byte(token)) var pat PAT has, err := s.engine.Where("token_hash = ?", hex.EncodeToString(sum[:])).Get(&pat) if err != nil { return nil, fmt.Errorf("lookup pat: %w", err) } if !has { return nil, ErrInvalidToken } if pat.ExpiresAt != nil && time.Now().After(*pat.ExpiresAt) { return nil, ErrInvalidToken } now := time.Now() if _, err := s.engine.ID(pat.ID).Cols("last_used_at").Update(&PAT{LastUsedAt: &now}); err == nil { pat.LastUsedAt = &now } return &pat, nil }