Revert "*: providers and sources -> channels, PolicyModel to PolicyBindingModel that uses custom M2M through"
This reverts commit 7ed3ceb960
.
This commit is contained in:
@ -16,7 +16,7 @@ class ApplicationSerializer(ModelSerializer):
|
||||
"name",
|
||||
"slug",
|
||||
"skip_authorization",
|
||||
"outlet",
|
||||
"provider",
|
||||
"meta_launch_url",
|
||||
"meta_icon_url",
|
||||
"meta_description",
|
||||
|
@ -1,31 +0,0 @@
|
||||
"""Inlet API Views"""
|
||||
from rest_framework.serializers import ModelSerializer, SerializerMethodField
|
||||
from rest_framework.viewsets import ReadOnlyModelViewSet
|
||||
|
||||
from passbook.admin.forms.inlet import INLET_SERIALIZER_FIELDS
|
||||
from passbook.core.models import Inlet
|
||||
|
||||
|
||||
class InletSerializer(ModelSerializer):
|
||||
"""Inlet Serializer"""
|
||||
|
||||
__type__ = SerializerMethodField(method_name="get_type")
|
||||
|
||||
def get_type(self, obj):
|
||||
"""Get object type so that we know which API Endpoint to use to get the full object"""
|
||||
return obj._meta.object_name.lower().replace("inlet", "")
|
||||
|
||||
class Meta:
|
||||
|
||||
model = Inlet
|
||||
fields = INLET_SERIALIZER_FIELDS + ["__type__"]
|
||||
|
||||
|
||||
class InletViewSet(ReadOnlyModelViewSet):
|
||||
"""Inlet Viewset"""
|
||||
|
||||
queryset = Inlet.objects.all()
|
||||
serializer_class = InletSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
return Inlet.objects.select_subclasses()
|
@ -1,30 +0,0 @@
|
||||
"""Outlet API Views"""
|
||||
from rest_framework.serializers import ModelSerializer, SerializerMethodField
|
||||
from rest_framework.viewsets import ReadOnlyModelViewSet
|
||||
|
||||
from passbook.core.models import Outlet
|
||||
|
||||
|
||||
class OutletSerializer(ModelSerializer):
|
||||
"""Outlet Serializer"""
|
||||
|
||||
__type__ = SerializerMethodField(method_name="get_type")
|
||||
|
||||
def get_type(self, obj):
|
||||
"""Get object type so that we know which API Endpoint to use to get the full object"""
|
||||
return obj._meta.object_name.lower().replace("outlet", "")
|
||||
|
||||
class Meta:
|
||||
|
||||
model = Outlet
|
||||
fields = ["pk", "property_mappings", "__type__"]
|
||||
|
||||
|
||||
class OutletViewSet(ReadOnlyModelViewSet):
|
||||
"""Outlet Viewset"""
|
||||
|
||||
queryset = Outlet.objects.all()
|
||||
serializer_class = OutletSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
return Outlet.objects.select_subclasses()
|
@ -2,8 +2,8 @@
|
||||
from rest_framework.serializers import ModelSerializer, SerializerMethodField
|
||||
from rest_framework.viewsets import ReadOnlyModelViewSet
|
||||
|
||||
from passbook.core.models import Policy
|
||||
from passbook.policies.forms import GENERAL_FIELDS
|
||||
from passbook.policies.models import Policy
|
||||
|
||||
|
||||
class PolicySerializer(ModelSerializer):
|
||||
|
30
passbook/core/api/providers.py
Normal file
30
passbook/core/api/providers.py
Normal file
@ -0,0 +1,30 @@
|
||||
"""Provider API Views"""
|
||||
from rest_framework.serializers import ModelSerializer, SerializerMethodField
|
||||
from rest_framework.viewsets import ReadOnlyModelViewSet
|
||||
|
||||
from passbook.core.models import Provider
|
||||
|
||||
|
||||
class ProviderSerializer(ModelSerializer):
|
||||
"""Provider Serializer"""
|
||||
|
||||
__type__ = SerializerMethodField(method_name="get_type")
|
||||
|
||||
def get_type(self, obj):
|
||||
"""Get object type so that we know which API Endpoint to use to get the full object"""
|
||||
return obj._meta.object_name.lower().replace("provider", "")
|
||||
|
||||
class Meta:
|
||||
|
||||
model = Provider
|
||||
fields = ["pk", "property_mappings", "__type__"]
|
||||
|
||||
|
||||
class ProviderViewSet(ReadOnlyModelViewSet):
|
||||
"""Provider Viewset"""
|
||||
|
||||
queryset = Provider.objects.all()
|
||||
serializer_class = ProviderSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
return Provider.objects.select_subclasses()
|
31
passbook/core/api/sources.py
Normal file
31
passbook/core/api/sources.py
Normal file
@ -0,0 +1,31 @@
|
||||
"""Source API Views"""
|
||||
from rest_framework.serializers import ModelSerializer, SerializerMethodField
|
||||
from rest_framework.viewsets import ReadOnlyModelViewSet
|
||||
|
||||
from passbook.admin.forms.source import SOURCE_SERIALIZER_FIELDS
|
||||
from passbook.core.models import Source
|
||||
|
||||
|
||||
class SourceSerializer(ModelSerializer):
|
||||
"""Source Serializer"""
|
||||
|
||||
__type__ = SerializerMethodField(method_name="get_type")
|
||||
|
||||
def get_type(self, obj):
|
||||
"""Get object type so that we know which API Endpoint to use to get the full object"""
|
||||
return obj._meta.object_name.lower().replace("source", "")
|
||||
|
||||
class Meta:
|
||||
|
||||
model = Source
|
||||
fields = SOURCE_SERIALIZER_FIELDS + ["__type__"]
|
||||
|
||||
|
||||
class SourceViewSet(ReadOnlyModelViewSet):
|
||||
"""Source Viewset"""
|
||||
|
||||
queryset = Source.objects.all()
|
||||
serializer_class = SourceSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
return Source.objects.select_subclasses()
|
@ -3,14 +3,14 @@ from django import forms
|
||||
from django.contrib.admin.widgets import FilteredSelectMultiple
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
|
||||
from passbook.core.models import Application, Outlet
|
||||
from passbook.core.models import Application, Provider
|
||||
|
||||
|
||||
class ApplicationForm(forms.ModelForm):
|
||||
"""Application Form"""
|
||||
|
||||
outlet = forms.ModelChoiceField(
|
||||
queryset=Outlet.objects.all().order_by("pk").select_subclasses(),
|
||||
provider = forms.ModelChoiceField(
|
||||
queryset=Provider.objects.all().order_by("pk").select_subclasses(),
|
||||
required=False,
|
||||
)
|
||||
|
||||
@ -21,7 +21,7 @@ class ApplicationForm(forms.ModelForm):
|
||||
"name",
|
||||
"slug",
|
||||
"skip_authorization",
|
||||
"outlet",
|
||||
"provider",
|
||||
"meta_launch_url",
|
||||
"meta_icon_url",
|
||||
"meta_description",
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Generated by Django 3.0.5 on 2020-05-15 19:59
|
||||
# Generated by Django 2.2.6 on 2019-10-07 14:06
|
||||
|
||||
import uuid
|
||||
|
||||
@ -7,7 +7,6 @@ import django.contrib.auth.validators
|
||||
import django.contrib.postgres.fields.jsonb
|
||||
import django.db.models.deletion
|
||||
import django.utils.timezone
|
||||
import guardian.mixins
|
||||
from django.conf import settings
|
||||
from django.db import migrations, models
|
||||
|
||||
@ -20,7 +19,6 @@ class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("auth", "0011_update_proxy_permissions"),
|
||||
("passbook_policies", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
@ -107,41 +105,63 @@ class Migration(migrations.Migration):
|
||||
),
|
||||
),
|
||||
("uuid", models.UUIDField(default=uuid.uuid4, editable=False)),
|
||||
("name", models.TextField(help_text="User's display name.")),
|
||||
("name", models.TextField()),
|
||||
("password_change_date", models.DateTimeField(auto_now_add=True)),
|
||||
(
|
||||
"attributes",
|
||||
django.contrib.postgres.fields.jsonb.JSONField(
|
||||
blank=True, default=dict
|
||||
),
|
||||
),
|
||||
],
|
||||
options={"permissions": (("reset_user_password", "Reset Password"),),},
|
||||
bases=(guardian.mixins.GuardianUserMixin, models.Model),
|
||||
options={
|
||||
"verbose_name": "user",
|
||||
"verbose_name_plural": "users",
|
||||
"abstract": False,
|
||||
},
|
||||
managers=[("objects", django.contrib.auth.models.UserManager()),],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Inlet",
|
||||
name="Policy",
|
||||
fields=[
|
||||
("created", models.DateTimeField(auto_now_add=True)),
|
||||
("last_updated", models.DateTimeField(auto_now=True)),
|
||||
(
|
||||
"policybindingmodel_ptr",
|
||||
models.OneToOneField(
|
||||
auto_created=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
parent_link=True,
|
||||
"uuid",
|
||||
models.UUIDField(
|
||||
default=uuid.uuid4,
|
||||
editable=False,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
to="passbook_policies.PolicyBindingModel",
|
||||
),
|
||||
),
|
||||
("name", models.TextField(help_text="Inlet's display Name.")),
|
||||
("name", models.TextField(blank=True, null=True)),
|
||||
(
|
||||
"slug",
|
||||
models.SlugField(help_text="Internal source name, used in URLs."),
|
||||
"action",
|
||||
models.CharField(
|
||||
choices=[("allow", "allow"), ("deny", "deny")], max_length=20
|
||||
),
|
||||
),
|
||||
("enabled", models.BooleanField(default=True)),
|
||||
("negate", models.BooleanField(default=False)),
|
||||
("order", models.IntegerField(default=0)),
|
||||
("timeout", models.IntegerField(default=30)),
|
||||
],
|
||||
bases=("passbook_policies.policybindingmodel",),
|
||||
options={"abstract": False,},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="PolicyModel",
|
||||
fields=[
|
||||
("created", models.DateTimeField(auto_now_add=True)),
|
||||
("last_updated", models.DateTimeField(auto_now=True)),
|
||||
(
|
||||
"uuid",
|
||||
models.UUIDField(
|
||||
default=uuid.uuid4,
|
||||
editable=False,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
),
|
||||
),
|
||||
(
|
||||
"policies",
|
||||
models.ManyToManyField(blank=True, to="passbook_core.Policy"),
|
||||
),
|
||||
],
|
||||
options={"abstract": False,},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="PropertyMapping",
|
||||
@ -156,7 +176,6 @@ class Migration(migrations.Migration):
|
||||
),
|
||||
),
|
||||
("name", models.TextField()),
|
||||
("expression", models.TextField()),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "Property Mapping",
|
||||
@ -164,38 +183,74 @@ class Migration(migrations.Migration):
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="UserInletConnection",
|
||||
name="DebugPolicy",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
models.AutoField(
|
||||
"policy_ptr",
|
||||
models.OneToOneField(
|
||||
auto_created=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
parent_link=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("created", models.DateTimeField(auto_now_add=True)),
|
||||
("last_updated", models.DateTimeField(auto_now=True)),
|
||||
(
|
||||
"inlet",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="passbook_core.Inlet",
|
||||
),
|
||||
),
|
||||
(
|
||||
"user",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
to="passbook_core.Policy",
|
||||
),
|
||||
),
|
||||
("result", models.BooleanField(default=False)),
|
||||
("wait_min", models.IntegerField(default=5)),
|
||||
("wait_max", models.IntegerField(default=30)),
|
||||
],
|
||||
options={"unique_together": {("user", "inlet")},},
|
||||
options={
|
||||
"verbose_name": "Debug Policy",
|
||||
"verbose_name_plural": "Debug Policies",
|
||||
},
|
||||
bases=("passbook_core.policy",),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Outlet",
|
||||
name="Factor",
|
||||
fields=[
|
||||
(
|
||||
"policymodel_ptr",
|
||||
models.OneToOneField(
|
||||
auto_created=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
parent_link=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
to="passbook_core.PolicyModel",
|
||||
),
|
||||
),
|
||||
("name", models.TextField()),
|
||||
("slug", models.SlugField(unique=True)),
|
||||
("order", models.IntegerField()),
|
||||
("enabled", models.BooleanField(default=True)),
|
||||
],
|
||||
options={"abstract": False,},
|
||||
bases=("passbook_core.policymodel",),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Source",
|
||||
fields=[
|
||||
(
|
||||
"policymodel_ptr",
|
||||
models.OneToOneField(
|
||||
auto_created=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
parent_link=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
to="passbook_core.PolicyModel",
|
||||
),
|
||||
),
|
||||
("name", models.TextField()),
|
||||
("slug", models.SlugField()),
|
||||
("enabled", models.BooleanField(default=True)),
|
||||
],
|
||||
options={"abstract": False,},
|
||||
bases=("passbook_core.policymodel",),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Provider",
|
||||
fields=[
|
||||
(
|
||||
"id",
|
||||
@ -215,7 +270,7 @@ class Migration(migrations.Migration):
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Token",
|
||||
name="Nonce",
|
||||
fields=[
|
||||
(
|
||||
"uuid",
|
||||
@ -229,11 +284,10 @@ class Migration(migrations.Migration):
|
||||
(
|
||||
"expires",
|
||||
models.DateTimeField(
|
||||
default=passbook.core.models.default_token_duration
|
||||
default=passbook.core.models.default_nonce_duration
|
||||
),
|
||||
),
|
||||
("expiring", models.BooleanField(default=True)),
|
||||
("description", models.TextField(blank=True, default="")),
|
||||
(
|
||||
"user",
|
||||
models.ForeignKey(
|
||||
@ -242,14 +296,36 @@ class Migration(migrations.Migration):
|
||||
),
|
||||
),
|
||||
],
|
||||
options={"verbose_name": "Token", "verbose_name_plural": "Tokens",},
|
||||
options={"verbose_name": "Nonce", "verbose_name_plural": "Nonces",},
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="inlet",
|
||||
name="property_mappings",
|
||||
field=models.ManyToManyField(
|
||||
blank=True, default=None, to="passbook_core.PropertyMapping"
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Invitation",
|
||||
fields=[
|
||||
(
|
||||
"uuid",
|
||||
models.UUIDField(
|
||||
default=uuid.uuid4,
|
||||
editable=False,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
),
|
||||
),
|
||||
("expires", models.DateTimeField(blank=True, default=None, null=True)),
|
||||
("fixed_username", models.TextField(blank=True, default=None)),
|
||||
("fixed_email", models.TextField(blank=True, default=None)),
|
||||
("needs_confirmation", models.BooleanField(default=True)),
|
||||
(
|
||||
"created_by",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
),
|
||||
),
|
||||
],
|
||||
options={
|
||||
"verbose_name": "Invitation",
|
||||
"verbose_name_plural": "Invitations",
|
||||
},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Group",
|
||||
@ -265,7 +341,7 @@ class Migration(migrations.Migration):
|
||||
),
|
||||
("name", models.CharField(max_length=80, verbose_name="name")),
|
||||
(
|
||||
"attributes",
|
||||
"tags",
|
||||
django.contrib.postgres.fields.jsonb.JSONField(
|
||||
blank=True, default=dict
|
||||
),
|
||||
@ -283,57 +359,11 @@ class Migration(migrations.Migration):
|
||||
],
|
||||
options={"unique_together": {("name", "parent")},},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Application",
|
||||
fields=[
|
||||
(
|
||||
"policybindingmodel_ptr",
|
||||
models.OneToOneField(
|
||||
auto_created=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
parent_link=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
to="passbook_policies.PolicyBindingModel",
|
||||
),
|
||||
),
|
||||
("name", models.TextField(help_text="Application's display Name.")),
|
||||
(
|
||||
"slug",
|
||||
models.SlugField(
|
||||
help_text="Internal application name, used in URLs."
|
||||
),
|
||||
),
|
||||
("skip_authorization", models.BooleanField(default=False)),
|
||||
("meta_launch_url", models.URLField(blank=True, default="")),
|
||||
("meta_icon_url", models.TextField(blank=True, default="")),
|
||||
("meta_description", models.TextField(blank=True, default="")),
|
||||
("meta_publisher", models.TextField(blank=True, default="")),
|
||||
(
|
||||
"outlet",
|
||||
models.OneToOneField(
|
||||
blank=True,
|
||||
default=None,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_DEFAULT,
|
||||
to="passbook_core.Outlet",
|
||||
),
|
||||
),
|
||||
],
|
||||
bases=("passbook_policies.policybindingmodel",),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="user",
|
||||
name="groups",
|
||||
field=models.ManyToManyField(to="passbook_core.Group"),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="user",
|
||||
name="inlets",
|
||||
field=models.ManyToManyField(
|
||||
through="passbook_core.UserInletConnection", to="passbook_core.Inlet"
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="user",
|
||||
name="user_permissions",
|
||||
@ -347,33 +377,74 @@ class Migration(migrations.Migration):
|
||||
),
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="PropertyMappingBinding",
|
||||
name="UserSourceConnection",
|
||||
fields=[
|
||||
(
|
||||
"uuid",
|
||||
models.UUIDField(
|
||||
default=uuid.uuid4,
|
||||
editable=False,
|
||||
"id",
|
||||
models.AutoField(
|
||||
auto_created=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
verbose_name="ID",
|
||||
),
|
||||
),
|
||||
("order", models.IntegerField(default=0)),
|
||||
("created", models.DateTimeField(auto_now_add=True)),
|
||||
("last_updated", models.DateTimeField(auto_now=True)),
|
||||
(
|
||||
"outlet",
|
||||
"user",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="passbook_core.Outlet",
|
||||
to=settings.AUTH_USER_MODEL,
|
||||
),
|
||||
),
|
||||
(
|
||||
"property_mapping",
|
||||
"source",
|
||||
models.ForeignKey(
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
to="passbook_core.PropertyMapping",
|
||||
to="passbook_core.Source",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={"unique_together": {("property_mapping", "outlet", "order")},},
|
||||
options={"unique_together": {("user", "source")},},
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name="Application",
|
||||
fields=[
|
||||
(
|
||||
"policymodel_ptr",
|
||||
models.OneToOneField(
|
||||
auto_created=True,
|
||||
on_delete=django.db.models.deletion.CASCADE,
|
||||
parent_link=True,
|
||||
primary_key=True,
|
||||
serialize=False,
|
||||
to="passbook_core.PolicyModel",
|
||||
),
|
||||
),
|
||||
("name", models.TextField()),
|
||||
("slug", models.SlugField()),
|
||||
("launch_url", models.URLField(blank=True, null=True)),
|
||||
("icon_url", models.TextField(blank=True, null=True)),
|
||||
("skip_authorization", models.BooleanField(default=False)),
|
||||
(
|
||||
"provider",
|
||||
models.OneToOneField(
|
||||
blank=True,
|
||||
default=None,
|
||||
null=True,
|
||||
on_delete=django.db.models.deletion.SET_DEFAULT,
|
||||
to="passbook_core.Provider",
|
||||
),
|
||||
),
|
||||
],
|
||||
options={"abstract": False,},
|
||||
bases=("passbook_core.policymodel",),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="user",
|
||||
name="sources",
|
||||
field=models.ManyToManyField(
|
||||
through="passbook_core.UserSourceConnection", to="passbook_core.Source"
|
||||
),
|
||||
),
|
||||
]
|
||||
|
17
passbook/core/migrations/0002_auto_20191010_1058.py
Normal file
17
passbook/core/migrations/0002_auto_20191010_1058.py
Normal file
@ -0,0 +1,17 @@
|
||||
# Generated by Django 2.2.6 on 2019-10-10 10:58
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("passbook_core", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterModelOptions(
|
||||
name="user",
|
||||
options={"permissions": (("reset_user_password", "Reset Password"),)},
|
||||
),
|
||||
]
|
18
passbook/core/migrations/0002_nonce_description.py
Normal file
18
passbook/core/migrations/0002_nonce_description.py
Normal file
@ -0,0 +1,18 @@
|
||||
# Generated by Django 2.2.6 on 2019-10-10 11:48
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("passbook_core", "0001_initial"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="nonce",
|
||||
name="description",
|
||||
field=models.TextField(blank=True, default=""),
|
||||
),
|
||||
]
|
31
passbook/core/migrations/0003_auto_20191011_0914.py
Normal file
31
passbook/core/migrations/0003_auto_20191011_0914.py
Normal file
@ -0,0 +1,31 @@
|
||||
# Generated by Django 2.2.6 on 2019-10-11 09:14
|
||||
|
||||
import django.contrib.postgres.fields.jsonb
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("passbook_core", "0002_nonce_description"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name="group", old_name="tags", new_name="attributes",
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="source",
|
||||
name="property_mappings",
|
||||
field=models.ManyToManyField(
|
||||
blank=True, default=None, to="passbook_core.PropertyMapping"
|
||||
),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="user",
|
||||
name="attributes",
|
||||
field=django.contrib.postgres.fields.jsonb.JSONField(
|
||||
blank=True, default=dict
|
||||
),
|
||||
),
|
||||
]
|
13
passbook/core/migrations/0003_merge_20191010_1541.py
Normal file
13
passbook/core/migrations/0003_merge_20191010_1541.py
Normal file
@ -0,0 +1,13 @@
|
||||
# Generated by Django 2.2.6 on 2019-10-10 15:41
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("passbook_core", "0002_auto_20191010_1058"),
|
||||
("passbook_core", "0002_nonce_description"),
|
||||
]
|
||||
|
||||
operations = []
|
14
passbook/core/migrations/0004_remove_policy_action.py
Normal file
14
passbook/core/migrations/0004_remove_policy_action.py
Normal file
@ -0,0 +1,14 @@
|
||||
# Generated by Django 2.2.6 on 2019-10-14 11:56
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("passbook_core", "0003_auto_20191011_0914"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RemoveField(model_name="policy", name="action",),
|
||||
]
|
13
passbook/core/migrations/0005_merge_20191025_2022.py
Normal file
13
passbook/core/migrations/0005_merge_20191025_2022.py
Normal file
@ -0,0 +1,13 @@
|
||||
# Generated by Django 2.2.6 on 2019-10-25 20:22
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("passbook_core", "0004_remove_policy_action"),
|
||||
("passbook_core", "0003_merge_20191010_1541"),
|
||||
]
|
||||
|
||||
operations = []
|
19
passbook/core/migrations/0006_propertymapping_template.py
Normal file
19
passbook/core/migrations/0006_propertymapping_template.py
Normal file
@ -0,0 +1,19 @@
|
||||
# Generated by Django 3.0.3 on 2020-02-17 16:15
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("passbook_core", "0005_merge_20191025_2022"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="propertymapping",
|
||||
name="template",
|
||||
field=models.TextField(default=""),
|
||||
preserve_default=False,
|
||||
),
|
||||
]
|
16
passbook/core/migrations/0007_auto_20200217_1934.py
Normal file
16
passbook/core/migrations/0007_auto_20200217_1934.py
Normal file
@ -0,0 +1,16 @@
|
||||
# Generated by Django 3.0.3 on 2020-02-17 19:34
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("passbook_core", "0006_propertymapping_template"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name="propertymapping", old_name="template", new_name="expression",
|
||||
),
|
||||
]
|
29
passbook/core/migrations/0008_auto_20200220_1242.py
Normal file
29
passbook/core/migrations/0008_auto_20200220_1242.py
Normal file
@ -0,0 +1,29 @@
|
||||
# Generated by Django 3.0.3 on 2020-02-20 12:42
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("passbook_core", "0007_auto_20200217_1934"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.RenameField(
|
||||
model_name="application", old_name="icon_url", new_name="meta_icon_url",
|
||||
),
|
||||
migrations.RenameField(
|
||||
model_name="application", old_name="launch_url", new_name="meta_launch_url",
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="application",
|
||||
name="meta_description",
|
||||
field=models.TextField(blank=True, null=True),
|
||||
),
|
||||
migrations.AddField(
|
||||
model_name="application",
|
||||
name="meta_publisher",
|
||||
field=models.TextField(blank=True, null=True),
|
||||
),
|
||||
]
|
52
passbook/core/migrations/0009_auto_20200221_1410.py
Normal file
52
passbook/core/migrations/0009_auto_20200221_1410.py
Normal file
@ -0,0 +1,52 @@
|
||||
# Generated by Django 3.0.3 on 2020-02-21 14:10
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("passbook_core", "0008_auto_20200220_1242"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="application",
|
||||
name="name",
|
||||
field=models.TextField(help_text="Application's display Name."),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="application",
|
||||
name="slug",
|
||||
field=models.SlugField(
|
||||
help_text="Internal application name, used in URLs."
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="factor",
|
||||
name="name",
|
||||
field=models.TextField(help_text="Factor's display Name."),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="factor",
|
||||
name="slug",
|
||||
field=models.SlugField(
|
||||
help_text="Internal factor name, used in URLs.", unique=True
|
||||
),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="source",
|
||||
name="name",
|
||||
field=models.TextField(help_text="Source's display Name."),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="source",
|
||||
name="slug",
|
||||
field=models.SlugField(help_text="Internal source name, used in URLs."),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="user",
|
||||
name="name",
|
||||
field=models.TextField(help_text="User's display name."),
|
||||
),
|
||||
]
|
33
passbook/core/migrations/0010_auto_20200221_2208.py
Normal file
33
passbook/core/migrations/0010_auto_20200221_2208.py
Normal file
@ -0,0 +1,33 @@
|
||||
# Generated by Django 3.0.3 on 2020-02-21 22:08
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("passbook_core", "0009_auto_20200221_1410"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterField(
|
||||
model_name="application",
|
||||
name="meta_description",
|
||||
field=models.TextField(blank=True, default=""),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="application",
|
||||
name="meta_icon_url",
|
||||
field=models.TextField(blank=True, default=""),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="application",
|
||||
name="meta_launch_url",
|
||||
field=models.URLField(blank=True, default=""),
|
||||
),
|
||||
migrations.AlterField(
|
||||
model_name="application",
|
||||
name="meta_publisher",
|
||||
field=models.TextField(blank=True, default=""),
|
||||
),
|
||||
]
|
27
passbook/core/migrations/0011_auto_20200222_1822.py
Normal file
27
passbook/core/migrations/0011_auto_20200222_1822.py
Normal file
@ -0,0 +1,27 @@
|
||||
# Generated by Django 3.0.3 on 2020-02-22 18:22
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
def fix_application_null(apps, schema_editor):
|
||||
"""Fix Application meta_fields being null"""
|
||||
Application = apps.get_model("passbook_core", "Application")
|
||||
for app in Application.objects.all():
|
||||
if app.meta_launch_url is None:
|
||||
app.meta_launch_url = ""
|
||||
if app.meta_icon_url is None:
|
||||
app.meta_icon_url = ""
|
||||
if app.meta_description is None:
|
||||
app.meta_description = ""
|
||||
if app.meta_publisher is None:
|
||||
app.meta_publisher = ""
|
||||
app.save()
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("passbook_core", "0010_auto_20200221_2208"),
|
||||
]
|
||||
|
||||
operations = [migrations.RunPython(fix_application_null)]
|
14
passbook/core/migrations/0012_delete_factor.py
Normal file
14
passbook/core/migrations/0012_delete_factor.py
Normal file
@ -0,0 +1,14 @@
|
||||
# Generated by Django 3.0.3 on 2020-05-08 17:58
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("passbook_core", "0011_auto_20200222_1822"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.DeleteModel(name="Factor",),
|
||||
]
|
16
passbook/core/migrations/0013_delete_debugpolicy.py
Normal file
16
passbook/core/migrations/0013_delete_debugpolicy.py
Normal file
@ -0,0 +1,16 @@
|
||||
# Generated by Django 3.0.5 on 2020-05-10 10:01
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("passbook_policies", "0003_auto_20200508_1642"),
|
||||
("passbook_stages_password", "0001_initial"),
|
||||
("passbook_core", "0012_delete_factor"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.DeleteModel(name="DebugPolicy",),
|
||||
]
|
14
passbook/core/migrations/0014_delete_invitation.py
Normal file
14
passbook/core/migrations/0014_delete_invitation.py
Normal file
@ -0,0 +1,14 @@
|
||||
# Generated by Django 3.0.5 on 2020-05-11 19:57
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("passbook_core", "0013_delete_debugpolicy"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.DeleteModel(name="Invitation",),
|
||||
]
|
@ -10,6 +10,7 @@ from django.db import models
|
||||
from django.http import HttpRequest
|
||||
from django.utils.timezone import now
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django_prometheus.models import ExportModelOperationsMixin
|
||||
from guardian.mixins import GuardianUserMixin
|
||||
from jinja2 import Undefined
|
||||
from jinja2.exceptions import TemplateSyntaxError, UndefinedError
|
||||
@ -21,18 +22,19 @@ from passbook.core.exceptions import PropertyMappingExpressionException
|
||||
from passbook.core.signals import password_changed
|
||||
from passbook.core.types import UILoginButton, UIUserSettings
|
||||
from passbook.lib.models import CreatedUpdatedModel, UUIDModel
|
||||
from passbook.policies.models import PolicyBindingModel
|
||||
from passbook.policies.exceptions import PolicyException
|
||||
from passbook.policies.types import PolicyRequest, PolicyResult
|
||||
|
||||
LOGGER = get_logger()
|
||||
NATIVE_ENVIRONMENT = NativeEnvironment()
|
||||
|
||||
|
||||
def default_token_duration():
|
||||
"""Default duration a Token is valid"""
|
||||
def default_nonce_duration():
|
||||
"""Default duration a Nonce is valid"""
|
||||
return now() + timedelta(minutes=30)
|
||||
|
||||
|
||||
class Group(UUIDModel):
|
||||
class Group(ExportModelOperationsMixin("group"), UUIDModel):
|
||||
"""Custom Group model which supports a basic hierarchy"""
|
||||
|
||||
name = models.CharField(_("name"), max_length=80)
|
||||
@ -53,13 +55,13 @@ class Group(UUIDModel):
|
||||
unique_together = (("name", "parent",),)
|
||||
|
||||
|
||||
class User(GuardianUserMixin, AbstractUser):
|
||||
class User(ExportModelOperationsMixin("user"), GuardianUserMixin, AbstractUser):
|
||||
"""Custom User model to allow easier adding o f user-based settings"""
|
||||
|
||||
uuid = models.UUIDField(default=uuid4, editable=False)
|
||||
name = models.TextField(help_text=_("User's display name."))
|
||||
|
||||
inlets = models.ManyToManyField("Inlet", through="UserInletConnection")
|
||||
sources = models.ManyToManyField("Source", through="UserSourceConnection")
|
||||
groups = models.ManyToManyField("Group")
|
||||
password_change_date = models.DateTimeField(auto_now_add=True)
|
||||
|
||||
@ -76,7 +78,29 @@ class User(GuardianUserMixin, AbstractUser):
|
||||
permissions = (("reset_user_password", "Reset Password"),)
|
||||
|
||||
|
||||
class Application(PolicyBindingModel):
|
||||
class Provider(ExportModelOperationsMixin("provider"), models.Model):
|
||||
"""Application-independent Provider instance. For example SAML2 Remote, OAuth2 Application"""
|
||||
|
||||
property_mappings = models.ManyToManyField(
|
||||
"PropertyMapping", default=None, blank=True
|
||||
)
|
||||
|
||||
objects = InheritanceManager()
|
||||
|
||||
# This class defines no field for easier inheritance
|
||||
def __str__(self):
|
||||
if hasattr(self, "name"):
|
||||
return getattr(self, "name")
|
||||
return super().__str__()
|
||||
|
||||
|
||||
class PolicyModel(UUIDModel, CreatedUpdatedModel):
|
||||
"""Base model which can have policies applied to it"""
|
||||
|
||||
policies = models.ManyToManyField("Policy", blank=True)
|
||||
|
||||
|
||||
class Application(ExportModelOperationsMixin("application"), PolicyModel):
|
||||
"""Every Application which uses passbook for authentication/identification/authorization
|
||||
needs an Application record. Other authentication types can subclass this Model to
|
||||
add custom fields and other properties"""
|
||||
@ -84,8 +108,8 @@ class Application(PolicyBindingModel):
|
||||
name = models.TextField(help_text=_("Application's display Name."))
|
||||
slug = models.SlugField(help_text=_("Internal application name, used in URLs."))
|
||||
skip_authorization = models.BooleanField(default=False)
|
||||
outlet = models.OneToOneField(
|
||||
"Outlet", null=True, blank=True, default=None, on_delete=models.SET_DEFAULT
|
||||
provider = models.OneToOneField(
|
||||
"Provider", null=True, blank=True, default=None, on_delete=models.SET_DEFAULT
|
||||
)
|
||||
|
||||
meta_launch_url = models.URLField(default="", blank=True)
|
||||
@ -95,20 +119,20 @@ class Application(PolicyBindingModel):
|
||||
|
||||
objects = InheritanceManager()
|
||||
|
||||
def get_outlet(self) -> Optional["Outlet"]:
|
||||
"""Get casted outlet instance"""
|
||||
if not self.outlet:
|
||||
def get_provider(self) -> Optional[Provider]:
|
||||
"""Get casted provider instance"""
|
||||
if not self.provider:
|
||||
return None
|
||||
return Outlet.objects.get_subclass(pk=self.outlet.pk)
|
||||
return Provider.objects.get_subclass(pk=self.provider.pk)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
|
||||
class Inlet(PolicyBindingModel):
|
||||
class Source(ExportModelOperationsMixin("source"), PolicyModel):
|
||||
"""Base Authentication source, i.e. an OAuth Provider, SAML Remote or LDAP Server"""
|
||||
|
||||
name = models.TextField(help_text=_("Inlet's display Name."))
|
||||
name = models.TextField(help_text=_("Source's display Name."))
|
||||
slug = models.SlugField(help_text=_("Internal source name, used in URLs."))
|
||||
|
||||
enabled = models.BooleanField(default=True)
|
||||
@ -141,69 +165,56 @@ class Inlet(PolicyBindingModel):
|
||||
return self.name
|
||||
|
||||
|
||||
class UserInletConnection(CreatedUpdatedModel):
|
||||
"""Connection between User and Inlet."""
|
||||
class UserSourceConnection(CreatedUpdatedModel):
|
||||
"""Connection between User and Source."""
|
||||
|
||||
user = models.ForeignKey(User, on_delete=models.CASCADE)
|
||||
inlet = models.ForeignKey(Inlet, on_delete=models.CASCADE)
|
||||
source = models.ForeignKey(Source, on_delete=models.CASCADE)
|
||||
|
||||
class Meta:
|
||||
|
||||
unique_together = (("user", "inlet"),)
|
||||
unique_together = (("user", "source"),)
|
||||
|
||||
|
||||
class Token(UUIDModel):
|
||||
class Policy(ExportModelOperationsMixin("policy"), UUIDModel, CreatedUpdatedModel):
|
||||
"""Policies which specify if a user is authorized to use an Application. Can be overridden by
|
||||
other types to add other fields, more logic, etc."""
|
||||
|
||||
name = models.TextField(blank=True, null=True)
|
||||
negate = models.BooleanField(default=False)
|
||||
order = models.IntegerField(default=0)
|
||||
timeout = models.IntegerField(default=30)
|
||||
|
||||
objects = InheritanceManager()
|
||||
|
||||
def __str__(self):
|
||||
return f"Policy {self.name}"
|
||||
|
||||
def passes(self, request: PolicyRequest) -> PolicyResult:
|
||||
"""Check if user instance passes this policy"""
|
||||
raise PolicyException()
|
||||
|
||||
|
||||
class Nonce(ExportModelOperationsMixin("nonce"), UUIDModel):
|
||||
"""One-time link for password resets/sign-up-confirmations"""
|
||||
|
||||
expires = models.DateTimeField(default=default_token_duration)
|
||||
user = models.ForeignKey("User", on_delete=models.CASCADE, related_name="+")
|
||||
expires = models.DateTimeField(default=default_nonce_duration)
|
||||
user = models.ForeignKey("User", on_delete=models.CASCADE)
|
||||
expiring = models.BooleanField(default=True)
|
||||
description = models.TextField(default="", blank=True)
|
||||
|
||||
@property
|
||||
def is_expired(self) -> bool:
|
||||
"""Check if token is expired yet."""
|
||||
"""Check if nonce is expired yet."""
|
||||
return now() > self.expires
|
||||
|
||||
def __str__(self):
|
||||
return f"Token f{self.uuid.hex} {self.description} (expires={self.expires})"
|
||||
return f"Nonce f{self.uuid.hex} {self.description} (expires={self.expires})"
|
||||
|
||||
class Meta:
|
||||
|
||||
verbose_name = _("Token")
|
||||
verbose_name_plural = _("Tokens")
|
||||
|
||||
|
||||
class Outlet(models.Model):
|
||||
"""Application-independent Outlet instance. For example SAML2 Remote, OAuth2 Application"""
|
||||
|
||||
property_mappings = models.ManyToManyField(
|
||||
"PropertyMapping", default=None, blank=True
|
||||
)
|
||||
|
||||
objects = InheritanceManager()
|
||||
|
||||
# This class defines no field for easier inheritance
|
||||
def __str__(self):
|
||||
if hasattr(self, "name"):
|
||||
return getattr(self, "name")
|
||||
return super().__str__()
|
||||
|
||||
|
||||
class PropertyMappingBinding(UUIDModel):
|
||||
"""Binds a PropertyMapping instance to an outlet"""
|
||||
|
||||
property_mapping = models.ForeignKey("PropertyMapping", on_delete=models.CASCADE)
|
||||
outlet = models.ForeignKey("Outlet", on_delete=models.CASCADE)
|
||||
|
||||
order = models.IntegerField(default=0)
|
||||
|
||||
def __str__(self):
|
||||
return f"PropertyMapping Binding p={self.property_mapping} outlet={self.outlet}"
|
||||
|
||||
class Meta:
|
||||
|
||||
unique_together = (("property_mapping", "outlet", "order"),)
|
||||
verbose_name = _("Nonce")
|
||||
verbose_name_plural = _("Nonces")
|
||||
|
||||
|
||||
class PropertyMapping(UUIDModel):
|
||||
|
@ -17,7 +17,7 @@ password_changed = Signal(providing_args=["user", "password"])
|
||||
# pylint: disable=unused-argument
|
||||
def invalidate_policy_cache(sender, instance, **_):
|
||||
"""Invalidate Policy cache when policy is updated"""
|
||||
from passbook.policies.models import Policy
|
||||
from passbook.core.models import Policy
|
||||
from passbook.policies.process import cache_key
|
||||
|
||||
if isinstance(instance, Policy):
|
||||
|
@ -2,14 +2,14 @@
|
||||
from django.utils.timezone import now
|
||||
from structlog import get_logger
|
||||
|
||||
from passbook.core.models import Token
|
||||
from passbook.core.models import Nonce
|
||||
from passbook.root.celery import CELERY_APP
|
||||
|
||||
LOGGER = get_logger()
|
||||
|
||||
|
||||
@CELERY_APP.task()
|
||||
def clean_tokens():
|
||||
"""Remove expired tokens"""
|
||||
amount, _ = Token.objects.filter(expires__lt=now(), expiring=True).delete()
|
||||
LOGGER.debug("Deleted expired tokens", amount=amount)
|
||||
def clean_nonces():
|
||||
"""Remove expired nonces"""
|
||||
amount, _ = Nonce.objects.filter(expires__lt=now(), expiring=True).delete()
|
||||
LOGGER.debug("Deleted expired nonces", amount=amount)
|
||||
|
@ -34,17 +34,17 @@
|
||||
</ul>
|
||||
</section>
|
||||
{% endif %}
|
||||
{% user_inlets as user_inlets_loc %}
|
||||
{% if user_inlets_loc %}
|
||||
{% user_sources as user_sources_loc %}
|
||||
{% if user_sources_loc %}
|
||||
<section class="pf-c-nav__section">
|
||||
<h2 class="pf-c-nav__section-title">{% trans 'Sources' %}</h2>
|
||||
<ul class="pf-c-nav__list">
|
||||
{% for inlet in user_inlets_loc %}
|
||||
{% for source in user_sources_loc %}
|
||||
<li class="pf-c-nav__item">
|
||||
<a href="{{ inlet.view_name }}"
|
||||
<a href="{{ source.view_name }}"
|
||||
class="pf-c-nav__link {% if user_settings.view_name == request.get_full_path %} pf-m-current {% endif %}">
|
||||
<i class="{{ inlet.icon }}"></i>
|
||||
{{ inlet.name }}
|
||||
<i class="{{ source.icon }}"></i>
|
||||
{{ source.name }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
|
@ -4,7 +4,7 @@ from typing import Iterable, List
|
||||
from django import template
|
||||
from django.template.context import RequestContext
|
||||
|
||||
from passbook.core.models import Inlet
|
||||
from passbook.core.models import Source
|
||||
from passbook.core.types import UIUserSettings
|
||||
from passbook.flows.models import Stage
|
||||
from passbook.policies.engine import PolicyEngine
|
||||
@ -27,14 +27,14 @@ def user_stages(context: RequestContext) -> List[UIUserSettings]:
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
def user_inlets(context: RequestContext) -> List[UIUserSettings]:
|
||||
"""Return a list of all inlets which are enabled for the user"""
|
||||
def user_sources(context: RequestContext) -> List[UIUserSettings]:
|
||||
"""Return a list of all sources which are enabled for the user"""
|
||||
user = context.get("request").user
|
||||
_all_inlets: Iterable[(Inlet)] = (
|
||||
(Inlet).objects.filter(enabled=True).select_subclasses()
|
||||
_all_sources: Iterable[Source] = (
|
||||
Source.objects.filter(enabled=True).select_subclasses()
|
||||
)
|
||||
matching_inlets: List[UIUserSettings] = []
|
||||
for source in _all_inlets:
|
||||
matching_sources: List[UIUserSettings] = []
|
||||
for source in _all_sources:
|
||||
user_settings = source.ui_user_settings
|
||||
if not user_settings:
|
||||
continue
|
||||
@ -43,5 +43,5 @@ def user_inlets(context: RequestContext) -> List[UIUserSettings]:
|
||||
)
|
||||
policy_engine.build()
|
||||
if policy_engine.passing:
|
||||
matching_inlets.append(user_settings)
|
||||
return matching_inlets
|
||||
matching_sources.append(user_settings)
|
||||
return matching_sources
|
||||
|
@ -6,7 +6,7 @@ from django.http import HttpRequest
|
||||
from django.utils.translation import gettext as _
|
||||
from structlog import get_logger
|
||||
|
||||
from passbook.core.models import Application, Outlet, User
|
||||
from passbook.core.models import Application, Provider, User
|
||||
from passbook.policies.engine import PolicyEngine
|
||||
|
||||
LOGGER = get_logger()
|
||||
@ -14,19 +14,22 @@ LOGGER = get_logger()
|
||||
|
||||
class AccessMixin:
|
||||
"""Mixin class for usage in Authorization views.
|
||||
Outlet functions to check application access, etc"""
|
||||
Provider functions to check application access, etc"""
|
||||
|
||||
# request is set by view but since this Mixin has no base class
|
||||
request: HttpRequest = None
|
||||
|
||||
def outlet_to_application(self, outlet: Outlet) -> Application:
|
||||
"""Lookup application assigned to outlet, throw error if no application assigned"""
|
||||
def provider_to_application(self, provider: Provider) -> Application:
|
||||
"""Lookup application assigned to provider, throw error if no application assigned"""
|
||||
try:
|
||||
return outlet.application
|
||||
return provider.application
|
||||
except Application.DoesNotExist as exc:
|
||||
messages.error(
|
||||
self.request,
|
||||
_('Outlet "%(name)s" has no application assigned' % {"name": outlet}),
|
||||
_(
|
||||
'Provider "%(name)s" has no application assigned'
|
||||
% {"name": provider}
|
||||
),
|
||||
)
|
||||
raise exc
|
||||
|
||||
|
Reference in New Issue
Block a user