Re[8]: Помогите правильно спроектировать микросервисное приложение
От: Miroff Россия  
Дата: 16.04.25 11:44
Оценка:
Здравствуйте, busk, Вы писали:

B>а я думал что фронт тоже распиливают на отдельные сервисы, но подумал, что для SPA не получится тогда сделать без третьего агрегирующего фронт сервиса.


Бывает такое, микрофронтенд называется. Идея, в целом, довольно грамотная с точки зрения не превращать фронт в неподдерживаемое месиво. А еще бывает backend for frontend (BFF)
Re[8]: Помогите правильно спроектировать микросервисное приложение
От: Qulac Россия  
Дата: 16.04.25 11:55
Оценка:
Здравствуйте, busk, Вы писали:

B>Здравствуйте, Qulac, Вы писали:




B>>>>а вот у меня получается 2 бэкенд сервиса, а на фронте тоже 2 реакт приложения, или на фронте одним можно разрулить?


B>>>вопрос еще связан с тем, что у меня SPA а если будет 2 фронт приложения то тут же получается будет обновление страницы после страницы логина на основное приложение


Q>>А зачем так делать? Фронт можно один оставить, просто сервис на беке будет сам вызывать сервис авторизации когда это надо.


B>а я думал что фронт тоже распиливают на отдельные сервисы, но подумал, что для SPA не получится тогда сделать без третьего агрегирующего фронт сервиса.

B>Тогда одно на фронте, понял

Вариант с распиливанием фронта возможен, особенно для систем с устанавливаемыми плагинами.
Программа – это мысли спрессованные в код
Re[6]: Каких программ вам не хватает?
От: Константин Л.  
Дата: 16.04.25 14:31
Оценка: +1
Здравствуйте, Miroff, Вы писали:

M>Здравствуйте, m2user, Вы писали:


M>>Как минимум нужно предоставить документацию на API и получить feedback


M>Прелесть RMM L3 в том, что он самодокументируемый и на 99% фидбека можно сразу отвечать: "это не RESTful, мы этого делать не будем"



RMM L3 не нужен, потому что:

1. не заменяет документацию, зато дикий оверхед
2. добавляет лишней связности — теперь я должен грузить ссылки на апи (и, судя по твоим дальнейшим постам, еще и в зависимости от пермиссий) для всех связных сущностей
3. почти всегда бесполезен, тк говорит что можно, а не что нужно — то есть протекание недоделанной (бизнес-логика на базе только доступных ссылок? ну-ну) бизнес логики туда, куда не надо
Re[12]: Каких программ вам не хватает?
От: Константин Л.  
Дата: 16.04.25 14:34
Оценка:
Здравствуйте, Miroff, Вы писали:

[]

M>Опять же, можешь раскрыть тему? Пейджинг это простая штука если перестать думать о нем, как о RPC и начать думать как об отдельном ресурсе. Ты СОЗДАЕШЬ отдельный объект "поисковый запрос" и в ответ получаешь список страниц с результатами этого запроса. И, внезапно, у тебя уже нет проблем со стабильностью, сортировки, изменению состава страниц, кэшированию и т.п. Результат фиксируется в момент создания запроса и далее до нового поиска уже не меняется.


на практике никто так не делает потому что это просто не работает. думать можно как угодно красиво, конечно

[]
Re[13]: Каких программ вам не хватает?
От: Константин Л.  
Дата: 16.04.25 14:40
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Например, можно воткнуть reverse proxy перед сервером приложения, и тогда он сможет снять значительную часть нагрузки с сервера.

S>Как только мы начинаем менять представление объекта в зависимости от пользователя, о кэшировании можно забыть.

чет мне кажется никто ничего уже давно не кеширует

ну и

Как только мы начинаем менять представление объекта в зависимости от пользователя


тоже повсеместная практика
Re[15]: Каких программ вам не хватает?
От: Константин Л.  
Дата: 16.04.25 14:48
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Вариантов три:

S>1. При отдаче текста постановления смотрим в токен пользователя, и либо заменяем все имена плейсхолдерами, либо вставляем как надо.
S>2. Делаем два ресурса: "анонимизированное постановление", "полноценное постановление". Анонимный доступ ко второму получает 401, аутентифицированный доступ без прав на данное дело получает 403.
S>3. Делаем два ресурса: постановление, в "тексте" которого есть ссылки на фигурантов, каждый из которых — самостоятельный ресурс. Постановления отдаём всем желающим, детали фигурантов — только авторизованным пользователям. Остальные получают 403.
S>Как по мне, так первый вариант, очевидно, самый-самый плохой. Он плохо масштабируется, и крайне плохо проверяется на корректность.


Он плохо масштабируется, и крайне плохо проверяется на корректность.


вообще не очевидно. в любом случае тебе надо сделать фильтр данных, как ты его сделал и на каком этапе не так важно. введением магического второго ресурса проблема фильтра никуда не уйдет. и про комбинаторный взрыв тебе правильно сказали. Номер 1 самый рабочий и адекватный — по токену получаем список пермиссий и по ним фильтруем резалтсет.

И вообще зря ты критикуешь "клиентскую секьюрити", просто она должна дублироваться серверной. Нормально возвращать на клиента список допустимых действий для оптимизации, но HATEOAS для этого не нужен и на сервере тоже должны быть чеки.
Re[10]: Каких программ вам не хватает?
От: Константин Л.  
Дата: 16.04.25 14:52
Оценка: +1
Здравствуйте, Miroff, Вы писали:

M>Это же ресурс, делаешь GET, смотришь, меняешь, делаешь PUT.


PUT без параметров?

S>>2. Evolvability улучшается крайне незначительно. У нас нет никакого способа научить клиентов всегда ходить только по указанным нами ссылкам. Если мы решили перенести endpoint для рефандов в другое место, то недостаточно просто отдавать новую ссылку в links.


M>Правильно делать GET перед PUT, потому что ссылки могут измениться, и вообще конкурентные обновления. Если разработчики не умеют пользоваться REST API это их проблема. Можно тупо менять ссылки при каждом запросе, чтобы даже желания сохранять их куда либо не возникало.


а если ссылки поменялись между GET и PUT? "и вообще конкурентные обновления" — какие ужасы ты пишешь

S>>3. Накладные расходы значительно увеличиваются.


M>Я тебя умоляю, мы видео в 4К по сети гоняем и GUID вместо id используем. Несколько ссылок погоды не сделают.


я не гоняю, а ты можешь гонять свои ссылки 720p тогда раз кто-то 4k гоняет
Re[16]: Каких программ вам не хватает?
От: Sinclair Россия https://github.com/evilguest/
Дата: 16.04.25 16:37
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>вообще не очевидно. в любом случае тебе надо сделать фильтр данных, как ты его сделал и на каком этапе не так важно.

Не, не в любом. Только в том, если кому-то нужны дополнительные подробности.
КЛ>введением магического второго ресурса проблема фильтра никуда не уйдет.
Я не очень понимаю, что такое "проблема фильтра". Магический второй ресурс означает, что есть два ресурса: один даже join в базе не делает с таблицами "смежных сущностей", другой делает джойн, но проверяет ровно одну пермиссию в токене, а не отдаёт 2^10 вариантов в зависимости от хидера.

КЛ>и про комбинаторный взрыв тебе правильно сказали. Номер 1 самый рабочий и адекватный — по токену получаем список пермиссий и по ним фильтруем резалтсет.

Ну я бы так дизайнить не стал. Соображения я привёл. У каждого они свои — вон кто-то хочет просто написать универсальный код на питоне, который через рефлексию всю базу наружу отдаёт, а пермиссии берёт из токена.
Можно и так делать, если результат не шибко важен.

КЛ>И вообще зря ты критикуешь "клиентскую секьюрити", просто она должна дублироваться серверной. Нормально возвращать на клиента список допустимых действий для оптимизации, но HATEOAS для этого не нужен и на сервере тоже должны быть чеки.

Да, тут я согласен.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[17]: Каких программ вам не хватает?
От: Константин Л.  
Дата: 16.04.25 16:58
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Константин Л., Вы писали:


КЛ>>вообще не очевидно. в любом случае тебе надо сделать фильтр данных, как ты его сделал и на каком этапе не так важно.

S>Не, не в любом. Только в том, если кому-то нужны дополнительные подробности.

ну когда не нужны тогда и фильтр не нужен, верно?

КЛ>>введением магического второго ресурса проблема фильтра никуда не уйдет.


S>Я не очень понимаю, что такое "проблема фильтра". Магический второй ресурс означает, что есть два ресурса: один даже join в базе не делает с таблицами "смежных сущностей", другой делает джойн, но проверяет ровно одну пермиссию в токене, а не отдаёт 2^10 вариантов в зависимости от хидера.


фильтр — это способ либо собрать либо очистить ресурс. принципиальной разницы между виртуальными ресурсами (как в твоем случае) и одним ресурсом нет вообще. все равно где-то придется ответить на вопрос какие данные возвращаем

КЛ>>и про комбинаторный взрыв тебе правильно сказали. Номер 1 самый рабочий и адекватный — по токену получаем список пермиссий и по ним фильтруем резалтсет.

S>Ну я бы так дизайнить не стал. Соображения я привёл. У каждого они свои — вон кто-то хочет просто написать универсальный код на питоне, который через рефлексию всю базу наружу отдаёт, а пермиссии берёт из токена.

это детали, можно и в базе пермиссии проверять

S>Можно и так делать, если результат не шибко важен.


не понимаю в чем принципиальная разница с одним ресурсом и несколькими (кроме как комбинаторики)

КЛ>>И вообще зря ты критикуешь "клиентскую секьюрити", просто она должна дублироваться серверной. Нормально возвращать на клиента список допустимых действий для оптимизации, но HATEOAS для этого не нужен и на сервере тоже должны быть чеки.

S>Да, тут я согласен.

кул
Re[18]: Каких программ вам не хватает?
От: Sinclair Россия https://github.com/evilguest/
Дата: 17.04.25 06:15
Оценка:
Здравствуйте, Константин Л., Вы писали:
КЛ>ну когда не нужны тогда и фильтр не нужен, верно?
Вот эту фразу не понял.

КЛ>фильтр — это способ либо собрать либо очистить ресурс. принципиальной разницы между виртуальными ресурсами (как в твоем случае) и одним ресурсом нет вообще. все равно где-то придется ответить на вопрос какие данные возвращаем

Принципиальная разница тут только в надёжности. Меньше ветвлений в коде — меньше способов в них напороть.
В остальном — да, другие решения (типа расположение фильтра "перед запросом" или "после результата") сильнее влияют на параметры итогового сервиса.

S>>Ну я бы так дизайнить не стал. Соображения я привёл. У каждого они свои — вон кто-то хочет просто написать универсальный код на питоне, который через рефлексию всю базу наружу отдаёт, а пермиссии берёт из токена.

КЛ>это детали, можно и в базе пермиссии проверять
Ну... в целом-то да, можно и в базе. Но у меня возникают вопросы прежде всего к надёжности такой модели. Слишком много движущихся частей => слишком много возможных путей исполнения и вариантов, когда всё может пойти "не так". При этом большинство из возможных конфигураций как настроек, так и устройства кода, являются заведомо некорректными.
По большому счёту, это является одной из причин, по которой сейчас не принято выставлять в интернет напрямую базу данных.
Казалось бы — ачего, давайте пермиссий навесим, и алга. Что-то есть в СУБД из коробки, что-то можно докрутить при помощи хранимок и представлений. Если всё делать аккуратно, получим могучую REST-подобную систему.
Однакож, нет, не делают так. Обожглись, и клиент-сервер остался только внутри "безопасных периметров", а в открытый интернет торчит исключительно трёхзвенка.
Собственно, все эти идеи "давайте отдавать базу через рефлексию" и есть способ завернуть SQL в HTTP, и ничего полезного архитектуре не добавляют.
Более продуктивный способ, имхо, всё же делить логику по уровням так, чтобы на каждом уровне по максимуму использовать его преимущества.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[19]: Каких программ вам не хватает?
От: Константин Л.  
Дата: 17.04.25 09:05
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Здравствуйте, Константин Л., Вы писали:

КЛ>>ну когда не нужны тогда и фильтр не нужен, верно?
S>Вот эту фразу не понял.

вот:

КЛ>вообще не очевидно. в любом случае тебе надо сделать фильтр данных, как ты его сделал и на каком этапе не так важно.

S>Не, не в любом. Только в том, если кому-то нужны дополнительные подробности.

не нужны подробности -> не нужен фильтр. нужны -> нужен фильтр или доп-ресурс.

КЛ>>фильтр — это способ либо собрать либо очистить ресурс. принципиальной разницы между виртуальными ресурсами (как в твоем случае) и одним ресурсом нет вообще. все равно где-то придется ответить на вопрос какие данные возвращаем

S>Принципиальная разница тут только в надёжности. Меньше ветвлений в коде — меньше способов в них напороть.

ну смотри, у тебя два юзкейса — полный ресурс или урезанный. даже если ты будешь разруливать их через отдельные ресурсы где-то будет ветвление на создание (фильтрацию, сборку, как угодно) одного и другого.

S>В остальном — да, другие решения (типа расположение фильтра "перед запросом" или "после результата") сильнее влияют на параметры итогового сервиса.


S>>>Ну я бы так дизайнить не стал. Соображения я привёл. У каждого они свои — вон кто-то хочет просто написать универсальный код на питоне, который через рефлексию всю базу наружу отдаёт, а пермиссии берёт из токена.

КЛ>>это детали, можно и в базе пермиссии проверять
S>Ну... в целом-то да, можно и в базе. Но у меня возникают вопросы прежде всего к надёжности такой модели. Слишком много движущихся частей => слишком много возможных путей исполнения и вариантов, когда всё может пойти "не так". При этом большинство из возможных конфигураций как настроек, так и устройства кода, являются заведомо некорректными.

я до сих пор не понимаю как добавление ресурсов принципиально что-то меняет в твоей модели и что это у меня за такая модель?

S>По большому счёту, это является одной из причин, по которой сейчас не принято выставлять в интернет напрямую базу данных.


а кто такое предлагает? я такое не предлагаю. и, кстати, популярный graphql именно это и делает, насколько я понимаю и я это осуждаю.

S>Казалось бы — ачего, давайте пермиссий навесим, и алга. Что-то есть в СУБД из коробки, что-то можно докрутить при помощи хранимок и представлений. Если всё делать аккуратно, получим могучую REST-подобную систему.


не понимаю к чему ты. мы лишь про то, что по токену на беке получаем пермиссии и в зависимости он них отдаем респонс.

S>Однакож, нет, не делают так. Обожглись, и клиент-сервер остался только внутри "безопасных периметров", а в открытый интернет торчит исключительно трёхзвенка.

S>Собственно, все эти идеи "давайте отдавать базу через рефлексию" и есть способ завернуть SQL в HTTP, и ничего полезного архитектуре не добавляют.
S>Более продуктивный способ, имхо, всё же делить логику по уровням так, чтобы на каждом уровне по максимуму использовать его преимущества.

graphql! и да, это бред, но это не то, что я предлагаю
Re[25]: Каких программ вам не хватает?
От: Константин Л.  
Дата: 17.04.25 11:42
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

[]

S>Я вам рассказываю практический замкнутый пример: нет никаких "привилегий на втрибуты". Есть два вида ресурсов. Доступ к каждому их них либо есть, либо нету.


что значит есть? физически есть? то есть реально в базе 2 таблицы?

S>·>Каким образом закрыт-то? Заклятие наложено что-ли? Субресурс возвращает джсон, как ты ресурсом гарантируешь отстутствие там какого-нибудь contragent.homeAddress?

S>Очень просто: contragent.homeAddress там нет вообще, вне зависимости от привилегий.

кто его оттуда вырезал?

S>·>Нет, это просто несколько байт в определённом месте хедера запроса, а обрабатывает всё это дело тот же самый условно питонячий код, что и для других ресурсов.

S>Если у вас так, то всё плохо. Попробуйте перепроектировать так, чтобы в одном коде не смешивалась обработка "своих" и "чужих" инвойсов. Человечество изобрело массу способов факторизации кода.

ты тут смешиваешь свои и чужие инвойсы, чтобы навести туману. давай мы будем всегда про свои инвойсы, но в одном случае для отчетности, в другом для превью — как хранить будешь и разделять?

S>Впрочем, можно спроектировать и так, как вы предлагаете — вынести БД в отдельный сервис, из которого торчит очень широкий контракт.


он так не предлагает

S>И, естественно, у него очень грубый набор привилегий. Ваша модель "давайте мы будем ограничивать доступ путём передачи пользовательского токена вдоль всей иерархии вызовов" работает примерно никогда.


примерно всегда так и работает

S>Все практики безопасности как раз так и устроены, что у принципала X нету привилегий к "сырому" ресурсу A, но есть привилегии на доступ к "производному" ресурсу B. Сервис, выполняющий построение ресурса B, выполняется под принципалом Y, который имеет полные привилегии для A, но учитывает привилегии X при отдаче ему производного ресурса B.


ну то есть делает именно то, что мы тут тебе и говорим, только ты все это каким-то магическим образом разрулишь всего лишь через роутинг?

S>Типичный пример применения концепции в рамках SQL99: пользователю нельзя видеть часть строк в таблице X. Мы не можем навесить привилегию на каждую строку.


почему это мы не можем?

Зато можем сделать следующее:
S>1. Отбираем у пользователя привилегии на таблицу X

зачем? только столбцы выбросить? такое работает только когда у тебя 2-3 роли в аппке и мало пермиссий

S>2. Строим на основе X представление Y, в котором добавлен предикат безопасности (типа select * from X where TotalAmount < 100000)

S>3. Выдаём пользователю привилегии на Y и указываем, что Y исполняется под привилегиями админа, а не пользователя.

это все не надо. у каждой строки есть поле, по которому мы понимаем какая пермиссия нужна, чтобы его читать.
селект учитывает пермиссии юзера, получение по токену, чтобы выбрать только нужные строки, поля. работает с любым сочетанием и количеством ролей и пермиссий.
а ведь еще ничего не сказано про ABAC, который часто нужен и который в твою схему вообще не вписывается

S>Аналогично мы могли бы поступить и с ограничениями на колонки таблицы. Квадратно-гнездовая система, где чётко видна вся схема Y и легко проверить, что туда попадает, а что нет, как методом статического анализа, так и методом выполнения динамических тестов. Вы предлагаете заменить её на некий невнятный код "хранимой процедуры", которая возвращает всякий раз разный набор строк и колонок в зависимости от рантайм-содержимого параметров.


действительно, результат поискового запроса зависит от критериев поиска (пермиссии один из них внезапно), вот это дичь, да?

S>И всё это под тем предлогом, что "какая нам разница, где передаётся информация о привилегиях — всё равно это текст SQL запроса".

S>Нет, увы. Факторизация кода позволяет нам изолировать разные сценарии.

для петпроджектов да, но мы о нормальных системах говорим

S>Фрагмент в урле существует не сам по себе. Структура урла применятся для роутинга — выбора кода, который будет обслуживать поступивший запрос. Правила роутинга — простая, понятная логика, которую легко отладить и гарантировать отсутствие неожиданностей вроде "в ответ на запрос чужих инвойсов внезапно вызвался код по подготовке своих инвойсов".


а если ты внутри роутинга не туда нароутил?

S>В вашем же подходе в коде какая-то каша, отдаётся примерно произвольный набор атрибутов с соответствии с хитро устроенными предикатами, смешивающими проверку нескольких разных claims. Доказать, что код выдаёт корректное сочетание атрибутов для произвольного сочетания claims — та ещё задача.


ну это звучит как "доказать, что код выдает правильную поисковую выдачу та еще задача".
Re[27]: Каких программ вам не хватает?
От: Константин Л.  
Дата: 17.04.25 11:46
Оценка:
Здравствуйте, Sinclair, Вы писали:

[]

S>·>Ну я просто написал когда этот твой способ не работает. Но я, конечно, верю, что в некоторых случаях и твой способ работает. Но это не значит, что он универсальный всемогутер.

S>Скорее наоборот: бывают задачи с низкой ответственностью, где можно игнорировать best practices и писать с надеждой на авось.

сколько систем ты так сделал и сколько у них юзеров и ролей?
Re[26]: Каких программ вам не хватает?
От: Sinclair Россия https://github.com/evilguest/
Дата: 17.04.25 12:37
Оценка: +1
Здравствуйте, Константин Л., Вы писали:

S>>Я вам рассказываю практический замкнутый пример: нет никаких "привилегий на втрибуты". Есть два вида ресурсов. Доступ к каждому их них либо есть, либо нету.

КЛ>что значит есть? физически есть? то есть реально в базе 2 таблицы?
Совершенно необязательно. В базе это может быть одна таблица, 2 таблицы, или 17 таблиц. Структура базы тут очень косвенно задействована.

КЛ>кто его оттуда вырезал?

Я не понимаю термина "вырезал". Никто никого ниоткуда не "вырезал".
Просто у нас есть такой тип данных, InboundInvoice, который отличается от OutboundInvoice.
На стороне сервиса они могут находиться в каких-то взаимоотношениях друг с другом (типа — оба отнаследованы от общей базы, или собираются путём алгебры типов из запчастей, вроде CommonInvoice & InboundInvoice / CommonInvoice & OutboundInvoice).
Снаружи мы всё равно видим только схему Json, и она разная для разных ендпоинтов.

КЛ>ты тут смешиваешь свои и чужие инвойсы, чтобы навести туману.

Это не я смешиваю
КЛ>давай мы будем всегда про свои инвойсы, но в одном случае для отчетности, в другом для превью — как хранить будешь и разделять?
Я не буду их разделять — зачем? Мне непонятен сценарий. Если дадите больше деталей — можно спроектировать.
КЛ>он так не предлагает
Цитирую:

А на самом деле json генерится питонячим кодом, который рефлексией вываливает всё что есть

КЛ>примерно всегда так и работает
Поверю вам на слово.

КЛ>ну то есть делает именно то, что мы тут тебе и говорим

Нет, делает ровно противоположное. Более того, прямо тут в топике приводились утверждения про то, что "на самом деле" микросервисы не только пользовательских принципалов не используют, а вообще бегают все под одним и тем же аккаунтом.

КЛ>почему это мы не можем?

Потому что row level security есть далеко не в любой СУБД. И даже в тех, где такое есть, далеко не всегда это будет наиболее эффективным решением.
КЛ>зачем? только столбцы выбросить?
И строки тоже.

КЛ>такое работает только когда у тебя 2-3 роли в аппке и мало пермиссий

Такое работает примерно всегда. Я ещё ни разу не видел настолько безумной архитектуры, чтобы SQL исполнялся в контексте безопасности конечного пользователя, пришедшего из интернета.

КЛ>это все не надо. у каждой строки есть поле, по которому мы понимаем какая пермиссия нужна, чтобы его читать.

"Его" — это кого? Поле?

КЛ>селект учитывает пермиссии юзера, получение по токену, чтобы выбрать только нужные строки, поля. работает с любым сочетанием и количеством ролей и пермиссий.

Можете привести пример такого select? Я вроде понимаю, о чём вы пишете, но уверенности нет.

КЛ>а ведь еще ничего не сказано про ABAC, который часто нужен и который в твою схему вообще не вписывается

Да, для ABAC нужна другая схема. Но он очень часто является оверкиллом.

КЛ>действительно, результат поискового запроса зависит от критериев поиска (пермиссии один из них внезапно), вот это дичь, да?

Отож. Не, я всё это умею делать. Но в эксплуатации такие "гибкие схемы" гораздо чаще приносят вред, чем пользу.
Вот, в прошлом году в одной крупной компании был случай, когда из-за цепочки нечаянных совпадений и недопониманий друг друга, одному из сотрудников выдали чутка больше "пермиссий", чем надо было по его роли.
В итоге сотрудник из лучших побуждений наворотил делов. Хорошо, что речь шла о добронамеренном сотруднике, поэтому последствия были не очень тяжкими (ну, там, зарплату задержали на пару дней части сотрудников). А в иной ситуации это бы вышло таким боком, что никакая экономия на архитектуре не окупилась бы.

КЛ>для петпроджектов да, но мы о нормальных системах говорим

Ну, критерии "нормальных систем" у всех разные.

КЛ>а если ты внутри роутинга не туда нароутил?

То это будет обнаружено первым же smoke test.

КЛ>ну это звучит как "доказать, что код выдает правильную поисковую выдачу та еще задача".

Конечно. Это вполне актуальная проблема; и основное её решение ровно то же, что я предлагаю — факторизация. Потому что иначе вы точно так же утонете в объёме тестирования.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[20]: Каких программ вам не хватает?
От: Sinclair Россия https://github.com/evilguest/
Дата: 17.04.25 12:47
Оценка:
Здравствуйте, Константин Л., Вы писали:


КЛ>>вообще не очевидно. в любом случае тебе надо сделать фильтр данных, как ты его сделал и на каком этапе не так важно.

S>>Не, не в любом. Только в том, если кому-то нужны дополнительные подробности.
КЛ>не нужны подробности -> не нужен фильтр. нужны -> нужен фильтр или доп-ресурс.
Вы фильтром называете проекцию или что-то ещё?

КЛ>ну смотри, у тебя два юзкейса — полный ресурс или урезанный.

Строго говоря, у нас может быть и больше юзкейзов.

КЛ>даже если ты будешь разруливать их через отдельные ресурсы где-то будет ветвление на создание (фильтрацию, сборку, как угодно) одного и другого.

Если я это делаю явным образом, то у меня это ветвление покрывается системой типов, и его статически контролирует компилятор ещё до того, как запустятся тесты.

КЛ>я до сих пор не понимаю как добавление ресурсов принципиально что-то меняет в твоей модели и что это у меня за такая модель?

У вас модель, в которой заранее неизвестно, какая структура ресурса будет получена при обращении по тому или иному ендпоинту. Она типа "динамически" определяется где-то внутри кода непрозрачными правилами.

КЛ>а кто такое предлагает? я такое не предлагаю. и, кстати, популярный graphql именно это и делает, насколько я понимаю и я это осуждаю.

Нет, graphQL делает не это.

КЛ>не понимаю к чему ты. мы лишь про то, что по токену на беке получаем пермиссии и в зависимости он них отдаем респонс.

Как мы это будем тестировать?

КЛ>graphql! и да, это бред, но это не то, что я предлагаю

В graphQL принято несколько неудачных решений, но не потому, что он "выставляет наружу БД".
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[27]: Каких программ вам не хватает?
От: Константин Л.  
Дата: 17.04.25 15:07
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

S>Снаружи мы всё равно видим только схему Json, и она разная для разных ендпоинтов.


и как и откуда в эту схему кладутся данные?

я, кажется, начинаю понимать — по dto на роль, ORM, отдельные endpoints и вуаля? но тут есть 2 проблемы — работает только на простых security моделях, и никак не решает проблем, когда внутри этого dto есть многокардинальные поля (массивы etc, которые тоже надо фильтровать по роли).


ну есть еще конечно другой вариант — когда очень много денег и очень много ответственности и надо прям все по-красоте. но это не индустриальный стандарт

КЛ>>ты тут смешиваешь свои и чужие инвойсы, чтобы навести туману.

S>Это не я смешиваю


КЛ>>давай мы будем всегда про свои инвойсы, но в одном случае для отчетности, в другом для превью — как хранить будешь и разделять?

S>Я не буду их разделять — зачем? Мне непонятен сценарий. Если дадите больше деталей — можно спроектировать.
КЛ>>он так не предлагает

мне кажется он специально преувеличил, но не суть

S>Цитирую:

S>

S>А на самом деле json генерится питонячим кодом, который рефлексией вываливает всё что есть



КЛ>>ну то есть делает именно то, что мы тут тебе и говорим

S>Нет, делает ровно противоположное. Более того, прямо тут в топике приводились утверждения про то, что "на самом деле" микросервисы не только пользовательских принципалов не используют, а вообще бегают все под одним и тем же аккаунтом.

я вообще про микросервисы ничего не писал, я утверждаю, что ты делаешь ту же самую работу по проверке пермиссий для резалтсета, только криво, а мы прямо)

КЛ>>почему это мы не можем?

S>Потому что row level security есть далеко не в любой СУБД. И даже в тех, где такое есть, далеко не всегда это будет наиболее эффективным решением.

вот и начинается, часть пермиссий через средства субд, часть сбоку, чтд

КЛ>>зачем? только столбцы выбросить?

S>И строки тоже.

так у вас нет row-level permission же

КЛ>>такое работает только когда у тебя 2-3 роли в аппке и мало пермиссий


S>Такое работает примерно всегда. Я ещё ни разу не видел настолько безумной архитектуры, чтобы SQL исполнялся в контексте безопасности конечного пользователя, пришедшего из интернета.


" SQL исполнялся в контексте безопасности конечного пользователя " — вот это вообще что такое? что тут ты понимаешь под контекстом? а когда ты делаешь эти свои лишние телодвижения из 3х пунктов, ты разве не мапишь "контексте безопасности конечного пользователя, пришедшего из интернета" на конкретную роль в базе?

sql исполняется от админа всегда и точка. резалсеты зависят от пермиссий юзера из интернета.

КЛ>>это все не надо. у каждой строки есть поле, по которому мы понимаем какая пермиссия нужна, чтобы его читать.

S>"Его" — это кого? Поле?

строку, опечатка конечно

КЛ>>селект учитывает пермиссии юзера, получение по токену, чтобы выбрать только нужные строки, поля. работает с любым сочетанием и количеством ролей и пермиссий.

S>Можете привести пример такого select? Я вроде понимаю, о чём вы пишете, но уверенности нет.

select * from rows r
join rows_perms p on r.id = p.r_id
where p.perm = 'row_read' and p.user_id = :userid

или

select * from rows r where r.group_id in :user_groups

userid/user_groups резолвятся по токену из запроса

да как угодно, при том, что работает тот самый швейцарский сыр, про который тут упоминали —
возможность вообще что-то читать из таблицы rows проверяется до отправки sql в базу. все запросы от админа. в базе никакой встроенной security не используется, потому что, опять же, нет нормально row-level security встроенного. С полями — либо динамически генеришь строку sql, либо jooq (предпочтительнее)

select fields from field_perm where field_perm.perm = 'row_read_for_report'

и дальше ипользуешь результат для генерации верхних селектов с конкретными полями.
либо уже просто в коде фильтруешь


КЛ>>а ведь еще ничего не сказано про ABAC, который часто нужен и который в твою схему вообще не вписывается

S>Да, для ABAC нужна другая схема. Но он очень часто является оверкиллом.

ABAC, это когда ты принимаешь решение не только от роли, но и контекста — времени запроса и пт. То есть довольно часто.

КЛ>>действительно, результат поискового запроса зависит от критериев поиска (пермиссии один из них внезапно), вот это дичь, да?

S>Отож. Не, я всё это умею делать. Но в эксплуатации такие "гибкие схемы" гораздо чаще приносят вред, чем пользу.
S>Вот, в прошлом году в одной крупной компании был случай, когда из-за цепочки нечаянных совпадений и недопониманий друг друга, одному из сотрудников выдали чутка больше "пермиссий", чем надо было по его роли.
S>В итоге сотрудник из лучших побуждений наворотил делов. Хорошо, что речь шла о добронамеренном сотруднике, поэтому последствия были не очень тяжкими (ну, там, зарплату задержали на пару дней части сотрудников). А в иной ситуации это бы вышло таким боком, что никакая экономия на архитектуре не окупилась бы.

да, но ничего с точки зрения трейдоффа разработка/результат не придумали. открываешь google aim и видишь и роли, и отдельные пермиссии.

КЛ>>для петпроджектов да, но мы о нормальных системах говорим

S>Ну, критерии "нормальных систем" у всех разные.

много ролей, много разных пермиссий

КЛ>>а если ты внутри роутинга не туда нароутил?

S>То это будет обнаружено первым же smoke test.

ага, то есть любой смоук тест у нас в лобой системе обнаруживает любую проблему?

КЛ>>ну это звучит как "доказать, что код выдает правильную поисковую выдачу та еще задача".

S>Конечно. Это вполне актуальная проблема; и основное её решение ровно то же, что я предлагаю — факторизация. Потому что иначе вы точно так же утонете в объёме тестирования.

и никто ее не делает, потому что это невозможно поддерживать
Отредактировано 17.04.2025 15:24 Кt Л. . Предыдущая версия .
Re[21]: Каких программ вам не хватает?
От: Константин Л.  
Дата: 17.04.25 15:17
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Вы фильтром называете проекцию или что-то ещё?


да

КЛ>>ну смотри, у тебя два юзкейса — полный ресурс или урезанный.

S>Строго говоря, у нас может быть и больше юзкейзов.

вам и говорят, когда много, тогда у вас проблемы.

КЛ>>даже если ты будешь разруливать их через отдельные ресурсы где-то будет ветвление на создание (фильтрацию, сборку, как угодно) одного и другого.

S>Если я это делаю явным образом, то у меня это ветвление покрывается системой типов, и его статически контролирует компилятор ещё до того, как запустятся тесты.

система типов это только про поля, а что со строками?
это не гибко

КЛ>>я до сих пор не понимаю как добавление ресурсов принципиально что-то меняет в твоей модели и что это у меня за такая модель?

S>У вас модель, в которой заранее неизвестно, какая структура ресурса будет получена при обращении по тому или иному ендпоинту. Она типа "динамически" определяется где-то внутри кода непрозрачными правилами.

sql уже стал непрозрачными правилами. "у вас данные отдаются динамически по непрозрачным правилам". дело не сколько в структуре, а вообще в данных.
еше раз — пермисии это такой же фильтр данных как и остальные. разрулить их системой типов хорошо не получится.

пример — у юзера есть 5 основных воркфлоу, в один из которых входит создание внутренних отчетов из таблицы rows, в другой создание анонимизтированных отчетов для регулятора.
внутренний отчет показывает конфиденциальные данные, для регулятора отрезает их.
опиши security-модель для такого? сколько ролей? как все работает?


КЛ>>а кто такое предлагает? я такое не предлагаю. и, кстати, популярный graphql именно это и делает, насколько я понимаю и я это осуждаю.

S>Нет, graphQL делает не это.

а что он делает?

КЛ>>не понимаю к чему ты. мы лишь про то, что по токену на беке получаем пермиссии и в зависимости он них отдаем респонс.

S>Как мы это будем тестировать?

а как вы тестируете все остальное, что отдает данные на основании пользовательского контекста?

КЛ>>graphql! и да, это бред, но это не то, что я предлагаю

S>В graphQL принято несколько неудачных решений, но не потому, что он "выставляет наружу БД".

да, но выставляет наружу псевдо-бд
Отредактировано 17.04.2025 15:38 Кt Л. . Предыдущая версия .
Re[28]: Каких программ вам не хватает?
От: Sinclair Россия https://github.com/evilguest/
Дата: 17.04.25 17:10
Оценка:
Здравствуйте, Константин Л., Вы писали:

КЛ>и как и откуда в эту схему кладутся данные?

Маппером, который сгенерирован по типу данных. Кладутся из DTO, который поднят из базы.

КЛ>я, кажется, начинаю понимать — по dto на роль, ORM, отдельные endpoints и вуаля?

Конечно.
КЛ>но тут есть 2 проблемы — работает только на простых security моделях,
Модели безопасности и должны быть простыми. Сложные модели снижают надёжность. Парадокс в том, что когда стоимость ошибки в секурити низкая, на неё можно просто забить. А когда высокая, то сложные модели слишком рискованны.
КЛ>и никак не решает проблем, когда внутри этого dto есть многокардинальные поля (массивы etc, которые тоже надо фильтровать по роли).
Их не надо фильтровать по роли. Это плохая идея — слишком легко напороть.
КЛ>ну есть еще конечно другой вариант — когда очень много денег и очень много ответственности и надо прям все по-красоте. но это не индустриальный стандарт
Да, я и говорю про серьёзные приложения, где ответственности много. А если её мало, то примерно любая секурити подойдёт.

КЛ>я вообще про микросервисы ничего не писал, я утверждаю, что ты делаешь ту же самую работу по проверке пермиссий для резалтсета, только криво, а мы прямо)

Ну, с моей точки зрения криво делаете вы.
Получившимся API совершенно невозможно пользоваться, кроме как напрямую выкладывать его в ГУЙ. Любой сервис, который пытается стать клиентом этого API, вынужден жить в постоянной готовности получить не данные, а фигу.
И как-то осмысленно объяснять пользователю, что "у тебя, брат, нет пермиссии на атрибут 'НДС', сходи к админу, попроси, чтоб выдал". Ну, либо (что скорее всего) внезапно падать с internal error 500, потому что внутрях там NullReferenceException. Разобраться, что там стало первопричиной, потребует привлечения дорогостоящего саппорта. Так что в пет проджектах, где пользователей меньше, чем ролей и пермиссий вместе взятых — велком, можно и так. А для чего-то серьёзного, где нужна предсказуемость работы — увольте.

КЛ>вот и начинается, часть пермиссий через средства субд, часть сбоку, чтд

Где это я предложил часть пермиссий через средства СУБД? Я вам привёл стандартный способ разделения доступа "построчно" без использования row-level security.

КЛ>так у вас нет row-level permission же

Я вроде дал пошаговое описание того, как решается проблема отсутствия row-level permissions в RDBMS. Причём не как рекомендацию использовать эту схему, а как пример реализации "послойной" безопасности.
Точно такие же рецепты применяются и в сервисах.
То есть токен пользователя у нас роляет только во фронт-сервисе. Когда пользователь U запрашивает API сервиса A, а сервис A в рамках этого запроса стучится в сервис B, то никакие токены U в этот B не передаются. У U вообще нет никакого доступа до сервиса B. В этот сервис обращается A, под собственным токеном.
Поэтому идея "а давайте у нас инвойс будет содержать данные контрагента если у вызывающего пользователя есть пермиссия на этого контрагента" сразу идёт навзничь.
У вызываюшего пользователя нет никаких пермиссий на контрагента — господь упаси. А вот право видеть реквизиты получателя платежа по выставленному счёту у него есть в силу федерального закона.


КЛ>" SQL исполнялся в контексте безопасности конечного пользователя " — вот это вообще что такое?

Это когда мы заводим для пользователя №44487 виндовый аккаунт, даём этому аккаунту права на SQL базу с табличками forums, topics, replies, и marks, при логине на сайт создаём виндовую сессию, и все запросы в SQL Server выполняем через новое соединение под правами этого виндового аккаунта.

КЛ>что тут ты понимаешь под контекстом? а когда ты делаешь эти свои лишние телодвижения из 3х пунктов, ты разве не мапишь "контексте безопасности конечного пользователя, пришедшего из интернета" на конкретную роль в базе?

Это был иллюстративный пример про послойную безопасность. Там как раз фишка в том и есть, что реальный select исполняется под правами админа, а не конкретного конечного пользователя.

КЛ>sql исполняется от админа всегда и точка. резалсеты зависят от пермиссий юзера из интернета.

Воот, уже лучше.

КЛ>>>это все не надо. у каждой строки есть поле, по которому мы понимаем какая пермиссия нужна, чтобы его читать.

S>>"Его" — это кого? Поле?

КЛ>строку, опечатка конечно


КЛ>>>селект учитывает пермиссии юзера, получение по токену, чтобы выбрать только нужные строки, поля. работает с любым сочетанием и количеством ролей и пермиссий.

S>>Можете привести пример такого select? Я вроде понимаю, о чём вы пишете, но уверенности нет.

КЛ>select * from rows r

КЛ>join rows_perms p on r.id = p.r_id
КЛ> where p.perm = 'row_read' and p.user_id = :userid
Прекрасно. Вы себе представляете производительность такого решения? Когда у нас табличка на пару миллионов строк, и есть тысяча пользователей с частично пересекающимися правами на эти строки?
КЛ>или
КЛ>select * from rows r where r.group_id in :user_groups
А как же "любое сочетание ролей и пермиссий"? Вы прибиваете доступ к r только к одной роли; невозможно выдать доступ к конкретной строке нескольким разным группам.
Собственно, вы изобретаете нормальную изоляцию на основе бизнес-правил, только задом наперёд.
Потому что в прямом направлении мы не стесняемся назвать этот абстрактный group_id своим именем.
Например,
select * from topics t where t.owner_id = :user_id

Или
select * from invoices i where i.sender_organization = :current_org_id


Это — совершенно нормальная история, которая работает и применяется.
КЛ>userid/user_groups резолвятся по токену из запроса
Ну, вы же только что собирались сделать универсальную схему, которая работает с любым количеством пермиссий и ролей. А получается вполне себе узкоспециализированная штука.

КЛ>да как угодно, при том, что работает тот самый швейцарский сыр, про который тут упоминали —

КЛ>возможность вообще что-то читать из таблицы rows проверяется до отправки sql в базу. все запросы от админа. в базе никакой встроенной security не используется, потому что, опять же, нет нормально row-level security встроенного. С полями — либо динамически генеришь строку sql, либо jooq (предпочтительнее)
КЛ>select fields from field_perm where field_perm.perm = 'row_read_for_report'
КЛ>и дальше ипользуешь результат для генерации верхних селектов с конкретными полями.
КЛ>либо уже просто в коде фильтруешь
Непонятно. Как я смогу получить разный набор полей для разных строк одной и той же таблицы? Речь-то шла именно об этом — что состав результата определяется не объектом, а правами пользователя на него.

КЛ>ABAC, это когда ты принимаешь решение не только от роли, но и контекста — времени запроса и пт. То есть довольно часто.

Я в курсе.

КЛ>да, но ничего с точки зрения трейдоффа разработка/результат не придумали. открываешь google aim и видишь и роли, и отдельные пермиссии.

Надо внимательно смотреть на то, как именно используются эти роли и пермиссии. Потому что я так-то не против ролей и пермиссий; я против смешивания мух и котлет.
И если я запрашиваю, допустим, GET /resources/{resourceId}?$include(usageHistory), а у меня нет пермиссий смотреть usageHistory по этому ресурсу, я получаю не пустую историю и не JSON с "вырезанным" атрибутом, а честный 403. А если у меня пермиссия есть, то я могу полагаться на то, что в результате будет атрибут usageHistory с описанной в схеме структурой.
В итоге сторонний сервис, который потребляет мой API, может выдавать осмысленные ошибки, которые можно быстро исправить. А не просто падать оттого, что его авторы тестировались с аккаунтом, у которого были все нужные пермиссии, и понятия не имели, что у кого-то пермиссия на usageHistory на какой-то отдельный объект может быть отобрана.

Обратите внимание — это то самое "разведение ресурсов по разным URL", над которым вы так потешались.


КЛ>много ролей, много разных пермиссий

Количество ни на что не влияет.

КЛ>ага, то есть любой смоук тест у нас в лобой системе обнаруживает любую проблему?

Нет, только детерминистические вещи.

КЛ>и никто ее не делает, потому что это невозможно поддерживать

Надо просто уметь это готовить.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[22]: Каких программ вам не хватает?
От: Sinclair Россия https://github.com/evilguest/
Дата: 17.04.25 17:23
Оценка:
Здравствуйте, Константин Л., Вы писали:
S>>Вы фильтром называете проекцию или что-то ещё?
КЛ>да
Хорошо.

КЛ>вам и говорят, когда много, тогда у вас проблемы.

У нас нет никаких проблем.

КЛ>система типов это только про поля, а что со строками?

КЛ>это не гибко
Излишняя гибкость, в целом, только вредит. Но фильтрация, в отличие от проекции, не нарушает никаких инвариантов.
Поэтому в ней запросто можно учитывать предикаты, в том числе и построенные на токене пользователя.
По-прежнему у нас границы безопасности совпадают с границами ресурса.
Смотрите: вот я делаю какой-нибудь
GET /invoices/

И мне приезжает какой-то список инвойсов. Как правило — без деталей, только ссылки.
И если я пойду по этим ссылкам, типа GET /invoices/32423423423/, то скорее всего буду получать 200 Ok.
А вот те из инвойсов, на которые у меня прав нет, дадут при прямом обращении 403 либо 404, и в общем списке фигурировать не будут.

КЛ>еше раз — пермисии это такой же фильтр данных как и остальные. разрулить их системой типов хорошо не получится.

Прекрасно получится.

КЛ>пример — у юзера есть 5 основных воркфлоу, в один из которых входит создание внутренних отчетов из таблицы rows, в другой создание анонимизтированных отчетов для регулятора.

КЛ>внутренний отчет показывает конфиденциальные данные, для регулятора отрезает их.
КЛ>опиши security-модель для такого? сколько ролей? как все работает?
Пока что роль ровно одна. Всё работает так, как написано. Причин изобретать разные роли тут нет.
Для проектирования безопасности у нас недостаточно вводных.

КЛ>а что он делает?

Он делает возможность формировать запросы к иерархии объектов, без всех плюшек REST.

КЛ>а как вы тестируете все остальное, что отдает данные на основании пользовательского контекста?



КЛ>да, но выставляет наружу псевдо-бд

Есть много разных способов выставить наружу псевдо-бд, и не все из них одинаково полезны.
Надо понимать, какая проблема решается.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[29]: Каких программ вам не хватает?
От: Константин Л.  
Дата: 17.04.25 18:02
Оценка:
Здравствуйте, Sinclair, Вы писали:

КЛ>>и как и откуда в эту схему кладутся данные?

S>Маппером, который сгенерирован по типу данных. Кладутся из DTO, который поднят из базы.

то есть пермисии определяются декларативно просто наличием полей в типе? ну-ну

КЛ>>я, кажется, начинаю понимать — по dto на роль, ORM, отдельные endpoints и вуаля?

S>Конечно.

вау

КЛ>>но тут есть 2 проблемы — работает только на простых security моделях,

S>Модели безопасности и должны быть простыми. Сложные модели снижают надёжность. Парадокс в том, что когда стоимость ошибки в секурити низкая, на неё можно просто забить. А когда высокая, то сложные модели слишком рискованны.

"хорошо это когда хорошо".

КЛ>>и никак не решает проблем, когда внутри этого dto есть многокардинальные поля (массивы etc, которые тоже надо фильтровать по роли).

S>Их не надо фильтровать по роли. Это плохая идея — слишком легко напороть.

тогда _какую_ проблему решают твои виртуальные ресурсы? никакую

КЛ>>ну есть еще конечно другой вариант — когда очень много денег и очень много ответственности и надо прям все по-красоте. но это не индустриальный стандарт

S>Да, я и говорю про серьёзные приложения, где ответственности много. А если её мало, то примерно любая секурити подойдёт.

серьезные приложения это софт для АЭС, там можно. В 99 процентах других случаев твоя модель не работает, такая моя оценка

КЛ>>я вообще про микросервисы ничего не писал, я утверждаю, что ты делаешь ту же самую работу по проверке пермиссий для резалтсета, только криво, а мы прямо)

S>Ну, с моей точки зрения криво делаете вы.
S>Получившимся API совершенно невозможно пользоваться, кроме как напрямую выкладывать его в ГУЙ. Любой сервис, который пытается стать клиентом этого API, вынужден жить в постоянной готовности получить не данные, а фигу.

при чем здесь вообще апи, когда мы говорим про то, как делать секьюрити внутри?

S>И как-то осмысленно объяснять пользователю, что "у тебя, брат, нет пермиссии на атрибут 'НДС', сходи к админу, попроси, чтоб выдал".


Google Cloud так и делает если что

S>Ну, либо (что скорее всего) внезапно падать с internal error 500, потому что внутрях там NullReferenceException.


домыслы

S>Разобраться, что там стало первопричиной, потребует привлечения дорогостоящего саппорта. Так что в пет проджектах, где пользователей меньше, чем ролей и пермиссий вместе взятых — велком, можно и так. А для чего-то серьёзного, где нужна предсказуемость работы — увольте.


дорогостоящий саппорт? дороже разработки?

КЛ>>вот и начинается, часть пермиссий через средства субд, часть сбоку, чтд

S>Где это я предложил часть пермиссий через средства СУБД? Я вам привёл стандартный способ разделения доступа "построчно" без использования row-level security.

ваши роли в субд и есть часть пермиссий через субд

КЛ>>так у вас нет row-level permission же

S>Я вроде дал пошаговое описание того, как решается проблема отсутствия row-level permissions в RDBMS. Причём не как рекомендацию использовать эту схему, а как пример реализации "послойной" безопасности.

а что тогда надо использовать в твоем случае?

S>Точно такие же рецепты применяются и в сервисах.

S>То есть токен пользователя у нас роляет только во фронт-сервисе. Когда пользователь U запрашивает API сервиса A, а сервис A в рамках этого запроса стучится в сервис B, то никакие токены U в этот B не передаются. У U вообще нет никакого доступа до сервиса B. В этот сервис обращается A, под собственным токеном.
S>Поэтому идея "а давайте у нас инвойс будет содержать данные контрагента если у вызывающего пользователя есть пермиссия на этого контрагента" сразу идёт навзничь.
S>У вызываюшего пользователя нет никаких пермиссий на контрагента — господь упаси. А вот право видеть реквизиты получателя платежа по выставленному счёту у него есть в силу федерального закона.

даже не буду комментировать, причем тут несколько сервисов и их взаимодействие я не понимаю, это вне контекста нашего обсуждения

КЛ>>" SQL исполнялся в контексте безопасности конечного пользователя " — вот это вообще что такое?

S>Это когда мы заводим для пользователя №44487 виндовый аккаунт, даём этому аккаунту права на SQL базу с табличками forums, topics, replies, и marks, при логине на сайт создаём виндовую сессию, и все запросы в SQL Server выполняем через новое соединение под правами этого виндового аккаунта.

кто так вообще делает? выглядит как полная дичь если честно

КЛ>>>>селект учитывает пермиссии юзера, получение по токену, чтобы выбрать только нужные строки, поля. работает с любым сочетанием и количеством ролей и пермиссий.

S>>>Можете привести пример такого select? Я вроде понимаю, о чём вы пишете, но уверенности нет.

КЛ>>select * from rows r

КЛ>>join rows_perms p on r.id = p.r_id
КЛ>> where p.perm = 'row_read' and p.user_id = :userid
S>Прекрасно. Вы себе представляете производительность такого решения? Когда у нас табличка на пару миллионов строк, и есть тысяча пользователей с частично пересекающимися правами на эти строки?

да, индекс на rows_perms.user_id и будет быстро, плюс там еще в 99 процентах будет предикат на индексированное поле как часть фильтра поискового запроса. да, часто данные для всех лежать в одной таблице и когда нужен row-level security у тебя просто нет выбора. либо копии данных (твои views видимо) либо так.

но это на запрос коллекции, а на запрос одного ресурса вообще все быстро потому что индекс и на rows_perms.id

select * from rows r
join rows_perms p on r.id = p.r_id
where p.perm = 'row_read' and p.user_id = :userid and r.id = :id

КЛ>>или

КЛ>>select * from rows r where r.group_id in :user_groups
S>А как же "любое сочетание ролей и пермиссий"? Вы прибиваете доступ к r только к одной роли; невозможно выдать доступ к конкретной строке нескольким разным группам.
S>Собственно, вы изобретаете нормальную изоляцию на основе бизнес-правил, только задом наперёд.

ты просил примеры, я привел сложный и простой (для твоей модели где есть только роли)

S>Это — совершенно нормальная история, которая работает и применяется.

КЛ>>userid/user_groups резолвятся по токену из запроса
S>Ну, вы же только что собирались сделать универсальную схему, которая работает с любым количеством пермиссий и ролей. А получается вполне себе узкоспециализированная штука.

первый пример довольно универсален, он иллюстрирует подход "на основании токена фильтруем резалтсет и тп"

S>Непонятно. Как я смогу получить разный набор полей для разных строк одной и той же таблицы? Речь-то шла именно об этом — что состав результата определяется не объектом, а правами пользователя на него.


на чистом sql очевидно никак, для некоторых строк в резалтсете надо фильтровать поля (будут null), если ты об этом
а в твоем случае как? у тебя же схема прибита гвоздями

КЛ>>да, но ничего с точки зрения трейдоффа разработка/результат не придумали. открываешь google aim и видишь и роли, и отдельные пермиссии.

S>Надо внимательно смотреть на то, как именно используются эти роли и пермиссии. Потому что я так-то не против ролей и пермиссий; я против смешивания мух и котлет.
S>И если я запрашиваю, допустим, GET /resources/{resourceId}?$include(usageHistory), а у меня нет пермиссий смотреть usageHistory по этому ресурсу, я получаю не пустую историю и не JSON с "вырезанным" атрибутом, а честный 403. А если у меня пермиссия есть, то я могу полагаться на то, что в результате будет атрибут usageHistory с описанной в схеме структурой.

как тут помогают роутеры?

S>В итоге сторонний сервис, который потребляет мой API, может выдавать осмысленные ошибки, которые можно быстро исправить. А не просто падать оттого, что его авторы тестировались с аккаунтом, у которого были все нужные пермиссии, и понятия не имели, что у кого-то пермиссия на usageHistory на какой-то отдельный объект может быть отобрана.


да ну я тебе сделаю отдельный endpoint, но внутри будет один движок по доставке данных, который может тебе отдавать 403 в когда надо

S>Обратите внимание — это то самое "разведение ресурсов по разным URL", над которым вы так потешались.


мы потешаемся не над ним, а над тем, что ты полагаешься только на него

КЛ>>много ролей, много разных пермиссий

S>Количество ни на что не влияет.

на комбинаторный взрыв сущностей

КЛ>>ага, то есть любой смоук тест у нас в лобой системе обнаруживает любую проблему?

S>Нет, только детерминистические вещи.

это что? каков критерий?

КЛ>>и никто ее не делает, потому что это невозможно поддерживать

S> Надо просто уметь это готовить.


сколько раз мы уже это слышали по поводу всего. похоже на отмазку для неадекватного задаче решения
Отредактировано 17.04.2025 19:26 Кt Л. . Предыдущая версия . Еще …
Отредактировано 17.04.2025 18:57 Кt Л. . Предыдущая версия .
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.