package nextcloud import ( "context" "errors" "fmt" "github.com/jackc/pgx/v5" "github.com/jackc/pgx/v5/pgxpool" "github.com/ultisuite/ulti-backend/internal/mail/credentials" ) var ErrDAVCredentialsMissing = errors.New("nextcloud dav credentials missing") type DAVCredentialStore struct { db *pgxpool.Pool enc *credentials.Manager } func NewDAVCredentialStore(db *pgxpool.Pool, enc *credentials.Manager) *DAVCredentialStore { if db == nil || enc == nil { return nil } return &DAVCredentialStore{db: db, enc: enc} } func (s *DAVCredentialStore) GetToken(ctx context.Context, ncUserID string) (string, error) { if s == nil { return "", ErrDAVCredentialsMissing } var blob []byte err := s.db.QueryRow(ctx, ` SELECT dav_token FROM nextcloud_dav_credentials WHERE nc_user_id = $1 `, ncUserID).Scan(&blob) if errors.Is(err, pgx.ErrNoRows) { return "", ErrDAVCredentialsMissing } if err != nil { return "", err } _, token, err := s.enc.Decrypt(blob) return token, err } func (s *DAVCredentialStore) SaveToken(ctx context.Context, ncUserID, token string) error { if s == nil { return fmt.Errorf("nextcloud dav credential store unavailable") } blob, err := s.enc.Encrypt(ncUserID, token) if err != nil { return err } _, err = s.db.Exec(ctx, ` INSERT INTO nextcloud_dav_credentials (nc_user_id, dav_token, updated_at) VALUES ($1, $2, NOW()) ON CONFLICT (nc_user_id) DO UPDATE SET dav_token = EXCLUDED.dav_token, updated_at = NOW() `, ncUserID, blob) return err } func (s *DAVCredentialStore) DeleteToken(ctx context.Context, ncUserID string) error { if s == nil { return nil } _, err := s.db.Exec(ctx, `DELETE FROM nextcloud_dav_credentials WHERE nc_user_id = $1`, ncUserID) return err }