145 lines
4.3 KiB
PL/PgSQL
145 lines
4.3 KiB
PL/PgSQL
-- Anonim geziler için token sistemi ekle
|
||
-- Bu migration güvenlik açığını kapatır
|
||
|
||
-- 1. trips tablosuna anonymous_token sütunu ekle
|
||
ALTER TABLE trips ADD COLUMN IF NOT EXISTS anonymous_token TEXT;
|
||
|
||
-- 2. Unique index oluştur (NULL değerler için unique constraint çalışmaz, bu yüzden partial index)
|
||
CREATE UNIQUE INDEX IF NOT EXISTS trips_anonymous_token_key
|
||
ON trips(anonymous_token)
|
||
WHERE anonymous_token IS NOT NULL;
|
||
|
||
-- 3. Index oluştur (performans için)
|
||
CREATE INDEX IF NOT EXISTS trips_anonymous_token_idx
|
||
ON trips(anonymous_token)
|
||
WHERE anonymous_token IS NOT NULL;
|
||
|
||
-- 4. Eski güvensiz politikaları kaldır
|
||
DROP POLICY IF EXISTS "Herkes public seyahatleri görebilir" ON trips;
|
||
DROP POLICY IF EXISTS "Kullanıcılar kendi seyahatlerini güncelleyebilir" ON trips;
|
||
DROP POLICY IF EXISTS "Kullanıcılar kendi seyahatlerini silebilir" ON trips;
|
||
|
||
-- 5. Yeni güvenli politikalar oluştur
|
||
|
||
-- SELECT: Public geziler, kendi gezileri, veya token ile anonim geziler
|
||
CREATE POLICY "Güvenli seyahat görüntüleme"
|
||
ON trips FOR SELECT
|
||
USING (
|
||
is_public = true
|
||
OR user_id = auth.uid()
|
||
OR (user_id IS NULL AND anonymous_token = current_setting('request.headers', true)::json->>'x-anonymous-token')
|
||
);
|
||
|
||
-- UPDATE: Sadece kendi gezileri veya token ile anonim geziler
|
||
CREATE POLICY "Güvenli seyahat güncelleme"
|
||
ON trips FOR UPDATE
|
||
USING (
|
||
user_id = auth.uid()
|
||
OR (user_id IS NULL AND anonymous_token = current_setting('request.headers', true)::json->>'x-anonymous-token')
|
||
);
|
||
|
||
-- DELETE: Sadece kendi gezileri veya token ile anonim geziler
|
||
CREATE POLICY "Güvenli seyahat silme"
|
||
ON trips FOR DELETE
|
||
USING (
|
||
user_id = auth.uid()
|
||
OR (user_id IS NULL AND anonymous_token = current_setting('request.headers', true)::json->>'x-anonymous-token')
|
||
);
|
||
|
||
-- 6. trip_days için güvenli politikalar
|
||
DROP POLICY IF EXISTS "Herkes seyahat günlerini yönetebilir" ON trip_days;
|
||
|
||
CREATE POLICY "Güvenli seyahat günleri yönetimi"
|
||
ON trip_days FOR ALL
|
||
USING (
|
||
EXISTS (
|
||
SELECT 1 FROM trips
|
||
WHERE trips.id = trip_days.trip_id
|
||
AND (
|
||
trips.is_public = true
|
||
OR trips.user_id = auth.uid()
|
||
OR (trips.user_id IS NULL AND trips.anonymous_token = current_setting('request.headers', true)::json->>'x-anonymous-token')
|
||
)
|
||
)
|
||
);
|
||
|
||
-- 7. trip_places için güvenli politikalar
|
||
DROP POLICY IF EXISTS "Herkes seyahat yerlerini yönetebilir" ON trip_places;
|
||
|
||
CREATE POLICY "Güvenli seyahat yerleri yönetimi"
|
||
ON trip_places FOR ALL
|
||
USING (
|
||
EXISTS (
|
||
SELECT 1 FROM trip_days
|
||
JOIN trips ON trips.id = trip_days.trip_id
|
||
WHERE trip_days.id = trip_places.trip_day_id
|
||
AND (
|
||
trips.is_public = true
|
||
OR trips.user_id = auth.uid()
|
||
OR (trips.user_id IS NULL AND trips.anonymous_token = current_setting('request.headers', true)::json->>'x-anonymous-token')
|
||
)
|
||
)
|
||
);
|
||
|
||
-- 8. Anonim gezi sahipliğini transfer etme fonksiyonu
|
||
CREATE OR REPLACE FUNCTION claim_anonymous_trip(
|
||
trip_id_param UUID,
|
||
token_param TEXT
|
||
)
|
||
RETURNS BOOLEAN
|
||
LANGUAGE plpgsql
|
||
SECURITY DEFINER
|
||
AS $$
|
||
DECLARE
|
||
current_user_id UUID;
|
||
BEGIN
|
||
-- Mevcut kullanıcıyı al
|
||
current_user_id := auth.uid();
|
||
|
||
-- Kullanıcı giriş yapmamışsa hata
|
||
IF current_user_id IS NULL THEN
|
||
RAISE EXCEPTION 'Kullanıcı giriş yapmamış';
|
||
END IF;
|
||
|
||
-- Token eşleşiyorsa ve user_id NULL ise ownership transfer et
|
||
UPDATE trips
|
||
SET
|
||
user_id = current_user_id,
|
||
anonymous_token = NULL -- Token'ı temizle
|
||
WHERE
|
||
id = trip_id_param
|
||
AND user_id IS NULL
|
||
AND anonymous_token = token_param;
|
||
|
||
-- Güncelleme başarılı mı kontrol et
|
||
RETURN FOUND;
|
||
END;
|
||
$$;
|
||
|
||
-- 9. Eski anonim gezileri temizleme fonksiyonu
|
||
CREATE OR REPLACE FUNCTION cleanup_old_anonymous_trips()
|
||
RETURNS INTEGER
|
||
LANGUAGE plpgsql
|
||
SECURITY DEFINER
|
||
AS $$
|
||
DECLARE
|
||
deleted_count INTEGER;
|
||
BEGIN
|
||
-- 7 günden eski, user_id NULL olan gezileri sil
|
||
WITH deleted AS (
|
||
DELETE FROM trips
|
||
WHERE
|
||
user_id IS NULL
|
||
AND created_at < NOW() - INTERVAL '7 days'
|
||
RETURNING id
|
||
)
|
||
SELECT COUNT(*) INTO deleted_count FROM deleted;
|
||
|
||
RETURN deleted_count;
|
||
END;
|
||
$$;
|
||
|
||
-- 10. Fonksiyonlara yorum ekle
|
||
COMMENT ON FUNCTION claim_anonymous_trip IS 'Anonim bir geziyi giriş yapmış kullanıcıya transfer eder';
|
||
COMMENT ON FUNCTION cleanup_old_anonymous_trips IS '7 günden eski anonim gezileri siler';
|