{"id":400746,"date":"2024-06-29T15:26:53","date_gmt":"2024-06-29T15:26:53","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=400746"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=400746","title":{"rendered":"<span>Claim-based \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044f \u043d\u0430 PL\/pgSQL<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0417\u0434\u0440\u0430\u0432\u0441\u0442\u0432\u0443\u0439\u0442\u0435!\u00a0<\/p>\n<p>\u0421\u0442\u0430\u0442\u044c\u044f \u043e\u00a0\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0441\u0443\u043f\u0435\u0440\u0433\u0438\u0431\u043a\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0440\u0430\u0432 \u043a\u00a0\u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c \u043d\u0430\u00a0\u043e\u0441\u043d\u043e\u0432\u0435 \u043a\u043b\u044d\u0439\u043c\u043e\u0432 \u0438 \u043f\u043e\u043b\u0438\u0442\u0438\u043a. \u0412\u00a0\u0441\u0432\u043e\u0435 \u0432\u0440\u0435\u043c\u044f\u00a0\u0431\u044b\u043b \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u043b\u0435\u043d \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 <a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/security\/authorization\/claims?view=aspnetcore-6.0\" rel=\"noopener noreferrer nofollow\"><u>Claims\u2011based authorization in ASP.NET Core<\/u><\/a>, \u043d\u043e\u00a0\u043d\u0443\u0436\u043d\u043e\u00a0\u0431\u044b\u043b\u043e \u043d\u0430\u00a0Node.js (\u0430 \u0442\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0430\u00a0\u043b\u044e\u0431\u0443\u044e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443, \u0433\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f PostgreSQL). \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0435\u0448\u0438\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0440\u0430\u0432 \u043d\u0430\u00a0PL\/pgSQL. \u0415\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u0433\u043e. <\/p>\n<h2>\u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435<\/h2>\n<p>\u041d\u0430\u00a0\u043e\u0434\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u043a\u00a0\u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043f\u043e\u043a\u0430 \u0441\u0432\u0435\u0442 \u043d\u0435\u00a0\u0443\u0432\u0438\u0434\u0435\u043b \u0438 \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u043d\u0435\u00a0\u0443\u0432\u0438\u0434\u0438\u0442, \u043d\u0443\u0436\u043d\u043e \u0434\u0430\u0432\u0430\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c \u043e\u0447\u0435\u043d\u044c \u0433\u0438\u0431\u043a\u0438\u0435 \u043f\u0440\u0430\u0432\u0430. \u041f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u0430\u0432\u0438\u043b \u0434\u043b\u044f\u00a0\u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a\u00a0\u0440\u0435\u0441\u0443\u0440\u0441\u0443:<\/p>\n<ul>\n<li>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u043e\u043b\u0436\u0435\u043d\u00a0\u0431\u044b\u0442\u044c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d \u0447\u0435\u0440\u0435\u0437 Facebook, \u0441\u0442\u0430\u0440\u0448\u0435 18\u00a0\u043b\u0435\u0442, \u043d\u043e\u00a0\u043c\u043e\u043b\u043e\u0436\u0435 50. \u0410\u00a0\u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0432\u00a0\u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0435 \u043b\u044e\u0431\u0438\u0442\u0435\u043b\u0435\u0439 \u043c\u0430\u0448\u0438\u043d \u0424\u0435\u0440\u0440\u0430\u0440\u0438. <\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u0430\u043a\u043e\u0435\u2011\u0442\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u0435, \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043e\u0442\u043a\u0440\u043e\u0435\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0443\u043f \u043a\u00a0\u0440\u0435\u0441\u0443\u0440\u0441\u0443.<\/p>\n<\/li>\n<li>\n<p>\u0412\u0441\u0435 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e\u043b\u0435\u0442\u043d\u0438\u0435, \u043d\u0435\u00a0\u043f\u0440\u043e\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u0435 \u0432\u00a0\u041c\u043e\u0441\u043a\u0432\u0435.<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u0442\u044c \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u00a0\u0440\u0430\u0437\u043d\u044b\u0435 \u0431\u0438\u0437\u043d\u0435\u0441\u2011\u0437\u0430\u0434\u0430\u0447\u0438.<\/p>\n<p>\u041d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u0430\u044f \u043c\u043d\u043e\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0430, \u043a\u00a0\u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0441\u0432\u0435\u0442 \u043d\u0435\u00a0\u0443\u0432\u0438\u0434\u0435\u043b\u0430 (\u043f\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u0444\u0438\u043d\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430) \u0438 \u043f\u043e\u043a\u0430 \u043d\u0435\u00a0\u0431\u044b\u043b\u0430 \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0432\u00a0\u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435. <\/p>\n<p>\u041a\u043e\u043b\u043b\u0435\u0433\u0438, \u0441\u00a0\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u043b \u044d\u0442\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u0438 \u044f\u00a0\u0431\u044b\u043b\u0438 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u044b\u00a0\u2014 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e \u0432\u043f\u0438\u0441\u044b\u0432\u0430\u043b\u0430\u0441\u044c \u0432\u00a0\u043d\u0430\u0448\u0438 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f. \u0425\u043e\u0447\u0443 \u0443\u0441\u043b\u044b\u0448\u0430\u0442\u044c \u043c\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u043e\u043d\u0430\u043b\u043e\u0432 \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0442\u043d\u0443\u044e \u0441\u0432\u044f\u0437\u044c. <\/p>\n<h2>\u0422\u0435\u0440\u043c\u0438\u043d\u044b<\/h2>\n<p><em>\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043c\u043e\u0433\u0443\u0442\u00a0\u0431\u044b\u0442\u044c \u043d\u0435\u043f\u043e\u043d\u044f\u0442\u043d\u044b, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0439\u0442\u0435\u0441\u044c \u043a\u00a0\u043d\u0438\u043c \u043f\u043e\u00a0\u043c\u0435\u0440\u0435 \u043f\u0440\u043e\u0447\u0442\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438.<\/em> <\/p>\n<p><strong>\u0422\u0438\u043f \u0440\u0435\u0441\u0443\u0440\u0441\u0430<\/strong>\u00a0\u2014 \u0442\u0438\u043f \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u0441\u0442\u044b \u0431\u043b\u043e\u0433\u0430, \u0437\u0430\u043a\u0430\u0437\u044b. <\/p>\n<p><strong>\u0420\u0435\u0441\u0443\u0440\u0441 (\u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c, entity, resource)<\/strong>\u00a0\u2014 \u0442\u043e, \u0441\u00a0\u0447\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442\u00a0\u0431\u044b\u0442\u044c \u043f\u043e\u0441\u0442 \u0432\u00a0\u0431\u043b\u043e\u0433\u0435, \u0437\u0430\u043a\u0430\u0437 \u043d\u0430\u00a0\u0441\u0430\u0439\u0442\u0435. \u0412\u00a0\u043e\u0431\u0449\u0435\u043c, \u044d\u0442\u043e \u0442\u043e, \u043a\u00a0\u0447\u0435\u043c\u0443 \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043f\u0440\u0430\u0432\u0430. \u041d\u0435\u00a0\u043f\u0443\u0442\u0430\u0442\u044c \u0441\u00a0\u0442\u0438\u043f\u043e\u043c \u0440\u0435\u0441\u0443\u0440\u0441\u0430. \u0420\u0435\u0441\u0443\u0440\u0441\u00a0\u2014 \u044d\u0442\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0430\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c (\u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e\u00a0\u2014 \u0442\u043e, \u0447\u0442\u043e\u00a0\u0438\u043c\u0435\u0435\u0442 id), \u0430\u00a0\u0442\u0438\u043f \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 \u0432\u0441\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438. <\/p>\n<p><strong>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u0430 (ability)<\/strong>\u00a0\u2014 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u043d\u0430\u0434 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u043c. \u0423\u00a0\u043e\u0434\u043d\u043e\u0433\u043e \u0440\u0435\u0441\u0443\u0440\u0441\u0430 \u043c\u043e\u0436\u0435\u0442\u00a0\u0431\u044b\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0440\u0435\u0441\u0443\u0440\u0441\u00a0\u2014 \u043f\u043e\u0441\u0442 \u0432\u00a0\u0431\u043b\u043e\u0433\u0435. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u00a0\u2014 \u0447\u0442\u0435\u043d\u0438\u0435, \u043f\u0440\u0430\u0432\u043a\u0430, \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435. <\/p>\n<p><strong>\u041a\u043b\u044d\u0439\u043c (\u043a\u043b\u044f\u0439\u043c, claim)<\/strong>\u00a0\u2014 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e\u00a0\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u043e\u0437\u0440\u0430\u0441\u0442, \u0432\u00a0\u043a\u0430\u043a\u0438\u0445 \u0433\u0440\u0443\u043f\u043f\u0430\u0445 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u00a0\u0442.\u00a0\u0434. \u041d\u0430\u00a0\u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0440\u0430\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u0441\u0435 \u0441\u0432\u043e\u0438 \u043a\u043b\u044d\u0439\u043c\u044b, \u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043d\u0430\u00a0\u043e\u0441\u043d\u043e\u0432\u0435 \u044d\u0442\u0438\u0445 \u043a\u043b\u044d\u0439\u043c\u043e\u0432 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0438\u043c\u0435\u0435\u0442\u00a0\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a\u00a0\u0442\u043e\u043c\u0443 \u0438\u043b\u0438\u00a0\u0438\u043d\u043e\u043c\u0443 \u0440\u0435\u0441\u0443\u0440\u0441\u0443. <\/p>\n<p><strong>\u041f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 (\u043f\u0440\u0430\u0432\u0438\u043b\u043e, policy)<\/strong>\u00a0\u2014 \u043d\u0430\u0431\u043e\u0440 \u043a\u043b\u044d\u0439\u043c\u043e\u0432 \u0434\u043b\u044f\u00a0\u043f\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 \u00ab\u0421\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e\u043b\u0435\u0442\u043d\u0438\u0435, \u043d\u0435\u00a0\u043f\u0440\u043e\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u0435 \u0432\u00a0\u041c\u043e\u0441\u043a\u0432\u0435\u00bb \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043a\u043b\u044d\u0439\u043c\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f: \u0432\u043e\u0437\u0440\u0430\u0441\u0442 (\u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d\u00a0\u0431\u044b\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 18) \u0438 \u0433\u043e\u0440\u043e\u0434 \u043f\u0440\u043e\u0436\u0438\u0432\u0430\u043d\u0438\u044f (\u0434\u043e\u043b\u0436\u0435\u043d\u00a0\u0431\u044b\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u043a\u0440\u043e\u043c\u0435 \u041c\u043e\u0441\u043a\u0432\u044b).<\/p>\n<h2>\u041f\u0440\u0438\u043d\u0446\u0438\u043f \u0440\u0430\u0431\u043e\u0442\u044b<\/h2>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0444\u043e\u0440\u043c\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043f\u043e\u0441\u0442\u0443 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c85\/36e\/904\/c8536e904db85d522bd3d86e80a01a91.png\" alt=\"\u0424\u043e\u0440\u043c\u0430 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0441\u0442\" title=\"\u0424\u043e\u0440\u043c\u0430 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0441\u0442\" width=\"606\" height=\"602\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/c85\/36e\/904\/c8536e904db85d522bd3d86e80a01a91.png\"\/><figcaption>\u0424\u043e\u0440\u043c\u0430 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0441\u0442<\/figcaption><\/figure>\n<p>\u041f\u043e\u044f\u0441\u043d\u044e: \u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0441\u0442 \u043c\u043e\u0436\u0435\u0442 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440 \u0438\u043b\u0438\u00a0\u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u0441\u0442\u0430\u0440\u0448\u0435 18\u00a0\u043b\u0435\u0442, \u043f\u0440\u043e\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u0439 \u0432\u00a0\u041c\u043e\u0441\u043a\u0432\u0435 \u0438\u043b\u0438\u00a0\u0421\u0430\u043d\u043a\u0442\u2011\u041f\u0435\u0442\u0435\u0440\u0431\u0443\u0440\u0433\u0435. \u0418\u043b\u0438\u00a0\u0418\u0432\u0430\u043d\u043e\u0432 \u0418.\u0418. \u0441\u00a0Id 123. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u043c. \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c 4\u00a0\u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438. \u0412\u0432\u0435\u0434\u0435\u043c \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044f:<\/p>\n<ul>\n<li>\n<p>P1\u00a0\u2014 \u0421\u043e\u0441\u0442\u043e\u0438\u0442 \u0432\u00a0\u0433\u0440\u0443\u043f\u043f\u0435<\/p>\n<\/li>\n<li>\n<p>P2\u00a0\u2014 \u0412\u043e\u0437\u0440\u0430\u0441\u0442 \u0441\u0442\u0430\u0440\u0448\u0435<\/p>\n<\/li>\n<li>\n<p>P3\u00a0\u2014 \u0413\u043e\u0440\u043e\u0434 \u043f\u0440\u043e\u0436\u0438\u0432\u0430\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>P4\u00a0\u2014 \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u043e\u0433\u0434\u0430 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430\u0448\u0435\u0439 \u0444\u043e\u0440\u043c\u044b \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c:<\/p>\n<pre><code>(   P1 = \u201c\u0410\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u201d   \u0418\u041b\u0418    (     P1 = \u201c\u0420\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u201d      \u0418      P2 >= 18      \u0418      (       P3 = \u201c\u041c\u043e\u0441\u043a\u0432\u0430\u201d        \u0418\u041b\u0418        P3 = \u201c\u0421\u0430\u043d\u043a\u0442-\u041f\u0435\u0442\u0435\u0440\u0431\u0443\u0440\u0433\u201d     )   )    \u0418\u041b\u0418    P4 = 123 )<\/code><\/pre>\n<p>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u0442 SQL \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 WHERE, \u043d\u0435\u00a0\u043f\u0440\u0430\u0432\u0434\u0430\u00a0\u043b\u0438? \u0418 \u043d\u0430\u0448\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u0441\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043a\u00a0\u0442\u043e\u043c\u0443, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u0443 \u0444\u043e\u0440\u043c\u0443 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u0432\u00a0\u0433\u043e\u0442\u043e\u0432\u043e\u0435 \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0435 SQL WHERE \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438 \u0432\u00a0\u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043d\u0430\u00a0\u043f\u0440\u0430\u0432\u043a\u0443 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0435\u0433\u043e.<\/p>\n<h2>\u041d\u0430\u0447\u043d\u0451\u043c \u043f\u043e\u0433\u0440\u0443\u0436\u0435\u043d\u0438\u0435<\/h2>\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441 \u043f\u043e\u0441\u0442\u0430\u043c\u0438 \u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u0435\u0451 \u0434\u0430\u043d\u043d\u044b\u043c\u0438.<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"sql\">CREATE TABLE IF NOT EXISTS post (    id serial primary key,    title text not null );   INSERT INTO post(title) VALUES ('Post 1'), ('Post 2');<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0440\u0430\u0432 \u0438\u0434\u0451\u0442 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445. \u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u043e\u0441\u0442\u044b, \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441.<\/p>\n<details class=\"spoiler\">\n<summary>\u0422\u0430\u043a \u043c\u044b \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0432\u0441\u0435 \u043f\u043e\u0441\u0442\u044b<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"sql\">SELECT p.* FROM post p;<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u044d\u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u043c\u044b \u0438 \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043f\u0440\u0430\u0432\u0430, \u043d\u043e \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u0442\u044c, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b.<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u0441\u0438\u0441\u0442\u0435\u043c\u044b<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"pgsql\">CREATE TYPE group_condition AS enum ('OR', 'AND');  CREATE TABLE IF NOT EXISTS policy (     id serial primary key,     name varchar,     resolver_code  varchar(255) not null );  CREATE TABLE IF NOT EXISTS claim (     id serial primary key,     code varchar,     name varchar,     replaceable_by_user boolean default true );  CREATE TABLE IF NOT EXISTS policy_claim (     policy_id integer not null         references policy on delete restrict,     claim_id integer not null references claim on delete restrict,     where_condition text default '%1$s = %2$s'::text not null,     primary key (policy_id, claim_id) );   CREATE TABLE IF NOT EXISTS post_group_policy (     id serial primary key,     type group_condition       not null,     parent_group integer         constraint post_group_policy_post_group_policy_id_fk             references post_group_policy             on delete cascade,     negative boolean default false not null );  CREATE TABLE IF NOT EXISTS post_ability (     code varchar not null primary key,     name varchar not null );  CREATE TABLE IF NOT EXISTS post_policy (     id serial primary key,     entity_id int not null constraint post_policy_post_id_fk             references post on delete cascade,     policy_id integer not null references policy on delete restrict,     group_id integer references post_group_policy on delete cascade,     ability varchar not null references post_ability on delete restrict,     negative  boolean default false not null );  CREATE TABLE IF NOT EXISTS post_policy_claim (     entity_policy_id integer not null         constraint post_policy_claim_post_policy_id_fkey             references post_policy             on delete cascade,     claim_id integer not null         references claim             on delete restrict,     value varchar not null,     primary key (entity_policy_id, claim_id, value) );  CREATE TABLE IF NOT EXISTS post_indexed_rule (     entity_id int not null,     condition text not null,     ability varchar not null references post_ability on delete cascade,     used_claims character varying[] not null,     constraint post_indexed_rule_pk         primary key (ability, entity_id) );  \/**   \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u0438\u0435, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e  *\/ DROP FUNCTION IF EXISTS __process_policy_negative; CREATE FUNCTION __process_policy_negative(_condition text, _is_negative boolean)     RETURNS text AS $$ DECLARE     _format text; BEGIN     IF _is_negative THEN         _format = 'NOT(%s)';     ELSE         _format = '%s';     END IF;     RETURN format(_format, _condition); END $$ LANGUAGE plpgsql;  \/**   \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0443\u0441\u043b\u043e\u0432\u0438\u0439 \u0434\u043b\u044f \u0433\u0440\u0443\u043f\u043f\u044b   \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u0430\u044f. \u0415\u0439 \u043d\u0430 \u0432\u0445\u043e\u0434 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u043a\u043e\u0440\u043d\u0435\u0432\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0430, \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043d\u0438\u0437 \u043f\u043e \u0434\u0435\u0440\u0435\u0432\u0443 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b  *\/ DROP FUNCTION IF EXISTS __process_policy_group_condition; CREATE FUNCTION __process_policy_group_condition(_entity_policy_group record, _query text)     RETURNS text AS $$ DECLARE     _group_policies record;     _format text; BEGIN     -- \u0441\u043a\u043b\u0435\u0439\u043c \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u044b \u0441 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u043e\u0439 (\u0438\u043b\u0438 \u043d\u0438 \u0441 \u0447\u0435\u043c \u0435\u0441\u043b\u0438 \u0444-\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0432\u044b\u0439 \u0440\u0430\u0437)     _query = format('%s%s', _query, _entity_policy_group.group_condition);      -- \u043d\u0430\u0439\u0434\u0451\u043c \u0432\u0441\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u0433\u0440\u0443\u043f\u043f\u044b \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0433\u0440\u0443\u043f\u043f\u044b     BEGIN FOR _group_policies IN         SELECT *         FROM policy_group_condition p         WHERE p.parent_group = _entity_policy_group.group_id         LOOP              -- \u0435\u0441\u043b\u0438 \u0433\u0440\u0443\u043f\u043f\u0430 \u0441 \u043e\u0442\u0440\u0438\u0446\u0430\u043d\u0438\u0435\u043c, \u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0435\u0439 \u0433\u0440\u0443\u043f\u043f\u044b             IF _entity_policy_group.negative THEN                 _format = '%s %s NOT(';             ELSE                 _format = '%s %s (';             end if;             _query := format(_format, _query, _entity_policy_group.type);             -- \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0434\u043e\u0447\u0435\u0440\u043d\u044e\u044e \u0433\u0440\u0443\u043f\u043f\u0443 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e             SELECT __process_policy_group_condition(_group_policies, _query) INTO _query;             _query := _query || ')';         END LOOP;     END;     return _query; END; $$ LANGUAGE plpgsql;  DROP FUNCTION IF EXISTS __process_user_claim_value; CREATE FUNCTION __process_user_claim_value(_user_claim_value_jsonb jsonb)     RETURNS text AS $$ DECLARE     _user_claim_value text;     _user_claim_value_type text;     _user_claim_value_array_item_jsonb jsonb;     _user_claim_value_array_item_type text;     _user_claim_value_array_int_result int[] DEFAULT ARRAY[]::int[];     _user_claim_value_array_text_result text[] DEFAULT ARRAY[]::text[]; BEGIN     -- \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043a\u043b\u044f\u0439\u043c\u0430     _user_claim_value := _user_claim_value_jsonb ->> 0;      -- \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u043b \u043a\u043b\u044f\u0439\u043c, \u0437\u043d\u0430\u0447\u0438\u0442 \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043d\u0430 \u043f\u0443\u0441\u0442\u043e\u0442\u0443 (\u0442.\u0435. \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c \u043f\u0443\u0441\u0442\u043e\u0439 \u043a\u043b\u044f\u0439\u043c)     IF _user_claim_value IS NULL THEN         _user_claim_value = format('%L', '');     ELSE         -- \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0438\u043f \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043e\u0433\u043e \u043a\u043b\u044f\u0439\u043c\u0430         _user_claim_value_type = jsonb_typeof(_user_claim_value_jsonb);         CASE              -- \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043c\u0430\u0441\u0441\u0438\u0432             WHEN _user_claim_value_type = 'array' THEN                  -- \u0435\u0441\u043b\u0438 \u043d\u0435 \u043f\u0443\u0441\u0442\u043e\u0439, \u0442\u043e\u0433\u0434\u0430 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043c jsonb \u043c\u0430\u0441\u0441\u0438\u0432 \u0432 \u0441\u0442\u0440\u043e\u043a\u0443, \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u0443\u044e \u0437\u0430\u043f\u044f\u0442\u044b\u043c\u044b ([1,2,3,4] => '1,2,3,4')                 IF jsonb_array_length(_user_claim_value_jsonb) > 0 THEN                     _user_claim_value := format('%L', '');                      -- \u0442\u0443\u0442 \u043d\u0430\u0434\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c jsonb \u043c\u0430\u0441\u0441\u0438\u0432 \u0432 \u0441\u0442\u0440\u043e\u043a\u0443 \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430.                     -- \u0441 \u0438\u043d\u0442\u0430\u043c\u0438 \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e [1,2,3] => 1,2,3                     -- \u0430 \u0441\u0442\u0440\u0438\u043d\u0433\u0438 \u043d\u0443\u0436\u043d\u043e \u0438\u0437 [\"s1\", \"s2\"] \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0432 's1','s2' (\u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u043a\u0430\u0432\u044b\u0447\u043a\u0438)                     -- \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0445\u043e\u0434\u0438\u043c \u043f\u043e \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443 \u043c\u0430\u0441\u0441\u0438\u0432\u0430                     -- \u0442\u0443\u0442 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c 2 \u043c\u0430\u0441\u0441\u0438\u0432\u0430: \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0439 (_user_claim_value_array_int_result) \u0438 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0439 (_user_claim_value_array_text_result)                     -- \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u0438\u043f\u0430 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043c\u044b \u043f\u043e\u043c\u0435\u0449\u0430\u0435\u043c \u0435\u0433\u043e \u0432 \u043d\u0443\u0436\u043d\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432                     -- \u043f\u043e\u0442\u043e\u043c \u043c\u044b \u043c\u0430\u0441\u0441\u0438\u0432, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0435\u0441\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u043d\u043a\u0430\u0442\u0438\u043c \u043f\u043e \u0437\u0430\u043f\u044f\u0442\u043e\u0439 \u0438 \u043f\u0440\u0438\u0441\u0432\u0430\u0438\u0432\u0430\u0435\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0443                     FOR _user_claim_value_array_item_jsonb IN SELECT a FROM jsonb_array_elements(_user_claim_value_jsonb) as a                         LOOP                             -- \u0431\u0435\u0440\u0435\u043c \u0435\u0433\u043e \u0442\u0438\u043f                             _user_claim_value_array_item_type = jsonb_typeof(_user_claim_value_array_item_jsonb );                             CASE                                 -- \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0438\u043d\u0442, \u0442\u043e \u043f\u0438\u0445\u0430\u0435\u043c \u043a\u0430\u043a \u0435\u0441\u0442\u044c \u0432 \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u0439 \u043c\u0430\u0441\u0441\u0438\u0432                                 WHEN _user_claim_value_array_item_type = 'number' THEN                                     SELECT array_append(_user_claim_value_array_int_result, _user_claim_value_array_item_jsonb::int) INTO _user_claim_value_array_int_result;                                  -- \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0441\u0442\u0440\u043e\u043a\u0430, \u0442\u043e \u044d\u043a\u0441\u0442\u0440\u0430\u043a\u0442\u0438\u043c \u0435\u0451 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438 \u043f\u0438\u0445\u0430\u0435\u043c \u0432 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432                                 WHEN _user_claim_value_array_item_type = 'string' THEN                                     SELECT array_append(_user_claim_value_array_text_result, format('%L', _user_claim_value_array_item_jsonb ->> 0)) INTO _user_claim_value_array_text_result;                                 END CASE;                         END LOOP;                      -- \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0435                     IF array_length(_user_claim_value_array_text_result, 1) > 0 THEN                         SELECT INTO _user_claim_value array_to_string(_user_claim_value_array_text_result, ',');                          -- \u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u0447\u0438\u0441\u043b\u043e\u0432\u043e\u043c \u043c\u0430\u0441\u0441\u0438\u0432\u0435                     ELSIF array_length(_user_claim_value_array_int_result, 1) > 0 THEN                         SELECT INTO _user_claim_value array_to_string(_user_claim_value_array_int_result, ',');                     END IF;                  ELSE                     _user_claim_value = 'NULL';                 END IF;             ELSE                  -- \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0441\u043a\u0430\u043b\u044f\u0440\u043d\u043e\u0435 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u0435\u0440\u043d\u0435\u043c \u0435\u0433\u043e \u0432 \u043a\u0430\u0432\u044b\u0447\u043a\u0438                 _user_claim_value = format('%L', _user_claim_value);             END CASE;     END IF;      RETURN _user_claim_value; END; $$ LANGUAGE plpgsql;   DROP FUNCTION IF EXISTS index_entity_policies; CREATE FUNCTION index_entity_policies(_table_prefix varchar, _entity_id anyelement, _ability anycompatible)     RETURNS void AS $$ DECLARE     _policy_group_condition record;     _check_query text;     _check_where text default '';     _used_claims varchar[] default ARRAY[]::varchar[]; BEGIN     -- \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u0432\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0432\u0441\u0435 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438     CREATE TEMPORARY TABLE IF NOT EXISTS entity_policies (                                                              id int,                                                              policy_id int,                                                              group_id int,                                                              negative boolean     );      TRUNCATE TABLE entity_policies;     EXECUTE format('INSERT INTO entity_policies ' ||                    'SELECT id, policy_id, group_id, negative FROM %I WHERE entity_id = $1 AND ability = $2;', _table_prefix || '_policy')         USING  _entity_id, _ability;      -- \u0435\u0441\u043b\u0438 \u043d\u0435\u0442 \u043f\u043e\u043b\u0438\u0442\u0438\u043a \u0438\u043b\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439     IF NOT EXISTS(SELECT 1 from entity_policies) THEN         RETURN;     END IF;      -- \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u0432\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0432\u0441\u0435 \u043a\u043b\u044f\u0439\u043c\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f. \u043f\u043e\u0434\u0446\u0435\u043f\u0438\u043c \u043a \u043d\u0438\u043c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0433\u0440\u0443\u043f\u043f\u0435, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043d\u0430\u0445\u043e\u0434\u044f\u0442\u0441\u044f \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438     CREATE TEMPORARY TABLE IF NOT EXISTS required_policy_claims(                                                                    id int,                                                                    policy_id int,                                                                    claim_id int,                                                                    code text,                                                                    value text,                                                                    where_condition text,                                                                    group_id int,                                                                    parent_group int,                                                                    type group_condition,                                                                    negative boolean,                                                                    entity_policy_negative boolean,                                                                    replaceable_by_user_claim boolean     );     TRUNCATE TABLE required_policy_claims;     EXECUTE format(                                     'INSERT INTO required_policy_claims ' ||                                     'SELECT ep.id, ep.policy_id, stpc.claim_id, c.code, stpc.value, pc.where_condition, ep.group_id, stgp.parent_group, stgp.type, stgp.negative, ep.negative as entity_policy_negative, c.replaceable_by_user replaceable_by_user_claim ' ||                                     'FROM %I stpc ' ||                                     'INNER JOIN entity_policies ep on stpc.entity_policy_id = ep.id ' ||                                     'INNER JOIN claim c on c.id = stpc.claim_id ' ||                                     'INNER JOIN %I stgp on stgp.id = ep.group_id ' ||                                     'INNER JOIN policy_claim pc on ep.policy_id = pc.policy_id AND stpc.claim_id = pc.claim_id',                                     _table_prefix || '_policy_claim', _table_prefix || '_group_policy'         );      -- \u0432 \u044d\u0442\u0443 \u0432\u0440\u0435\u043c\u0435\u043d\u043d\u0443\u044e \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u043c\u044b \u0441\u043a\u043b\u0430\u0434\u044b\u0432\u0430\u0435\u043c \u0443\u0436\u0435 \u0441\u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 \u043f\u043e \u0433\u0440\u0443\u043f\u043f\u0430\u043c     CREATE TEMPORARY TABLE IF NOT EXISTS policy_group_condition (                                                                     group_id int,                                                                     parent_group int,                                                                     group_condition text,                                                                     type text,                                                                     negative boolean     );     TRUNCATE TABLE policy_group_condition;     INSERT INTO policy_group_condition     WITH policits_with_cond AS (         SELECT rpc.id,                -- \u0442\u0443\u0442 \u043c\u044b \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u043c \u043a\u043b\u044f\u0439\u043c\u044b \u043e\u0434\u043d\u043e\u0439 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 \u043f\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044e AND                format('(%s)', array_to_string(array_agg(format(__process_policy_negative(rpc.where_condition, rpc.entity_policy_negative), quote_literal(rpc.value), format('[#%s#]', rpc.code))), ') AND (')) as condition,                rpc.group_id,                rpc.parent_group,                rpc.type,                rpc.negative         FROM required_policy_claims rpc         GROUP BY rpc.id, rpc.type, rpc.group_id, rpc.parent_group, rpc.type, rpc.negative         ORDER BY rpc.id     ), policits_by_groups AS (         SELECT             p.group_id,             p.parent_group,             -- \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u043c \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 \u0432 \u0433\u0440\u0443\u043f\u043f\u0435 \u043f\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044e, \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043d\u043d\u043e\u043c\u0443 \u0432 \u0433\u0440\u0443\u043f\u043f\u0435             format('(%s)', array_to_string(array_agg(__process_policy_negative(p.condition, p.negative)), format(') %s (', p.type))) as group_condition,             p.type,             p.negative         FROM policits_with_cond p         GROUP BY p.group_id, p.type, p.parent_group, p.negative         ORDER BY p.group_id     ) SELECT * FROM policits_by_groups;      -- \u043d\u0430\u0447\u0435\u043c \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442\u044c \u043f\u043e \u0433\u0440\u0443\u043f\u043f\u0430\u043c. \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u0441 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b     BEGIN FOR _policy_group_condition IN         SELECT * FROM policy_group_condition p WHERE p.parent_group IS NULL         LOOP             SELECT __process_policy_group_condition(_policy_group_condition, _check_where) INTO _check_where;         END LOOP;     END;      SELECT INTO _used_claims ARRAY(SELECT DISTINCT code FROM required_policy_claims WHERE replaceable_by_user_claim = true);      -- \u0438\u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c.     _check_query := format('SELECT true WHERE (%s)', _check_where);      EXECUTE format('INSERT INTO %I(entity_id, ability, condition, used_claims) ' ||                    'VALUES ($1, $2, $3, $4) ' ||                    'ON CONFLICT (entity_id, ability) DO UPDATE ' ||                    'SET condition = $3, used_claims = $4', _table_prefix || '_indexed_rule')         USING _entity_id, _ability, _check_where, _used_claims;   END $$ LANGUAGE plpgsql;  DROP FUNCTION IF EXISTS check_user_rights; CREATE FUNCTION check_user_rights(_table_prefix varchar, _entity_id anyelement, _ability anycompatible, _user_claims jsonb)     RETURNS boolean AS $$ DECLARE     _where_condition record;     _used_claim varchar;     _result_condition text;     _check_query boolean; BEGIN      EXECUTE format('SELECT condition, used_claims ' ||                    'FROM %I WHERE entity_id = $1 AND ability = $2;', _table_prefix || '_indexed_rule')         USING _entity_id, _ability INTO _where_condition ;      _result_condition = _where_condition.condition;      IF _where_condition IS NULL THEN         RETURN NULL;     END IF;      FOREACH _used_claim IN ARRAY _where_condition.used_claims         LOOP             SELECT INTO _result_condition replace(_result_condition, format('[#%s#]', _used_claim), COALESCE(_user_claims ->> _used_claim, quote_literal('')));         END LOOP;      EXECUTE format('SELECT true WHERE (%s)', _result_condition) INTO _check_query;     RETURN _check_query; END $$ LANGUAGE plpgsql;   DROP FUNCTION IF EXISTS __process_user_claim_values; CREATE FUNCTION __process_user_claim_values(_user_claims jsonb)     RETURNS jsonb AS $$ DECLARE     _json_el record;     _jsonb_result jsonb default '{}'::jsonb; BEGIN     BEGIN FOR _json_el IN         select key, value from jsonb_each(_user_claims)         LOOP             SELECT INTO _jsonb_result jsonb_set(_jsonb_result, ARRAY[_json_el.key], to_jsonb(__process_user_claim_value(_json_el.value)));         END LOOP;     END;     RETURN _jsonb_result; END; $$ LANGUAGE plpgsql;  DROP FUNCTION IF EXISTS check_index_rules CASCADE; CREATE FUNCTION check_index_rules() RETURNS trigger AS $$ DECLARE     _rows_count int; BEGIN     EXECUTE format('SELECT count(*) FROM %I ' ||                    'WHERE entity_id = $1 AND ability = $2', TG_ARGV[0] || '_policy')         USING old.entity_id, old.ability INTO _rows_count ;      IF _rows_count = 0 THEN         EXECUTE format('DELETE FROM %I WHERE entity_id = $1 AND ability = $2', TG_ARGV[0] || '_indexed_rule')             USING old.entity_id, old.ability;      END IF;     RETURN new; END; $$ LANGUAGE plpgsql;  -- \u0442\u0440\u0438\u0433\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043b\u0435\u0434\u0438\u0442 \u0437\u0430 \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c\u0438. \u0415\u0441\u043b\u0438 \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043b\u0435\u043d\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0442\u043e \u0443\u0434\u0430\u043b\u0438\u0442\u0441\u044f \u0438 \u043f\u0440\u043e\u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u043e CREATE TRIGGER post_clear_index AFTER DELETE ON post_policy FOR EACH ROW EXECUTE FUNCTION check_index_rules('post'); <\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0418\u0437\u043c\u0435\u043d\u0438\u043c \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0432\u044b\u0431\u043e\u0440\u043a\u0443 \u043f\u043e\u0434 \u043d\u0430\u0448\u0438 \u043d\u0443\u0436\u0434\u044b.<\/p>\n<details class=\"spoiler\">\n<summary>\u0417\u0430\u043f\u0440\u043e\u0441 \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u043f\u043e\u0441\u0442\u043e\u0432 \u0441 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u043e\u0439 \u043f\u0440\u0430\u0432<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"sql\">SELECT p.* FROM    post p,    LATERAL (SELECT \/* (1) *\/ __process_user_claim_values(\/* (2) *\/ '{\"age\": 24, \"location\": \"\u041c\u043e\u0441\u043a\u0432\u0430\", \"userId\": 123}'::jsonb) as processed_user_claim) l WHERE check_user_rights(    'post', \/* (3) *\/    p.id, \/* (4) *\/    'edit', \/* (5) *\/    l.processed_user_claim \/* (6) *\/ );<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0443\u0442 \u0443 \u043d\u0430\u0441 24-\u043b\u0435\u0442\u043d\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0438\u0437 \u041c\u043e\u0441\u043a\u0432\u044b \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u043e\u0441\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>check_user_rights<\/code> \u0434\u043e\u043b\u0436\u043d\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u0438\u0442\u044c, \u043c\u043e\u0436\u0435\u0442 \u043b\u0438 \u043d\u0430\u0448 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u043f\u043e\u0441\u0442\u044b.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0435\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c, \u043d\u0430\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0432\u0435\u0440\u043d\u0435\u0442\u0441\u044f, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0438 \u0434\u043b\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430 \u043d\u0435 \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043d\u044b \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430.<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u044d\u0442\u0443 \u0432\u044b\u0431\u043e\u0440\u043a\u0443.<\/p>\n<h3>\u0420\u0430\u0437\u0431\u043e\u0440 \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445<\/h3>\n<h4>\/* (1) *\/ \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043b\u044d\u0439\u043c\u043e\u0432<\/h4>\n<p>\u0412 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0438 <strong>FROM<\/strong> \u043c\u044b \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0435\u043c \u043a\u043b\u044d\u0439\u043c\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u0430\u043b\u0438\u0430\u0441 <strong>l.<\/strong> \u042d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0442\u0443\u0442, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0448\u043b\u043e \u043e\u0434\u0438\u043d \u0440\u0430\u0437, \u0430 \u043d\u0435 \u043f\u0440\u0438 \u043a\u0430\u0436\u0434\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0435 \u0432 <strong>WHERE<\/strong>.\u00a0<\/p>\n<p>\u0427\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>__process_user_claim_values<\/code>? \u041e\u043d\u0430 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u0443\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f <code>jsonb<\/code> \u0432 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0443\u0441\u043b\u043e\u0432\u0438\u0438 <strong>WHERE<\/strong>. \u041f\u043e\u044f\u0441\u043d\u044e \u043d\u0430 \u043f\u0440\u0438\u043c\u0435\u0440\u0435.<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u043b\u044d\u0439\u043c\u043e\u0432 \u0432 SQL \u043f\u0440\u0438\u0433\u043e\u0434\u043d\u044b\u0435 \u043b\u0438\u0442\u0435\u0440\u0430\u043b\u044b<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"sql\">SELECT __process_user_claim_values('{    \"intValue\": 12345,    \"stringValue\": \"abcde\",    \"stringArrayValue\": [\"a\", \"b\", \"c\"],    \"intArrayValue\": [1,2,3,4,5] }'::jsonb);<\/code><\/pre>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u043d\u044b\u0439 jsonb.<\/p>\n<pre><code class=\"json\">{    \"intValue\": \"'12345'\",    \"stringValue\": \"'abcde'\",    \"intArrayValue\": \"1,2,3,4,5\",    \"stringArrayValue\": \"'a','b','c'\" }<\/code><\/pre>\n<ul>\n<li>\n<p>intValue, stringValue &#8212; \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043e\u0431\u0435\u0440\u043d\u0443\u043b\u0438\u0441\u044c \u0432 \u043a\u0430\u0432\u044b\u0447\u043a\u0438.<\/p>\n<\/li>\n<li>\n<p>intArrayValue &#8212; \u043c\u0430\u0441\u0441\u0438\u0432 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u0432 \u0441\u0442\u0440\u043e\u043a\u0443, \u0433\u0434\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u044b \u0437\u0430\u043f\u044f\u0442\u043e\u0439.\u00a0<\/p>\n<\/li>\n<li>\n<p>stringArrayValue &#8212; \u043c\u0430\u0441\u0441\u0438\u0432 \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043b\u0441\u044f \u0432 \u0441\u0442\u0440\u043e\u043a\u0443, \u0433\u0434\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u044b \u0437\u0430\u043f\u044f\u0442\u043e\u0439, \u043d\u043e \u043a\u0430\u0436\u0434\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u043e \u0432 \u043a\u0430\u0432\u044b\u0447\u043a\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u044d\u0442\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u043d\u043e \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0432 <strong>WHERE<\/strong> \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>intArrayValue<\/code> \u0438 <code>stringArrayValue<\/code> \u043c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0438 IN.\u00a0<\/p>\n<pre><code class=\"sql\">SELECT \u2026 FROM \u2026 WHERE p.id IN (1,2,3,4,5).<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<h4>\/* (2) *\/ \u043e\u0442\u043a\u0443\u0434\u0430 \u0431\u0435\u0440\u0443\u0442\u0441\u044f \u043a\u043b\u044d\u0439\u043c\u044b<\/h4>\n<p>\u041d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435 \u043c\u043e\u0436\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f \u0432 \u0411\u0414 (\u043f\u0440\u0438\u043d\u0430\u0434\u043b\u0435\u0436\u043d\u043e\u0441\u0442\u044c \u043a \u0433\u0440\u0443\u043f\u043f\u0435, \u0432\u043e\u0437\u0440\u0430\u0441\u0442 \u0438 \u0442.\u0434.). \u0422\u0430\u043a\u0436\u0435 \u0447\u0430\u0441\u0442\u044c \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043c\u043e\u0436\u0435\u0442 \u0445\u0440\u0430\u043d\u0438\u0442\u044c\u0441\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432 Redis.\u00a0<\/p>\n<p>\u041d\u0430\u0448\u0430 \u0446\u0435\u043b\u044c &#8212; \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u043e\u0442\u043e\u0432\u0441\u044e\u0434\u0443 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435 \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0435\u0435 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>__process_user_claim_values<\/code>. \u0418 \u0434\u0430\u043b\u044c\u0448\u0435 \u0443\u0436\u0435 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u043b\u044d\u0439\u043c\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>check_user_rights<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438 \u0440\u0435\u0448\u0438\u0442, \u0438\u043c\u0435\u0435\u0442 \u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u043e\u0441\u0442\u0443\u043f.<\/p>\n<h4>\/* (3) *\/ \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u0430<\/h4>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044f <code>check_user_rights<\/code> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u0430. \u042d\u0442\u0438\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c \u043c\u044b \u0433\u043e\u0432\u043e\u0440\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0447\u0442\u043e \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u0441\u0442\u044b. \u041a \u0441\u043c\u044b\u0441\u043b\u0443 \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u0430 \u043c\u044b \u0435\u0449\u0435 \u0432\u0435\u0440\u043d\u0435\u043c\u0441\u044f \u0432\u043f\u043e\u0441\u043b\u0435\u0434\u0441\u0442\u0432\u0438\u0438. <\/p>\n<h4>\/* (4) *\/ id \u0440\u0435\u0441\u0443\u0440\u0441\u0430<\/h4>\n<p>\u0412\u0442\u043e\u0440\u043e\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 &#8212; \u044d\u0442\u043e id \u0440\u0435\u0441\u0443\u0440\u0441\u0430. \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c, \u0438\u043c\u0435\u0435\u0442 \u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e \u044d\u0442\u043e\u043c\u0443 \u0440\u0435\u0441\u0443\u0440\u0441\u0443.<\/p>\n<h4>\/* (5) *\/ \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c<\/h4>\n<p>\u0422\u0440\u0435\u0442\u0438\u0439 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440 \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438. \u0423 \u043d\u0430\u0441 \u0443\u043a\u0430\u0437\u0430\u043d\u043e <strong>edit<\/strong>, \u0442.\u0435. \u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c, \u0438\u043c\u0435\u0435\u0442 \u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0441\u0442.<\/p>\n<h4>\/* (6) *\/ \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u043b\u044d\u0439\u043c\u044b<\/h4>\n<p>\u0418 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u043c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u043c \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u043a\u043b\u044d\u0439\u043c\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043b\u0438 \u0432\u044b\u0448\u0435. \u0415\u0441\u043b\u0438 \u0431\u044b \u043c\u044b \u043d\u0435 \u0434\u0435\u043b\u0430\u043b\u0438 \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0435, \u0430 \u0441\u0440\u0430\u0437\u0443 \u0431\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u043b\u0438 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043d\u0435\u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u044b\u0435 \u043a\u043b\u044d\u0439\u043c\u044b, \u0442\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u043c\u0435\u0442\u043d\u043e \u0431\u044b \u043f\u043e\u0441\u0442\u0440\u0430\u0434\u0430\u043b\u0430. <\/p>\n<h4>\u0420\u0435\u0437\u044e\u043c\u0435<\/h4>\n<p>\u0418\u0442\u0430\u043a, \u044d\u0442\u0438\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c \u043c\u044b \u0433\u043e\u0432\u043e\u0440\u0438\u043c:\u00a0<\/p>\n<p>&#171;\u0412\u044b\u0431\u0435\u0440\u0438 \u0432\u0441\u0435 \u043f\u043e\u0441\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 24-\u043b\u0435\u0442\u043d\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0438\u0437 \u041c\u043e\u0441\u043a\u0432\u044b \u0441 id 123 \u043c\u043e\u0436\u0435\u0442 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c&#187;.<\/p>\n<p>\u041d\u043e \u0447\u0442\u043e \u0436\u0435 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>check_user_rights<\/code>? \u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c, \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u0438\u0437\u0443\u0447\u0438\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0411\u0414, \u0438 \u0447\u0442\u043e \u043d\u0430\u0434\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0439 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438. <\/p>\n<h3>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445<\/h3>\n<p>\u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c 3 \u043e\u0431\u0449\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0442\u0438\u043f\u043e\u0432 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432 \u0438 5 \u0442\u0430\u0431\u043b\u0438\u0446 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0442\u0438\u043f \u0440\u0435\u0441\u0443\u0440\u0441\u0430.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/98f\/285\/1db\/98f2851db12a8393cabd62752b4dfdc7.png\" width=\"2382\" height=\"1600\" data-src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/98f\/285\/1db\/98f2851db12a8393cabd62752b4dfdc7.png\"\/><figcaption><\/figcaption><\/figure>\n<p>\u041e\u0431\u0449\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b:<\/p>\n<ul>\n<li>\n<p><strong>policy<\/strong> &#8212; \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0434\u043b\u044f \u0432\u044b\u0431\u043e\u0440\u0430.\u00a0<\/p>\n<\/li>\n<li>\n<p><strong>claim<\/strong> &#8212; \u043a\u043b\u044d\u0439\u043c\u044b, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0435 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u043e\u043b\u0438\u0442\u0438\u043a.<\/p>\n<\/li>\n<li>\n<p><strong>policy_claim<\/strong> &#8212; \u043a\u043b\u044d\u0439\u043c\u044b, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430\u043c\u0438. \u0422\u0443\u0442 \u043c\u044b \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430\u043c, \u043a\u0430\u043a\u0438\u0435 \u043a\u043b\u044d\u0439\u043c\u044b \u043e\u043d\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u0438 \u043a\u0430\u043a.\u00a0<\/p>\n<\/li>\n<\/ul>\n<p>\u0414\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0440\u0430\u0432 \u043a \u0440\u0435\u0441\u0443\u0440\u0441\u0443 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f 5 \u0442\u0430\u0431\u043b\u0438\u0446 \u0441 \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u043e\u043c \u0432 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0438. \u041f\u0440\u0435\u0444\u0438\u043a\u0441 \u0434\u043b\u044f \u0442\u0430\u0431\u043b\u0438\u0446 &#8212; \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0442\u0438\u043f\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u0430. \u0412 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043d\u0438\u0436\u0435 \u043f\u0440\u0435\u0444\u0438\u043a\u0441 <strong>post<\/strong>. \u0414\u043b\u044f \u0437\u0430\u043a\u0430\u0437\u043e\u0432 \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043f\u0440\u0435\u0444\u0438\u043a\u0441 &#8212; <strong>order<\/strong> \u0438 \u0442.\u0434. \u0412\u0430\u0436\u043d\u043e \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u0430, \u0431\u0443\u0434\u0435\u0442 \u0441\u0432\u043e\u0439 \u043d\u0430\u0431\u043e\u0440 \u0442\u0430\u0431\u043b\u0438\u0446. \u0421\u0430\u043c\u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b:<\/p>\n<ul>\n<li>\n<p><strong>post_ability<\/strong> &#8212; \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u044b \u0432\u0441\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0440\u0435\u0441\u0443\u0440\u0441. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0440\u0435\u0441\u0443\u0440\u0441 \u043f\u043e\u0441\u0442 \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438: \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440, \u043f\u0440\u0430\u0432\u043a\u0430, \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435.<\/p>\n<\/li>\n<li>\n<p><strong>post_group_policy<\/strong> &#8212; \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u043e\u0432\u043a\u0430 \u043f\u043e\u043b\u0438\u0442\u0438\u043a \u0440\u0435\u0441\u0443\u0440\u0441\u0430. \u041f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 \u0433\u0440\u0443\u043f\u043f\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u0434\u0440\u0443\u0433 \u0441 \u0434\u0440\u0443\u0433\u043e\u043c \u043f\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0443 \u0418, \u0418\u041b\u0418, \u0418 \u041d\u0415, \u0418\u041b\u0418 \u041d\u0415. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u043f\u043e\u0441\u0442\u0443 \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c: <u>\u0432\u043e\u0437\u0440\u0430\u0441\u0442 \u0431\u043e\u043b\u044c\u0448\u0435 18 \u0418 \u041d\u0415 \u0436\u0438\u0432\u0451\u0442 \u0432 \u041c\u043e\u0441\u043a\u0432\u0435<\/u> \u0438\u043b\u0438 <u>\u0432\u043e\u0437\u0440\u0430\u0441\u0442 \u0431\u043e\u043b\u044c\u0448\u0435 18 \u0418\u041b\u0418 \u0436\u0438\u0432\u0451\u0442 \u0432 \u041c\u043e\u0441\u043a\u0432\u0435.<\/u><\/p>\n<\/li>\n<li>\n<p><strong>post_policy<\/strong> &#8212; \u0441\u0432\u044f\u0437\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u0430 \u0441 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u043e\u0439. \u0422\u0443\u0442 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u0430\u043a\u0438\u0435 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043a \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u0440\u0435\u0441\u0443\u0440\u0441\u0443.\u00a0<\/p>\n<\/li>\n<li>\n<p><strong>post_policy_claim<\/strong> &#8212; \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u043a\u043b\u044d\u0439\u043c\u044b \u043a \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430\u043c. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0430 \u0443\u043a\u0430\u0437\u0430\u043d\u0430 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 &#171;\u0412\u043e\u0437\u0440\u0430\u0441\u0442 \u0441\u0442\u0430\u0440\u0448\u0435&#187;. \u042d\u0442\u0430 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u043a\u043b\u044d\u0439\u043c &#171;\u0432\u043e\u0437\u0440\u0430\u0441\u0442&#187;, \u0432 \u044d\u0442\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0438 \u0431\u0443\u0434\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u043d \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u0439 \u0432\u043e\u0437\u0440\u0430\u0441\u0442.<\/p>\n<\/li>\n<li>\n<p><strong>post_indexed_rule<\/strong> &#8212; \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0434\u043b\u044f \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438.<\/p>\n<\/li>\n<\/ul>\n<h3>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0430<\/h3>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u043f\u0440\u043e\u0433\u043e\u0432\u0430\u0440\u0438\u0432\u0430\u044f \u0432\u0441\u0435 \u044d\u0442\u0430\u043f\u044b.<em>\u00a0<\/em><\/p>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043a \u043f\u043e\u0441\u0442\u0443 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0443 &#171;\u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0433\u0440\u0443\u043f\u043f\u0435&#187; \u0441\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435\u043c &#171;\u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440&#187;. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0433\u0440\u0443\u043f\u043f\u0430 \u201c\u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u201d \u0438\u043c\u0435\u0435\u0442 Id = 1. <\/p>\n<ol>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0443 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 <strong>policy.<\/strong><\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"sql\">INSERT INTO policy (name, resolver_code) VALUES('\u0421\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0433\u0440\u0443\u043f\u043f\u0435', 'inGroup');<\/code><\/pre>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438 \u043a\u043e\u0434 \u0434\u043b\u044f \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 (\u043c\u0430\u043b\u043e \u043b\u0438 \u0434\u043b\u044f \u0447\u0435\u0433\u043e \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f). \u042d\u0442\u043e\u0439 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u043b\u0441\u044f Id = 1. \u042d\u0442\u0443 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0443 \u043c\u043e\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u043b\u044e\u0431\u044b\u0445 \u0442\u0438\u043f\u043e\u0432 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432. <\/p>\n<ol start=\"2\">\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043a\u043b\u044d\u0439\u043c \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 <strong>claim.<\/strong><\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"sql\">INSERT INTO claim(name, code) VALUES ('\u0413\u0440\u0443\u043f\u043f\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f', 'group');<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u044d\u0442\u043e\u0442 \u043a\u043b\u044d\u0439\u043c \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u0432\u0438\u0434\u043e\u0432 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432.\u00a0\u041a\u043b\u044d\u0439\u043c\u0443 \u043f\u0440\u0438\u0441\u0432\u043e\u0438\u043b\u0441\u044f Id = 1.<\/p>\n<ol start=\"3\">\n<li>\n<p>\u0421\u0432\u044f\u0437\u0430\u0442\u044c \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u043a\u043b\u044d\u0439\u043c \u0441 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u043e\u0439.<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"sql\">INSERT INTO policy_claim (policy_id, claim_id, where_condition)  VALUES(1, 1, '%1$s::int IN (%2$s)');<\/code><\/pre>\n<p>\u0417\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0438\u0437 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 where_condition \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u0432 \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 <strong>WHERE<\/strong> \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435. \u042d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e <a href=\"https:\/\/www.postgresql.org\/docs\/current\/functions-string.html#FUNCTIONS-STRING-FORMAT\" rel=\"noopener noreferrer nofollow\"><u>format<\/u><\/a>.<\/p>\n<p>\u0412 \u043f\u043e\u0437\u0438\u0446\u0438\u044e <strong>%1$s<\/strong> &#8212; \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u044b\u0439 \u043a\u043b\u044d\u0439\u043c \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0430 \u044d\u0442\u043e\u0439 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 (\u0432 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 1, \u0442.\u043a. \u043c\u044b \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c, \u0447\u0442\u043e \u044d\u0442\u043e Id \u0433\u0440\u0443\u043f\u043f\u044b \u201c\u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u201d).<\/p>\n<p>\u0412 \u043f\u043e\u0437\u0438\u0446\u0438\u044e <strong>%2$s<\/strong> &#8212; \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043a\u043b\u044d\u0439\u043c\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u043b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c. \u0422.\u043a. \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u0433\u0440\u0443\u043f\u043f\u0430\u0445, \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 IN.<\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 \u0442\u0440\u0435\u0431\u0443\u0435\u0442, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0431\u044b\u043b \u0432 \u0433\u0440\u0443\u043f\u043f\u0435 \u0441 Id 1, \u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0433\u0440\u0443\u043f\u043f\u0430\u0445 1,2,3. \u0422\u043e\u0433\u0434\u0430 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c <code>where_condition<\/code> \u0431\u0443\u0434\u0435\u0442 <code>1::int in (1,2,3)<\/code>.<\/p>\n<ol start=\"4\">\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u043f\u0440\u0430\u0432\u043a\u0438 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0430.<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"sql\">INSERT INTO post_ability (code, name) VALUES ('edit', '\u041f\u0440\u0430\u0432\u043a\u0430');<\/code><\/pre>\n<p>\u042d\u0442\u0438\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u043e\u0432\u0443\u044e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u043e\u0432.<\/p>\n<ol start=\"5\">\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0430. <\/p>\n<\/li>\n<\/ol>\n<p>\u0411\u0443\u0434\u0435\u043c \u043d\u0430\u0437\u043d\u0430\u0447\u0430\u0442\u044c \u043f\u0440\u0430\u0432\u0430 \u0434\u043b\u044f \u043f\u043e\u0441\u0442\u0430 \u0441 Id 1. \u041f\u0435\u0440\u0432\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0441\u043e\u0437\u0434\u0430\u0435\u0442 \u0433\u0440\u0443\u043f\u043f\u0443 \u043f\u043e\u043b\u0438\u0442\u0438\u043a \u043f\u043e\u0441\u0442\u0430.<\/p>\n<pre><code class=\"sql\">INSERT INTO post_group_policy (type, parent_group, negative)  VALUES ('OR', null, false);<\/code><\/pre>\n<p>\u0417\u0430\u043f\u0440\u043e\u0441 \u0441\u043e\u0437\u0434\u0430\u043b \u0433\u0440\u0443\u043f\u043f\u0443 \u0441 Id 1. <code>parent_group<\/code> \u0443 \u043d\u0430\u0441 null (\u0437\u043d\u0430\u0447\u0438\u0442 \u0433\u0440\u0443\u043f\u043f\u0430 \u043f\u0440\u0430\u0432\u0438\u043b \u043d\u0430\u0445\u043e\u0434\u0438\u0442\u0441\u044f \u043d\u0430 \u0432\u0435\u0440\u0445\u043d\u0435\u043c \u0443\u0440\u043e\u0432\u043d\u0435). <code>parent_group<\/code> \u0441\u0441\u044b\u043b\u0430\u0435\u0442\u0441\u044f \u043d\u0430 id \u044d\u0442\u043e\u0439 \u0436\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b. \u0415\u0441\u043b\u0438 \u043e\u043d \u0437\u0430\u0434\u0430\u043d, \u0442\u043e \u044d\u0442\u0430 \u0433\u0440\u0443\u043f\u043f\u0430 \u043f\u0440\u0430\u0432\u0438\u043b \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0434\u043e\u0447\u0435\u0440\u043d\u0435\u0439 \u0434\u043b\u044f \u0442\u043e\u0439, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0441\u0441\u044b\u043b\u0430\u0435\u043c\u0441\u044f. \u0412\u0441\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0441\u0440\u0430\u0432\u043d\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0431\u043e\u0439 \u043f\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044e \u0438\u0437 \u043a\u043e\u043b\u043e\u043d\u043a\u0438 <code>type<\/code>.<\/p>\n<p><code>type<\/code> \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c <strong>AND<\/strong> \u0438\u043b\u0438 <strong>OR<\/strong>. \u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0441 \u043f\u043e\u044f\u0441\u043d\u0435\u043d\u0438\u044f\u043c\u0438 \u043d\u0438\u0436\u0435.\u00a0<\/p>\n<p><code>negative<\/code> &#8212; \u043e\u0442\u0440\u0438\u0446\u0430\u0442\u044c \u043b\u0438 \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u043f\u0440\u0430\u0432\u0438\u043b.<\/p>\n<p>\u0422\u0430\u0431\u043b\u0438\u0446\u0430 \u0441\u0440\u0430\u0432\u043d\u0435\u043d\u0438\u044f \u0433\u0440\u0443\u043f\u043f \u043f\u0440\u0430\u0432\u0438\u043b. P1, P2, P3 &#8212;\u00a0 \u0433\u0440\u0443\u043f\u043f\u0430 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043f\u0440\u0430\u0432\u0438\u043b. \u0413\u0440\u0443\u043f\u043f\u0430 \u043c\u043e\u0436\u0435\u0442 \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0434\u0440\u0443\u0433\u0438\u0435 \u0433\u0440\u0443\u043f\u043f\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043d\u0435\u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u043d\u043e \u0432\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u043c\u0438. <\/p>\n<div>\n<div class=\"table\">\n<table>\n<tbody>\n<tr>\n<td data-colwidth=\"165\" width=\"165\">\n<p align=\"left\"><strong>negative \/ condition<\/strong><\/p>\n<\/td>\n<td data-colwidth=\"240\" width=\"240\">\n<p align=\"left\">OR<\/p>\n<\/td>\n<td>\n<p align=\"left\">AND<\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"165\" width=\"165\">\n<p align=\"left\">true<\/p>\n<\/td>\n<td data-colwidth=\"240\" width=\"240\">\n<p>\u041b\u044e\u0431\u043e\u0435 \u0438\u0437 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043f\u0440\u0430\u0432\u0438\u043b \u0434\u043e\u043b\u0436\u043d\u043e \u043d\u0435 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u0438\u044e<\/p>\n<p><code>WHERE NOT(P1) OR NOT(P2) OR NOT(P3)<\/code><\/p>\n<\/td>\n<td>\n<p>\u0412\u0441\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043d\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u0438\u044e<\/p>\n<p><code>WHERE NOT(P1) AND NOT(P2) AND NOT(P3)<\/code><\/p>\n<\/td>\n<\/tr>\n<tr>\n<td data-colwidth=\"165\" width=\"165\">\n<p align=\"left\">false<\/p>\n<\/td>\n<td data-colwidth=\"240\" width=\"240\">\n<p>\u041b\u044e\u0431\u043e\u0435 \u0438\u0437 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043f\u0440\u0430\u0432\u0438\u043b \u0434\u043e\u043b\u0436\u043d\u043e \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u0438\u044e<\/p>\n<p><code>WHERE P1 OR P2 OR P3<\/code><\/p>\n<\/td>\n<td>\n<p>\u0412\u0441\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0434\u043e\u043b\u0436\u043d\u044b \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u0438\u044e\u00a0<\/p>\n<p><code>WHERE P1 AND P2 AND P3<\/code><\/p>\n<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<\/div>\n<\/div>\n<p>\u0414\u0430\u043b\u0435\u0435<\/p>\n<pre><code class=\"sql\">INSERT INTO post_policy(policy_id, entity_id, group_id, negative, ability)  VALUES (1,1,1, false, 'edit');<\/code><\/pre>\n<p>\u042d\u0442\u0438\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c \u043c\u044b \u043d\u0430\u0437\u043d\u0430\u0447\u0438\u043b\u0438 \u043f\u043e\u0441\u0442\u0443 \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u043d\u0430 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f. \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0441 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u043e\u0439 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u043e\u0433\u043e \u043a\u043b\u044d\u0439\u043c\u0430.<\/p>\n<ol start=\"6\">\n<li>\n<p>\u041d\u0430\u0437\u043d\u0430\u0447\u0430\u0435\u043c \u043a\u043b\u044d\u0439\u043c.<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"sql\">INSERT INTO post_policy_claim(entity_policy_id, claim_id, value)  VALUES (1, 1, 1);<\/code><\/pre>\n<p>\u0412 \u043a\u043e\u043b\u043e\u043d\u043a\u0443 <code>entity_policy_id<\/code> \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f Id, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u044b\u0439 \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430.\u00a0<\/p>\n<p><code>claim_id<\/code> &#8212; \u043a\u043b\u044d\u0439\u043c, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 claims. \u041a\u043b\u044d\u0439\u043c \u0441 Id 1 &#8212; \u044d\u0442\u043e &#171;\u0433\u0440\u0443\u043f\u043f\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f&#187;.\u00a0<\/p>\n<p><code>value<\/code> &#8212; \u043a\u043b\u044d\u0439\u043c \u0442\u0440\u0435\u0431\u0443\u0435\u0442, \u0447\u0442\u043e\u0431\u044b \u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0431\u044b\u043b\u0430 \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0430 \u0433\u0440\u0443\u043f\u043f\u0430 1.<\/p>\n<p>\u0412\u0441\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0434\u043b\u044f \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043c\u044b \u043d\u0430\u0437\u043d\u0430\u0447\u0438\u043b\u0438. <\/p>\n<ol start=\"7\">\n<li>\n<p>\u041f\u0440\u043e\u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u0443\u0435\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"sql\">SELECT index_entity_policies(\/* _table_prefix *\/ 'post', \/* _entity_id *\/ 1, \/* _ability *\/ 'edit');<\/code><\/pre>\n<p>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432:<\/p>\n<ul>\n<li>\n<p><strong>_table_prefix<\/strong> &#8212; \u043f\u0440\u0435\u0444\u0438\u043a\u0441 \u0434\u043b\u044f \u0442\u0430\u0431\u043b\u0438\u0446, \u0430 \u043f\u0440\u0435\u0444\u0438\u043a\u0441 &#8212; \u044d\u0442\u043e \u0442\u0438\u043f \u0440\u0435\u0441\u0443\u0440\u0441\u0430. \u0412 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043c\u044b \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u0443\u0435\u043c \u043f\u043e\u0441\u0442\u044b.<\/p>\n<\/li>\n<li>\n<p><strong>_entity_id<\/strong> &#8212; id \u0440\u0435\u0441\u0443\u0440\u0441\u0430 (\u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438). \u0412 \u043d\u0430\u0448\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e \u043f\u043e\u0441\u0442 \u0441 id = 1.<\/p>\n<\/li>\n<li>\n<p><strong>_ability<\/strong> &#8212; \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u0443\u0435\u043c. \u0422.\u0435. \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0441\u0442\u0430.\u00a0<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a: \u043f\u0440\u043e\u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u0443\u0439 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u043d\u0430 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0441\u0442\u0430 \u0441 id = 1.<\/p>\n<p>\u0420\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 <strong>WHERE<\/strong> \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0443 <code>post_indexed_rule<\/code><\/p>\n<pre><code class=\"sql\">(('1'::int in ([#group#]))).<\/code><\/pre>\n<p>\u0412 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u043f\u043b\u044d\u0439\u0441\u0445\u043e\u043b\u0434\u0435\u0440\u044b <code>[#placeholder_name#]<\/code>. \u0412 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u044d\u0442\u0438 \u043f\u043b\u0435\u0439\u0441\u0445\u043e\u043b\u0434\u0435\u0440\u044b \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043c\u0435\u043d\u0435\u043d\u044b \u043a\u043b\u044d\u0439\u043c\u0430\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u0435\u0441\u0442\u044c \u043a\u043e\u043b\u043e\u043d\u043a\u0430 <code>used_claims<\/code>. \u0412 \u043d\u0435\u0439 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u043c\u0430\u0441\u0441\u0438\u0432 \u043a\u043b\u044d\u0439\u043c\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 <strong>WHERE<\/strong> \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0438 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043f\u043b\u044d\u0439\u0441\u0445\u043e\u043b\u0434\u0435\u0440\u0430. \u041a\u043e\u043b\u043e\u043d\u043a\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043b\u044f \u0443\u0441\u043a\u043e\u0440\u0435\u043d\u0438\u044f \u0437\u0430\u043c\u0435\u043d\u044b \u043a\u043b\u044d\u0439\u043c\u043e\u0432 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0440\u0430\u0432.<\/p>\n<ol start=\"8\">\n<li>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u0432\u044b\u0431\u043e\u0440\u043a\u0443. <\/p>\n<\/li>\n<\/ol>\n<pre><code class=\"sql\">SELECT p.id, p.* FROM    post p,    LATERAL (SELECT __process_user_claim_values('{\"group\": [1,2]}'::jsonb) as processed_user_claim) l WHERE check_user_rights(    'post',    p.id,    'edit',    l.processed_user_claim );<\/code><\/pre>\n<p>\u041a\u0430\u043a \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u0432 \u0432\u044b\u0431\u043e\u0440\u043a\u0435 \u043e\u0434\u043d\u0430 \u0437\u0430\u043f\u0438\u0441\u044c, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u0435\u0442 \u043d\u0430\u0448\u0435\u043c\u0443 \u0443\u0441\u043b\u043e\u0432\u0438\u044e. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0433\u0440\u0443\u043f\u043f\u0435 1. <\/p>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0435\u0442 \u0432 \u044d\u0442\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u0435.<\/p>\n<pre><code class=\"sql\">SELECT p.id, p.* FROM    post p,    LATERAL (SELECT __process_user_claim_values('{\"group\": [2]}'::jsonb) as processed_user_claim) l WHERE check_user_rights(    'post',    p.id,    'edit',    l.processed_user_claim );<\/code><\/pre>\n<p>\u0410 \u0442\u0443\u0442 \u0443\u0436\u0435 \u043f\u0443\u0441\u0442\u043e. \u041a\u043b\u044d\u0439\u043c\u044b \u043d\u0435 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0442 \u0442\u0440\u0435\u0431\u0443\u0435\u043c\u043e\u043c\u0443 \u043f\u0440\u0430\u0432\u0438\u043b\u0443. <\/p>\n<h4>\u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430<\/h4>\n<p>\u041d\u0435 \u0431\u0443\u0434\u0443 \u043f\u043e\u0432\u0442\u043e\u0440\u044f\u0442\u044c\u0441\u044f, \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u044e\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0432\u0435\u0449\u0430\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0435 \u043e\u043f\u0438\u0441\u0430\u043b \u0432\u044b\u0448\u0435.\u00a0\u00a0<\/p>\n<details class=\"spoiler\">\n<summary>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u0430\u0432\u0438\u043b<\/summary>\n<div class=\"spoiler__content\">\n<ul>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"sql\">INSERT INTO policy (name, resolver_code) VALUES ('\u0412\u043e\u0437\u0440\u0430\u0441\u0442 \u0441\u0442\u0430\u0440\u0448\u0435', 'age_older'),         ('\u0413\u043e\u0440\u043e\u0434 \u043f\u0440\u043e\u0436\u0438\u0432\u0430\u043d\u0438\u044f', 'location'),         ('ID \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f', 'user_id');<\/code><\/pre>\n<ul>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043a\u043b\u044d\u0439\u043c\u044b.<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"sql\">INSERT INTO claim (code, name) VALUES ('age', '\u0412\u043e\u0437\u0440\u0430\u0441\u0442'),         ('location', '\u0413\u043e\u0440\u043e\u0434 \u043f\u0440\u043e\u0436\u0438\u0432\u0430\u043d\u0438\u044f'),         ('user_id', 'ID \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f');   INSERT INTO policy_claim (policy_id, claim_id, where_condition) VALUES (2, 2, '%1$s::int &lt;= %2$s::int'),         (3, 3, '%1$s = %2$s'),         (4, 4, '%1$s = %2$s');<\/code><\/pre>\n<ul>\n<li>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043f\u0440\u0430\u0432\u0438\u043b\u0430.<\/p>\n<\/li>\n<\/ul>\n<pre><code class=\"sql\">-- \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0433\u0440\u0443\u043f\u043f INSERT INTO post_group_policy (type, parent_group) VALUES ('AND', 1); -- \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u0433\u0440\u0443\u043f\u043f\u0430 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u0441 ID: 2 INSERT INTO post_group_policy (type, parent_group) VALUES ('OR', 2); -- \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u0433\u0440\u0443\u043f\u043f\u0430 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f \u0441 ID: 3   -- \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 INSERT INTO post_policy (entity_id, policy_id, group_id, ability) VALUES (1 \/* ID \u043f\u043e\u0441\u0442\u0430 *\/, 1 \/* \u041f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 \"\u0421\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0433\u0440\u0443\u043f\u043f\u0435\" *\/, 2 \/* \u0433\u0440\u0443\u043f\u043f\u0430 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f *\/ , 'edit'); -- \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0441 ID: 2   INSERT INTO post_policy_claim (entity_policy_id, claim_id, value) VALUES (2 \/* \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0435 \u0432 \u043f\u0440\u0435\u0434. \u0437\u0430\u043f\u0440\u043e\u0441\u0435 *\/, 1 \/* \u043a\u043b\u044d\u0439\u043c \"\u0421\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0433\u0440\u0443\u043f\u043f\u0435\" *\/, 2 \/* ID \u0433\u0440\u0443\u043f\u043f\u044b *\/);   INSERT INTO post_policy (entity_id, policy_id, group_id, ability) VALUES (1 \/* ID \u043f\u043e\u0441\u0442\u0430 *\/, 2 \/* \u041f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 \"\u0412\u043e\u0437\u0440\u0430\u0441\u0442 \u0441\u0442\u0430\u0440\u0448\u0435\" *\/, 2 \/* \u0433\u0440\u0443\u043f\u043f\u0430 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f *\/, 'edit'); -- \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0441 ID: 3   INSERT INTO post_policy_claim (entity_policy_id, claim_id, value) VALUES (3 \/* \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0435 \u0432 \u043f\u0440\u0435\u0434. \u0437\u0430\u043f\u0440\u043e\u0441\u0435 *\/, 2 \/* \u043a\u043b\u044d\u0439\u043c \"\u0412\u043e\u0437\u0440\u0430\u0441\u0442\" *\/, 18 \/* \u0412\u043e\u0437\u0440\u0430\u0441\u0442 *\/);   INSERT INTO post_policy (entity_id, policy_id, group_id, ability) VALUES (1 \/* ID \u043f\u043e\u0441\u0442\u0430 *\/, 3 \/* \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 \"\u0413\u043e\u0440\u043e\u0434 \u043f\u0440\u043e\u0436\u0438\u0432\u0430\u043d\u0438\u044f\" *\/, 3 \/* \u0433\u0440\u0443\u043f\u043f\u0430 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f *\/, 'edit'); -- \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0441 ID: 4   INSERT INTO post_policy_claim (entity_policy_id, claim_id, value) VALUES (4 \/* \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0435 \u0432 \u043f\u0440\u0435\u0434. \u0437\u0430\u043f\u0440\u043e\u0441\u0435 *\/, 3 \/* \u043a\u043b\u044d\u0439\u043c \"\u0413\u043e\u0440\u043e\u0434 \u043f\u0440\u043e\u0436\u0438\u0432\u0430\u043d\u0438\u044f\" *\/, '\u041c\u043e\u0441\u043a\u0432\u0430');   INSERT INTO post_policy (entity_id, policy_id, group_id, ability) VALUES (1 \/* ID \u043f\u043e\u0441\u0442\u0430 *\/, 3 \/* \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 \"\u0413\u043e\u0440\u043e\u0434 \u043f\u0440\u043e\u0436\u0438\u0432\u0430\u043d\u0438\u044f\" *\/, 3 \/* \u0433\u0440\u0443\u043f\u043f\u0430 \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f *\/, 'edit'); -- \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0441 ID: 5   INSERT INTO post_policy_claim (entity_policy_id, claim_id, value) VALUES (5 \/* \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0435 \u0432 \u043f\u0440\u0435\u0434. \u0437\u0430\u043f\u0440\u043e\u0441\u0435 *\/, 3 \/* \u043a\u043b\u044d\u0439\u043c \"\u0413\u043e\u0440\u043e\u0434 \u043f\u0440\u043e\u0436\u0438\u0432\u0430\u043d\u0438\u044f\" *\/, '\u0421\u0430\u043d\u043a\u0442-\u041f\u0435\u0442\u0435\u0440\u0431\u0443\u0440\u0433');   INSERT INTO post_policy (entity_id, policy_id, group_id, ability) VALUES (1 \/* ID \u043f\u043e\u0441\u0442\u0430 *\/, 4 \/* \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 \"ID \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\" *\/, 1 \/* \u043a\u043e\u0440\u043d\u0435\u0432\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0430 *\/, 'edit'); -- \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0441 ID: 6   INSERT INTO post_policy_claim (entity_policy_id, claim_id, value) VALUES (6 \/* \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0435 \u0432 \u043f\u0440\u0435\u0434. \u0437\u0430\u043f\u0440\u043e\u0441\u0435 *\/, 4 \/* \u043a\u043b\u044d\u0439\u043c \"ID \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\" *\/, 123);   -- \u043f\u0440\u043e\u0438\u043d\u0434\u0435\u043a\u0441\u0438\u0440\u0443\u0435\u043c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f SELECT index_entity_policies('post', 1, 'edit');<\/code><\/pre>\n<p>\u041f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0442\u0430\u043a\u043e\u0435 WHERE \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435<\/p>\n<pre><code>(   ('1'::int in ([#group#])) ) OR (   ('123' = [#user_id#]) ) OR (   (     ('2'::int in ([#group#]))   ) AND (     ('18'::int &lt; [#age#]::int)   ) AND (     (       ('\u041c\u043e\u0441\u043a\u0432\u0430' = [#location#])     ) OR (       ('\u0421\u0430\u043d\u043a\u0442-\u041f\u0435\u0442\u0435\u0440\u0431\u0443\u0440\u0433' = [#location#])     )   ) ).<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043c \u0432\u044b\u0431\u043e\u0440\u043a\u0443. \u041f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u044f \u0440\u0430\u0437\u043d\u044b\u0435 \u043a\u043b\u0439\u044d\u043c\u044b.<\/p>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 1. \u041a\u043b\u044d\u0439\u043c\u044b \u043d\u0435 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0442 \u0443\u0441\u043b\u043e\u0432\u0438\u044e<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0433\u0440\u0443\u043f\u043f\u0435 2, 17 \u043b\u0435\u0442, \u0436\u0438\u0432\u0435\u0442 \u0432 \u041c\u043e\u0441\u043a\u0432\u0435. ID = 124<\/p>\n<pre><code class=\"sql\">SELECT p.id, p.* FROM   post p,   LATERAL (SELECT __process_user_claim_values('{\"group\": [2], \"age\": 17, \"location\": \"\u041c\u043e\u0441\u043a\u0432\u0430\", \"user_id\": 124}'::jsonb) as processed_user_claim) l WHERE check_user_rights(           'post',           p.id,           'edit',           l.processed_user_claim        );<\/code><\/pre>\n<p>\u041d\u0438\u0447\u0435\u0433\u043e \u043d\u0435\u0442. \u041a\u043b\u044d\u0439\u043c\u044b \u043d\u0435 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0442 \u0443\u0441\u043b\u043e\u0432\u0438\u044e.<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 2. \u041a\u043b\u044d\u0439\u043c\u044b \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0442 \u0443\u0441\u043b\u043e\u0432\u0438\u044e. \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0433\u0440\u0443\u043f\u043f\u0435 2 (\u0420\u0435\u0434\u0430\u043a\u0442\u043e\u0440), \u0435\u043c\u0443 25 \u043b\u0435\u0442 \u0438 \u0436\u0438\u0432\u0435\u0442 \u0432 \u041c\u043e\u0441\u043a\u0432\u0435<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0433\u0440\u0443\u043f\u043f\u0435 2, 25 \u043b\u0435\u0442, \u0436\u0438\u0432\u0435\u0442 \u0432 \u041c\u043e\u0441\u043a\u0432\u0435. ID = 124<\/p>\n<pre><code class=\"sql\">SELECT p.id, p.* FROM   post p,   LATERAL (SELECT __process_user_claim_values('{\"group\": [2], \"age\": 25, \"location\": \"\u041c\u043e\u0441\u043a\u0432\u0430\", \"user_id\": 124}'::jsonb) as processed_user_claim) l WHERE check_user_rights(           'post',           p.id,           'edit',           l.processed_user_claim        );<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 3. \u041a\u043b\u044d\u0439\u043c\u044b \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0442 \u0443\u0441\u043b\u043e\u0432\u0438\u044e. ID \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f = 123<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0433\u0440\u0443\u043f\u043f\u0435 2, 17 \u043b\u0435\u0442, \u0436\u0438\u0432\u0435\u0442 \u0432 \u041c\u043e\u0441\u043a\u0432\u0435. ID = 123<\/p>\n<pre><code class=\"sql\">SELECT p.id, p.* FROM   post p,   LATERAL (SELECT __process_user_claim_values('{\"group\": [2], \"age\": 17, \"location\": \"\u041c\u043e\u0441\u043a\u0432\u0430\", \"user_id\": 123}'::jsonb) as processed_user_claim) l WHERE check_user_rights(           'post',           p.id,           'edit',           l.processed_user_claim        );<\/code><\/pre>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e 17 \u043b\u0435\u0442 \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 2 \u043e\u043d \u0443\u0436\u0435 \u043d\u0435 \u043f\u0440\u043e\u0439\u0434\u0435\u0442, \u0437\u0430\u0442\u043e \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 <strong>ID \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f = 123<\/strong><\/p>\n<\/div>\n<\/details>\n<details class=\"spoiler\">\n<summary>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 4.  \u041a\u043b\u044d\u0439\u043c\u044b \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0442 \u0443\u0441\u043b\u043e\u0432\u0438\u044e. \u0421\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0433\u0440\u0443\u043f\u043f\u0435 1<\/summary>\n<div class=\"spoiler__content\">\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0433\u0440\u0443\u043f\u043f\u0435 1 \u0438 2, 17 \u043b\u0435\u0442, \u0436\u0438\u0432\u0435\u0442 \u0432 \u041c\u043e\u0441\u043a\u0432\u0435. ID = 124<\/p>\n<pre><code class=\"sql\">SELECT p.id, p.* FROM   post p,   LATERAL (SELECT __process_user_claim_values('{\"group\": [1, 2], \"age\": 17, \"location\": \"\u041c\u043e\u0441\u043a\u0432\u0430\", \"user_id\": 124}'::jsonb) as processed_user_claim) l WHERE check_user_rights(           'post',           p.id,           'edit',           l.processed_user_claim        ); <\/code><\/pre>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 2 \u0438 3 \u0443\u0436\u0435 \u043d\u0435 \u043f\u0440\u043e\u0439\u0434\u0443\u0442, \u0437\u0430\u0442\u043e \u044d\u0442\u0438 \u043a\u043b\u044d\u0439\u043c\u044b \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u044f\u044e\u0442 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0435 <strong>\u0421\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u0433\u0440\u0443\u043f\u043f\u0435 = 1<\/strong><\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0437\u043d\u0430\u0447\u0430\u0442\u044c \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u0430\u0432\u0430 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u0432. <\/p>\n<h3>\u0426\u0435\u043b\u043e\u0441\u0442\u043d\u043e\u0441\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0445 <\/h3>\n<p>\u0426\u0435\u043b\u043e\u0441\u0442\u043d\u043e\u0441\u0442\u044c \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043d\u0435\u0448\u043d\u0438\u043c\u0438 \u043a\u043b\u044e\u0447\u0430\u043c\u0438. \u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435, \u0447\u0442\u043e \u043d\u0435 \u043f\u043e\u0434\u0434\u0430\u043b\u043e\u0441\u044c \u043a\u043b\u044e\u0447\u0430\u043c, \u044d\u0442\u043e \u0442\u0430\u0431\u043b\u0438\u0446\u0430 <code>post_indexed_rule<\/code>. \u0414\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0438 \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u0442\u0440\u0438\u0433\u0433\u0435\u0440 \u043d\u0430 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0437\u0430\u043f\u0438\u0441\u0435\u0439 \u0438\u0437 <code>post_policy<\/code>. \u041f\u0440\u0438 \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0443\u0434\u0430\u043b\u044f\u0435\u0442\u0441\u044f \u0437\u0430\u043f\u0438\u0441\u044c. <\/p>\n<h2>\u0420\u0435\u0437\u044e\u043c\u0435<\/h2>\n<p>\u0421\u0438\u0441\u0442\u0435\u043c\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c \u043e\u0447\u0435\u043d\u044c \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439. \u042f \u043f\u0440\u0438\u043e\u0431\u0440\u0435\u043b \u0446\u0435\u043d\u043d\u044b\u0439 \u043e\u043f\u044b\u0442. \u041d\u0430 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u044d\u0442\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u044f \u043f\u043e\u0442\u0440\u0430\u0442\u0438\u043b \u043e\u043a\u043e\u043b\u043e \u043f\u043e\u043b\u0443\u0442\u043e\u0440\u0430 \u043d\u0435\u0434\u0435\u043b\u044c \u0441 \u0443\u0447\u0451\u0442\u043e\u043c \u0442\u043e\u0433\u043e, \u0447\u0442\u043e \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u043f\u0438\u0441\u0430\u043b \u043d\u0430 PL\/PgSql.<\/p>\n<p>\u0427\u0442\u043e \u043c\u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f:<\/p>\n<ul>\n<li>\n<p>\u0413\u0438\u0431\u043a\u043e\u0441\u0442\u044c \u043f\u0440\u0430\u0432\u0438\u043b.<\/p>\n<\/li>\n<li>\n<p>\u0421\u043a\u043e\u0440\u043e\u0441\u0442\u044c. \u041f\u0440\u0430\u0432\u0438\u043b\u0430 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u044e\u0442\u0441\u044f \u0431\u044b\u0441\u0442\u0440\u043e. \u041f\u0440\u043e\u0432\u0435\u0440\u0438\u043b \u043d\u0430 \u0432\u044b\u0431\u043e\u0440\u043a\u0435 \u0432 150000 \u0437\u0430\u043f\u0438\u0441\u0435\u0439. \u041e\u0442\u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0430 \u0437\u0430 600 \u043c\u0441. \u041f\u043e\u043a\u0430 \u0434\u043b\u044f \u043d\u0430\u0448\u0438\u0445 \u0437\u0430\u0434\u0430\u0447 \u044d\u0442\u043e \u0432\u044b\u0448\u0435 \u043a\u0440\u044b\u0448\u0438, \u043d\u043e \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u043f\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u0432\u0430\u0448\u0438 \u043c\u043d\u0435\u043d\u0438\u044f \u043f\u043e \u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0432\u043e\u0434\u0443.\u00a0<\/p>\n<\/li>\n<li>\n<p>\u041c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043b\u044e\u0431\u043e\u0439 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0435, \u044f\u0437\u044b\u043a\u0435. \u0413\u043b\u0430\u0432\u043d\u043e\u0435, \u0447\u0442\u043e\u0431\u044b PostgreSQL \u0441\u0442\u043e\u044f\u043b\u0430.\u00a0<\/p>\n<\/li>\n<\/ul>\n<p>\u0427\u0442\u043e \u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f:<\/p>\n<ul>\n<li>\n<p>\u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0440\u0435\u0441\u0443\u0440\u0441\u0430 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c 5 \u0442\u0430\u0431\u043b\u0438\u0446. \u0415\u0441\u043b\u0438 \u0442\u0438\u043f\u043e\u0432 \u043c\u043d\u043e\u0433\u043e, \u0442\u043e \u0431\u0430\u0437\u0430 \u0440\u0430\u0437\u0440\u0430\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u043e\u0433\u0440\u043e\u043c\u043d\u044b\u043c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c \u0442\u0430\u0431\u043b\u0438\u0446. \u041d\u0435 \u0434\u0443\u043c\u0430\u044e, \u0447\u0442\u043e \u044d\u0442\u043e \u0431\u043e\u043b\u044c\u0448\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430, \u0432\u0435\u0434\u044c \u0438\u0445 \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043d\u0435\u0441\u0442\u0438 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0441\u0445\u0435\u043c\u0443. \u0414\u0443\u043c\u0430\u044e, \u0442\u0430\u043c \u0438\u043c \u0438 \u043c\u0435\u0441\u0442\u043e.\u00a0<\/p>\n<\/li>\n<li>\n<p>\u041a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e, \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043f\u043e\u0441\u0442\u043e\u0432 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0431\u0443\u0434\u0443\u0442 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0435, \u0438 \u0441\u0442\u0440\u0430\u043d\u043d\u043e \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043f\u043e\u0441\u0442\u043e\u0432 \u043e\u0434\u043d\u0438 \u0438 \u0442\u0435 \u0436\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0421\u0431\u043e\u0440 \u043a\u043b\u0435\u0439\u043c\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u0415\u0441\u043b\u0438 \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044e \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 \u043a\u043e\u0434 \u043d\u0430 typescript \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c typeorm \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441 \u0441\u0438\u0441\u0442\u0435\u043c\u043e\u0439.\u00a0<\/p>\n<p>\u041a\u0430\u043a \u0432\u0430\u043c \u043c\u043e\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430? \u0411\u0443\u0434\u0443 \u0440\u0430\u0434 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0439 \u0441\u0432\u044f\u0437\u0438. \u0421\u043f\u0430\u0441\u0438\u0431\u043e \u0437\u0430 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435!<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/714530\/\"> https:\/\/habr.com\/ru\/articles\/714530\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0417\u0434\u0440\u0430\u0432\u0441\u0442\u0432\u0443\u0439\u0442\u0435!\u00a0<\/p>\n<p>\u0421\u0442\u0430\u0442\u044c\u044f \u043e\u00a0\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0441\u0443\u043f\u0435\u0440\u0433\u0438\u0431\u043a\u043e\u0439 \u0441\u0438\u0441\u0442\u0435\u043c\u044b \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0440\u0430\u0432 \u043a\u00a0\u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c \u043d\u0430\u00a0\u043e\u0441\u043d\u043e\u0432\u0435 \u043a\u043b\u044d\u0439\u043c\u043e\u0432 \u0438 \u043f\u043e\u043b\u0438\u0442\u0438\u043a. \u0412\u00a0\u0441\u0432\u043e\u0435 \u0432\u0440\u0435\u043c\u044f\u00a0\u0431\u044b\u043b \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u043b\u0435\u043d \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0435\u0439 <a href=\"https:\/\/learn.microsoft.com\/en-us\/aspnet\/core\/security\/authorization\/claims?view=aspnetcore-6.0\" rel=\"noopener noreferrer nofollow\"><u>Claims\u2011based authorization in ASP.NET Core<\/u><\/a>, \u043d\u043e\u00a0\u043d\u0443\u0436\u043d\u043e\u00a0\u0431\u044b\u043b\u043e \u043d\u0430\u00a0Node.js (\u0430 \u0442\u0435\u043e\u0440\u0435\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043d\u0430\u00a0\u043b\u044e\u0431\u0443\u044e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0443, \u0433\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f PostgreSQL). \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0440\u0435\u0448\u0438\u043b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0440\u0430\u0432 \u043d\u0430\u00a0PL\/pgSQL. \u0415\u0441\u043b\u0438 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u0433\u043e. <\/p>\n<h2>\u041f\u0440\u0435\u0434\u0438\u0441\u043b\u043e\u0432\u0438\u0435<\/h2>\n<p>\u041d\u0430\u00a0\u043e\u0434\u043d\u043e\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439, \u043a\u00a0\u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u043f\u043e\u043a\u0430 \u0441\u0432\u0435\u0442 \u043d\u0435\u00a0\u0443\u0432\u0438\u0434\u0435\u043b \u0438 \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u043d\u0435\u00a0\u0443\u0432\u0438\u0434\u0438\u0442, \u043d\u0443\u0436\u043d\u043e \u0434\u0430\u0432\u0430\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u043c \u043e\u0447\u0435\u043d\u044c \u0433\u0438\u0431\u043a\u0438\u0435 \u043f\u0440\u0430\u0432\u0430. \u041f\u0440\u0438\u043c\u0435\u0440 \u043f\u0440\u0430\u0432\u0438\u043b \u0434\u043b\u044f\u00a0\u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a\u00a0\u0440\u0435\u0441\u0443\u0440\u0441\u0443:<\/p>\n<ul>\n<li>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u043e\u043b\u0436\u0435\u043d\u00a0\u0431\u044b\u0442\u044c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d \u0447\u0435\u0440\u0435\u0437 Facebook, \u0441\u0442\u0430\u0440\u0448\u0435 18\u00a0\u043b\u0435\u0442, \u043d\u043e\u00a0\u043c\u043e\u043b\u043e\u0436\u0435 50. \u0410\u00a0\u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043e\u0441\u0442\u043e\u044f\u0442\u044c \u0432\u00a0\u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0435 \u043b\u044e\u0431\u0438\u0442\u0435\u043b\u0435\u0439 \u043c\u0430\u0448\u0438\u043d \u0424\u0435\u0440\u0440\u0430\u0440\u0438. <\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u043a\u0430\u043a\u043e\u0435\u2011\u0442\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u0435, \u043f\u043e\u0441\u043b\u0435 \u044d\u0442\u043e\u0433\u043e \u043e\u0442\u043a\u0440\u043e\u0435\u0442\u0441\u044f \u0434\u043e\u0441\u0442\u0443\u043f \u043a\u00a0\u0440\u0435\u0441\u0443\u0440\u0441\u0443.<\/p>\n<\/li>\n<li>\n<p>\u0412\u0441\u0435 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e\u043b\u0435\u0442\u043d\u0438\u0435, \u043d\u0435\u00a0\u043f\u0440\u043e\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u0435 \u0432\u00a0\u041c\u043e\u0441\u043a\u0432\u0435.<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u0446\u0435\u043d\u0430\u0440\u0438\u0435\u0432 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0438\u0434\u0443\u043c\u0430\u0442\u044c \u043e\u0447\u0435\u043d\u044c \u043c\u043d\u043e\u0433\u043e \u043f\u043e\u0434\u00a0\u0440\u0430\u0437\u043d\u044b\u0435 \u0431\u0438\u0437\u043d\u0435\u0441\u2011\u0437\u0430\u0434\u0430\u0447\u0438.<\/p>\n<p>\u041d\u0430\u043f\u0438\u0441\u0430\u043d\u043d\u0430\u044f \u043c\u043d\u043e\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u0430, \u043a\u00a0\u0441\u043e\u0436\u0430\u043b\u0435\u043d\u0438\u044e, \u0441\u0432\u0435\u0442 \u043d\u0435\u00a0\u0443\u0432\u0438\u0434\u0435\u043b\u0430 (\u043f\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0435 \u0444\u0438\u043d\u0430\u043d\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430) \u0438 \u043f\u043e\u043a\u0430 \u043d\u0435\u00a0\u0431\u044b\u043b\u0430 \u043f\u0440\u043e\u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0432\u00a0\u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435. <\/p>\n<p>\u041a\u043e\u043b\u043b\u0435\u0433\u0438, \u0441\u00a0\u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043e\u0431\u0441\u0443\u0436\u0434\u0430\u043b \u044d\u0442\u0443 \u0441\u0438\u0441\u0442\u0435\u043c\u0443, \u0438 \u044f\u00a0\u0431\u044b\u043b\u0438 \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u044b\u00a0\u2014 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e \u0432\u043f\u0438\u0441\u044b\u0432\u0430\u043b\u0430\u0441\u044c \u0432\u00a0\u043d\u0430\u0448\u0438 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f. \u0425\u043e\u0447\u0443 \u0443\u0441\u043b\u044b\u0448\u0430\u0442\u044c \u043c\u043d\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0444\u0435\u0441\u0441\u0438\u043e\u043d\u0430\u043b\u043e\u0432 \u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u0431\u0440\u0430\u0442\u043d\u0443\u044e \u0441\u0432\u044f\u0437\u044c. <\/p>\n<h2>\u0422\u0435\u0440\u043c\u0438\u043d\u044b<\/h2>\n<p><em>\u041d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u044f \u043c\u043e\u0433\u0443\u0442\u00a0\u0431\u044b\u0442\u044c \u043d\u0435\u043f\u043e\u043d\u044f\u0442\u043d\u044b, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0439\u0442\u0435\u0441\u044c \u043a\u00a0\u043d\u0438\u043c \u043f\u043e\u00a0\u043c\u0435\u0440\u0435 \u043f\u0440\u043e\u0447\u0442\u0435\u043d\u0438\u044f \u0441\u0442\u0430\u0442\u044c\u0438.<\/em> <\/p>\n<p><strong>\u0422\u0438\u043f \u0440\u0435\u0441\u0443\u0440\u0441\u0430<\/strong>\u00a0\u2014 \u0442\u0438\u043f \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u043c\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u0441\u0442\u044b \u0431\u043b\u043e\u0433\u0430, \u0437\u0430\u043a\u0430\u0437\u044b. <\/p>\n<p><strong>\u0420\u0435\u0441\u0443\u0440\u0441 (\u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c, entity, resource)<\/strong>\u00a0\u2014 \u0442\u043e, \u0441\u00a0\u0447\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442\u00a0\u0431\u044b\u0442\u044c \u043f\u043e\u0441\u0442 \u0432\u00a0\u0431\u043b\u043e\u0433\u0435, \u0437\u0430\u043a\u0430\u0437 \u043d\u0430\u00a0\u0441\u0430\u0439\u0442\u0435. \u0412\u00a0\u043e\u0431\u0449\u0435\u043c, \u044d\u0442\u043e \u0442\u043e, \u043a\u00a0\u0447\u0435\u043c\u0443 \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043f\u0440\u0430\u0432\u0430. \u041d\u0435\u00a0\u043f\u0443\u0442\u0430\u0442\u044c \u0441\u00a0\u0442\u0438\u043f\u043e\u043c \u0440\u0435\u0441\u0443\u0440\u0441\u0430. \u0420\u0435\u0441\u0443\u0440\u0441\u00a0\u2014 \u044d\u0442\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0430\u044f \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u044c (\u043a\u0430\u043a \u043f\u0440\u0430\u0432\u0438\u043b\u043e\u00a0\u2014 \u0442\u043e, \u0447\u0442\u043e\u00a0\u0438\u043c\u0435\u0435\u0442 id), \u0430\u00a0\u0442\u0438\u043f \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u044f\u0435\u0442 \u0432\u0441\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438. <\/p>\n<p><strong>\u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0435\u0441\u0443\u0440\u0441\u0430 (ability)<\/strong>\u00a0\u2014 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u043d\u0430\u0434 \u0440\u0435\u0441\u0443\u0440\u0441\u043e\u043c. \u0423\u00a0\u043e\u0434\u043d\u043e\u0433\u043e \u0440\u0435\u0441\u0443\u0440\u0441\u0430 \u043c\u043e\u0436\u0435\u0442\u00a0\u0431\u044b\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0435\u0439. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0440\u0435\u0441\u0443\u0440\u0441\u00a0\u2014 \u043f\u043e\u0441\u0442 \u0432\u00a0\u0431\u043b\u043e\u0433\u0435. \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u0441\u0443\u0440\u0441\u0430\u00a0\u2014 \u0447\u0442\u0435\u043d\u0438\u0435, \u043f\u0440\u0430\u0432\u043a\u0430, \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435. <\/p>\n<p><strong>\u041a\u043b\u044d\u0439\u043c (\u043a\u043b\u044f\u0439\u043c, claim)<\/strong>\u00a0\u2014 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u0430\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f \u043e\u00a0\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0432\u043e\u0437\u0440\u0430\u0441\u0442, \u0432\u00a0\u043a\u0430\u043a\u0438\u0445 \u0433\u0440\u0443\u043f\u043f\u0430\u0445 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0438\u00a0\u0442.\u00a0\u0434. \u041d\u0430\u00a0\u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u043f\u0440\u0430\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0432\u0441\u0435 \u0441\u0432\u043e\u0438 \u043a\u043b\u044d\u0439\u043c\u044b, \u0438 \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043d\u0430\u00a0\u043e\u0441\u043d\u043e\u0432\u0435 \u044d\u0442\u0438\u0445 \u043a\u043b\u044d\u0439\u043c\u043e\u0432 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0435\u0442, \u0438\u043c\u0435\u0435\u0442\u00a0\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a\u00a0\u0442\u043e\u043c\u0443 \u0438\u043b\u0438\u00a0\u0438\u043d\u043e\u043c\u0443 \u0440\u0435\u0441\u0443\u0440\u0441\u0443. <\/p>\n<p><strong>\u041f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 (\u043f\u0440\u0430\u0432\u0438\u043b\u043e, policy)<\/strong>\u00a0\u2014 \u043d\u0430\u0431\u043e\u0440 \u043a\u043b\u044d\u0439\u043c\u043e\u0432 \u0434\u043b\u044f\u00a0\u043f\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 \u00ab\u0421\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e\u043b\u0435\u0442\u043d\u0438\u0435, \u043d\u0435\u00a0\u043f\u0440\u043e\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u0435 \u0432\u00a0\u041c\u043e\u0441\u043a\u0432\u0435\u00bb \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043a\u043b\u044d\u0439\u043c\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f: \u0432\u043e\u0437\u0440\u0430\u0441\u0442 (\u043e\u043d \u0434\u043e\u043b\u0436\u0435\u043d\u00a0\u0431\u044b\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 18) \u0438 \u0433\u043e\u0440\u043e\u0434 \u043f\u0440\u043e\u0436\u0438\u0432\u0430\u043d\u0438\u044f (\u0434\u043e\u043b\u0436\u0435\u043d\u00a0\u0431\u044b\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u043a\u0440\u043e\u043c\u0435 \u041c\u043e\u0441\u043a\u0432\u044b).<\/p>\n<h2>\u041f\u0440\u0438\u043d\u0446\u0438\u043f \u0440\u0430\u0431\u043e\u0442\u044b<\/h2>\n<p>\u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0444\u043e\u0440\u043c\u0430 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043a \u043f\u043e\u0441\u0442\u0443 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0442\u0430\u043a.<\/p>\n<figure class=\"full-width\"><figcaption>\u0424\u043e\u0440\u043c\u0430 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u0434\u043b\u044f \u0442\u0435\u0445, \u043a\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0441\u0442<\/figcaption><\/figure>\n<p>\u041f\u043e\u044f\u0441\u043d\u044e: \u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043f\u043e\u0441\u0442 \u043c\u043e\u0436\u0435\u0442 \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440 \u0438\u043b\u0438\u00a0\u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u0441\u0442\u0430\u0440\u0448\u0435 18\u00a0\u043b\u0435\u0442, \u043f\u0440\u043e\u0436\u0438\u0432\u0430\u044e\u0449\u0438\u0439 \u0432\u00a0\u041c\u043e\u0441\u043a\u0432\u0435 \u0438\u043b\u0438\u00a0\u0421\u0430\u043d\u043a\u0442\u2011\u041f\u0435\u0442\u0435\u0440\u0431\u0443\u0440\u0433\u0435. \u0418\u043b\u0438\u00a0\u0418\u0432\u0430\u043d\u043e\u0432 \u0418.\u0418. \u0441\u00a0Id 123. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u043c. \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c 4\u00a0\u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438. \u0412\u0432\u0435\u0434\u0435\u043c \u0441\u043e\u043a\u0440\u0430\u0449\u0435\u043d\u0438\u044f:<\/p>\n<ul>\n<li>\n<p>P1\u00a0\u2014 \u0421\u043e\u0441\u0442\u043e\u0438\u0442 \u0432\u00a0\u0433\u0440\u0443\u043f\u043f\u0435<\/p>\n<\/li>\n<li>\n<p>P2\u00a0\u2014 \u0412\u043e\u0437\u0440\u0430\u0441\u0442 \u0441\u0442\u0430\u0440\u0448\u0435<\/p>\n<\/li>\n<li>\n<p>P3\u00a0\u2014 \u0413\u043e\u0440\u043e\u0434 \u043f\u0440\u043e\u0436\u0438\u0432\u0430\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>P4\u00a0\u2014 \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u043e\u0433\u0434\u0430 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0430\u0448\u0435\u0439 \u0444\u043e\u0440\u043c\u044b \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435\u043c:<\/p>\n<pre><code>(   P1 = \u201c\u0410\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u201d   \u0418\u041b\u0418    (     P1 = \u201c\u0420\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u201d      \u0418      P2 >= 18      \u0418      (       P3 = \u201c\u041c\u043e\u0441\u043a\u0432\u0430\u201d        \u0418\u041b\u0418        P3 = \u201c\u0421\u0430\u043d\u043a\u0442-\u041f\u0435\u0442\u0435\u0440\u0431\u0443\u0440\u0433\u201d     )   )    \u0418\u041b\u0418    P4 = 123 )<\/code><\/pre>\n<p>\u041d\u0435\u043c\u043d\u043e\u0433\u043e \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u0435\u0442 SQL \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 WHERE, \u043d\u0435\u00a0\u043f\u0440\u0430\u0432\u0434\u0430\u00a0\u043b\u0438? \u0418 \u043d\u0430\u0448\u0430 \u0437\u0430\u0434\u0430\u0447\u0430 \u0441\u0432\u043e\u0434\u0438\u0442\u0441\u044f \u043a\u00a0\u0442\u043e\u043c\u0443, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u0443 \u0444\u043e\u0440\u043c\u0443 \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u0432\u00a0\u0433\u043e\u0442\u043e\u0432\u043e\u0435 \u0432\u0430\u043b\u0438\u0434\u043d\u043e\u0435 SQL WHERE \u0432\u044b\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438 \u0432\u00a0\u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0438 \u0434\u043e\u0441\u0442\u0443\u043f\u0430 \u043d\u0430\u00a0\u043f\u0440\u0430\u0432\u043a\u0443 \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0435\u0433\u043e.<\/p>\n<h2>\u041d\u0430\u0447\u043d\u0451\u043c \u043f\u043e\u0433\u0440\u0443\u0436\u0435\u043d\u0438\u0435<\/h2>\n<details class=\"spoiler\">\n<summary>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 \u0441 \u043f\u043e\u0441\u0442\u0430\u043c\u0438 \u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u043c \u0435\u0451 \u0434\u0430\u043d\u043d\u044b\u043c\u0438.<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"sql\">CREATE TABLE IF NOT EXISTS post (    id serial primary key,    title text not null );   INSERT INTO post(title) VALUES ('Post 1'), ('Post 2');<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u041f\u0440\u043e\u0432\u0435\u0440\u043a\u0430 \u043f\u0440\u0430\u0432 \u0438\u0434\u0451\u0442 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0432\u044b\u0431\u043e\u0440\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445. \u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043f\u043e\u0441\u0442\u044b, \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u0437\u0430\u043f\u0440\u043e\u0441.<\/p>\n<details class=\"spoiler\">\n<summary>\u0422\u0430\u043a \u043c\u044b \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u0432\u0441\u0435 \u043f\u043e\u0441\u0442\u044b<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"sql\">SELECT p.* FROM post p;<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0412 \u044d\u0442\u043e\u0442 \u043c\u043e\u043c\u0435\u043d\u0442 \u043c\u044b \u0438 \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043f\u0440\u0430\u0432\u0430, \u043d\u043e \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u0442\u044c, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0438 \u0442\u0430\u0431\u043b\u0438\u0446\u044b.<\/p>\n<details class=\"spoiler\">\n<summary>\u041a\u043e\u0434 \u0441\u0438\u0441\u0442\u0435\u043c\u044b<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"pgsql\">CREATE TYPE group_condition AS enum ('OR', 'AND');  CREATE TABLE IF NOT EXISTS policy (     id serial primary key,     name varchar,     resolver_code  varchar(255) not null );  CREATE TABLE IF NOT EXISTS claim (     id serial primary key,     code varchar,     name varchar,     replaceable_by_user boolean default true );  CREATE TABLE IF NOT EXISTS policy_claim (     policy_id integer not null         references policy on delete restrict,     claim_id integer not null references claim on delete restrict,     where_condition text default '%1$s = %2$s'::text not null,     primary key (policy_id, claim_id) );   CREATE TABLE IF NOT EXISTS post_group_policy (     id serial primary key,     type group_condition       not null,     parent_group integer         constraint post_group_policy_post_group_policy_id_fk             references post_group_policy             on delete cascade,     negative boolean default false not null );  CREATE TABLE IF NOT EXISTS post_ability (     code varchar not null primary key,     name varchar not null );  CREATE TABLE IF NOT EXISTS post_policy (     id serial primary key,     entity_id int not null constraint post_policy_post_id_fk             references post on delete cascade,     policy_id integer not null references policy on delete restrict,     group_id integer references post_group_policy on delete cascade,     ability varchar not null references post_ability on delete restrict,     negative  boolean default false not null );  CREATE TABLE IF NOT EXISTS post_policy_claim (     entity_policy_id integer not null         constraint post_policy_claim_post_policy_id_fkey             references post_policy             on delete cascade,     claim_id integer not null         references claim             on delete restrict,     value varchar not null,     primary key (entity_policy_id, claim_id, value) );  CREATE TABLE IF NOT EXISTS post_indexed_rule (     entity_id int not null,     condition text not null,     ability varchar not null references post_ability on delete cascade,     used_claims character varying[] not null,     constraint post_indexed_rule_pk         primary key (ability, entity_id) );  \/**   \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u0438\u0435, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e  *\/ DROP FUNCTION IF EXISTS __process_policy_negative; CREATE FUNCTION __process_policy_negative(_condition text, _is_negative boolean)     RETURNS text AS $$ DECLARE     _format text; BEGIN     IF _is_negative THEN         _format = 'NOT(%s)';     ELSE         _format = '%s';     END IF;     RETURN format(_format, _condition); END $$ LANGUAGE plpgsql;  \/**   \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0443\u0441\u043b\u043e\u0432\u0438\u0439 \u0434\u043b\u044f \u0433\u0440\u0443\u043f\u043f\u044b   \u0424\u0443\u043d\u043a\u0446\u0438\u044f \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u0430\u044f. \u0415\u0439 \u043d\u0430 \u0432\u0445\u043e\u0434 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u043a\u043e\u0440\u043d\u0435\u0432\u0430\u044f \u0433\u0440\u0443\u043f\u043f\u0430, \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432\u043d\u0438\u0437 \u043f\u043e \u0434\u0435\u0440\u0435\u0432\u0443 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b  *\/ DROP FUNCTION IF EXISTS __process_policy_group_condition; CREATE FUNCTION __process_policy_group_condition(_entity_policy_group record, _query text)     RETURNS text AS $$ DECLARE     _group_policies record;     _format text; BEGIN     -- \u0441\u043a\u043b\u0435\u0439\u043c \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u044b \u0441 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u043e\u0439 (\u0438\u043b\u0438 \u043d\u0438 \u0441 \u0447\u0435\u043c \u0435\u0441\u043b\u0438 \u0444-\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0432\u044b\u0439 \u0440\u0430\u0437)     _query = format('%s%s', _query, _entity_policy_group.group_condition);      -- \u043d\u0430\u0439\u0434\u0451\u043c \u0432\u0441\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0435 \u0433\u0440\u0443\u043f\u043f\u044b \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u0433\u0440\u0443\u043f\u043f\u044b     BEGIN FOR _group_policies IN         SELECT *         FROM policy_group_condition p         WHERE p.parent_group = _entity_policy_group.group_id         LOOP              -- \u0435\u0441\u043b\u0438 \u0433\u0440\u0443\u043f\u043f\u0430 \u0441 \u043e\u0442\u0440\u0438\u0446\u0430\u043d\u0438\u0435\u043c, \u0442\u043e \u043d\u0443\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0443\u0441\u043b\u043e\u0432\u0438\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0435\u0439 \u0433\u0440\u0443\u043f\u043f\u044b             IF _entity_policy_group.negative THEN                 _format = '%s %s NOT(';             ELSE                 _format = '%s %s (';             end if;             _query := format(_format, _query, _entity_policy_group.type);             -- \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0434\u043e\u0447\u0435\u0440\u043d\u044e\u044e \u0433\u0440\u0443\u043f\u043f\u0443 \u0440\u0435\u043a\u0443\u0440\u0441\u0438\u0432\u043d\u043e             SELECT __process_policy_group_condition(_group_policies, _query) INTO _query;             _query := _query || ')';         END LOOP;     END;     return _query; END; $$ LANGUAGE plpgsql;  DROP FUNCTION IF EXISTS __process_user_claim_value; CREATE FUNCTION __process_user_claim_value(_user_claim_value_jsonb jsonb)     RETURNS text AS $$ DECLARE     _user_claim_value text;     _user_claim_value_type text;     _user_claim_value_array_item_jsonb jsonb;     _user_claim_value_array_item_type text;     _user_claim_value_array_int_result int[] DEFAULT ARRAY[]::int[];     _user_claim_value_array_text_result text[] DEFAULT ARRAY[]::text[]; BEGIN     -- \u0442\u0435\u043a\u0441\u0442\u043e\u0432\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043a\u043b\u044f\u0439\u043c\u0430     _user_claim_value := _user_claim_value_jsonb ->> 0;      -- \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u043b \u043a\u043b\u044f\u0439\u043c, \u0437\u043d\u0430\u0447\u0438\u0442 \u0431\u0443\u0434\u0435\u043c \u043f\u0440\u043e\u0432\u0435\u0440\u044f\u0442\u044c \u043d\u0430 \u043f\u0443\u0441\u0442\u043e\u0442\u0443 (\u0442.\u0435. \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c \u043f\u0443\u0441\u0442\u043e\u0439 \u043a\u043b\u044f\u0439\u043c)     IF _user_claim_value IS NULL THEN         _user_claim_value = format('%L', '');     ELSE         -- \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0438\u043f \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043e\u0433\u043e \u043a\u043b\u044f\u0439\u043c\u0430         _user_claim_value_type = jsonb_typeof(_user_claim_value_jsonb);         CASE              -- \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043c\u0430\u0441\u0441\u0438\u0432             WHEN _user_claim_value_type = 'array' THEN                  -- \u0435\u0441\u043b\u0438 \u043d\u0435 \u043f\u0443\u0441\u0442\u043e\u0439, \u0442\u043e\u0433\u0434\u0430 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043c jsonb \u043c\u0430\u0441\u0441\u0438\u0432 \u0432 \u0441\u0442\u0440\u043e\u043a\u0443, \u0441\u043e\u0435\u0434\u0438\u043d\u0435\u043d\u043d\u0443\u044e \u0437\u0430\u043f\u044f\u0442\u044b\u043c\u044b ([1,2,3,4] => '1,2,3,4')                 IF jsonb_array_length(_user_claim_value_jsonb) > 0 THEN                     _user_claim_value := format('%L', '');                      -- \u0442\u0443\u0442 \u043d\u0430\u0434\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c jsonb \u043c\u0430\u0441\u0441\u0438\u0432 \u0432 \u0441\u0442\u0440\u043e\u043a\u0443 \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430.                     -- \u0441 \u0438\u043d\u0442\u0430\u043c\u0438 \u0432\u0441\u0435 \u043f\u0440\u043e\u0441\u0442\u043e [1,2,3] => 1,2,3                     -- \u0430 \u0441\u0442\u0440\u0438\u043d\u0433\u0438 \u043d\u0443\u0436\u043d\u043e \u0438\u0437 [\"s1\", \"s2\"] \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0432 's1','s2' (\u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u043a\u0430\u0432\u044b\u0447\u043a\u0438)                     -- \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0445\u043e\u0434\u0438\u043c \u043f\u043e \u043a\u0430\u0436\u0434\u043e\u043c\u0443 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0443 \u043c\u0430\u0441\u0441\u0438\u0432\u0430                     -- \u0442\u0443\u0442 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c 2 \u043c\u0430\u0441\u0441\u0438\u0432\u0430:<\/code><\/pre>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-400746","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/400746","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=400746"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/400746\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=400746"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=400746"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=400746"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}