mirror of
https://github.com/andwati/zitadel.git
synced 2026-11-08 23:25:12 +00:00
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]>
This commit is contained in:
co-authored by
Stefan Benz
parent
ae32508225
commit
ca4bba3992
@@ -10,6 +10,10 @@ import (
|
||||
"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
|
||||
@@ -54,6 +58,9 @@ func wrapPgError(err *pgconn.PgError) error {
|
||||
// 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)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
package migration
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
)
|
||||
|
||||
var (
|
||||
//go:embed 017_archived_sessions_table/up.sql
|
||||
up017ArchivedSessionsTable string
|
||||
//go:embed 017_archived_sessions_table/down.sql
|
||||
down017ArchivedSessionsTable string
|
||||
)
|
||||
|
||||
func init() {
|
||||
registerSQLMigration(17, up017ArchivedSessionsTable, down017ArchivedSessionsTable)
|
||||
}
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
DROP TRIGGER IF EXISTS trg_move_to_archived_sessions ON zitadel.sessions;
|
||||
DROP FUNCTION IF EXISTS zitadel.move_to_archived_sessions() CASCADE;
|
||||
DROP TABLE IF EXISTS zitadel.archived_sessions CASCADE;
|
||||
DROP FUNCTION IF EXISTS zitadel.throw_not_permitted();
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
CREATE TABLE zitadel.archived_sessions (
|
||||
instance_id TEXT NOT NULL
|
||||
, id TEXT NOT NULL CHECK (id <> '')
|
||||
, token_id TEXT
|
||||
, user_agent_id TEXT
|
||||
, expiration TIMESTAMPTZ
|
||||
, user_id TEXT
|
||||
, creator_id TEXT
|
||||
, deleted_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
|
||||
|
||||
, PRIMARY KEY (instance_id, id)
|
||||
, FOREIGN KEY (instance_id) REFERENCES zitadel.instances(id)
|
||||
, FOREIGN KEY (instance_id, user_id) REFERENCES zitadel.users(instance_id, id) ON DELETE CASCADE
|
||||
, FOREIGN KEY (instance_id, user_agent_id) REFERENCES zitadel.session_user_agents(instance_id, fingerprint_id) ON DELETE SET NULL (user_agent_id)
|
||||
);
|
||||
|
||||
CREATE OR REPLACE FUNCTION zitadel.move_to_archived_sessions() RETURNS trigger AS $$
|
||||
BEGIN
|
||||
INSERT INTO zitadel.archived_sessions (instance_id, id, token_id, user_agent_id, expiration, user_id, creator_id, deleted_at)
|
||||
VALUES (OLD.instance_id, OLD.id, OLD.token_id, OLD.user_agent_id, OLD.expiration, OLD.user_id, OLD.creator_id, now());
|
||||
RETURN OLD;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
|
||||
CREATE TRIGGER trg_move_to_archived_sessions
|
||||
AFTER DELETE ON zitadel.sessions
|
||||
FOR EACH ROW
|
||||
EXECUTE FUNCTION zitadel.move_to_archived_sessions();
|
||||
|
||||
-- placeholder for permissions, will be replaced by actual permission checks in the future,
|
||||
-- respectively will be used to fallback to when permissions are not yet implemented for a specific action
|
||||
CREATE OR REPLACE FUNCTION zitadel.throw_not_permitted() returns boolean AS $$
|
||||
BEGIN
|
||||
RAISE EXCEPTION 'Permission denied: User does not have permission'
|
||||
USING ERRCODE = 'ZIT01';
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
||||
Reference in New Issue
Block a user