Utilities

General purpose utilities available on a project-wide base.

Django Rest Framework extensions

class openforms.api.throttle_classes.PollingRateThrottle

Provide a “polling” scope for throttling configuration.

This scope exists for endpoints intended to be called automatically and frequently.

allow_request(request, view)

Implement the check to see if the request should be throttled.

On success calls throttle_success. On failure calls throttle_failure.

class openforms.api.views.mixins.ListMixin

Fetch and serialize a list of objects.

Alternative to rest_framework.mixins.ListModelMixin for non-database backed collections of objects.

Django Admin

class openforms.utils.admin.CSPReportOverrideAdmin(model, admin_site)
get_readonly_fields(request, obj=None)

Hook for specifying custom readonly fields.

class openforms.utils.admin.SubmitActions(value)

An enumeration.

Email

openforms.emails.utils.sanitize_content(content: str) str

Sanitize the content by stripping untrusted content.

This function is meant to protect against untrusted user input in e-mail bodies. It performs the following sanitizations:

  • strip URLs that are not present in the explicit allow list

openforms.emails.utils.send_mail_html(subject: str, html_body: str, from_email: str, recipient_list: list[str], cc: Optional[list[str]] = None, attachment_tuples: Optional[Sequence[tuple[str, str, Any]]] = None, fail_silently: bool = False, text_message: Optional[str] = None, extra_headers: Optional[dict[str, str]] = None, theme: Optional[openforms.config.models.theme.Theme] = None) None

Send outoing email with HTML content, wrapped in our scaffolding.

If no explicit text variant if supplied, it will be generated best-effort by strip_tags_plus().

Internationalization (i18n)

openforms.utils.translations.runtime_gettext(literal) Callable[[], str]

Generate a callable for migration defaults resolving to a translated literal.

When using literal gettext() or gettext_lazy() default values in migrations, the defaults are evaluated and frozen in the migration files.

By using a callable, we can defer this, see https://docs.djangoproject.com/en/2.2/topics/migrations/#serializing-values

Decorators

class openforms.utils.decorators.IndexingOptions(block: bool, content: str)
openforms.utils.decorators.conditional_search_engine_index(config_attr: str, content='noindex, nofollow')

Conditially allow search engines to list the page in their search results.

Applying this decorator exposes request.indexing_options, which is a IndexingOptions instance.

If indexing is not allowed, the X_ROBOTS_TAG_HEADER will be emitted in the response.

Parameters

config_attr – Name of the configuration attribute from the GlobalConfiguration class.

openforms.utils.decorators.never_cache(view_func)

Decorator that wraps around Django’s never_cache, adding the “Pragma” header.

Django doesn’t add the Pragma: no-cache header by itself, but it is desired by users of Open Forms, so we add it.

Admin decorators

openforms.admin.decorators.suppress_requests_errors(model: type[django.db.models.base.Model], fields: list[str])

Add robustness to admin fields which make outgoing requests that may fail.

If a requests.RequestException is caught, return the base (non-enhanced) form field that Django would generate by default and append an error message for the end-user.

Parameters

fields – A list of model field names for which to suppress errors.

URL handling and manipulation

openforms.utils.redirect.allow_redirect_url(url: str) bool

Check that a redirect target is allowed against the CORS policy.

The “Cross-Origin Resource Sharing” configuration specifies which external hosts are allowed to access Open Forms. We leverage this configuration to block or allow redirects to external hosts.

openforms.utils.urls.build_absolute_uri(location: str, request: Optional[Union[django.http.request.HttpRequest, rest_framework.request.Request]] = None)

Construct an absolutely qualified URI from a location/path.

If no request argument is provided, the fully qualified URI is constructed via settings.BASE_URL.

Parameters
  • location – the path to make absolute, without protocol, netloc or port number. Assumed to be an absolute path.

  • request – optionally - the current request object. If provided, request.build_absolute_uri() is called.

openforms.utils.urls.is_admin_request(request: django.http.request.HttpRequest | rest_framework.request.Request) bool

Checks whether a request is made from the admin

Parameters

request – the request object to be checked.

openforms.utils.urls.reverse_plus(name: str, *, args=None, kwargs=None, request: Optional[Union[django.http.request.HttpRequest, rest_framework.request.Request]] = None, query: Optional[dict[str, Any]] = None, make_absolute: bool = True)

Reverse a named URL with GET query params, absolute URL with internal build_absolute_uri()

This is both more readable and formatter friendly than a local reverse/furl/build_absolute_uri

If make_absolute is True and no request argument is provided, the fully qualified URI is constructed via settings.BASE_URL.

Parameters
  • name – the URL name to reverse.

  • args – optionally - arg-argument to reverse().

  • kwargs – optionally - kwargs-argument to reverse().

  • request – optionally - the current request object. If provided, request.build_absolute_uri() is called.

  • query – optionally - add key/values as URL GET parameter

  • make_absolute – optionally - disable absolute URL

Validators

class openforms.utils.validators.AllowedRedirectValidator(*args, **kwargs)

Validate that a redirect target is not an open redirect.

deconstruct()

Return a 3-tuple of class import path, positional arguments, and keyword arguments.

class openforms.utils.validators.BSNValidator(*args, **kwargs)

Validate a BSN value by applying the “11-proef”.

deconstruct()

Return a 3-tuple of class import path, positional arguments, and keyword arguments.

class openforms.utils.validators.RSINValidator(*args, **kwargs)

Validate a RSIN value by applying the “11-proef”.

deconstruct()

Return a 3-tuple of class import path, positional arguments, and keyword arguments.

class openforms.utils.validators.SerializerValidator(*args, **kwargs)

Validate a value against a DRF serializer class.

deconstruct()

Return a 3-tuple of class import path, positional arguments, and keyword arguments.

class openforms.utils.validators.UniqueValuesValidator(*args, **kwargs)

Validate a collection of unique values.

deconstruct()

Return a 3-tuple of class import path, positional arguments, and keyword arguments.

Model file fields

Implement django.db.models.FileField related utilities.

These utilities apply to file fields and subclasses thereof.

class openforms.utils.files.DeleteFileFieldFilesMixin

Model mixin ensuring file deletion on database record deletion.

All file fields as part of the model will have the content removed as part of the instance deletion.

class openforms.utils.files.DeleteFilesQuerySetMixin

Delete files on django.db.models.QuerySet.delete() calls.

All file fields as part of the model will have the content removed as part of the deletion of every instance in the queryset.

Note

For cascading deletes with related objects, you should specify model.Meta.base_manager_name on the related model(s), otherwise Django doesn’t use your custom queryset class.

openforms.utils.files.get_file_field_names(model: type[django.db.models.base.Model]) list[str]

Collect names of django.db.models.FileField (& subclass) model fields.

class openforms.utils.files.log_failed_deletes(filefield: django.db.models.fields.files.FieldFile)

Context manager adding robustness to model file field deletes.

Deletes that fail for whatever reason are logged with level and exceptions are surpressed.

XML

XML parsing with DTD/Entities blocking.

Inspired by https://github.com/mvantellingen/python-zeep/pull/1179/ as their solution for the deprecated defusedxml.lxml module and the defaults applied in defusedxml.lxml.

openforms.utils.xml.fromstring(content: str | bytes)

Create an LXML etree from the string content without resolving entities.

Resolving entities is a security risk, which is why we disable it.

Variables

openforms.variables.utils.get_variables_for_context(submission: Submission) dict[str, 'JSONPrimitive | JSONObject | list[JSONValue]']

Return the key/value pairs of static variables and submission variables.

This returns the saved component variables and user defined variables for a submission, plus the static variables (which are never saved). Note that depending on when it is called, the ‘auth’ static variables (auth_bsn, auth_kvk…) can be already hashed.