synops/migrations/006_alias_aware_rls.sql
vegard f81c8a96e0 Fullfør oppgave 8.2: Kontekstbasert identitet med alias
Når en bruker oppretter en node i en kommunikasjonskontekst der
brukerens alias er deltaker (owner/member_of/host_of), settes
created_by til alias-noden i stedet for brukerens hovednode.

Endringer:
- resolve_context_identity(): slår opp brukerens alias i konteksten
- create_node(): bruker alias som created_by når context_id er satt
- user_can_modify_node/edge(): gjenkjenner alias-eierskap ved endring/sletting
- 006_alias_aware_rls.sql: RLS-policies inkluderer alias-opprettede noder
- current_node_alias_ids(): PG-funksjon for alias-oppslag i RLS

Verifisert med integrasjonstest på server:
- Node i alias-kontekst → created_by = alias ✓
- Node uten kontekst → created_by = bruker ✓
- Update/delete av alias-node fungerer for hovedbruker ✓

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 19:19:36 +01:00

79 lines
2.9 KiB
PL/PgSQL

-- 006_alias_aware_rls.sql
-- Oppdaterer RLS-policies til å håndtere alias-basert created_by.
--
-- Når en bruker opererer via et alias (oppgave 8.2), settes created_by
-- til alias-noden i stedet for brukerens hovednode. RLS-policies må
-- da gjenkjenne at brukeren eier sine aliaser og dermed har tilgang
-- til noder/edges opprettet av aliaset.
--
-- Ref: docs/primitiver/nodes.md (created_by), docs/primitiver/edges.md (alias)
BEGIN;
-- =============================================================================
-- Hjelpefunksjon: henter brukerens alias-IDer
-- =============================================================================
CREATE OR REPLACE FUNCTION current_node_alias_ids() RETURNS SETOF UUID AS $$
BEGIN
RETURN QUERY
SELECT target_id FROM edges
WHERE source_id = current_node_id()
AND edge_type = 'alias'
AND system = true;
END;
$$ LANGUAGE plpgsql STABLE;
GRANT EXECUTE ON FUNCTION current_node_alias_ids() TO synops_reader;
-- =============================================================================
-- Oppdatert RLS på nodes — inkluderer alias-eierskap
-- =============================================================================
DROP POLICY IF EXISTS node_select ON nodes;
CREATE POLICY node_select ON nodes FOR SELECT TO synops_reader
USING (
-- Egne noder (direkte created_by)
created_by = current_node_id()
-- Noder opprettet av et av brukerens aliaser
OR created_by IN (SELECT current_node_alias_ids())
-- Eksplisitt tilgang via node_access
OR id IN (
SELECT object_id FROM node_access
WHERE subject_id = current_node_id()
)
-- Offentlig synlige noder
OR visibility >= 'discoverable'
);
-- =============================================================================
-- Oppdatert RLS på edges — inkluderer alias-eierskap
-- =============================================================================
DROP POLICY IF EXISTS edge_select ON edges;
CREATE POLICY edge_select ON edges FOR SELECT TO synops_reader
USING (
-- Ikke vis system-edges til andre enn eieren
(NOT system OR source_id = current_node_id())
AND (
-- Bruker opprettet edgen (direkte eller via alias)
created_by = current_node_id()
OR created_by IN (SELECT current_node_alias_ids())
-- Bruker er source eller target
OR source_id = current_node_id()
OR target_id = current_node_id()
-- Bruker har tilgang til source- eller target-noden
OR source_id IN (
SELECT object_id FROM node_access
WHERE subject_id = current_node_id()
)
OR target_id IN (
SELECT object_id FROM node_access
WHERE subject_id = current_node_id()
)
)
);
COMMIT;