PolicyEditorModal.constants.ts 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. import { safeSql } from '@supabase/pg-meta/src/pg-format'
  2. import { PolicyTemplate } from '../PolicyTemplates/PolicyTemplates.constants'
  3. /**
  4. * ----------------------------------------------------------------
  5. * PostgreSQL policy templates for the auth policies page
  6. * ----------------------------------------------------------------
  7. * id: Unique identifier for the monaco editor to dynamically refresh
  8. * templateName: As a display for a more descriptive title for the policy
  9. * description: Additional details about the template and how to make it yours
  10. * statement: SQL statement template for the policy
  11. *
  12. * name: Actual policy name that will be used in the editor
  13. * definition: Actual policy using expression that will be used in the editor
  14. * check: Actual policy with check expression that will be used in the editor
  15. * command: Operation to create policy for
  16. */
  17. export const getGeneralPolicyTemplates = (schema: string, table: string): PolicyTemplate[] => [
  18. {
  19. id: 'policy-1',
  20. preview: false,
  21. templateName: 'Enable read access to everyone',
  22. description:
  23. 'This policy gives read access to your table for all users via the SELECT operation.',
  24. statement: `
  25. create policy "Enable read access for all users"
  26. on "${schema}"."${table}"
  27. for select using (true);`.trim(),
  28. name: 'Enable read access for all users',
  29. definition: safeSql`true`,
  30. check: safeSql``,
  31. command: 'SELECT',
  32. roles: [],
  33. },
  34. {
  35. id: 'policy-2',
  36. preview: false,
  37. templateName: 'Enable insert access for authenticated users only',
  38. description: 'This policy gives insert access to your table for all authenticated users only.',
  39. statement: `
  40. create policy "Enable insert for authenticated users only"
  41. on "${schema}"."${table}"
  42. for insert to authenticated
  43. with check (true);`.trim(),
  44. name: 'Enable insert for authenticated users only',
  45. definition: safeSql``,
  46. check: safeSql`true`,
  47. command: 'INSERT',
  48. roles: ['authenticated'],
  49. },
  50. {
  51. id: 'policy-3',
  52. preview: false,
  53. templateName: 'Enable delete access for users based on their user ID *',
  54. description:
  55. 'This policy assumes that your table has a column "user_id", and allows users to delete rows which the "user_id" column matches their ID',
  56. statement: `
  57. create policy "Enable delete for users based on user_id"
  58. on "${schema}"."${table}"
  59. for delete using (
  60. (select auth.uid()) = user_id
  61. );`.trim(),
  62. name: 'Enable delete for users based on user_id',
  63. definition: safeSql`(select auth.uid()) = user_id`,
  64. check: safeSql``,
  65. command: 'DELETE',
  66. roles: [],
  67. },
  68. {
  69. id: 'policy-4',
  70. preview: false,
  71. templateName: 'Enable insert access for users based on their user ID *',
  72. description:
  73. 'This policy assumes that your table has a column "user_id", and allows users to insert rows which the "user_id" column matches their ID',
  74. statement: `
  75. create policy "Enable insert for users based on user_id"
  76. on "${schema}"."${table}"
  77. for insert with check (
  78. (select auth.uid()) = user_id
  79. );`.trim(),
  80. name: 'Enable insert for users based on user_id',
  81. definition: safeSql``,
  82. check: safeSql`(select auth.uid()) = user_id`,
  83. command: 'INSERT',
  84. roles: [],
  85. },
  86. {
  87. id: 'policy-5',
  88. preview: true,
  89. name: 'Policy with table joins',
  90. templateName: 'Policy with table joins',
  91. description: `
  92. Query across tables to build more advanced RLS rules
  93. Assuming 2 tables called \`teams\` and \`members\`, you can query both tables in the policy to control access to the members table.`,
  94. statement: `
  95. create policy "Members can update team details if they belong to the team"
  96. on teams for update using (
  97. (select auth.uid()) in (
  98. select user_id from members where team_id = id
  99. )
  100. );
  101. `.trim(),
  102. definition: safeSql`(select auth.uid()) in (select user_id from members where team_id = id)`,
  103. check: safeSql``,
  104. command: 'UPDATE',
  105. roles: [],
  106. },
  107. {
  108. id: 'policy-6',
  109. preview: true,
  110. templateName: 'Policy with security definer functions',
  111. description: `
  112. Useful in a many-to-many relationship where you want to restrict access to the linking table.
  113. Assuming 2 tables called \`teams\` and \`members\`, you can use a security definer function in combination with a policy to control access to the members table.`.trim(),
  114. statement: `
  115. create or replace function get_teams_for_user(user_id uuid)
  116. returns setof bigint as $$
  117. select team_id from members where user_id = $1
  118. $$ stable language sql security definer;
  119. create policy "Team members can update team members if they belong to the team"
  120. on members
  121. for all using (
  122. team_id in (select get_teams_for_user(auth.uid()))
  123. );
  124. `.trim(),
  125. name: 'Policy with security definer functions',
  126. definition: safeSql`team_id in (select get_teams_for_user(auth.uid()))`,
  127. check: safeSql``,
  128. command: 'ALL',
  129. roles: [],
  130. },
  131. {
  132. id: 'policy-7',
  133. preview: true,
  134. name: 'Policy to implement Time To Live (TTL)',
  135. templateName: 'Policy to implement Time To Live (TTL)',
  136. description: `
  137. Implement a TTL-like feature that you see in Instagram stories or Snapchat where messages expire after a day.
  138. Rows under the table are available only if they have been created within the last 24 hours.`,
  139. statement: `
  140. create policy "Stories are live for a day"
  141. on "${schema}"."${table}"
  142. for select using (
  143. created_at > (current_timestamp - interval '1 day')
  144. );
  145. `.trim(),
  146. definition: safeSql`created_at > (current_timestamp - interval '1 day')`,
  147. check: safeSql``,
  148. command: 'SELECT',
  149. roles: [],
  150. },
  151. {
  152. id: 'policy-8',
  153. preview: false,
  154. templateName: 'Allow users to only view their own data',
  155. description: 'Restrict users to reading only their own data.',
  156. statement: `
  157. create policy "Enable users to view their own data only"
  158. on "${schema}"."${table}"
  159. for select
  160. to authenticated
  161. using (
  162. (select auth.uid()) = user_id
  163. );`.trim(),
  164. name: 'Enable users to view their own data only',
  165. definition: safeSql`(select auth.uid()) = user_id`,
  166. check: safeSql``,
  167. command: 'SELECT',
  168. roles: ['authenticated'],
  169. },
  170. ]
  171. export const getRealtimePolicyTemplates = (): PolicyTemplate[] => {
  172. const results = [
  173. {
  174. id: 'policy-broadcast-1',
  175. preview: false,
  176. templateName: 'Allow listening for broadcasts for authenticated users only',
  177. description: 'This policy allows listening for broadcasts for authenticated users only.',
  178. statement: `
  179. create policy "Allow listening for broadcasts for authenticated users only"
  180. on realtime.messages for select
  181. to authenticated
  182. using ( realtime.messages.extension = 'broadcast' );`.trim(),
  183. name: 'Allow listening for broadcasts for authenticated users only',
  184. definition: safeSql`realtime.messages.extension = 'broadcast'`,
  185. check: safeSql``,
  186. command: 'SELECT',
  187. roles: ['authenticated'],
  188. },
  189. {
  190. id: 'policy-broadcast-2',
  191. preview: false,
  192. templateName: 'Allow pushing broadcasts for authenticated users only',
  193. description: 'This policy allows pushing broadcasts for authenticated users only.',
  194. statement: `
  195. create policy "Allow pushing broadcasts for authenticated users only"
  196. ON realtime.messages for insert
  197. TO authenticated
  198. with check ( realtime.messages.extension = 'broadcast' );`.trim(),
  199. name: 'Allow pushing broadcasts for authenticated users only',
  200. definition: safeSql`realtime.messages.extension = 'broadcast'`,
  201. check: safeSql`realtime.messages.extension = 'broadcast'`,
  202. command: 'INSERT',
  203. roles: ['authenticated'],
  204. },
  205. {
  206. id: 'policy-broadcast-3',
  207. preview: false,
  208. templateName: 'Allow listening for broadcasts from a specific channel',
  209. description: 'This policy allows listening for broadcasts from a specific channel.',
  210. statement: `
  211. create policy "Allow listening for broadcasts from a specific channel"
  212. on realtime.messages for select
  213. using ( realtime.messages.extension = 'broadcast' AND realtime.topic() = 'channel_name' );`.trim(),
  214. name: 'Allow listening for broadcasts from a specific channel',
  215. definition: safeSql`realtime.messages.extension = 'broadcast' AND realtime.topic() = 'channel_name'`,
  216. check: safeSql``,
  217. command: 'SELECT',
  218. roles: [],
  219. },
  220. {
  221. id: 'policy-broadcast-4',
  222. preview: false,
  223. templateName: 'Allow pushing broadcasts to specific channel',
  224. description: 'This policy allow pushing broadcasts to specific channel.',
  225. statement: `
  226. create policy "Allow pushing broadcasts to specific channel"
  227. ON realtime.messages for insert
  228. with check ( realtime.messages.extension = 'broadcast' AND realtime.topic() = 'channel_name' );`.trim(),
  229. name: 'Allow pushing broadcasts to specific channel',
  230. definition: safeSql`realtime.messages.extension = 'broadcast' AND realtime.topic() = 'channel_name'`,
  231. check: safeSql`realtime.messages.extension = 'broadcast' AND realtime.topic() = 'channel_name'`,
  232. command: 'INSERT',
  233. roles: [],
  234. },
  235. {
  236. id: 'policy-presences-1',
  237. preview: false,
  238. templateName: 'Allow listening for presences on all channels for authenticated users only',
  239. description:
  240. 'This policy enables listening for presences on all channels for all authenticated users only.',
  241. statement: `
  242. create policy "Allow listening for presences on all channels for authenticated users only"
  243. on realtime.messages for select
  244. to authenticated
  245. using ( realtime.messages.extension = 'presence' );`.trim(),
  246. name: 'Allow listening for presences on all channels for authenticated users only',
  247. definition: safeSql`realtime.messages.extension = 'presence'`,
  248. check: safeSql``,
  249. command: 'SELECT',
  250. roles: ['authenticated'],
  251. },
  252. {
  253. id: 'policy-presences-2',
  254. preview: false,
  255. templateName: 'Allow broadcasting presences on all channels for authenticated users only',
  256. description:
  257. 'This policy enables broadcasting presences on all channels for all authenticated users only.',
  258. statement: `
  259. create policy "Allow broadcasting presences on all channels for authenticated users only"
  260. ON realtime.messages for insert
  261. TO authenticated
  262. with check ( realtime.messages.extension = 'presence' );
  263. ;`.trim(),
  264. name: 'Allow broadcasting presences on all channels for authenticated users only',
  265. definition: safeSql`realtime.messages.extension = 'presence'`,
  266. check: safeSql`realtime.messages.extension = 'presence'`,
  267. command: 'INSERT',
  268. roles: ['authenticated'],
  269. },
  270. {
  271. id: 'policy-presences-3',
  272. preview: false,
  273. templateName: 'Allow listening for presences from a specific channel',
  274. description: 'This policy enables listening for presences from a specific channel.',
  275. statement: `
  276. create policy "Allow listening for presences from a specific channel"
  277. on realtime.messages for select
  278. using ( realtime.messages.extension = 'presence' AND realtime.topic() = 'channel_name' );`.trim(),
  279. name: 'Allow listening for presences from a specific channel',
  280. definition: safeSql`realtime.messages.extension = 'presence' AND realtime.topic() = 'channel_name'`,
  281. check: safeSql``,
  282. command: 'SELECT',
  283. roles: [],
  284. },
  285. {
  286. id: 'policy-presences-4',
  287. preview: false,
  288. templateName: 'Publish presence to a specific channel',
  289. description: 'This policy allows publishing presence to a specific channel.',
  290. statement: `
  291. create policy "Publish presence to a specific channel"
  292. ON realtime.messages for insert
  293. with check ( realtime.messages.extension = 'presence' AND realtime.topic() = 'channel_name' );
  294. ;`.trim(),
  295. name: 'Publish presence to a specific channel',
  296. definition: safeSql`realtime.messages.extension = 'presence' AND realtime.topic() = 'channel_name'`,
  297. check: safeSql`realtime.messages.extension = 'presence' AND realtime.topic() = 'channel_name'`,
  298. command: 'INSERT',
  299. roles: [],
  300. },
  301. ] as PolicyTemplate[]
  302. return results
  303. }
  304. export const getQueuePolicyTemplates = (): PolicyTemplate[] => {
  305. return [
  306. {
  307. id: 'policy-queues-1',
  308. preview: false,
  309. templateName: 'Allow access to queue',
  310. statement: ``.trim(),
  311. name: 'Allow anon and authenticated to access messages from queue',
  312. description:
  313. 'Base policy to ensure that anon and authenticated can only access appropriate rows. USING and CHECK statements will need to be adjusted accordingly',
  314. definition: safeSql`true`,
  315. check: safeSql`true`,
  316. command: 'ALL',
  317. roles: ['anon', 'authenticated'],
  318. },
  319. ]
  320. }