policies: remove redundant policies which can be easily implemented with expressions
This commit is contained in:
parent
0f6dd33a6b
commit
7f3d0113c2
|
@ -24,13 +24,10 @@ from passbook.factors.otp.api import OTPFactorViewSet
|
||||||
from passbook.factors.password.api import PasswordFactorViewSet
|
from passbook.factors.password.api import PasswordFactorViewSet
|
||||||
from passbook.lib.utils.reflection import get_apps
|
from passbook.lib.utils.reflection import get_apps
|
||||||
from passbook.policies.expiry.api import PasswordExpiryPolicyViewSet
|
from passbook.policies.expiry.api import PasswordExpiryPolicyViewSet
|
||||||
from passbook.policies.group.api import GroupMembershipPolicyViewSet
|
|
||||||
from passbook.policies.expression.api import ExpressionPolicyViewSet
|
from passbook.policies.expression.api import ExpressionPolicyViewSet
|
||||||
from passbook.policies.hibp.api import HaveIBeenPwendPolicyViewSet
|
from passbook.policies.hibp.api import HaveIBeenPwendPolicyViewSet
|
||||||
from passbook.policies.matcher.api import FieldMatcherPolicyViewSet
|
|
||||||
from passbook.policies.password.api import PasswordPolicyViewSet
|
from passbook.policies.password.api import PasswordPolicyViewSet
|
||||||
from passbook.policies.reputation.api import ReputationPolicyViewSet
|
from passbook.policies.reputation.api import ReputationPolicyViewSet
|
||||||
from passbook.policies.sso.api import SSOLoginPolicyViewSet
|
|
||||||
from passbook.policies.webhook.api import WebhookPolicyViewSet
|
from passbook.policies.webhook.api import WebhookPolicyViewSet
|
||||||
from passbook.providers.app_gw.api import ApplicationGatewayProviderViewSet
|
from passbook.providers.app_gw.api import ApplicationGatewayProviderViewSet
|
||||||
from passbook.providers.oauth.api import OAuth2ProviderViewSet
|
from passbook.providers.oauth.api import OAuth2ProviderViewSet
|
||||||
|
@ -58,12 +55,9 @@ router.register("sources/ldap", LDAPSourceViewSet)
|
||||||
router.register("sources/oauth", OAuthSourceViewSet)
|
router.register("sources/oauth", OAuthSourceViewSet)
|
||||||
router.register("policies/all", PolicyViewSet)
|
router.register("policies/all", PolicyViewSet)
|
||||||
router.register("policies/passwordexpiry", PasswordExpiryPolicyViewSet)
|
router.register("policies/passwordexpiry", PasswordExpiryPolicyViewSet)
|
||||||
router.register("policies/groupmembership", GroupMembershipPolicyViewSet)
|
|
||||||
router.register("policies/haveibeenpwned", HaveIBeenPwendPolicyViewSet)
|
router.register("policies/haveibeenpwned", HaveIBeenPwendPolicyViewSet)
|
||||||
router.register("policies/fieldmatcher", FieldMatcherPolicyViewSet)
|
|
||||||
router.register("policies/password", PasswordPolicyViewSet)
|
router.register("policies/password", PasswordPolicyViewSet)
|
||||||
router.register("policies/reputation", ReputationPolicyViewSet)
|
router.register("policies/reputation", ReputationPolicyViewSet)
|
||||||
router.register("policies/ssologin", SSOLoginPolicyViewSet)
|
|
||||||
router.register("policies/webhook", WebhookPolicyViewSet)
|
router.register("policies/webhook", WebhookPolicyViewSet)
|
||||||
router.register("policies/expression", ExpressionPolicyViewSet)
|
router.register("policies/expression", ExpressionPolicyViewSet)
|
||||||
router.register("providers/all", ProviderViewSet)
|
router.register("providers/all", ProviderViewSet)
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
"""autodiscover admin"""
|
|
||||||
from passbook.lib.admin import admin_autoregister
|
|
||||||
|
|
||||||
admin_autoregister("passbook_policies_group")
|
|
|
@ -1,21 +0,0 @@
|
||||||
"""Source API Views"""
|
|
||||||
from rest_framework.serializers import ModelSerializer
|
|
||||||
from rest_framework.viewsets import ModelViewSet
|
|
||||||
|
|
||||||
from passbook.policies.forms import GENERAL_SERIALIZER_FIELDS
|
|
||||||
from passbook.policies.group.models import GroupMembershipPolicy
|
|
||||||
|
|
||||||
|
|
||||||
class GroupMembershipPolicySerializer(ModelSerializer):
|
|
||||||
"""Group Membership Policy Serializer"""
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = GroupMembershipPolicy
|
|
||||||
fields = GENERAL_SERIALIZER_FIELDS + ["group"]
|
|
||||||
|
|
||||||
|
|
||||||
class GroupMembershipPolicyViewSet(ModelViewSet):
|
|
||||||
"""Source Viewset"""
|
|
||||||
|
|
||||||
queryset = GroupMembershipPolicy.objects.all()
|
|
||||||
serializer_class = GroupMembershipPolicySerializer
|
|
|
@ -1,11 +0,0 @@
|
||||||
"""passbook Group policy app config"""
|
|
||||||
|
|
||||||
from django.apps import AppConfig
|
|
||||||
|
|
||||||
|
|
||||||
class PassbookPoliciesGroupConfig(AppConfig):
|
|
||||||
"""passbook Group policy app config"""
|
|
||||||
|
|
||||||
name = "passbook.policies.group"
|
|
||||||
label = "passbook_policies_group"
|
|
||||||
verbose_name = "passbook Policies.Group"
|
|
|
@ -1,21 +0,0 @@
|
||||||
"""passbook Policy forms"""
|
|
||||||
|
|
||||||
from django import forms
|
|
||||||
|
|
||||||
from passbook.policies.forms import GENERAL_FIELDS
|
|
||||||
from passbook.policies.group.models import GroupMembershipPolicy
|
|
||||||
|
|
||||||
|
|
||||||
class GroupMembershipPolicyForm(forms.ModelForm):
|
|
||||||
"""GroupMembershipPolicy Form"""
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
|
|
||||||
model = GroupMembershipPolicy
|
|
||||||
fields = GENERAL_FIELDS + [
|
|
||||||
"group",
|
|
||||||
]
|
|
||||||
widgets = {
|
|
||||||
"name": forms.TextInput(),
|
|
||||||
"order": forms.NumberInput(),
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
# Generated by Django 2.2.6 on 2019-10-07 14:07
|
|
||||||
|
|
||||||
import django.db.models.deletion
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
initial = True
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
("passbook_core", "0001_initial"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name="GroupMembershipPolicy",
|
|
||||||
fields=[
|
|
||||||
(
|
|
||||||
"policy_ptr",
|
|
||||||
models.OneToOneField(
|
|
||||||
auto_created=True,
|
|
||||||
on_delete=django.db.models.deletion.CASCADE,
|
|
||||||
parent_link=True,
|
|
||||||
primary_key=True,
|
|
||||||
serialize=False,
|
|
||||||
to="passbook_core.Policy",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"group",
|
|
||||||
models.ForeignKey(
|
|
||||||
on_delete=django.db.models.deletion.CASCADE,
|
|
||||||
to="passbook_core.Group",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
"verbose_name": "Group Membership Policy",
|
|
||||||
"verbose_name_plural": "Group Membership Policies",
|
|
||||||
},
|
|
||||||
bases=("passbook_core.policy",),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,22 +0,0 @@
|
||||||
"""passbook group models models"""
|
|
||||||
from django.db import models
|
|
||||||
from django.utils.translation import gettext as _
|
|
||||||
|
|
||||||
from passbook.core.models import Group, Policy
|
|
||||||
from passbook.policies.struct import PolicyRequest, PolicyResult
|
|
||||||
|
|
||||||
|
|
||||||
class GroupMembershipPolicy(Policy):
|
|
||||||
"""Policy to check if the user is member in a certain group"""
|
|
||||||
|
|
||||||
group = models.ForeignKey(Group, on_delete=models.CASCADE)
|
|
||||||
|
|
||||||
form = "passbook.policies.group.forms.GroupMembershipPolicyForm"
|
|
||||||
|
|
||||||
def passes(self, request: PolicyRequest) -> PolicyResult:
|
|
||||||
return PolicyResult(self.group.user_set.filter(pk=request.user.pk).exists())
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
|
|
||||||
verbose_name = _("Group Membership Policy")
|
|
||||||
verbose_name_plural = _("Group Membership Policies")
|
|
|
@ -1,4 +0,0 @@
|
||||||
"""autodiscover admin"""
|
|
||||||
from passbook.lib.admin import admin_autoregister
|
|
||||||
|
|
||||||
admin_autoregister("passbook_policies_matcher")
|
|
|
@ -1,25 +0,0 @@
|
||||||
"""Source API Views"""
|
|
||||||
from rest_framework.serializers import ModelSerializer
|
|
||||||
from rest_framework.viewsets import ModelViewSet
|
|
||||||
|
|
||||||
from passbook.policies.forms import GENERAL_SERIALIZER_FIELDS
|
|
||||||
from passbook.policies.matcher.models import FieldMatcherPolicy
|
|
||||||
|
|
||||||
|
|
||||||
class FieldMatcherPolicySerializer(ModelSerializer):
|
|
||||||
"""Field Matcher Policy Serializer"""
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = FieldMatcherPolicy
|
|
||||||
fields = GENERAL_SERIALIZER_FIELDS + [
|
|
||||||
"user_field",
|
|
||||||
"match_action",
|
|
||||||
"value",
|
|
||||||
]
|
|
||||||
|
|
||||||
|
|
||||||
class FieldMatcherPolicyViewSet(ModelViewSet):
|
|
||||||
"""Source Viewset"""
|
|
||||||
|
|
||||||
queryset = FieldMatcherPolicy.objects.all()
|
|
||||||
serializer_class = FieldMatcherPolicySerializer
|
|
|
@ -1,11 +0,0 @@
|
||||||
"""passbook Matcher policy app config"""
|
|
||||||
|
|
||||||
from django.apps import AppConfig
|
|
||||||
|
|
||||||
|
|
||||||
class PassbookPoliciesMatcherConfig(AppConfig):
|
|
||||||
"""passbook Matcher policy app config"""
|
|
||||||
|
|
||||||
name = "passbook.policies.matcher"
|
|
||||||
label = "passbook_policies_matcher"
|
|
||||||
verbose_name = "passbook Policies.Matcher"
|
|
|
@ -1,23 +0,0 @@
|
||||||
"""passbook Policy forms"""
|
|
||||||
|
|
||||||
from django import forms
|
|
||||||
|
|
||||||
from passbook.policies.forms import GENERAL_FIELDS
|
|
||||||
from passbook.policies.matcher.models import FieldMatcherPolicy
|
|
||||||
|
|
||||||
|
|
||||||
class FieldMatcherPolicyForm(forms.ModelForm):
|
|
||||||
"""FieldMatcherPolicy Form"""
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
|
|
||||||
model = FieldMatcherPolicy
|
|
||||||
fields = GENERAL_FIELDS + [
|
|
||||||
"user_field",
|
|
||||||
"match_action",
|
|
||||||
"value",
|
|
||||||
]
|
|
||||||
widgets = {
|
|
||||||
"name": forms.TextInput(),
|
|
||||||
"value": forms.TextInput(),
|
|
||||||
}
|
|
|
@ -1,64 +0,0 @@
|
||||||
# Generated by Django 2.2.6 on 2019-10-07 14:07
|
|
||||||
|
|
||||||
import django.db.models.deletion
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
initial = True
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
("passbook_core", "0001_initial"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name="FieldMatcherPolicy",
|
|
||||||
fields=[
|
|
||||||
(
|
|
||||||
"policy_ptr",
|
|
||||||
models.OneToOneField(
|
|
||||||
auto_created=True,
|
|
||||||
on_delete=django.db.models.deletion.CASCADE,
|
|
||||||
parent_link=True,
|
|
||||||
primary_key=True,
|
|
||||||
serialize=False,
|
|
||||||
to="passbook_core.Policy",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"user_field",
|
|
||||||
models.TextField(
|
|
||||||
choices=[
|
|
||||||
("username", "Username"),
|
|
||||||
("name", "Name"),
|
|
||||||
("email", "E-Mail"),
|
|
||||||
("is_staff", "Is staff"),
|
|
||||||
("is_active", "Is active"),
|
|
||||||
("data_joined", "Date joined"),
|
|
||||||
]
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
"match_action",
|
|
||||||
models.CharField(
|
|
||||||
choices=[
|
|
||||||
("startswith", "Starts with"),
|
|
||||||
("endswith", "Ends with"),
|
|
||||||
("contains", "Contains"),
|
|
||||||
("regexp", "Regexp"),
|
|
||||||
("exact", "Exact"),
|
|
||||||
],
|
|
||||||
max_length=50,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
("value", models.TextField()),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
"verbose_name": "Field matcher Policy",
|
|
||||||
"verbose_name_plural": "Field matcher Policies",
|
|
||||||
},
|
|
||||||
bases=("passbook_core.policy",),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,83 +0,0 @@
|
||||||
"""user field matcher models"""
|
|
||||||
import re
|
|
||||||
|
|
||||||
from django.db import models
|
|
||||||
from django.utils.translation import gettext as _
|
|
||||||
from structlog import get_logger
|
|
||||||
|
|
||||||
from passbook.core.models import Policy
|
|
||||||
from passbook.policies.struct import PolicyRequest, PolicyResult
|
|
||||||
|
|
||||||
LOGGER = get_logger()
|
|
||||||
|
|
||||||
|
|
||||||
class FieldMatcherPolicy(Policy):
|
|
||||||
"""Policy which checks if a field of the User model matches/doesn't match a
|
|
||||||
certain pattern"""
|
|
||||||
|
|
||||||
MATCH_STARTSWITH = "startswith"
|
|
||||||
MATCH_ENDSWITH = "endswith"
|
|
||||||
MATCH_CONTAINS = "contains"
|
|
||||||
MATCH_REGEXP = "regexp"
|
|
||||||
MATCH_EXACT = "exact"
|
|
||||||
|
|
||||||
MATCHES = (
|
|
||||||
(MATCH_STARTSWITH, _("Starts with")),
|
|
||||||
(MATCH_ENDSWITH, _("Ends with")),
|
|
||||||
(MATCH_CONTAINS, _("Contains")),
|
|
||||||
(MATCH_REGEXP, _("Regexp")),
|
|
||||||
(MATCH_EXACT, _("Exact")),
|
|
||||||
)
|
|
||||||
|
|
||||||
USER_FIELDS = (
|
|
||||||
("username", _("Username"),),
|
|
||||||
("name", _("Name"),),
|
|
||||||
("email", _("E-Mail"),),
|
|
||||||
("is_staff", _("Is staff"),),
|
|
||||||
("is_active", _("Is active"),),
|
|
||||||
("data_joined", _("Date joined"),),
|
|
||||||
)
|
|
||||||
|
|
||||||
user_field = models.TextField(choices=USER_FIELDS)
|
|
||||||
match_action = models.CharField(max_length=50, choices=MATCHES)
|
|
||||||
value = models.TextField()
|
|
||||||
|
|
||||||
form = "passbook.policies.matcher.forms.FieldMatcherPolicyForm"
|
|
||||||
|
|
||||||
def __str__(self):
|
|
||||||
description = (
|
|
||||||
f"{self.name}, user.{self.user_field} {self.match_action} '{self.value}'"
|
|
||||||
)
|
|
||||||
if self.name:
|
|
||||||
description = f"{self.name}: {description}"
|
|
||||||
return description
|
|
||||||
|
|
||||||
def passes(self, request: PolicyRequest) -> PolicyResult:
|
|
||||||
"""Check if user instance passes this role"""
|
|
||||||
if not hasattr(request.user, self.user_field):
|
|
||||||
raise ValueError("Field does not exist")
|
|
||||||
user_field_value = getattr(request.user, self.user_field, None)
|
|
||||||
LOGGER.debug(
|
|
||||||
"Checking field",
|
|
||||||
value=user_field_value,
|
|
||||||
action=self.match_action,
|
|
||||||
should_be=self.value,
|
|
||||||
)
|
|
||||||
passes = False
|
|
||||||
if self.match_action == FieldMatcherPolicy.MATCH_STARTSWITH:
|
|
||||||
passes = user_field_value.startswith(self.value)
|
|
||||||
if self.match_action == FieldMatcherPolicy.MATCH_ENDSWITH:
|
|
||||||
passes = user_field_value.endswith(self.value)
|
|
||||||
if self.match_action == FieldMatcherPolicy.MATCH_CONTAINS:
|
|
||||||
passes = self.value in user_field_value
|
|
||||||
if self.match_action == FieldMatcherPolicy.MATCH_REGEXP:
|
|
||||||
pattern = re.compile(self.value)
|
|
||||||
passes = bool(pattern.match(user_field_value))
|
|
||||||
if self.match_action == FieldMatcherPolicy.MATCH_EXACT:
|
|
||||||
passes = user_field_value == self.value
|
|
||||||
return PolicyResult(passes)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
|
|
||||||
verbose_name = _("Field matcher Policy")
|
|
||||||
verbose_name_plural = _("Field matcher Policies")
|
|
|
@ -1,4 +0,0 @@
|
||||||
"""autodiscover admin"""
|
|
||||||
from passbook.lib.admin import admin_autoregister
|
|
||||||
|
|
||||||
admin_autoregister("passbook_policies_sso")
|
|
|
@ -1,21 +0,0 @@
|
||||||
"""Source API Views"""
|
|
||||||
from rest_framework.serializers import ModelSerializer
|
|
||||||
from rest_framework.viewsets import ModelViewSet
|
|
||||||
|
|
||||||
from passbook.policies.forms import GENERAL_SERIALIZER_FIELDS
|
|
||||||
from passbook.policies.sso.models import SSOLoginPolicy
|
|
||||||
|
|
||||||
|
|
||||||
class SSOLoginPolicySerializer(ModelSerializer):
|
|
||||||
"""SSO Login Policy Serializer"""
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
model = SSOLoginPolicy
|
|
||||||
fields = GENERAL_SERIALIZER_FIELDS
|
|
||||||
|
|
||||||
|
|
||||||
class SSOLoginPolicyViewSet(ModelViewSet):
|
|
||||||
"""Source Viewset"""
|
|
||||||
|
|
||||||
queryset = SSOLoginPolicy.objects.all()
|
|
||||||
serializer_class = SSOLoginPolicySerializer
|
|
|
@ -1,11 +0,0 @@
|
||||||
"""passbook sso policy app config"""
|
|
||||||
|
|
||||||
from django.apps import AppConfig
|
|
||||||
|
|
||||||
|
|
||||||
class PassbookPoliciesSSOConfig(AppConfig):
|
|
||||||
"""passbook sso policy app config"""
|
|
||||||
|
|
||||||
name = "passbook.policies.sso"
|
|
||||||
label = "passbook_policies_sso"
|
|
||||||
verbose_name = "passbook Policies.SSO"
|
|
|
@ -1,19 +0,0 @@
|
||||||
"""passbook Policy forms"""
|
|
||||||
|
|
||||||
from django import forms
|
|
||||||
|
|
||||||
from passbook.policies.forms import GENERAL_FIELDS
|
|
||||||
from passbook.policies.sso.models import SSOLoginPolicy
|
|
||||||
|
|
||||||
|
|
||||||
class SSOLoginPolicyForm(forms.ModelForm):
|
|
||||||
"""Edit SSOLoginPolicy instances"""
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
|
|
||||||
model = SSOLoginPolicy
|
|
||||||
fields = GENERAL_FIELDS
|
|
||||||
widgets = {
|
|
||||||
"name": forms.TextInput(),
|
|
||||||
"order": forms.NumberInput(),
|
|
||||||
}
|
|
|
@ -1,37 +0,0 @@
|
||||||
# Generated by Django 2.2.6 on 2019-10-07 14:07
|
|
||||||
|
|
||||||
import django.db.models.deletion
|
|
||||||
from django.db import migrations, models
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
|
||||||
|
|
||||||
initial = True
|
|
||||||
|
|
||||||
dependencies = [
|
|
||||||
("passbook_core", "0001_initial"),
|
|
||||||
]
|
|
||||||
|
|
||||||
operations = [
|
|
||||||
migrations.CreateModel(
|
|
||||||
name="SSOLoginPolicy",
|
|
||||||
fields=[
|
|
||||||
(
|
|
||||||
"policy_ptr",
|
|
||||||
models.OneToOneField(
|
|
||||||
auto_created=True,
|
|
||||||
on_delete=django.db.models.deletion.CASCADE,
|
|
||||||
parent_link=True,
|
|
||||||
primary_key=True,
|
|
||||||
serialize=False,
|
|
||||||
to="passbook_core.Policy",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
options={
|
|
||||||
"verbose_name": "SSO Login Policy",
|
|
||||||
"verbose_name_plural": "SSO Login Policies",
|
|
||||||
},
|
|
||||||
bases=("passbook_core.policy",),
|
|
||||||
),
|
|
||||||
]
|
|
|
@ -1,25 +0,0 @@
|
||||||
"""sso models"""
|
|
||||||
from django.utils.translation import gettext as _
|
|
||||||
|
|
||||||
from passbook.core.models import Policy
|
|
||||||
from passbook.policies.struct import PolicyRequest, PolicyResult
|
|
||||||
|
|
||||||
|
|
||||||
class SSOLoginPolicy(Policy):
|
|
||||||
"""Policy that applies to users that have authenticated themselves through SSO"""
|
|
||||||
|
|
||||||
form = "passbook.policies.sso.forms.SSOLoginPolicyForm"
|
|
||||||
|
|
||||||
def passes(self, request: PolicyRequest) -> PolicyResult:
|
|
||||||
"""Check if user instance passes this policy"""
|
|
||||||
from passbook.factors.view import AuthenticationView
|
|
||||||
|
|
||||||
is_sso_login = request.user.session.get(
|
|
||||||
AuthenticationView.SESSION_IS_SSO_LOGIN, False
|
|
||||||
)
|
|
||||||
return PolicyResult(is_sso_login)
|
|
||||||
|
|
||||||
class Meta:
|
|
||||||
|
|
||||||
verbose_name = _("SSO Login Policy")
|
|
||||||
verbose_name_plural = _("SSO Login Policies")
|
|
|
@ -93,10 +93,7 @@ INSTALLED_APPS = [
|
||||||
"passbook.policies.expiry.apps.PassbookPolicyExpiryConfig",
|
"passbook.policies.expiry.apps.PassbookPolicyExpiryConfig",
|
||||||
"passbook.policies.reputation.apps.PassbookPolicyReputationConfig",
|
"passbook.policies.reputation.apps.PassbookPolicyReputationConfig",
|
||||||
"passbook.policies.hibp.apps.PassbookPolicyHIBPConfig",
|
"passbook.policies.hibp.apps.PassbookPolicyHIBPConfig",
|
||||||
"passbook.policies.group.apps.PassbookPoliciesGroupConfig",
|
|
||||||
"passbook.policies.matcher.apps.PassbookPoliciesMatcherConfig",
|
|
||||||
"passbook.policies.password.apps.PassbookPoliciesPasswordConfig",
|
"passbook.policies.password.apps.PassbookPoliciesPasswordConfig",
|
||||||
"passbook.policies.sso.apps.PassbookPoliciesSSOConfig",
|
|
||||||
"passbook.policies.webhook.apps.PassbookPoliciesWebhookConfig",
|
"passbook.policies.webhook.apps.PassbookPoliciesWebhookConfig",
|
||||||
"passbook.policies.expression.apps.PassbookPolicyExpressionConfig",
|
"passbook.policies.expression.apps.PassbookPolicyExpressionConfig",
|
||||||
]
|
]
|
||||||
|
|
Reference in New Issue