Я пытаюсь разработать систему для API, который предоставляет пользователям доступ к таблице данных Data на основе таблицы разрешений Permissions, которая связана с группой таблицы Group. Когда пользователь делает запрос данных (из таблицы данных), мой API должен возвращать только строки из таблицы данных на основе значений в столбцах таблицы данных, которые ему разрешено просматривать.
По умолчанию у пользователя не будет доступа ни к каким строкам при запросе данных через мой API. Однако я хотел бы предоставить доступ к данным на основе значений в столбцах.
Например, Если моя таблица данных содержит информацию о новостных статьях и имеет заголовок столбцов, news_source, posted_date и другие похожие столбцы
id | title | news_source | posted_date | ...
-----+----------+-----------------------+-------------+------
1 | ... | NYTimes | 2019-12-30 |
2 | ... | BBC | 2019-12-30 |
3 | ... | BBC | 2019-12-30 |
4 | ... | Washington Post | 2019-12-30 |
5 | ... | NYTimes | 2019-12-30 |
6 | ... | NYTimes | 2020-01-01 |
7 | ... | Boston Globe | 2020-01-01 |
В этом примере я хотел бы предоставить групповой доступ для получения данных только из NYTimes, опубликованных после 01.01.2020, et c ...
Для этого я реализовал схему ниже
+-----+ +--------------+
|Group|<-------|Permission |
+-----+ +--------------+
|name | |group_id |
|... | |column_name |
+-----+ |text_value |
|date_value |
+--------------+
Для группы имя - это просто имя группы, а эллипс представляет некоторые другие несущественные столбцы. В разрешениях у меня есть внешний ключ для группы (group_id), имя столбца в таблице данных, к которой я обращаюсь (имя_столбца), и значение, к которому я предоставляю доступ (text_value или date_value, в зависимости от столбца I. ссылаюсь).
Прямо сейчас, когда пользователь делает запрос данных, я запускаю этот SQL, чтобы применить разрешения (если у группы пользователя id = 1).
SELECT * FROM Data d
INNER JOIN Permission p1 ON p1.group_id = 1 AND p1.column_name = 'news_source' AND p1.text_value = d.news_source
INNER JOIN Permission p2 ON p2.group_id = 1 AND p2.column_name = 'posted_date' AND p2.date_value >= d.posted_date;
Это будет работать, но мне было интересно, есть ли более организованный способ go по этому поводу. Я думаю, что в этой модели будет много избыточности для нескольких групп с одинаковыми разрешениями.