-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
413 additions
and
122 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
# flake8: noqa | ||
from flags.conditions.conditions import ( | ||
RequiredForCondition, | ||
after_date_condition, | ||
anonymous_condition, | ||
before_date_condition, | ||
boolean_condition, | ||
date_condition, | ||
parameter_condition, | ||
path_condition, | ||
user_condition, | ||
) | ||
from flags.conditions.registry import ( | ||
DuplicateCondition, | ||
get_condition, | ||
get_condition_validator, | ||
get_conditions, | ||
register, | ||
) | ||
from flags.conditions.validators import ( | ||
validate_boolean, | ||
validate_date, | ||
validate_parameter, | ||
validate_path, | ||
validate_user, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
# These will be maintained by register() as a global dictionary of | ||
# condition_name: function/validator_function | ||
_conditions = {} | ||
_validators = {} | ||
|
||
|
||
class DuplicateCondition(ValueError): | ||
""" Raised when registering a condition that is already registered """ | ||
|
||
|
||
def register(condition_name, fn=None, validator=None): | ||
""" Register a condition to test for flag state. Can be decorator. | ||
Conditions can be any callable that takes a value and some number of | ||
required arguments (specified in 'requires') that were passed as kwargs | ||
when checking the flag state. """ | ||
global _conditions, _validators | ||
|
||
if fn is None: | ||
# Be a decorator | ||
def decorator(fn): | ||
register(condition_name, fn=fn, validator=validator) | ||
return fn | ||
|
||
return decorator | ||
|
||
# Don't be a decorator, just register | ||
if condition_name in _conditions: | ||
raise DuplicateCondition( | ||
'Flag condition "{name}" already registered.'.format( | ||
name=condition_name | ||
) | ||
) | ||
|
||
_conditions[condition_name] = fn | ||
_validators[condition_name] = validator | ||
|
||
|
||
def get_conditions(): | ||
""" Return the names of all available conditions """ | ||
return _conditions.keys() | ||
|
||
|
||
def get_condition(condition_name): | ||
""" Fetch condition checker functions from the registry """ | ||
if condition_name in _conditions: | ||
return _conditions[condition_name] | ||
|
||
|
||
def get_condition_validator(condition_name): | ||
""" Fetch condition validators from the registry """ | ||
if condition_name in _validators: | ||
return _validators[condition_name] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import re | ||
from distutils.util import strtobool | ||
|
||
from django.contrib.auth import get_user_model | ||
from django.core.exceptions import ValidationError | ||
from django.core.validators import RegexValidator | ||
from django.utils import dateparse | ||
|
||
|
||
validate_path = RegexValidator( | ||
re.compile(r"^[^\s:?#]+$", re.UNICODE), | ||
message=( | ||
"Enter a valid path without a URL scheme, query string, or fragment." | ||
), | ||
code="invalid", | ||
) | ||
|
||
|
||
validate_parameter = RegexValidator( | ||
re.compile(r"^[-_\w=]+$", re.UNICODE), | ||
message="Enter a valid HTTP parameter name.", | ||
code="invalid", | ||
) | ||
|
||
|
||
def validate_boolean(value): | ||
message = "Enter one of 'on', 'off', 'true', 'false', etc." | ||
try: | ||
strtobool(value) | ||
except ValueError: | ||
# This was a string with an invalid boolean value | ||
raise ValidationError(message) | ||
except AttributeError: | ||
# This was not a string | ||
if not isinstance(value, (int, bool)): | ||
raise ValidationError(message) | ||
|
||
|
||
def validate_user(value): | ||
UserModel = get_user_model() | ||
|
||
try: | ||
UserModel.objects.get(**{UserModel.USERNAME_FIELD: value}) | ||
except UserModel.DoesNotExist: | ||
raise ValidationError("Enter the username of a valid user.") | ||
|
||
|
||
def validate_date(value): | ||
datetime = dateparse.parse_datetime(value) | ||
if datetime is None: | ||
raise ValidationError("Enter an ISO 8601 date representation.") |
Oops, something went wrong.