-- Migration: Secure User Roles from Self-Escalation
-- Purpose: Prevent users from updating their own roles to 'admin' using RLS / Triggers.

-- Ensure RLS is enabled on users
ALTER TABLE public.users ENABLE ROW LEVEL SECURITY;

-- Policy to allow users to view their own records
CREATE POLICY select_own_user ON public.users
    FOR SELECT
    TO authenticated
    USING (auth.uid() = id);

-- Policy to allow admins to view all users
CREATE POLICY select_all_users_for_admin ON public.users
    FOR SELECT
    TO authenticated
    USING (
        (SELECT role FROM public.users WHERE id = auth.uid()) = 'admin'
    );

-- Trigger to prevent any role updates to 'admin' from unauthorized users
CREATE OR REPLACE FUNCTION check_user_role_escalation()
RETURNS TRIGGER AS $$
BEGIN
    -- Only allow changes to the role column if executed by the service_role
    IF (TG_OP = 'UPDATE' AND OLD.role IS DISTINCT FROM NEW.role) OR (TG_OP = 'INSERT') THEN
        IF current_setting('role', true) <> 'service_role' THEN
            -- Partners cannot upgrade themselves or others to admin
            IF NEW.role = 'admin' THEN
                RAISE EXCEPTION 'Unberechtigtes Rollen-Upgrade verweigert.';
            END IF;
        END IF;
    END IF;
    RETURN NEW;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

DROP TRIGGER IF EXISTS enforce_role_protection ON public.users;
CREATE TRIGGER enforce_role_protection
    BEFORE INSERT OR UPDATE ON public.users
    FOR EACH ROW
    EXECUTE FUNCTION check_user_role_escalation();
