Ну путь правильный, с универсальной зависимостью - get_owner_id. Хотя я бы сделал чуть шире - get_resource общий как вспомогательную функцию (прочитаете ниже - поймете почему даже это не обязательно).
Будто бы сейчас смешаны два уровня:
получение owner_id
принятие решения о доступе
Именно из-за этого появляются:
дублирование мидлвэра,
хрупкость (post_id vs id),
риск забыть “правильный” checker,
протекание правил в маршруты.
И тп)
Главная мысль, как это исправить - тут вообще НЕ нужен отдельный мидлвэр на каждый ресурс.
Я бы сделал так:
один универсальный dependency/checker,
единый build_env,
передача owner_id в resource.attrs,
ну и собственно настроенная политика в rbacx.
У меня в либе уже есть под это нужные болванки - require_access под фастапи и пример энв билдера. По сути надо его адаптировать, вписав туда чисто свою логику получения Subject, Resource, Action, Context (оно именуется в доках SARC для краткости).
Middleware (вообще зависимость, а не мидлвэр, но про это ниже) должен:
И ТпПермишнЧекер...это можно было бы решить фабрикой конечно, но я немного скорректировал бы принципиально подход.
По сути нужно перейти от:
“middleware знает как проверять ownership”
к:
“middleware только собирает env и дёргает гварда”.
А чтобы собрать энв, мы в каждом роуте передаем в энв-билдер или в класс-зависимость правильный репо и фильтры. И делов)
А репо 99% у вас абстрактный и конкретные репо наследуются от общего родителя. И там в родителе есть метод find_one(self, **filter_by: dict), а в детях он наследуется. Название замените на своё :)
П.С. почему зависимость, а не мидлвэр - тк в фастапи мидлвэр отрабатывает раньше резолва роутинга. А нам понадобятся параметры пути.
П.С.С. в моем бесплатном открытом курсе на степике есть пример работы с паттерном репозитория и тем, как это все делается лаконично и общо.
А теперь спойлер кода, как пример (но может сделаете еще красивее):
# ваша цель, плюс минус
Depends(
require_access(
guard=guard, # где-то у вас уже заинициализирован гвард с политикой
env_builder=EnvBuilder( # напишите сами класс с методом call или можно функцию, смотрите сами, это для примера
repo=PostRepo,
filter_by={
"id": path("post_id"),
},
resource_type="post",
owner_attr="user_id", # по какому атрибуту поймем кто владелец - для юзера просто айди, для других user_id
action="update",
),
)
)
А сам энв билдер напишете сами, потому что я не знаю деталей кода.
Итого, ваша задача написать этот класс, а может даже всего лишь функцию.
Если нужна помощь, то напишите что, постараюсь ответить или накидать на коленке пример класса билдера окружения с теми данными, которые вы мне дали)
Привет! Спасибо за положительный фидбек, рад что либа показалась более дружелюбной 😊
Насколько понял, owner_id живёт в БД, а в URL/запросе его нет — правильно?
Если да, то надо уточнить пару моментов, чтобы дать адекватный ответ.
Вас интересует минимизация обращений к БД, или скорее чистота архитектуры? Тут можно решить двумя способами — либо две проверки (первая: «юзер вообще может патчить этот тип ресурса?», потом вторая уже с owner_id), но это два вызова guard и одно обращение к БД. Или интересует кейс, где ресурс один раз достаётся на запрос — кладётся куда-то в зависимость/мидлвэр — и дальше по коду уже не нужно его тащить повторно?
В итоге у вас финальная цель такая: загрузить ресурс, достать из него owner_id, положить в Resource(attrs={"owner_id": ...}) и выполнить проверку условия subject.id == resource.attrs.owner_id — я правильно понимаю?
Чтобы в политике оно выглядело как-то так:
# Юзер может изменять только свой ресурс
{
"id": "user_update_own",
"effect": "permit",
"actions": ["update"],
"resource": {"type": "user"},
"roles": ["user"],
"condition": {
"==": [
{"attr": "subject.id"},
{"attr": "resource.attrs.owner_id"}
]
}
}
Агась, тоже видел его. В целом встречал и чисто на рбак заточенные либы. Абак в чистом виде сложноватая история как по мне, если делать все по теории. Но умолчу про сравнение, пусть каждый сам решает :)
Про такое применение я не думал, но да, за счет того, что ядро не привязано ни к чему и не требует ничего дополнительного, то можно будет это сделать. Надо будет написать логику аутентификации в вашем приложении (если нужна, но скорее всего нужна), написать политику (какие действия кому доступны), один раз при страте собрать Guard, и потом на кликах/командах создаете среду принятия решения (формируете Subject/Action/Resource/Context) и запрашиваете решение. Так что ответ да
Совершенно не технарский подход к уровню статьи, не по хабровски, как мне кажется. Плюс эти ссылки на ютуб, тг, они и есть цель статьи? Засаморекламиться?
А почему вас это расстраивает? Я, допустим, автор бесплатного курса по программированию, даю код бесплатно, даю примеры проектов бесплатно. И люди потом делают проекты по аналогии, их берут на работу изза наличия проектов, они потом пишут так свои проекты уже на работе. Меня это радует, я помог людям получить деньги. Помогать это круто. Помогаем же мы не за что-то, а просто так) иначе это уже торговля. Вы помогли дизайнерам вк допустим, они заметили крутую идею, внедрили. Почему они не должны за это получить бонус? Они же идею заметили, и быстро внедрили. Идеи, еще разок, не стоят ничего. А вот поиск идей оплачивается. Если не хотите, чтобы ваши идеи брали бесплатно, то зачем ими тогда делиться? Можно было написать статью платную, к примеру, на бусти или еще где, книгу выпустить и тп, и тогда бы вы получили вознаграждение.
Человек придумал DDD-подход, куча людей стали так писать, но никто не указывает в соавторах автора концепции. Я автору идеи не писал спасибо)
Кнопка у вас и у них отличаются, поэтому нельзя говорить о нарушении прав. Знали бы вы сколько идей стырено и каков процент успеха оспариваний, там и не в таком плагиате отказывали, тут я вообще не вижу плагиата дизайна, кроме как плагиат идеи, что не наказуемо. Дуров взял идею фейсбука, рутуб - ютуба (даже название содержит туб), кто-то тырит идею сторис, кто-то тиктоковских коротких видео (шортсов), кто-то идеи бизнесов (увидели как у других - сделали так у себя, икея-хофф, окей-глобус-ашан-волмарт, амазон-озон, вотсап-телеграм). Автомобили - идеи функционала авто, военные - идеи вооружений, и так далее. И никто не говорит спасибо, инфа сотка) ибо идея не есть реализация, это еще сделать надо)
Ну тут автор не прав с юридической стороны. Идеи не подлежат защите авторским правом. Концепция же автора отличается от реализованной в вк (у вк кстати чуточку удобнее, тк не нужно перепрыгивать пробел каждый раз, и цифры ниже пробела не оч смотрится субъективно). Поэтому нет никаких оснований требовать указания автора, с ним связываться и прочее.
Например, я скажу, что дизайн должен быть красивым и удобным. У кого красивое и удобное приложение - отчисляйте мне денежку или укажите меня в качестве источника идеи (условно).
Или еще пример, юзеры в отзывах на приложение пишут "вау круто, разрабы молодцы, добавьте ещё такую-то фичу" (например был только текстовый ввод, а они просят добавить возможность ввода голосового). Я, как разраб, иду и реализую это. Я же не должен указывать на условного Петю, связываться с ним, согласовывать и так далее? Потому что он дал идею, и она принадлежит теперь всем, а вот уже моя реализация конкретная - она защищается.
Пруф: Авторские права не распространяются на идеи, концепции, принципы, методы, процессы, системы, способы, решения технических, организационных или иных задач, открытия, факты, языки программирования, геологическую информацию о недрах (п. 5 ст. 1259 ГК РФ).
Поэтому на месте автора я был бы доволен тем, что кто-то улучшил бесплатно их приложуху, и теперь нам всем, в тч автору, будет жить удобнее.
Интересно, зачем оставлять знания о себе на случай исчезновения вида? Пусть и другие развивающиеся (в будущем разумные) виды повторяют нашу судьбу. Пусть находят скелеты человеков и гадают что там было 100500 миллиардов лет назад, что все люди вымерли. Нас-то уже не будет. Почему должно быть не все равно? Мне кажется тут и древние структуры мозга (отвечают за выживание и эмоции), и рациональный неокортикс солидарны - не надо никому ничего оставлять, это наше конкурентное преимущество, надо просто не вымирать, звучит вроде не так сложно.
Ну путь правильный, с универсальной зависимостью - get_owner_id. Хотя я бы сделал чуть шире - get_resource общий как вспомогательную функцию (прочитаете ниже - поймете почему даже это не обязательно).
Будто бы сейчас смешаны два уровня:
получение owner_id
принятие решения о доступе
Именно из-за этого появляются:
дублирование мидлвэра,
хрупкость (
post_idvsid),риск забыть “правильный” checker,
протекание правил в маршруты.
И тп)
Главная мысль, как это исправить - тут вообще НЕ нужен отдельный мидлвэр на каждый ресурс.
Я бы сделал так:
один универсальный dependency/checker,
единый
build_env,передача owner_id в
resource.attrs,ну и собственно настроенная политика в rbacx.
У меня в либе уже есть под это нужные болванки - require_access под фастапи и пример энв билдера. По сути надо его адаптировать, вписав туда чисто свою логику получения Subject, Resource, Action, Context (оно именуется в доках SARC для краткости).
Middleware (вообще зависимость, а не мидлвэр, но про это ниже) должен:
собрать SARC, сам или заюзав энв-билдер;
вызвать guard.
Архитектурная проблема начинается тут:
PostPermissionChecker UserPermissionChecker CommentPermissionChecker
И ТпПермишнЧекер...это можно было бы решить фабрикой конечно, но я немного скорректировал бы принципиально подход.
По сути нужно перейти от:
к:
А чтобы собрать энв, мы в каждом роуте передаем в энв-билдер или в класс-зависимость правильный репо и фильтры. И делов)
А репо 99% у вас абстрактный и конкретные репо наследуются от общего родителя. И там в родителе есть метод find_one(self, **filter_by: dict), а в детях он наследуется. Название замените на своё :)
П.С. почему зависимость, а не мидлвэр - тк в фастапи мидлвэр отрабатывает раньше резолва роутинга. А нам понадобятся параметры пути.
П.С.С. в моем бесплатном открытом курсе на степике есть пример работы с паттерном репозитория и тем, как это все делается лаконично и общо.
А теперь спойлер кода, как пример (но может сделаете еще красивее):
А сам энв билдер напишете сами, потому что я не знаю деталей кода.
Итого, ваша задача написать этот класс, а может даже всего лишь функцию.
Если нужна помощь, то напишите что, постараюсь ответить или накидать на коленке пример класса билдера окружения с теми данными, которые вы мне дали)
Привет! Спасибо за положительный фидбек, рад что либа показалась более дружелюбной 😊
Насколько понял,
owner_idживёт в БД, а в URL/запросе его нет — правильно?Если да, то надо уточнить пару моментов, чтобы дать адекватный ответ.
Вас интересует минимизация обращений к БД, или скорее чистота архитектуры? Тут можно решить двумя способами — либо две проверки (первая: «юзер вообще может патчить этот тип ресурса?», потом вторая уже с owner_id), но это два вызова guard и одно обращение к БД. Или интересует кейс, где ресурс один раз достаётся на запрос — кладётся куда-то в зависимость/мидлвэр — и дальше по коду уже не нужно его тащить повторно?
В итоге у вас финальная цель такая: загрузить ресурс, достать из него
owner_id, положить вResource(attrs={"owner_id": ...})и выполнить проверку условияsubject.id== resource.attrs.owner_id— я правильно понимаю?Чтобы в политике оно выглядело как-то так:
Правильно?
Я так понимаю, это бревно в огород Америки. Ждем-с краха, наблюдаем
П.С. Не понимать, почему дети в школе пишут рукой, ну как-то не солидно для статьи на Хабре.
Агась, тоже видел его. В целом встречал и чисто на рбак заточенные либы. Абак в чистом виде сложноватая история как по мне, если делать все по теории. Но умолчу про сравнение, пусть каждый сам решает :)
Про такое применение я не думал, но да, за счет того, что ядро не привязано ни к чему и не требует ничего дополнительного, то можно будет это сделать. Надо будет написать логику аутентификации в вашем приложении (если нужна, но скорее всего нужна), написать политику (какие действия кому доступны), один раз при страте собрать Guard, и потом на кликах/командах создаете среду принятия решения (формируете Subject/Action/Resource/Context) и запрашиваете решение. Так что ответ да
Интересное исследование. Но продолжу юзать дипсик и квен, а не более вражеский и зацензуренный openai.
Совершенно не технарский подход к уровню статьи, не по хабровски, как мне кажется. Плюс эти ссылки на ютуб, тг, они и есть цель статьи? Засаморекламиться?
А почему вас это расстраивает? Я, допустим, автор бесплатного курса по программированию, даю код бесплатно, даю примеры проектов бесплатно. И люди потом делают проекты по аналогии, их берут на работу изза наличия проектов, они потом пишут так свои проекты уже на работе. Меня это радует, я помог людям получить деньги. Помогать это круто. Помогаем же мы не за что-то, а просто так) иначе это уже торговля. Вы помогли дизайнерам вк допустим, они заметили крутую идею, внедрили. Почему они не должны за это получить бонус? Они же идею заметили, и быстро внедрили. Идеи, еще разок, не стоят ничего. А вот поиск идей оплачивается. Если не хотите, чтобы ваши идеи брали бесплатно, то зачем ими тогда делиться? Можно было написать статью платную, к примеру, на бусти или еще где, книгу выпустить и тп, и тогда бы вы получили вознаграждение.
Человек придумал DDD-подход, куча людей стали так писать, но никто не указывает в соавторах автора концепции. Я автору идеи не писал спасибо)
Кнопка у вас и у них отличаются, поэтому нельзя говорить о нарушении прав. Знали бы вы сколько идей стырено и каков процент успеха оспариваний, там и не в таком плагиате отказывали, тут я вообще не вижу плагиата дизайна, кроме как плагиат идеи, что не наказуемо. Дуров взял идею фейсбука, рутуб - ютуба (даже название содержит туб), кто-то тырит идею сторис, кто-то тиктоковских коротких видео (шортсов), кто-то идеи бизнесов (увидели как у других - сделали так у себя, икея-хофф, окей-глобус-ашан-волмарт, амазон-озон, вотсап-телеграм). Автомобили - идеи функционала авто, военные - идеи вооружений, и так далее. И никто не говорит спасибо, инфа сотка) ибо идея не есть реализация, это еще сделать надо)
Ну тут автор не прав с юридической стороны. Идеи не подлежат защите авторским правом. Концепция же автора отличается от реализованной в вк (у вк кстати чуточку удобнее, тк не нужно перепрыгивать пробел каждый раз, и цифры ниже пробела не оч смотрится субъективно). Поэтому нет никаких оснований требовать указания автора, с ним связываться и прочее.
Например, я скажу, что дизайн должен быть красивым и удобным. У кого красивое и удобное приложение - отчисляйте мне денежку или укажите меня в качестве источника идеи (условно).
Или еще пример, юзеры в отзывах на приложение пишут "вау круто, разрабы молодцы, добавьте ещё такую-то фичу" (например был только текстовый ввод, а они просят добавить возможность ввода голосового). Я, как разраб, иду и реализую это. Я же не должен указывать на условного Петю, связываться с ним, согласовывать и так далее? Потому что он дал идею, и она принадлежит теперь всем, а вот уже моя реализация конкретная - она защищается.
Пруф: Авторские права не распространяются на идеи, концепции, принципы, методы, процессы, системы, способы, решения технических, организационных или иных задач, открытия, факты, языки программирования, геологическую информацию о недрах (п. 5 ст. 1259 ГК РФ).
Поэтому на месте автора я был бы доволен тем, что кто-то улучшил бесплатно их приложуху, и теперь нам всем, в тч автору, будет жить удобнее.
Как это будет выглядеть в продакшене? Допустим когда у меня 5 воркеров? Люди будут коннектиться в разные чаты?
Хехе завтра буду собеситься на вакансию под такую задачу... Спасибо за инфу)
Интересно, зачем оставлять знания о себе на случай исчезновения вида? Пусть и другие развивающиеся (в будущем разумные) виды повторяют нашу судьбу. Пусть находят скелеты человеков и гадают что там было 100500 миллиардов лет назад, что все люди вымерли. Нас-то уже не будет. Почему должно быть не все равно? Мне кажется тут и древние структуры мозга (отвечают за выживание и эмоции), и рациональный неокортикс солидарны - не надо никому ничего оставлять, это наше конкурентное преимущество, надо просто не вымирать, звучит вроде не так сложно.