factors: -> stage
This commit is contained in:
@ -1,30 +0,0 @@
|
||||
"""Factor API Views"""
|
||||
from rest_framework.serializers import ModelSerializer, SerializerMethodField
|
||||
from rest_framework.viewsets import ReadOnlyModelViewSet
|
||||
|
||||
from passbook.core.models import Factor
|
||||
|
||||
|
||||
class FactorSerializer(ModelSerializer):
|
||||
"""Factor 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("factor", "")
|
||||
|
||||
class Meta:
|
||||
|
||||
model = Factor
|
||||
fields = ["pk", "name", "slug", "order", "enabled", "__type__"]
|
||||
|
||||
|
||||
class FactorViewSet(ReadOnlyModelViewSet):
|
||||
"""Factor Viewset"""
|
||||
|
||||
queryset = Factor.objects.all()
|
||||
serializer_class = FactorSerializer
|
||||
|
||||
def get_queryset(self):
|
||||
return Factor.objects.select_subclasses()
|
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",),
|
||||
]
|
@ -103,30 +103,6 @@ class PolicyModel(UUIDModel, CreatedUpdatedModel):
|
||||
policies = models.ManyToManyField("Policy", blank=True)
|
||||
|
||||
|
||||
class Factor(ExportModelOperationsMixin("factor"), PolicyModel):
|
||||
"""Authentication factor, multiple instances of the same Factor can be used"""
|
||||
|
||||
name = models.TextField(help_text=_("Factor's display Name."))
|
||||
slug = models.SlugField(
|
||||
unique=True, help_text=_("Internal factor name, used in URLs.")
|
||||
)
|
||||
order = models.IntegerField()
|
||||
enabled = models.BooleanField(default=True)
|
||||
|
||||
objects = InheritanceManager()
|
||||
type = ""
|
||||
form = ""
|
||||
|
||||
@property
|
||||
def ui_user_settings(self) -> Optional[UIUserSettings]:
|
||||
"""Entrypoint to integrate with User settings. Can either return None if no
|
||||
user settings are available, or an instanace of UIUserSettings."""
|
||||
return None
|
||||
|
||||
def __str__(self):
|
||||
return f"Factor {self.slug}"
|
||||
|
||||
|
||||
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
|
||||
|
@ -18,16 +18,16 @@
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
{% user_factors as user_factors_loc %}
|
||||
{% if user_factors_loc %}
|
||||
{% user_stages as user_stages_loc %}
|
||||
{% if user_stages_loc %}
|
||||
<section class="pf-c-nav__section">
|
||||
<h2 class="pf-c-nav__section-title">{% trans 'Factors' %}</h2>
|
||||
<ul class="pf-c-nav__list">
|
||||
{% for factor in user_factors_loc %}
|
||||
{% for stage in user_stages_loc %}
|
||||
<li class="pf-c-nav__item">
|
||||
<a href="{% url factor.view_name %}" class="pf-c-nav__link {% is_active factor.view_name %}">
|
||||
<i class="{{ factor.icon }}"></i>
|
||||
{{ factor.name }}
|
||||
<a href="{% url stage.view_name %}" class="pf-c-nav__link {% is_active stage.view_name %}">
|
||||
<i class="{{ stage.icon }}"></i>
|
||||
{{ stage.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 Factor, Source
|
||||
from passbook.core.models import Source
|
||||
from passbook.core.types import UIUserSettings
|
||||
from passbook.policies.engine import PolicyEngine
|
||||
|
||||
@ -12,24 +12,24 @@ register = template.Library()
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
def user_factors(context: RequestContext) -> List[UIUserSettings]:
|
||||
"""Return list of all factors which apply to user"""
|
||||
user = context.get("request").user
|
||||
_all_factors: Iterable[Factor] = (
|
||||
Factor.objects.filter(enabled=True).order_by("order").select_subclasses()
|
||||
)
|
||||
matching_factors: List[UIUserSettings] = []
|
||||
for factor in _all_factors:
|
||||
user_settings = factor.ui_user_settings
|
||||
if not user_settings:
|
||||
continue
|
||||
policy_engine = PolicyEngine(
|
||||
factor.policies.all(), user, context.get("request")
|
||||
)
|
||||
policy_engine.build()
|
||||
if policy_engine.passing:
|
||||
matching_factors.append(user_settings)
|
||||
return matching_factors
|
||||
# pylint: disable=unused-argument
|
||||
def user_stages(context: RequestContext) -> List[UIUserSettings]:
|
||||
"""Return list of all stages which apply to user"""
|
||||
# TODO: Rewrite this based on flows
|
||||
# user = context.get("request").user
|
||||
# _all_stages: Iterable[Stage] = (Stage.objects.all().select_subclasses())
|
||||
matching_stages: List[UIUserSettings] = []
|
||||
# for stage in _all_stages:
|
||||
# user_settings = stage.ui_user_settings
|
||||
# if not user_settings:
|
||||
# continue
|
||||
# policy_engine = PolicyEngine(
|
||||
# stage.policies.all(), user, context.get("request")
|
||||
# )
|
||||
# policy_engine.build()
|
||||
# if policy_engine.passing:
|
||||
# matching_stages.append(user_settings)
|
||||
return matching_stages
|
||||
|
||||
|
||||
@register.simple_tag(takes_context=True)
|
||||
@ -40,12 +40,12 @@ def user_sources(context: RequestContext) -> List[UIUserSettings]:
|
||||
Source.objects.filter(enabled=True).select_subclasses()
|
||||
)
|
||||
matching_sources: List[UIUserSettings] = []
|
||||
for factor in _all_sources:
|
||||
user_settings = factor.ui_user_settings
|
||||
for source in _all_sources:
|
||||
user_settings = source.ui_user_settings
|
||||
if not user_settings:
|
||||
continue
|
||||
policy_engine = PolicyEngine(
|
||||
factor.policies.all(), user, context.get("request")
|
||||
source.policies.all(), user, context.get("request")
|
||||
)
|
||||
policy_engine.build()
|
||||
if policy_engine.passing:
|
||||
|
@ -5,7 +5,7 @@ from typing import Optional
|
||||
|
||||
@dataclass
|
||||
class UIUserSettings:
|
||||
"""Dataclass for Factor and Source's user_settings"""
|
||||
"""Dataclass for Stage and Source's user_settings"""
|
||||
|
||||
name: str
|
||||
icon: str
|
||||
|
@ -15,12 +15,12 @@ from structlog import get_logger
|
||||
from passbook.core.forms.authentication import LoginForm, SignUpForm
|
||||
from passbook.core.models import Invitation, Nonce, Source, User
|
||||
from passbook.core.signals import invitation_used, user_signed_up
|
||||
from passbook.factors.password.exceptions import PasswordPolicyInvalid
|
||||
from passbook.flows.models import Flow, FlowDesignation
|
||||
from passbook.flows.planner import PLAN_CONTEXT_PENDING_USER, FlowPlanner
|
||||
from passbook.flows.views import SESSION_KEY_PLAN
|
||||
from passbook.lib.config import CONFIG
|
||||
from passbook.lib.utils.urls import redirect_with_qs
|
||||
from passbook.stages.password.exceptions import PasswordPolicyInvalid
|
||||
|
||||
LOGGER = get_logger()
|
||||
|
||||
|
@ -10,8 +10,8 @@ from django.utils.translation import gettext as _
|
||||
from django.views.generic import DeleteView, FormView, UpdateView
|
||||
|
||||
from passbook.core.forms.users import PasswordChangeForm, UserDetailForm
|
||||
from passbook.factors.password.exceptions import PasswordPolicyInvalid
|
||||
from passbook.lib.config import CONFIG
|
||||
from passbook.stages.password.exceptions import PasswordPolicyInvalid
|
||||
|
||||
|
||||
class UserSettingsView(SuccessMessageMixin, LoginRequiredMixin, UpdateView):
|
||||
|
Reference in New Issue
Block a user