mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-23 14:46:43 +02:00
first auth impl
This commit is contained in:
parent
8f7c63950c
commit
2a002bf6be
79 changed files with 13355 additions and 6076 deletions
247
services/mana-core-auth/postgres/init/03-organization-rls.sql
Normal file
247
services/mana-core-auth/postgres/init/03-organization-rls.sql
Normal file
|
|
@ -0,0 +1,247 @@
|
|||
-- =====================================================
|
||||
-- RLS POLICIES FOR BETTER AUTH ORGANIZATION TABLES
|
||||
-- =====================================================
|
||||
|
||||
-- Enable RLS on organization tables
|
||||
ALTER TABLE auth.organizations ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE auth.members ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE auth.invitations ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE credits.organization_balances ENABLE ROW LEVEL SECURITY;
|
||||
ALTER TABLE credits.credit_allocations ENABLE ROW LEVEL SECURITY;
|
||||
|
||||
-- =====================================================
|
||||
-- HELPER FUNCTIONS FOR ORGANIZATION RLS
|
||||
-- =====================================================
|
||||
|
||||
-- Get user's role in an organization
|
||||
CREATE OR REPLACE FUNCTION auth.user_organization_role(org_id TEXT) RETURNS TEXT AS $$
|
||||
SELECT role FROM auth.members
|
||||
WHERE organization_id = org_id
|
||||
AND user_id = auth.uid()::text
|
||||
LIMIT 1;
|
||||
$$ LANGUAGE SQL STABLE SECURITY DEFINER;
|
||||
|
||||
-- Check if user is member of organization
|
||||
CREATE OR REPLACE FUNCTION auth.is_organization_member(org_id TEXT) RETURNS BOOLEAN AS $$
|
||||
SELECT EXISTS(
|
||||
SELECT 1 FROM auth.members
|
||||
WHERE organization_id = org_id
|
||||
AND user_id = auth.uid()::text
|
||||
);
|
||||
$$ LANGUAGE SQL STABLE SECURITY DEFINER;
|
||||
|
||||
-- Check if user is owner or admin of organization
|
||||
CREATE OR REPLACE FUNCTION auth.is_organization_owner_or_admin(org_id TEXT) RETURNS BOOLEAN AS $$
|
||||
SELECT EXISTS(
|
||||
SELECT 1 FROM auth.members
|
||||
WHERE organization_id = org_id
|
||||
AND user_id = auth.uid()::text
|
||||
AND role IN ('owner', 'admin')
|
||||
);
|
||||
$$ LANGUAGE SQL STABLE SECURITY DEFINER;
|
||||
|
||||
-- Check if user is owner of organization
|
||||
CREATE OR REPLACE FUNCTION auth.is_organization_owner(org_id TEXT) RETURNS BOOLEAN AS $$
|
||||
SELECT EXISTS(
|
||||
SELECT 1 FROM auth.members
|
||||
WHERE organization_id = org_id
|
||||
AND user_id = auth.uid()::text
|
||||
AND role = 'owner'
|
||||
);
|
||||
$$ LANGUAGE SQL STABLE SECURITY DEFINER;
|
||||
|
||||
-- =====================================================
|
||||
-- ORGANIZATIONS TABLE POLICIES
|
||||
-- =====================================================
|
||||
|
||||
-- Users can view organizations they are members of
|
||||
CREATE POLICY "Users can view their organizations"
|
||||
ON auth.organizations
|
||||
FOR SELECT
|
||||
USING (
|
||||
auth.is_organization_member(id)
|
||||
OR auth.role() = 'admin'
|
||||
);
|
||||
|
||||
-- Users can create organizations (Better Auth will handle adding them as owner)
|
||||
CREATE POLICY "Users can create organizations"
|
||||
ON auth.organizations
|
||||
FOR INSERT
|
||||
WITH CHECK (true);
|
||||
|
||||
-- Only owners can update organization
|
||||
CREATE POLICY "Owners can update their organizations"
|
||||
ON auth.organizations
|
||||
FOR UPDATE
|
||||
USING (auth.is_organization_owner(id))
|
||||
WITH CHECK (auth.is_organization_owner(id));
|
||||
|
||||
-- Only owners can delete organization
|
||||
CREATE POLICY "Owners can delete their organizations"
|
||||
ON auth.organizations
|
||||
FOR DELETE
|
||||
USING (auth.is_organization_owner(id));
|
||||
|
||||
-- =====================================================
|
||||
-- MEMBERS TABLE POLICIES
|
||||
-- =====================================================
|
||||
|
||||
-- Members can view other members in their organizations
|
||||
CREATE POLICY "Members can view organization members"
|
||||
ON auth.members
|
||||
FOR SELECT
|
||||
USING (
|
||||
auth.is_organization_member(organization_id)
|
||||
OR auth.role() = 'admin'
|
||||
);
|
||||
|
||||
-- Owners and admins can add members (Better Auth handles invitation flow)
|
||||
CREATE POLICY "Owners and admins can add members"
|
||||
ON auth.members
|
||||
FOR INSERT
|
||||
WITH CHECK (
|
||||
auth.is_organization_owner_or_admin(organization_id)
|
||||
OR auth.role() = 'admin'
|
||||
);
|
||||
|
||||
-- Owners and admins can update member roles
|
||||
CREATE POLICY "Owners and admins can update members"
|
||||
ON auth.members
|
||||
FOR UPDATE
|
||||
USING (auth.is_organization_owner_or_admin(organization_id))
|
||||
WITH CHECK (auth.is_organization_owner_or_admin(organization_id));
|
||||
|
||||
-- Owners and admins can remove members
|
||||
-- Members can remove themselves
|
||||
CREATE POLICY "Owners/admins can remove members, members can leave"
|
||||
ON auth.members
|
||||
FOR DELETE
|
||||
USING (
|
||||
auth.is_organization_owner_or_admin(organization_id)
|
||||
OR user_id = auth.uid()::text
|
||||
OR auth.role() = 'admin'
|
||||
);
|
||||
|
||||
-- =====================================================
|
||||
-- INVITATIONS TABLE POLICIES
|
||||
-- =====================================================
|
||||
|
||||
-- Members can view invitations in their organizations
|
||||
CREATE POLICY "Members can view organization invitations"
|
||||
ON auth.invitations
|
||||
FOR SELECT
|
||||
USING (
|
||||
auth.is_organization_member(organization_id)
|
||||
OR email = (SELECT email FROM auth.users WHERE id = auth.uid())
|
||||
OR auth.role() = 'admin'
|
||||
);
|
||||
|
||||
-- Owners and admins can create invitations
|
||||
CREATE POLICY "Owners and admins can create invitations"
|
||||
ON auth.invitations
|
||||
FOR INSERT
|
||||
WITH CHECK (
|
||||
auth.is_organization_owner_or_admin(organization_id)
|
||||
OR auth.role() = 'admin'
|
||||
);
|
||||
|
||||
-- Owners and admins can update invitations (cancel, etc)
|
||||
CREATE POLICY "Owners and admins can update invitations"
|
||||
ON auth.invitations
|
||||
FOR UPDATE
|
||||
USING (
|
||||
auth.is_organization_owner_or_admin(organization_id)
|
||||
OR auth.role() = 'admin'
|
||||
)
|
||||
WITH CHECK (
|
||||
auth.is_organization_owner_or_admin(organization_id)
|
||||
OR auth.role() = 'admin'
|
||||
);
|
||||
|
||||
-- Inviter can delete their invitations
|
||||
-- Invitee can delete (reject) invitations sent to them
|
||||
CREATE POLICY "Inviters and invitees can delete invitations"
|
||||
ON auth.invitations
|
||||
FOR DELETE
|
||||
USING (
|
||||
inviter_id = auth.uid()::text
|
||||
OR email = (SELECT email FROM auth.users WHERE id = auth.uid())
|
||||
OR auth.is_organization_owner_or_admin(organization_id)
|
||||
OR auth.role() = 'admin'
|
||||
);
|
||||
|
||||
-- =====================================================
|
||||
-- ORGANIZATION BALANCES TABLE POLICIES
|
||||
-- =====================================================
|
||||
|
||||
-- Members can view their organization's balance
|
||||
CREATE POLICY "Members can view organization balance"
|
||||
ON credits.organization_balances
|
||||
FOR SELECT
|
||||
USING (
|
||||
auth.is_organization_member(organization_id)
|
||||
OR auth.role() = 'admin'
|
||||
);
|
||||
|
||||
-- Only owners can create organization balances (during org creation)
|
||||
CREATE POLICY "Owners can create organization balance"
|
||||
ON credits.organization_balances
|
||||
FOR INSERT
|
||||
WITH CHECK (
|
||||
auth.is_organization_owner(organization_id)
|
||||
OR auth.role() = 'admin'
|
||||
);
|
||||
|
||||
-- Only owners can update organization balances (allocations, purchases)
|
||||
CREATE POLICY "Owners can update organization balance"
|
||||
ON credits.organization_balances
|
||||
FOR UPDATE
|
||||
USING (auth.is_organization_owner(organization_id))
|
||||
WITH CHECK (auth.is_organization_owner(organization_id));
|
||||
|
||||
-- Only owners can delete (cascade handled by org deletion)
|
||||
CREATE POLICY "Owners can delete organization balance"
|
||||
ON credits.organization_balances
|
||||
FOR DELETE
|
||||
USING (auth.is_organization_owner(organization_id));
|
||||
|
||||
-- =====================================================
|
||||
-- CREDIT ALLOCATIONS TABLE POLICIES
|
||||
-- =====================================================
|
||||
|
||||
-- Employees can view allocations to them
|
||||
-- Owners/admins can view all allocations in their org
|
||||
CREATE POLICY "Users can view relevant credit allocations"
|
||||
ON credits.credit_allocations
|
||||
FOR SELECT
|
||||
USING (
|
||||
employee_id = auth.uid()
|
||||
OR auth.is_organization_owner_or_admin(organization_id)
|
||||
OR auth.role() = 'admin'
|
||||
);
|
||||
|
||||
-- Only owners can create credit allocations
|
||||
CREATE POLICY "Owners can create credit allocations"
|
||||
ON credits.credit_allocations
|
||||
FOR INSERT
|
||||
WITH CHECK (
|
||||
auth.is_organization_owner(organization_id)
|
||||
OR auth.role() = 'admin'
|
||||
);
|
||||
|
||||
-- No updates to allocations (immutable audit trail)
|
||||
-- No deletes to allocations (immutable audit trail)
|
||||
|
||||
-- =====================================================
|
||||
-- COMMENTS
|
||||
-- =====================================================
|
||||
|
||||
COMMENT ON POLICY "Users can view their organizations" ON auth.organizations IS 'Members can view organizations they belong to';
|
||||
COMMENT ON POLICY "Users can create organizations" ON auth.organizations IS 'Any authenticated user can create an organization';
|
||||
COMMENT ON POLICY "Owners can update their organizations" ON auth.organizations IS 'Only owners can modify organization details';
|
||||
COMMENT ON POLICY "Owners can delete their organizations" ON auth.organizations IS 'Only owners can delete organizations';
|
||||
|
||||
COMMENT ON FUNCTION auth.user_organization_role IS 'Returns the role of the current user in the specified organization';
|
||||
COMMENT ON FUNCTION auth.is_organization_member IS 'Checks if current user is a member of the organization';
|
||||
COMMENT ON FUNCTION auth.is_organization_owner_or_admin IS 'Checks if current user is owner or admin of the organization';
|
||||
COMMENT ON FUNCTION auth.is_organization_owner IS 'Checks if current user is owner of the organization';
|
||||
Loading…
Add table
Add a link
Reference in a new issue