Home / Function/ PolicyTableRowComponent() — supabase Function Reference

PolicyTableRowComponent() — supabase Function Reference

Architecture documentation for the PolicyTableRowComponent() function in index.tsx from the supabase codebase.

Entity Profile

Dependency Diagram

graph TD
  441727d0_c446_3a6f_942c_c3b18821ec7d["PolicyTableRowComponent()"]
  ba410685_ce1d_58f6_ebad_979437a12b9c["usePoliciesData()"]
  441727d0_c446_3a6f_942c_c3b18821ec7d -->|calls| ba410685_ce1d_58f6_ebad_979437a12b9c
  style 441727d0_c446_3a6f_942c_c3b18821ec7d fill:#6366f1,stroke:#818cf8,color:#fff

Relationship Graph

Source Code

apps/studio/components/interfaces/Auth/Policies/PolicyTableRow/index.tsx lines 37–188

const PolicyTableRowComponent = ({
  table,
  isLocked,
  onSelectToggleRLS = noop,
  onSelectCreatePolicy = noop,
  onSelectEditPolicy = noop,
  onSelectDeletePolicy = noop,
}: PolicyTableRowProps) => {
  const { ref } = useParams()
  const { data: project } = useSelectedProjectQuery()
  const { getPoliciesForTable, isPoliciesLoading, isPoliciesError, policiesError, exposedSchemas } =
    usePoliciesData()

  const policies = useMemo(
    () => getPoliciesForTable(table.schema, table.name),
    [getPoliciesForTable, table.schema, table.name]
  )

  // [Joshen] Changes here are so that warnings are more accurate and granular instead of purely relying if RLS is disabled or enabled
  // The following scenarios are technically okay if the table has RLS disabled, in which it won't be publicly readable / writable
  // - If the schema is not exposed through the API via Postgrest
  // - If the anon and authenticated roles do not have access to the table
  // Ideally we should just rely on the security lints as the source of truth, but the security lints currently have limitations
  // - They only consider the public schema
  // - They do not consider roles
  // Eventually if the security lints are able to cover those, we can look to using them as the source of truth instead then
  const isRLSEnabled = table.rls_enabled
  const isTableExposedThroughAPI = useMemo(
    () => exposedSchemas.has(table.schema),
    [exposedSchemas, table.schema]
  )

  const { data: tablesWithAnonAuthAccess = new Set() } = useTablesRolesAccessQuery({
    projectRef: project?.ref,
    connectionString: project?.connectionString,
    schema: table.schema,
  })

  const hasAnonAuthenticatedRolesAccess = tablesWithAnonAuthAccess.has(table.name)
  const hasApiAccess = isTableExposedThroughAPI && hasAnonAuthenticatedRolesAccess
  const isPubliclyReadableWritable = !isRLSEnabled && hasApiAccess
  const rlsEnabledNoPolicies = isRLSEnabled && hasApiAccess && policies.length === 0
  const isApiDisabledDueToRoles = isTableExposedThroughAPI && !hasAnonAuthenticatedRolesAccess
  const isRealtimeSchema = table.schema === 'realtime'
  const isRealtimeMessagesTable = isRealtimeSchema && table.name === 'messages'
  const isTableLocked = isRealtimeSchema ? !isRealtimeMessagesTable : isLocked

  const showPolicies = !isPoliciesLoading && !isPoliciesError

  const shouldHideHeaderBorder =
    isPubliclyReadableWritable ||
    rlsEnabledNoPolicies ||
    !isTableExposedThroughAPI ||
    isApiDisabledDueToRoles

  const admonitionMessage = useMemo(() => {
    if (isPubliclyReadableWritable) {
      return 'This table can be accessed by anyone via the Data API as RLS is disabled.'
    }
    if (isApiDisabledDueToRoles) {
      return 'This table cannot be accessed via the Data API as no permissions exist for the anon or authenticated roles.'
    }
    return 'This table can be accessed via the Data API but no RLS policies exist so no data will be returned.'
  }, [isPubliclyReadableWritable, isApiDisabledDueToRoles])

  return (
    <Card className={cn(isPubliclyReadableWritable && 'border-warning-500')}>
      <CardHeader className={cn('py-3 px-4', shouldHideHeaderBorder && 'border-b-0')}>
        <PolicyTableRowHeader
          table={table}
          isLocked={isLocked}
          hasApiAccess={hasApiAccess}
          onSelectToggleRLS={onSelectToggleRLS}
          onSelectCreatePolicy={onSelectCreatePolicy}
        />
      </CardHeader>

      {!isTableExposedThroughAPI && (
        <Admonition
          showIcon={false}
          type="warning"
          className="border-0 border-y rounded-none min-h-12 flex items-center"
        >
          <p className="text-foreground-light">
            No data will be selectable via Supabase APIs as this schema is not exposed. You may
            configure this in your project’s{' '}
            <InlineLink href={`/project/${ref}/settings/api`}>API settings</InlineLink>.
          </p>
        </Admonition>
      )}

      {(isPubliclyReadableWritable || rlsEnabledNoPolicies || isApiDisabledDueToRoles) &&
        isTableExposedThroughAPI && (
          <Admonition
            showIcon={false}
            type={isPubliclyReadableWritable ? 'warning' : 'default'}
            className="border-0 border-y rounded-none min-h-12 flex items-center"
          >
            <p>{admonitionMessage}</p>
          </Admonition>
        )}

      {isPoliciesLoading && (
        <CardContent>
          <ShimmeringLoader />
        </CardContent>
      )}

      {isPoliciesError && (
        <CardContent>
          <AlertError
            className="border-0 rounded-none"
            error={policiesError}
            subject="Failed to retrieve policies"
          />
        </CardContent>
      )}

      {showPolicies && (
        <CardContent className="p-0">
          {policies.length === 0 ? (
            <p className="text-foreground-lighter text-sm p-4">No policies created yet</p>
          ) : (
            <Table className="table-fixed">
              <TableHeader>
                <TableRow>
                  <TableHead className="w-[40%]">Name</TableHead>
                  <TableHead className="w-[20%]">Command</TableHead>
                  <TableHead className="w-[30%]">Applied to</TableHead>
                  <TableHead className="text-right">
                    <span className="sr-only">Actions</span>
                  </TableHead>
                </TableRow>
              </TableHeader>
              <TableBody>
                {policies.map((policy) => (
                  <PolicyRow
                    key={policy.id}
                    policy={policy}
                    isLocked={isTableLocked}
                    onSelectEditPolicy={onSelectEditPolicy}
                    onSelectDeletePolicy={onSelectDeletePolicy}
                  />
                ))}
              </TableBody>
            </Table>
          )}
        </CardContent>
      )}
    </Card>
  )
}

Subdomains

Frequently Asked Questions

What does PolicyTableRowComponent() do?
PolicyTableRowComponent() is a function in the supabase codebase.
What does PolicyTableRowComponent() call?
PolicyTableRowComponent() calls 1 function(s): usePoliciesData.

Analyze Your Own Codebase

Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.

Try Supermodel Free