summaryrefslogtreecommitdiffstats
path: root/utils/forms.py
blob: a6ff4ded499e9605aa5c7873f7bf82d47462b4ed (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
from flask import request, url_for, redirect
from urlparse import urlparse, urljoin
from wtforms import Field, HiddenField, ValidationError

from widgets import Static


class Unique(object):
    """ validator that checks field uniqueness """
    def __init__(self, model, field, message=None):
        self.model = model
        self.field = field
        if not message:
            message = u'This element already exists.'
        self.message = message

    def __call__(self, form, field):
        if self.model.query.filter(self.field == field.data).count() > 0:
            raise ValidationError(self.message)


class ReadonlyField(Field):
    widget = Static()

    def process_formdata(self, _):
        pass


class RedirectMixin(object):
    next = HiddenField()

    def __init__(self, *args, **kwargs):
        super(RedirectMixin, self).__init__(*args, **kwargs)
        if not self.next.data:
            self.next.data = self._get_redirect_target() or ''
    
    def _get_redirect_target(self):
        for target in request.args.get('next'), request.referrer:
            if not target:
                continue
            if self._is_safe_url(target):
                return target

    def _is_safe_url(self, target):
        ref_url = urlparse(request.host_url)
        test_url = urlparse(urljoin(request.host_url, target))
        return test_url.scheme in ('http', 'https') and \
            ref_url.netloc == test_url.netloc
    
    def redirect(self, endpoint='index', **values):
        if self._is_safe_url(self.next.data):
            return redirect(self.next.data)

        target = self._get_redirect_target()
        return redirect(target or url_for(endpoint, **values))