root: add group_membership policy
This commit is contained in:
		| @ -21,6 +21,7 @@ from passbook.policies.api import PolicyBindingViewSet, PolicyViewSet | ||||
| from passbook.policies.dummy.api import DummyPolicyViewSet | ||||
| from passbook.policies.expiry.api import PasswordExpiryPolicyViewSet | ||||
| from passbook.policies.expression.api import ExpressionPolicyViewSet | ||||
| from passbook.policies.group_membership.api import GroupMembershipPolicyViewSet | ||||
| from passbook.policies.hibp.api import HaveIBeenPwendPolicyViewSet | ||||
| from passbook.policies.password.api import PasswordPolicyViewSet | ||||
| from passbook.policies.reputation.api import ReputationPolicyViewSet | ||||
| @ -71,9 +72,10 @@ router.register("sources/oauth", OAuthSourceViewSet) | ||||
| router.register("policies/all", PolicyViewSet) | ||||
| router.register("policies/bindings", PolicyBindingViewSet) | ||||
| router.register("policies/expression", ExpressionPolicyViewSet) | ||||
| router.register("policies/group_membership", GroupMembershipPolicyViewSet) | ||||
| router.register("policies/haveibeenpwned", HaveIBeenPwendPolicyViewSet) | ||||
| router.register("policies/password_expiry", PasswordExpiryPolicyViewSet) | ||||
| router.register("policies/password", PasswordPolicyViewSet) | ||||
| router.register("policies/passwordexpiry", PasswordExpiryPolicyViewSet) | ||||
| router.register("policies/reputation", ReputationPolicyViewSet) | ||||
|  | ||||
| router.register("providers/all", ProviderViewSet) | ||||
|  | ||||
| @ -2,6 +2,7 @@ | ||||
| from django import forms | ||||
| from django.contrib.admin.widgets import FilteredSelectMultiple | ||||
|  | ||||
| from passbook.admin.fields import CodeMirrorWidget, YAMLField | ||||
| from passbook.core.models import Group, User | ||||
|  | ||||
|  | ||||
| @ -34,4 +35,8 @@ class GroupForm(forms.ModelForm): | ||||
|         fields = ["name", "parent", "members", "attributes"] | ||||
|         widgets = { | ||||
|             "name": forms.TextInput(), | ||||
|             "attributes": CodeMirrorWidget, | ||||
|         } | ||||
|         field_classes = { | ||||
|             "attributes": YAMLField, | ||||
|         } | ||||
|  | ||||
							
								
								
									
										23
									
								
								passbook/policies/group_membership/api.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								passbook/policies/group_membership/api.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| """Group Membership Policy API""" | ||||
| from rest_framework.serializers import ModelSerializer | ||||
| from rest_framework.viewsets import ModelViewSet | ||||
|  | ||||
| from passbook.policies.forms import GENERAL_SERIALIZER_FIELDS | ||||
| from passbook.policies.group_membership.models import GroupMembershipPolicy | ||||
|  | ||||
|  | ||||
| class GroupMembershipPolicySerializer(ModelSerializer): | ||||
|     """Group Membership Policy Serializer""" | ||||
|  | ||||
|     class Meta: | ||||
|         model = GroupMembershipPolicy | ||||
|         fields = GENERAL_SERIALIZER_FIELDS + [ | ||||
|             "group", | ||||
|         ] | ||||
|  | ||||
|  | ||||
| class GroupMembershipPolicyViewSet(ModelViewSet): | ||||
|     """Group Membership Policy Viewset""" | ||||
|  | ||||
|     queryset = GroupMembershipPolicy.objects.all() | ||||
|     serializer_class = GroupMembershipPolicySerializer | ||||
							
								
								
									
										11
									
								
								passbook/policies/group_membership/apps.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								passbook/policies/group_membership/apps.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,11 @@ | ||||
| """passbook Group Membership policy app config""" | ||||
|  | ||||
| from django.apps import AppConfig | ||||
|  | ||||
|  | ||||
| class PassbookPoliciesGroupMembershipConfig(AppConfig): | ||||
|     """passbook Group Membership policy app config""" | ||||
|  | ||||
|     name = "passbook.policies.group_membership" | ||||
|     label = "passbook_policies_group_membership" | ||||
|     verbose_name = "passbook Policies.Group Membership" | ||||
							
								
								
									
										20
									
								
								passbook/policies/group_membership/forms.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								passbook/policies/group_membership/forms.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,20 @@ | ||||
| """passbook Group Membership Policy forms""" | ||||
|  | ||||
| from django import forms | ||||
|  | ||||
| from passbook.policies.forms import GENERAL_FIELDS | ||||
| from passbook.policies.group_membership.models import GroupMembershipPolicy | ||||
|  | ||||
|  | ||||
| class GroupMembershipPolicyForm(forms.ModelForm): | ||||
|     """GroupMembershipPolicy Form""" | ||||
|  | ||||
|     class Meta: | ||||
|  | ||||
|         model = GroupMembershipPolicy | ||||
|         fields = GENERAL_FIELDS + [ | ||||
|             "group", | ||||
|         ] | ||||
|         widgets = { | ||||
|             "name": forms.TextInput(), | ||||
|         } | ||||
| @ -0,0 +1,47 @@ | ||||
| # Generated by Django 3.0.7 on 2020-07-01 19:01 | ||||
|  | ||||
| import django.db.models.deletion | ||||
| from django.db import migrations, models | ||||
|  | ||||
|  | ||||
| class Migration(migrations.Migration): | ||||
|  | ||||
|     initial = True | ||||
|  | ||||
|     dependencies = [ | ||||
|         ("passbook_policies", "0002_auto_20200528_1647"), | ||||
|         ("passbook_core", "0003_default_user"), | ||||
|     ] | ||||
|  | ||||
|     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_policies.Policy", | ||||
|                     ), | ||||
|                 ), | ||||
|                 ( | ||||
|                     "group", | ||||
|                     models.ForeignKey( | ||||
|                         blank=True, | ||||
|                         null=True, | ||||
|                         on_delete=django.db.models.deletion.SET_NULL, | ||||
|                         to="passbook_core.Group", | ||||
|                     ), | ||||
|                 ), | ||||
|             ], | ||||
|             options={ | ||||
|                 "verbose_name": "Group Membership Policy", | ||||
|                 "verbose_name_plural": "Group Membership Policies", | ||||
|             }, | ||||
|             bases=("passbook_policies.policy",), | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										23
									
								
								passbook/policies/group_membership/models.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								passbook/policies/group_membership/models.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | ||||
| """user field matcher models""" | ||||
| from django.db import models | ||||
| from django.utils.translation import gettext as _ | ||||
|  | ||||
| from passbook.core.models import Group | ||||
| from passbook.policies.models import Policy | ||||
| from passbook.policies.types import PolicyRequest, PolicyResult | ||||
|  | ||||
|  | ||||
| class GroupMembershipPolicy(Policy): | ||||
|     """Check that the user is member of the selected group.""" | ||||
|  | ||||
|     group = models.ForeignKey(Group, null=True, blank=True, on_delete=models.SET_NULL) | ||||
|  | ||||
|     form = "passbook.policies.group_membership.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") | ||||
							
								
								
									
										32
									
								
								passbook/policies/group_membership/tests.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								passbook/policies/group_membership/tests.py
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,32 @@ | ||||
| """evaluator tests""" | ||||
| from django.test import TestCase | ||||
| from guardian.shortcuts import get_anonymous_user | ||||
|  | ||||
| from passbook.core.models import Group | ||||
| from passbook.policies.group_membership.models import GroupMembershipPolicy | ||||
| from passbook.policies.types import PolicyRequest | ||||
|  | ||||
|  | ||||
| class TestGroupMembershipPolicy(TestCase): | ||||
|     """GroupMembershipPolicy tests""" | ||||
|  | ||||
|     def setUp(self): | ||||
|         self.request = PolicyRequest(user=get_anonymous_user()) | ||||
|  | ||||
|     def test_invalid(self): | ||||
|         """user not in group""" | ||||
|         group = Group.objects.create(name="test") | ||||
|         policy: GroupMembershipPolicy = GroupMembershipPolicy.objects.create( | ||||
|             group=group | ||||
|         ) | ||||
|         self.assertFalse(policy.passes(self.request).passing) | ||||
|  | ||||
|     def test_valid(self): | ||||
|         """user in group""" | ||||
|         group = Group.objects.create(name="test") | ||||
|         group.user_set.add(get_anonymous_user()) | ||||
|         group.save() | ||||
|         policy: GroupMembershipPolicy = GroupMembershipPolicy.objects.create( | ||||
|             group=group | ||||
|         ) | ||||
|         self.assertTrue(policy.passes(self.request).passing) | ||||
| @ -1,4 +1,4 @@ | ||||
| """Source API Views""" | ||||
| """Password Policy API Views""" | ||||
| from rest_framework.serializers import ModelSerializer | ||||
| from rest_framework.viewsets import ModelViewSet | ||||
|  | ||||
| @ -22,7 +22,7 @@ class PasswordPolicySerializer(ModelSerializer): | ||||
|  | ||||
|  | ||||
| class PasswordPolicyViewSet(ModelViewSet): | ||||
|     """Source Viewset""" | ||||
|     """Password Policy Viewset""" | ||||
|  | ||||
|     queryset = PasswordPolicy.objects.all() | ||||
|     serializer_class = PasswordPolicySerializer | ||||
|  | ||||
| @ -86,6 +86,7 @@ INSTALLED_APPS = [ | ||||
|     "passbook.policies.expression.apps.PassbookPolicyExpressionConfig", | ||||
|     "passbook.policies.hibp.apps.PassbookPolicyHIBPConfig", | ||||
|     "passbook.policies.password.apps.PassbookPoliciesPasswordConfig", | ||||
|     "passbook.policies.group_membership.apps.PassbookPoliciesGroupMembershipConfig", | ||||
|     "passbook.policies.reputation.apps.PassbookPolicyReputationConfig", | ||||
|     "passbook.providers.app_gw.apps.PassbookApplicationApplicationGatewayConfig", | ||||
|     "passbook.providers.oauth.apps.PassbookProviderOAuthConfig", | ||||
|  | ||||
| @ -0,0 +1,23 @@ | ||||
| # Generated by Django 3.0.7 on 2020-07-01 19:00 | ||||
|  | ||||
| from django.db import migrations, models | ||||
|  | ||||
|  | ||||
| class Migration(migrations.Migration): | ||||
|  | ||||
|     dependencies = [ | ||||
|         ("passbook_stages_otp_time", "0001_initial"), | ||||
|     ] | ||||
|  | ||||
|     operations = [ | ||||
|         migrations.AlterField( | ||||
|             model_name="otptimestage", | ||||
|             name="digits", | ||||
|             field=models.IntegerField( | ||||
|                 choices=[ | ||||
|                     (6, "6 digits, widely compatible"), | ||||
|                     (8, "8 digits, not compatible with apps like Google Authenticator"), | ||||
|                 ] | ||||
|             ), | ||||
|         ), | ||||
|     ] | ||||
							
								
								
									
										172
									
								
								swagger.yaml
									
									
									
									
									
								
							
							
						
						
									
										172
									
								
								swagger.yaml
									
									
									
									
									
								
							| @ -1222,6 +1222,133 @@ paths: | ||||
|         required: true | ||||
|         type: string | ||||
|         format: uuid | ||||
|   /policies/group_membership/: | ||||
|     get: | ||||
|       operationId: policies_group_membership_list | ||||
|       description: Group Membership Policy Viewset | ||||
|       parameters: | ||||
|         - name: ordering | ||||
|           in: query | ||||
|           description: Which field to use when ordering the results. | ||||
|           required: false | ||||
|           type: string | ||||
|         - name: search | ||||
|           in: query | ||||
|           description: A search term. | ||||
|           required: false | ||||
|           type: string | ||||
|         - name: limit | ||||
|           in: query | ||||
|           description: Number of results to return per page. | ||||
|           required: false | ||||
|           type: integer | ||||
|         - name: offset | ||||
|           in: query | ||||
|           description: The initial index from which to return the results. | ||||
|           required: false | ||||
|           type: integer | ||||
|       responses: | ||||
|         '200': | ||||
|           description: '' | ||||
|           schema: | ||||
|             required: | ||||
|               - count | ||||
|               - results | ||||
|             type: object | ||||
|             properties: | ||||
|               count: | ||||
|                 type: integer | ||||
|               next: | ||||
|                 type: string | ||||
|                 format: uri | ||||
|                 x-nullable: true | ||||
|               previous: | ||||
|                 type: string | ||||
|                 format: uri | ||||
|                 x-nullable: true | ||||
|               results: | ||||
|                 type: array | ||||
|                 items: | ||||
|                   $ref: '#/definitions/GroupMembershipPolicy' | ||||
|       tags: | ||||
|         - policies | ||||
|     post: | ||||
|       operationId: policies_group_membership_create | ||||
|       description: Group Membership Policy Viewset | ||||
|       parameters: | ||||
|         - name: data | ||||
|           in: body | ||||
|           required: true | ||||
|           schema: | ||||
|             $ref: '#/definitions/GroupMembershipPolicy' | ||||
|       responses: | ||||
|         '201': | ||||
|           description: '' | ||||
|           schema: | ||||
|             $ref: '#/definitions/GroupMembershipPolicy' | ||||
|       tags: | ||||
|         - policies | ||||
|     parameters: [] | ||||
|   /policies/group_membership/{policy_uuid}/: | ||||
|     get: | ||||
|       operationId: policies_group_membership_read | ||||
|       description: Group Membership Policy Viewset | ||||
|       parameters: [] | ||||
|       responses: | ||||
|         '200': | ||||
|           description: '' | ||||
|           schema: | ||||
|             $ref: '#/definitions/GroupMembershipPolicy' | ||||
|       tags: | ||||
|         - policies | ||||
|     put: | ||||
|       operationId: policies_group_membership_update | ||||
|       description: Group Membership Policy Viewset | ||||
|       parameters: | ||||
|         - name: data | ||||
|           in: body | ||||
|           required: true | ||||
|           schema: | ||||
|             $ref: '#/definitions/GroupMembershipPolicy' | ||||
|       responses: | ||||
|         '200': | ||||
|           description: '' | ||||
|           schema: | ||||
|             $ref: '#/definitions/GroupMembershipPolicy' | ||||
|       tags: | ||||
|         - policies | ||||
|     patch: | ||||
|       operationId: policies_group_membership_partial_update | ||||
|       description: Group Membership Policy Viewset | ||||
|       parameters: | ||||
|         - name: data | ||||
|           in: body | ||||
|           required: true | ||||
|           schema: | ||||
|             $ref: '#/definitions/GroupMembershipPolicy' | ||||
|       responses: | ||||
|         '200': | ||||
|           description: '' | ||||
|           schema: | ||||
|             $ref: '#/definitions/GroupMembershipPolicy' | ||||
|       tags: | ||||
|         - policies | ||||
|     delete: | ||||
|       operationId: policies_group_membership_delete | ||||
|       description: Group Membership Policy Viewset | ||||
|       parameters: [] | ||||
|       responses: | ||||
|         '204': | ||||
|           description: '' | ||||
|       tags: | ||||
|         - policies | ||||
|     parameters: | ||||
|       - name: policy_uuid | ||||
|         in: path | ||||
|         description: A UUID string identifying this Group Membership Policy. | ||||
|         required: true | ||||
|         type: string | ||||
|         format: uuid | ||||
|   /policies/haveibeenpwned/: | ||||
|     get: | ||||
|       operationId: policies_haveibeenpwned_list | ||||
| @ -1352,7 +1479,7 @@ paths: | ||||
|   /policies/password/: | ||||
|     get: | ||||
|       operationId: policies_password_list | ||||
|       description: Source Viewset | ||||
|       description: Password Policy Viewset | ||||
|       parameters: | ||||
|         - name: ordering | ||||
|           in: query | ||||
| @ -1401,7 +1528,7 @@ paths: | ||||
|         - policies | ||||
|     post: | ||||
|       operationId: policies_password_create | ||||
|       description: Source Viewset | ||||
|       description: Password Policy Viewset | ||||
|       parameters: | ||||
|         - name: data | ||||
|           in: body | ||||
| @ -1419,7 +1546,7 @@ paths: | ||||
|   /policies/password/{policy_uuid}/: | ||||
|     get: | ||||
|       operationId: policies_password_read | ||||
|       description: Source Viewset | ||||
|       description: Password Policy Viewset | ||||
|       parameters: [] | ||||
|       responses: | ||||
|         '200': | ||||
| @ -1430,7 +1557,7 @@ paths: | ||||
|         - policies | ||||
|     put: | ||||
|       operationId: policies_password_update | ||||
|       description: Source Viewset | ||||
|       description: Password Policy Viewset | ||||
|       parameters: | ||||
|         - name: data | ||||
|           in: body | ||||
| @ -1446,7 +1573,7 @@ paths: | ||||
|         - policies | ||||
|     patch: | ||||
|       operationId: policies_password_partial_update | ||||
|       description: Source Viewset | ||||
|       description: Password Policy Viewset | ||||
|       parameters: | ||||
|         - name: data | ||||
|           in: body | ||||
| @ -1462,7 +1589,7 @@ paths: | ||||
|         - policies | ||||
|     delete: | ||||
|       operationId: policies_password_delete | ||||
|       description: Source Viewset | ||||
|       description: Password Policy Viewset | ||||
|       parameters: [] | ||||
|       responses: | ||||
|         '204': | ||||
| @ -1476,9 +1603,9 @@ paths: | ||||
|         required: true | ||||
|         type: string | ||||
|         format: uuid | ||||
|   /policies/passwordexpiry/: | ||||
|   /policies/password_expiry/: | ||||
|     get: | ||||
|       operationId: policies_passwordexpiry_list | ||||
|       operationId: policies_password_expiry_list | ||||
|       description: Password Expiry Viewset | ||||
|       parameters: | ||||
|         - name: ordering | ||||
| @ -1527,7 +1654,7 @@ paths: | ||||
|       tags: | ||||
|         - policies | ||||
|     post: | ||||
|       operationId: policies_passwordexpiry_create | ||||
|       operationId: policies_password_expiry_create | ||||
|       description: Password Expiry Viewset | ||||
|       parameters: | ||||
|         - name: data | ||||
| @ -1543,9 +1670,9 @@ paths: | ||||
|       tags: | ||||
|         - policies | ||||
|     parameters: [] | ||||
|   /policies/passwordexpiry/{policy_uuid}/: | ||||
|   /policies/password_expiry/{policy_uuid}/: | ||||
|     get: | ||||
|       operationId: policies_passwordexpiry_read | ||||
|       operationId: policies_password_expiry_read | ||||
|       description: Password Expiry Viewset | ||||
|       parameters: [] | ||||
|       responses: | ||||
| @ -1556,7 +1683,7 @@ paths: | ||||
|       tags: | ||||
|         - policies | ||||
|     put: | ||||
|       operationId: policies_passwordexpiry_update | ||||
|       operationId: policies_password_expiry_update | ||||
|       description: Password Expiry Viewset | ||||
|       parameters: | ||||
|         - name: data | ||||
| @ -1572,7 +1699,7 @@ paths: | ||||
|       tags: | ||||
|         - policies | ||||
|     patch: | ||||
|       operationId: policies_passwordexpiry_partial_update | ||||
|       operationId: policies_password_expiry_partial_update | ||||
|       description: Password Expiry Viewset | ||||
|       parameters: | ||||
|         - name: data | ||||
| @ -1588,7 +1715,7 @@ paths: | ||||
|       tags: | ||||
|         - policies | ||||
|     delete: | ||||
|       operationId: policies_passwordexpiry_delete | ||||
|       operationId: policies_password_expiry_delete | ||||
|       description: Password Expiry Viewset | ||||
|       parameters: [] | ||||
|       responses: | ||||
| @ -5661,6 +5788,23 @@ definitions: | ||||
|         title: Expression | ||||
|         type: string | ||||
|         minLength: 1 | ||||
|   GroupMembershipPolicy: | ||||
|     type: object | ||||
|     properties: | ||||
|       pk: | ||||
|         title: Policy uuid | ||||
|         type: string | ||||
|         format: uuid | ||||
|         readOnly: true | ||||
|       name: | ||||
|         title: Name | ||||
|         type: string | ||||
|         x-nullable: true | ||||
|       group: | ||||
|         title: Group | ||||
|         type: string | ||||
|         format: uuid | ||||
|         x-nullable: true | ||||
|   HaveIBeenPwendPolicy: | ||||
|     type: object | ||||
|     properties: | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 Jens Langhammer
					Jens Langhammer