Tim Möhlmann 658ca3606b
feat(permissions): project member permission filter (#9757)
# Which Problems Are Solved

Add the possibility to filter project resources based on project member
roles.

# How the Problems Are Solved

Extend and refactor existing Pl/PgSQL functions to implement the
following:

- Solve O(n) complexity in returned resources IDs by returning a boolean
filter for instance level permissions.
- Individually permitted orgs are returned only if there was no instance
permission
- Individually permitted projects are returned only if there was no
instance permission
- Because of the multiple filter terms, use `INNER JOIN`s instead of
`WHERE` clauses.

# Additional Changes

- system permission function no longer query the organization view and
therefore can be `immutable`, giving big performance benefits for
frequently reused system users. (like our hosted login in Zitadel cloud)
- The permitted org and project functions are now defined as `stable`
because the don't modify on-disk data. This might give a small
performance gain
- The Pl/PgSQL functions are now tested using Go unit tests.

# Additional Context

- Depends on https://github.com/zitadel/zitadel/pull/9677
- Part of https://github.com/zitadel/zitadel/issues/9188
- Closes https://github.com/zitadel/zitadel/issues/9190
2025-04-22 08:42:59 +00:00

42 lines
991 B
Go

// Package setup_test implements tests for procedural PostgreSQL functions,
// created in the database during Zitadel setup.
// Tests depend on `zitadel setup` being run first and therefore is run as integration tests.
// A PGX connection is used directly to the integration test database.
// This package assumes the database server available as per integration test defaults.
// See the [ConnString] constant.
//go:build integration
package setup_test
import (
"context"
"os"
"testing"
"time"
"github.com/jackc/pgx/v5/pgxpool"
)
const ConnString = "host=localhost port=5432 user=zitadel dbname=zitadel sslmode=disable"
var (
CTX context.Context
dbPool *pgxpool.Pool
)
func TestMain(m *testing.M) {
var cancel context.CancelFunc
CTX, cancel = context.WithTimeout(context.Background(), time.Second*10)
var err error
dbPool, err = pgxpool.New(context.Background(), ConnString)
if err != nil {
panic(err)
}
exit := m.Run()
cancel()
dbPool.Close()
os.Exit(exit)
}