Hey!
I need to use the RLS features in the django admin panel, so that it would restrict the view for the users with is_staff, but it doesn’t seem to work.
In the code below i tried to test the capabilities of this module so that it would only show the ConferencePresentation object with the format_event being equal to Очный
the model i’ve used:
class ConferencePresentation(RLSModel):
STATUS_CHOICES = [
("Международная", "Международная"),
("Всероссийская", "Всероссийская"),
("Региональная", "Региональная"),
]
FORMAT_EVENT_CHOICES = [
("Очный", "Очный"),
("Онлайн", "Онлайн"),
]
FORMAT_PARTICIPATION_CHOICES = [
("Очный", "Очный"),
("Онлайн", "Онлайн"),
("Стендовый", "Стендовый"),
]
PUBLICATION_TYPE_CHOICES = [
("oral", "Презентация"),
("conference", "Конференция"),
]
id: AutoField = AutoField(primary_key=True)
author = GenericRelation(Author)
conference_name: CharField = CharField(max_length=255, verbose_name="Название")
place: CharField = CharField(max_length=255, verbose_name="Место проведения")
dates: DateRangeField = DateRangeField(verbose_name="Даты проведения")
single_date: DateField = DateField(null=True, blank=True)
format_event: CharField = CharField(
max_length=20, choices=FORMAT_EVENT_CHOICES, verbose_name="Формат проведения"
)
format_participation: CharField = CharField(
max_length=20,
choices=FORMAT_PARTICIPATION_CHOICES,
verbose_name="Формат участия",
)
publication_type: CharField = CharField(
max_length=20,
choices=PUBLICATION_TYPE_CHOICES,
verbose_name="Формат публикации",
)
status: CharField = CharField(
max_length=20,
choices=STATUS_CHOICES,
blank=True,
null=True,
verbose_name="Статус",
)
approx_count_participants = Uint2Field(
blank=True, null=True, verbose_name="Приблизительное количество участников"
)
url: models.URLField = models.URLField(
max_length=255, blank=True, null=True, verbose_name="Ссылка на мероприятие"
)
def save(self, *args, **kwargs):
if self.dates and self.dates.lower and self.dates.upper:
if self.dates.lower == self.dates.upper:
self.single_date = self.dates.lower
super().save(*args, **kwargs)
class Meta:
# db_table = 'schema_public.conference_presentations'
verbose_name = "Конференция / Выступление"
verbose_name_plural = "Конференции / Выступления"
constraints = [
models.CheckConstraint(
check=Q(
status__in=["Международная", "Всероссийская", "Региональная"]
),
name="cns_conference_presentations",
),
models.CheckConstraint(
check=Q(format_event__in=["Очный", "Онлайн"]),
name="cns_conference_presentations_0",
),
models.CheckConstraint(
check=Q(
format_participation__in=["Очный", "Онлайн", "Стендовый"]
),
name="cns_conference_presentations_1",
),
models.CheckConstraint(
check=Q(publication_type__in=["oral", "conference"]),
name="cns_conference_presentations_2",
),
]
rls_policies = [
ModelPolicy('access_policy', filters=Q(format_event="Очный"))
]
Settings:
INSTALLED_APPS = [
"polymorphic",
"users",
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"core",
"publications",
"conferences_presentations",
"reviews",
"organizational_work",
"scientific_guidance",
"teaching_activities",
"field_study",
"expertise",
"admin_autoregister",
"django_jsonform",
"django_rls",
]
ADMIN_AUTOREGISTER_EXCLUDE_INLINES = True
AUTH_USER_MODEL = "users.CustomUser"
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django_rls.middleware.RLSContextMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
DJANGO_RLS = {
'AUTO_ENABLE_RLS': True
}
DATABASES = {
"default": {
"ENGINE": "django_rls.backends.postgresql" # using that insted of the default because of warning message `Database backend postgresql does not support RLS. Use 'django_rls.backends.postgresql' as your database ENGINE.`
"NAME": getenv("DATABASE_NAME", "polls"),
"USER": getenv("DATABASE_USERNAME", "myprojectuser"),
"PASSWORD": getenv("DATABASE_PASSWORD", "password"),
"HOST": getenv("DATABASE_HOST", "127.0.0.1"),
"PORT": getenv("DATABASE_PORT", 5432),
}
}
As you can see, i made a test rls_policy as it says in the Quickstart, but it still displays for every user in the admin, regardless of the policy.