Files
zitadel/backend/v3/storage/database/dialect/postgres/error.go
T
ca4bba3992 feat: add delete session on relation tables (#11334)
# Which Problems Are Solved

As part of moving the session API to the relational database, this PR
adds the functionality to delete sessions through the session API v2 and
the OIDC end_session endpoint.

# How the Problems Are Solved

- added `SessionDeleteCommand` in domain package
- added possibility to pass the session token verifier to the domain
package
- use feature flag to switch API and OIDC usage from CQRS to relation
table
- added a `permissionCheck` condition to let permissions be checked
directly in the repository / sql
- part of it is still a placeholder until actual permission tables are
done
- added a `session_deleted` table to store (recently) deleted sessions
to handle necessary checks / cases like delete my own session, which
needs to be idempotent

# Additional Changes

Fixed `Matches` function of `existsCondition` (as missing an
implementation)

# Additional Context

- closes #11037

---------

Co-authored-by: Stefan Benz <[email protected]>
2026-03-19 08:35:53 +01:00

68 lines
1.9 KiB
Go

package postgres
import (
"errors"
"strings"
"github.com/jackc/pgx/v5"
"github.com/jackc/pgx/v5/pgconn"
"github.com/zitadel/zitadel/backend/v3/storage/database"
)
const (
ZIT01 = "ZIT01" // custom error code to express missing permissions by the end-user
)
func wrapError(err error) error {
if err == nil {
return nil
}
if errors.Is(err, pgx.ErrNoRows) {
return database.NewNoRowFoundError(err)
}
if errors.Is(err, pgx.ErrTooManyRows) {
return database.NewMultipleRowsFoundError(err)
}
var pgxErr *pgconn.PgError
if errors.As(err, &pgxErr) {
return wrapPgError(pgxErr)
}
// scany only exports its errors as strings
if strings.HasPrefix(err.Error(), "scany: expected 1 row, got: ") {
return database.NewMultipleRowsFoundError(err)
}
if strings.HasPrefix(err.Error(), "scany:") || strings.HasPrefix(err.Error(), "scanning:") {
return database.NewScanError(err)
}
return database.NewUnknownError(err)
}
func wrapPgError(err *pgconn.PgError) error {
switch err.Code {
// 23514: check_violation - A value violates a CHECK constraint.
case "23514":
return database.NewCheckError(err.TableName, err.ConstraintName, err)
// 23505: unique_violation - A value violates a UNIQUE constraint.
case "23505":
return database.NewUniqueError(err.TableName, err.ConstraintName, err)
// 23503: foreign_key_violation - A value violates a foreign key constraint.
case "23503":
return database.NewForeignKeyError(err.TableName, err.ConstraintName, err)
// 23502: not_null_violation - A value violates a NOT NULL constraint.
case "23502":
return database.NewNotNullError(err.TableName, err.ConstraintName, err)
// 22P02: integrity violation - A value is being inserted into a enum that is not valid
case "22P02":
return database.NewCheckError(err.TableName, err.ConstraintName, err)
// ZIT01: missing permissions by the end-user
case ZIT01:
return database.NewPermissionError(err)
default:
return database.NewUnknownError(err)
}
}