84 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			84 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| """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")
 | 
