package session import ( "context" "errors" "fmt" "strings" "tug/internal/platform/sshkey" "tug/internal/platform/sshkey/openssh" "tug/internal/storage" ) func (s *Service) SSHKeys(ctx context.Context, userID string) ([]storage.SSHKey, error) { keys, err := s.store.SSHKeysOf(ctx, userID) if err != nil { return nil, failure("list ssh keys", err) } return keys, nil } func (s *Service) AddSSHKey(ctx context.Context, p Principal, line, label string) (storage.SSHKey, error) { const operation = "add ssh key" if p.SessionID == "" { return storage.SSHKey{}, fmt.Errorf("session: %s: %w: no current session", operation, ErrNoSession) } key, err := openssh.Parse(line) if err != nil { return storage.SSHKey{}, fmt.Errorf("session: %s: %w", operation, err) } if err := storage.CheckSSHKeyLabel(strings.TrimSpace(label)); err != nil { return storage.SSHKey{}, fmt.Errorf("session: %s: %w", operation, err) } added, err := s.store.AddSSHKeyAudited(ctx, storage.AddSSHKeyInput{UserID: p.UserID, Key: key, Label: label, SessionID: p.SessionID}, p.UserID) switch { case errors.Is(err, sshkey.ErrOwned), errors.Is(err, sshkey.ErrTaken), errors.Is(err, sshkey.ErrLimit): return storage.SSHKey{}, fmt.Errorf("session: %s: %w", operation, err) case errors.Is(err, storage.ErrInvalid), errors.Is(err, storage.ErrSSHKeyDisabled), errors.Is(err, storage.ErrSSHKeyPending): return storage.SSHKey{}, fmt.Errorf("session: %s: %w: %w", operation, ErrNoSession, err) case err != nil: return storage.SSHKey{}, failure(operation, err) } return added, nil } func (s *Service) RemoveSSHKey(ctx context.Context, p Principal, keyID string) (storage.SSHKey, error) { const operation = "remove ssh key" if p.SessionID == "" { return storage.SSHKey{}, fmt.Errorf("session: %s: %w: no current session", operation, ErrNoSession) } removed, err := s.store.RemoveSSHKeyAudited(ctx, p.UserID, keyID, p.SessionID, p.UserID) switch { case errors.Is(err, storage.ErrSSHKeyNotFound): return storage.SSHKey{}, fmt.Errorf("session: %s: %w: %w", operation, ErrNoSuchSSHKey, err) case errors.Is(err, storage.ErrInvalid): return storage.SSHKey{}, fmt.Errorf("session: %s: %w: %w", operation, ErrNoSession, err) case err != nil: return storage.SSHKey{}, failure(operation, err) } return removed, nil }