Здравствуйте, busk, Вы писали:
B>а я думал что фронт тоже распиливают на отдельные сервисы, но подумал, что для SPA не получится тогда сделать без третьего агрегирующего фронт сервиса.
Бывает такое, микрофронтенд называется. Идея, в целом, довольно грамотная с точки зрения не превращать фронт в неподдерживаемое месиво. А еще бывает backend for frontend (BFF)
Здравствуйте, busk, Вы писали:
B>Здравствуйте, Qulac, Вы писали:
B>>>>а вот у меня получается 2 бэкенд сервиса, а на фронте тоже 2 реакт приложения, или на фронте одним можно разрулить?
B>>>вопрос еще связан с тем, что у меня SPA а если будет 2 фронт приложения то тут же получается будет обновление страницы после страницы логина на основное приложение
Q>>А зачем так делать? Фронт можно один оставить, просто сервис на беке будет сам вызывать сервис авторизации когда это надо.
B>а я думал что фронт тоже распиливают на отдельные сервисы, но подумал, что для SPA не получится тогда сделать без третьего агрегирующего фронт сервиса. B>Тогда одно на фронте, понял
Вариант с распиливанием фронта возможен, особенно для систем с устанавливаемыми плагинами.
Здравствуйте, Miroff, Вы писали:
M>Здравствуйте, m2user, Вы писали:
M>>Как минимум нужно предоставить документацию на API и получить feedback
M>Прелесть RMM L3 в том, что он самодокументируемый и на 99% фидбека можно сразу отвечать: "это не RESTful, мы этого делать не будем"
RMM L3 не нужен, потому что:
1. не заменяет документацию, зато дикий оверхед
2. добавляет лишней связности — теперь я должен грузить ссылки на апи (и, судя по твоим дальнейшим постам, еще и в зависимости от пермиссий) для всех связных сущностей
3. почти всегда бесполезен, тк говорит что можно, а не что нужно — то есть протекание недоделанной (бизнес-логика на базе только доступных ссылок? ну-ну) бизнес логики туда, куда не надо
[]
M>Опять же, можешь раскрыть тему? Пейджинг это простая штука если перестать думать о нем, как о RPC и начать думать как об отдельном ресурсе. Ты СОЗДАЕШЬ отдельный объект "поисковый запрос" и в ответ получаешь список страниц с результатами этого запроса. И, внезапно, у тебя уже нет проблем со стабильностью, сортировки, изменению состава страниц, кэшированию и т.п. Результат фиксируется в момент создания запроса и далее до нового поиска уже не меняется.
на практике никто так не делает потому что это просто не работает. думать можно как угодно красиво, конечно
Здравствуйте, Sinclair, Вы писали:
S>Например, можно воткнуть reverse proxy перед сервером приложения, и тогда он сможет снять значительную часть нагрузки с сервера. S>Как только мы начинаем менять представление объекта в зависимости от пользователя, о кэшировании можно забыть.
чет мне кажется никто ничего уже давно не кеширует
ну и
Как только мы начинаем менять представление объекта в зависимости от пользователя
Здравствуйте, Sinclair, Вы писали:
S>Вариантов три: S>1. При отдаче текста постановления смотрим в токен пользователя, и либо заменяем все имена плейсхолдерами, либо вставляем как надо. S>2. Делаем два ресурса: "анонимизированное постановление", "полноценное постановление". Анонимный доступ ко второму получает 401, аутентифицированный доступ без прав на данное дело получает 403. S>3. Делаем два ресурса: постановление, в "тексте" которого есть ссылки на фигурантов, каждый из которых — самостоятельный ресурс. Постановления отдаём всем желающим, детали фигурантов — только авторизованным пользователям. Остальные получают 403. S>Как по мне, так первый вариант, очевидно, самый-самый плохой. Он плохо масштабируется, и крайне плохо проверяется на корректность.
Он плохо масштабируется, и крайне плохо проверяется на корректность.
вообще не очевидно. в любом случае тебе надо сделать фильтр данных, как ты его сделал и на каком этапе не так важно. введением магического второго ресурса проблема фильтра никуда не уйдет. и про комбинаторный взрыв тебе правильно сказали. Номер 1 самый рабочий и адекватный — по токену получаем список пермиссий и по ним фильтруем резалтсет.
И вообще зря ты критикуешь "клиентскую секьюрити", просто она должна дублироваться серверной. Нормально возвращать на клиента список допустимых действий для оптимизации, но HATEOAS для этого не нужен и на сервере тоже должны быть чеки.
Здравствуйте, 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 гоняет
Здравствуйте, Константин Л., Вы писали:
КЛ>вообще не очевидно. в любом случае тебе надо сделать фильтр данных, как ты его сделал и на каком этапе не так важно.
Не, не в любом. Только в том, если кому-то нужны дополнительные подробности. КЛ>введением магического второго ресурса проблема фильтра никуда не уйдет.
Я не очень понимаю, что такое "проблема фильтра". Магический второй ресурс означает, что есть два ресурса: один даже join в базе не делает с таблицами "смежных сущностей", другой делает джойн, но проверяет ровно одну пермиссию в токене, а не отдаёт 2^10 вариантов в зависимости от хидера.
КЛ>и про комбинаторный взрыв тебе правильно сказали. Номер 1 самый рабочий и адекватный — по токену получаем список пермиссий и по ним фильтруем резалтсет.
Ну я бы так дизайнить не стал. Соображения я привёл. У каждого они свои — вон кто-то хочет просто написать универсальный код на питоне, который через рефлексию всю базу наружу отдаёт, а пермиссии берёт из токена.
Можно и так делать, если результат не шибко важен.
КЛ>И вообще зря ты критикуешь "клиентскую секьюрити", просто она должна дублироваться серверной. Нормально возвращать на клиента список допустимых действий для оптимизации, но HATEOAS для этого не нужен и на сервере тоже должны быть чеки.
Да, тут я согласен.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Константин Л., Вы писали:
КЛ>>вообще не очевидно. в любом случае тебе надо сделать фильтр данных, как ты его сделал и на каком этапе не так важно. S>Не, не в любом. Только в том, если кому-то нужны дополнительные подробности.
ну когда не нужны тогда и фильтр не нужен, верно?
КЛ>>введением магического второго ресурса проблема фильтра никуда не уйдет.
S>Я не очень понимаю, что такое "проблема фильтра". Магический второй ресурс означает, что есть два ресурса: один даже join в базе не делает с таблицами "смежных сущностей", другой делает джойн, но проверяет ровно одну пермиссию в токене, а не отдаёт 2^10 вариантов в зависимости от хидера.
фильтр — это способ либо собрать либо очистить ресурс. принципиальной разницы между виртуальными ресурсами (как в твоем случае) и одним ресурсом нет вообще. все равно где-то придется ответить на вопрос какие данные возвращаем
КЛ>>и про комбинаторный взрыв тебе правильно сказали. Номер 1 самый рабочий и адекватный — по токену получаем список пермиссий и по ним фильтруем резалтсет. S>Ну я бы так дизайнить не стал. Соображения я привёл. У каждого они свои — вон кто-то хочет просто написать универсальный код на питоне, который через рефлексию всю базу наружу отдаёт, а пермиссии берёт из токена.
это детали, можно и в базе пермиссии проверять
S>Можно и так делать, если результат не шибко важен.
не понимаю в чем принципиальная разница с одним ресурсом и несколькими (кроме как комбинаторики)
КЛ>>И вообще зря ты критикуешь "клиентскую секьюрити", просто она должна дублироваться серверной. Нормально возвращать на клиента список допустимых действий для оптимизации, но HATEOAS для этого не нужен и на сервере тоже должны быть чеки. S>Да, тут я согласен.
Здравствуйте, Константин Л., Вы писали: КЛ>ну когда не нужны тогда и фильтр не нужен, верно?
Вот эту фразу не понял.
КЛ>фильтр — это способ либо собрать либо очистить ресурс. принципиальной разницы между виртуальными ресурсами (как в твоем случае) и одним ресурсом нет вообще. все равно где-то придется ответить на вопрос какие данные возвращаем
Принципиальная разница тут только в надёжности. Меньше ветвлений в коде — меньше способов в них напороть.
В остальном — да, другие решения (типа расположение фильтра "перед запросом" или "после результата") сильнее влияют на параметры итогового сервиса.
S>>Ну я бы так дизайнить не стал. Соображения я привёл. У каждого они свои — вон кто-то хочет просто написать универсальный код на питоне, который через рефлексию всю базу наружу отдаёт, а пермиссии берёт из токена. КЛ>это детали, можно и в базе пермиссии проверять
Ну... в целом-то да, можно и в базе. Но у меня возникают вопросы прежде всего к надёжности такой модели. Слишком много движущихся частей => слишком много возможных путей исполнения и вариантов, когда всё может пойти "не так". При этом большинство из возможных конфигураций как настроек, так и устройства кода, являются заведомо некорректными.
По большому счёту, это является одной из причин, по которой сейчас не принято выставлять в интернет напрямую базу данных.
Казалось бы — ачего, давайте пермиссий навесим, и алга. Что-то есть в СУБД из коробки, что-то можно докрутить при помощи хранимок и представлений. Если всё делать аккуратно, получим могучую REST-подобную систему.
Однакож, нет, не делают так. Обожглись, и клиент-сервер остался только внутри "безопасных периметров", а в открытый интернет торчит исключительно трёхзвенка.
Собственно, все эти идеи "давайте отдавать базу через рефлексию" и есть способ завернуть SQL в HTTP, и ничего полезного архитектуре не добавляют.
Более продуктивный способ, имхо, всё же делить логику по уровням так, чтобы на каждом уровне по максимуму использовать его преимущества.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, Константин Л., Вы писали: КЛ>>ну когда не нужны тогда и фильтр не нужен, верно? S>Вот эту фразу не понял.
вот:
КЛ>вообще не очевидно. в любом случае тебе надо сделать фильтр данных, как ты его сделал и на каком этапе не так важно. S>Не, не в любом. Только в том, если кому-то нужны дополнительные подробности.
не нужны подробности -> не нужен фильтр. нужны -> нужен фильтр или доп-ресурс.
КЛ>>фильтр — это способ либо собрать либо очистить ресурс. принципиальной разницы между виртуальными ресурсами (как в твоем случае) и одним ресурсом нет вообще. все равно где-то придется ответить на вопрос какие данные возвращаем S>Принципиальная разница тут только в надёжности. Меньше ветвлений в коде — меньше способов в них напороть.
ну смотри, у тебя два юзкейса — полный ресурс или урезанный. даже если ты будешь разруливать их через отдельные ресурсы где-то будет ветвление на создание (фильтрацию, сборку, как угодно) одного и другого.
S>В остальном — да, другие решения (типа расположение фильтра "перед запросом" или "после результата") сильнее влияют на параметры итогового сервиса.
S>>>Ну я бы так дизайнить не стал. Соображения я привёл. У каждого они свои — вон кто-то хочет просто написать универсальный код на питоне, который через рефлексию всю базу наружу отдаёт, а пермиссии берёт из токена. КЛ>>это детали, можно и в базе пермиссии проверять S>Ну... в целом-то да, можно и в базе. Но у меня возникают вопросы прежде всего к надёжности такой модели. Слишком много движущихся частей => слишком много возможных путей исполнения и вариантов, когда всё может пойти "не так". При этом большинство из возможных конфигураций как настроек, так и устройства кода, являются заведомо некорректными.
я до сих пор не понимаю как добавление ресурсов принципиально что-то меняет в твоей модели и что это у меня за такая модель?
S>По большому счёту, это является одной из причин, по которой сейчас не принято выставлять в интернет напрямую базу данных.
а кто такое предлагает? я такое не предлагаю. и, кстати, популярный graphql именно это и делает, насколько я понимаю и я это осуждаю.
S>Казалось бы — ачего, давайте пермиссий навесим, и алга. Что-то есть в СУБД из коробки, что-то можно докрутить при помощи хранимок и представлений. Если всё делать аккуратно, получим могучую REST-подобную систему.
не понимаю к чему ты. мы лишь про то, что по токену на беке получаем пермиссии и в зависимости он них отдаем респонс.
S>Однакож, нет, не делают так. Обожглись, и клиент-сервер остался только внутри "безопасных периметров", а в открытый интернет торчит исключительно трёхзвенка. S>Собственно, все эти идеи "давайте отдавать базу через рефлексию" и есть способ завернуть SQL в HTTP, и ничего полезного архитектуре не добавляют. S>Более продуктивный способ, имхо, всё же делить логику по уровням так, чтобы на каждом уровне по максимуму использовать его преимущества.
graphql! и да, это бред, но это не то, что я предлагаю
[]
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 — та ещё задача.
ну это звучит как "доказать, что код выдает правильную поисковую выдачу та еще задача".
[]
S>·>Ну я просто написал когда этот твой способ не работает. Но я, конечно, верю, что в некоторых случаях и твой способ работает. Но это не значит, что он универсальный всемогутер. S>Скорее наоборот: бывают задачи с низкой ответственностью, где можно игнорировать best practices и писать с надеждой на авось.
сколько систем ты так сделал и сколько у них юзеров и ролей?
Здравствуйте, Константин Л., Вы писали:
S>>Я вам рассказываю практический замкнутый пример: нет никаких "привилегий на втрибуты". Есть два вида ресурсов. Доступ к каждому их них либо есть, либо нету. КЛ>что значит есть? физически есть? то есть реально в базе 2 таблицы?
Совершенно необязательно. В базе это может быть одна таблица, 2 таблицы, или 17 таблиц. Структура базы тут очень косвенно задействована.
КЛ>кто его оттуда вырезал?
Я не понимаю термина "вырезал". Никто никого ниоткуда не "вырезал".
Просто у нас есть такой тип данных, InboundInvoice, который отличается от OutboundInvoice.
На стороне сервиса они могут находиться в каких-то взаимоотношениях друг с другом (типа — оба отнаследованы от общей базы, или собираются путём алгебры типов из запчастей, вроде CommonInvoice & InboundInvoice / CommonInvoice & OutboundInvoice).
Снаружи мы всё равно видим только схему Json, и она разная для разных ендпоинтов.
КЛ>ты тут смешиваешь свои и чужие инвойсы, чтобы навести туману.
Это не я смешиваю КЛ>давай мы будем всегда про свои инвойсы, но в одном случае для отчетности, в другом для превью — как хранить будешь и разделять?
Я не буду их разделять — зачем? Мне непонятен сценарий. Если дадите больше деталей — можно спроектировать. КЛ>он так не предлагает
Цитирую:
А на самом деле json генерится питонячим кодом, который рефлексией вываливает всё что есть
КЛ>примерно всегда так и работает
Поверю вам на слово.
КЛ>ну то есть делает именно то, что мы тут тебе и говорим
Нет, делает ровно противоположное. Более того, прямо тут в топике приводились утверждения про то, что "на самом деле" микросервисы не только пользовательских принципалов не используют, а вообще бегают все под одним и тем же аккаунтом.
КЛ>почему это мы не можем?
Потому что row level security есть далеко не в любой СУБД. И даже в тех, где такое есть, далеко не всегда это будет наиболее эффективным решением. КЛ>зачем? только столбцы выбросить?
И строки тоже.
КЛ>такое работает только когда у тебя 2-3 роли в аппке и мало пермиссий
Такое работает примерно всегда. Я ещё ни разу не видел настолько безумной архитектуры, чтобы SQL исполнялся в контексте безопасности конечного пользователя, пришедшего из интернета.
КЛ>это все не надо. у каждой строки есть поле, по которому мы понимаем какая пермиссия нужна, чтобы его читать.
"Его" — это кого? Поле?
КЛ>селект учитывает пермиссии юзера, получение по токену, чтобы выбрать только нужные строки, поля. работает с любым сочетанием и количеством ролей и пермиссий.
Можете привести пример такого select? Я вроде понимаю, о чём вы пишете, но уверенности нет.
КЛ>а ведь еще ничего не сказано про ABAC, который часто нужен и который в твою схему вообще не вписывается
Да, для ABAC нужна другая схема. Но он очень часто является оверкиллом.
КЛ>действительно, результат поискового запроса зависит от критериев поиска (пермиссии один из них внезапно), вот это дичь, да?
Отож. Не, я всё это умею делать. Но в эксплуатации такие "гибкие схемы" гораздо чаще приносят вред, чем пользу.
Вот, в прошлом году в одной крупной компании был случай, когда из-за цепочки нечаянных совпадений и недопониманий друг друга, одному из сотрудников выдали чутка больше "пермиссий", чем надо было по его роли.
В итоге сотрудник из лучших побуждений наворотил делов. Хорошо, что речь шла о добронамеренном сотруднике, поэтому последствия были не очень тяжкими (ну, там, зарплату задержали на пару дней части сотрудников). А в иной ситуации это бы вышло таким боком, что никакая экономия на архитектуре не окупилась бы.
КЛ>для петпроджектов да, но мы о нормальных системах говорим
Ну, критерии "нормальных систем" у всех разные.
КЛ>а если ты внутри роутинга не туда нароутил?
То это будет обнаружено первым же smoke test.
КЛ>ну это звучит как "доказать, что код выдает правильную поисковую выдачу та еще задача".
Конечно. Это вполне актуальная проблема; и основное её решение ровно то же, что я предлагаю — факторизация. Потому что иначе вы точно так же утонете в объёме тестирования.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
КЛ>>вообще не очевидно. в любом случае тебе надо сделать фильтр данных, как ты его сделал и на каком этапе не так важно. S>>Не, не в любом. Только в том, если кому-то нужны дополнительные подробности. КЛ>не нужны подробности -> не нужен фильтр. нужны -> нужен фильтр или доп-ресурс.
Вы фильтром называете проекцию или что-то ещё?
КЛ>ну смотри, у тебя два юзкейса — полный ресурс или урезанный.
Строго говоря, у нас может быть и больше юзкейзов.
КЛ>даже если ты будешь разруливать их через отдельные ресурсы где-то будет ветвление на создание (фильтрацию, сборку, как угодно) одного и другого.
Если я это делаю явным образом, то у меня это ветвление покрывается системой типов, и его статически контролирует компилятор ещё до того, как запустятся тесты.
КЛ>я до сих пор не понимаю как добавление ресурсов принципиально что-то меняет в твоей модели и что это у меня за такая модель?
У вас модель, в которой заранее неизвестно, какая структура ресурса будет получена при обращении по тому или иному ендпоинту. Она типа "динамически" определяется где-то внутри кода непрозрачными правилами.
КЛ>а кто такое предлагает? я такое не предлагаю. и, кстати, популярный graphql именно это и делает, насколько я понимаю и я это осуждаю.
Нет, graphQL делает не это.
КЛ>не понимаю к чему ты. мы лишь про то, что по токену на беке получаем пермиссии и в зависимости он них отдаем респонс.
Как мы это будем тестировать?
КЛ>graphql! и да, это бред, но это не то, что я предлагаю
В graphQL принято несколько неудачных решений, но не потому, что он "выставляет наружу БД".
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, 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>Конечно. Это вполне актуальная проблема; и основное её решение ровно то же, что я предлагаю — факторизация. Потому что иначе вы точно так же утонете в объёме тестирования.
и никто ее не делает, потому что это невозможно поддерживать
Здравствуйте, Sinclair, Вы писали:
S>Вы фильтром называете проекцию или что-то ещё?
да
КЛ>>ну смотри, у тебя два юзкейса — полный ресурс или урезанный. S>Строго говоря, у нас может быть и больше юзкейзов.
вам и говорят, когда много, тогда у вас проблемы.
КЛ>>даже если ты будешь разруливать их через отдельные ресурсы где-то будет ветвление на создание (фильтрацию, сборку, как угодно) одного и другого. S>Если я это делаю явным образом, то у меня это ветвление покрывается системой типов, и его статически контролирует компилятор ещё до того, как запустятся тесты.
система типов это только про поля, а что со строками?
это не гибко
КЛ>>я до сих пор не понимаю как добавление ресурсов принципиально что-то меняет в твоей модели и что это у меня за такая модель? S>У вас модель, в которой заранее неизвестно, какая структура ресурса будет получена при обращении по тому или иному ендпоинту. Она типа "динамически" определяется где-то внутри кода непрозрачными правилами.
sql уже стал непрозрачными правилами. "у вас данные отдаются динамически по непрозрачным правилам". дело не сколько в структуре, а вообще в данных.
еше раз — пермисии это такой же фильтр данных как и остальные. разрулить их системой типов хорошо не получится.
пример — у юзера есть 5 основных воркфлоу, в один из которых входит создание внутренних отчетов из таблицы rows, в другой создание анонимизтированных отчетов для регулятора.
внутренний отчет показывает конфиденциальные данные, для регулятора отрезает их.
опиши security-модель для такого? сколько ролей? как все работает?
КЛ>>а кто такое предлагает? я такое не предлагаю. и, кстати, популярный graphql именно это и делает, насколько я понимаю и я это осуждаю. S>Нет, graphQL делает не это.
а что он делает?
КЛ>>не понимаю к чему ты. мы лишь про то, что по токену на беке получаем пермиссии и в зависимости он них отдаем респонс. S>Как мы это будем тестировать?
а как вы тестируете все остальное, что отдает данные на основании пользовательского контекста?
КЛ>>graphql! и да, это бред, но это не то, что я предлагаю S>В graphQL принято несколько неудачных решений, но не потому, что он "выставляет наружу БД".
Здравствуйте, Константин Л., Вы писали:
КЛ>и как и откуда в эту схему кладутся данные?
Маппером, который сгенерирован по типу данных. Кладутся из 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", над которым вы так потешались.
КЛ>много ролей, много разных пермиссий
Количество ни на что не влияет.
КЛ>ага, то есть любой смоук тест у нас в лобой системе обнаруживает любую проблему?
Нет, только детерминистические вещи.
КЛ>и никто ее не делает, потому что это невозможно поддерживать Надо просто уметь это готовить.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Константин Л., Вы писали: S>>Вы фильтром называете проекцию или что-то ещё? КЛ>да
Хорошо.
КЛ>вам и говорят, когда много, тогда у вас проблемы.
У нас нет никаких проблем.
КЛ>система типов это только про поля, а что со строками? КЛ>это не гибко
Излишняя гибкость, в целом, только вредит. Но фильтрация, в отличие от проекции, не нарушает никаких инвариантов.
Поэтому в ней запросто можно учитывать предикаты, в том числе и построенные на токене пользователя.
По-прежнему у нас границы безопасности совпадают с границами ресурса.
Смотрите: вот я делаю какой-нибудь
GET /invoices/
И мне приезжает какой-то список инвойсов. Как правило — без деталей, только ссылки.
И если я пойду по этим ссылкам, типа GET /invoices/32423423423/, то скорее всего буду получать 200 Ok.
А вот те из инвойсов, на которые у меня прав нет, дадут при прямом обращении 403 либо 404, и в общем списке фигурировать не будут.
КЛ>еше раз — пермисии это такой же фильтр данных как и остальные. разрулить их системой типов хорошо не получится.
Прекрасно получится.
КЛ>пример — у юзера есть 5 основных воркфлоу, в один из которых входит создание внутренних отчетов из таблицы rows, в другой создание анонимизтированных отчетов для регулятора. КЛ>внутренний отчет показывает конфиденциальные данные, для регулятора отрезает их. КЛ>опиши security-модель для такого? сколько ролей? как все работает?
Пока что роль ровно одна. Всё работает так, как написано. Причин изобретать разные роли тут нет.
Для проектирования безопасности у нас недостаточно вводных.
КЛ>а что он делает?
Он делает возможность формировать запросы к иерархии объектов, без всех плюшек REST.
КЛ>а как вы тестируете все остальное, что отдает данные на основании пользовательского контекста?
КЛ>да, но выставляет наружу псевдо-бд
Есть много разных способов выставить наружу псевдо-бд, и не все из них одинаково полезны.
Надо понимать, какая проблема решается.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, 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> Надо просто уметь это готовить.
сколько раз мы уже это слышали по поводу всего. похоже на отмазку для неадекватного задаче решения