Projet

Général

Profil

0001-general-add-support-for-substitution-variables-in-UR.patch

Frédéric Péters, 03 février 2017 15:19

Télécharger (9,36 ko)

Voir les différences:

Subject: [PATCH] general: add support for substitution variables in URLs
 (#14622)

 combo/apps/momo/utils.py         |  2 +-
 combo/apps/newsletters/models.py | 17 ++++++++++-------
 combo/data/models.py             |  9 ++++++---
 combo/public/views.py            | 11 +++++++----
 combo/utils.py                   | 11 +++++++++++
 tests/test_public.py             | 11 +++++++++++
 tests/test_utils.py              | 12 ++++++++++--
 7 files changed, 56 insertions(+), 17 deletions(-)
combo/apps/momo/utils.py
87 87

  
88 88
    if page.redirect_url:
89 89
        page_dict['external'] = True
90
        page_dict['url'] = page.redirect_url
90
        page_dict['url'] = page.get_redirect_url()
91 91

  
92 92
    if icon_cells:
93 93
        page_dict['icon'] = icon_cells[0].icon
combo/apps/newsletters/models.py
29 29

  
30 30
from combo.data.models import CellBase
31 31
from combo.data.library import register_cell_class
32
from combo.utils import sign_url
32
from combo.utils import sign_url, get_templated_url
33 33

  
34 34
from .forms import NewslettersManageForm
35 35

  
......
120 120
        return filtered
121 121

  
122 122
    def get_newsletters(self, **kwargs):
123
        endpoint = self.url + 'newsletters/'
124
        url = get_signed_url(endpoint, self.url, **kwargs)
123
        url = get_templated_url(self.url)
124
        endpoint = url + 'newsletters/'
125
        url = get_signed_url(endpoint, url, **kwargs)
125 126
        response = requests.get(url)
126 127
        if response.ok:
127 128
            json_response = response.json()
......
129 130
        return []
130 131

  
131 132
    def get_subscriptions(self, **kwargs):
132
        endpoint = self.url + 'subscriptions/'
133
        url = get_signed_url(endpoint, self.url, **kwargs)
133
        url = get_templated_url(self.url)
134
        endpoint = url + 'subscriptions/'
135
        url = get_signed_url(endpoint, url, **kwargs)
134 136
        response = requests.get(url)
135 137
        if response.ok:
136 138
            json_response = response.json()
......
140 142
    def set_subscriptions(self, subscriptions, **kwargs):
141 143
        logger = logging.getLogger(__name__)
142 144
        headers = {'Content-type': 'application/json', 'Accept': 'application/json'}
145
        url = get_templated_url(self.url)
143 146
        try:
144
            endpoint = self.url + 'subscriptions/'
145
            url = get_signed_url(endpoint, self.url, **kwargs)
147
            endpoint = url + 'subscriptions/'
148
            url = get_signed_url(endpoint, url, **kwargs)
146 149
            response = requests.post(url, data=json.dumps(subscriptions),
147 150
                                     headers=headers)
148 151
            if not response.json()['data']:
combo/data/models.py
258 258
        ordered_pages = Page.get_as_reordered_flat_hierarchy(cls.objects.all())
259 259
        return [x.get_serialized_page() for x in ordered_pages]
260 260

  
261
    def get_redirect_url(self):
262
        return utils.get_templated_url(self.redirect_url)
263

  
261 264

  
262 265
class CellMeta(MediaDefiningClass, ModelBase):
263 266
    pass
......
605 608
            context['url'] = self.link_page.get_online_url()
606 609
            context['title'] = self.title or self.link_page.title
607 610
        else:
608
            context['url'] = self.url
611
            context['url'] = utils.get_templated_url(self.url)
609 612
            context['title'] = self.title or self.url
610 613
        if self.anchor:
611 614
            context['url'] += '#' + self.anchor
......
632 635
        cache_key = hashlib.md5(self.url).hexdigest()
633 636
        feed_content = cache.get(cache_key)
634 637
        if not feed_content:
635
            feed_response = requests.get(self.url)
638
            feed_response = requests.get(utils.get_templated_url(self.url))
636 639
            if feed_response.status_code == 200:
637 640
                feed_content = feed_response.content
638 641
                cache.set(cache_key, feed_content, 600)
......
737 740
        if hasattr(self, '_form'):
738 741
            ctx['form'] = self._form
739 742
        ctx['title'] = self.title
740
        ctx['url'] = self.url
743
        ctx['url'] = utils.get_templated_url(self.url)
741 744
        return ctx
742 745

  
743 746
    def get_default_form_class(self):
combo/public/views.py
44 44
    get_idps = lambda: []
45 45

  
46 46
from combo.data.models import CellBase, Page, ParentContentCell, TextCell
47
from combo import utils
47 48

  
48 49

  
49 50
def login(request, *args, **kwargs):
......
147 148
    # look in redirect pages after the best match for the source
148 149
    redirect_pages = Page.objects.exclude(redirect_url__isnull=True).exclude(redirect_url='')
149 150
    for page in redirect_pages:
150
        if source.startswith(page.redirect_url):
151
            if selected_page is None or len(page.redirect_url) > len(selected_page.redirect_url):
151
        redirect_url = utils.get_templated_url(page.redirect_url)
152
        if source.startswith(redirect_url):
153
            if selected_page is None or len(redirect_url) > len(selected_page.get_redirect_url()):
152 154
                selected_page = page
153 155

  
154 156
    if selected_page is None:
155 157
        # if there was no page found, look for a domain match
156 158
        netloc = urlparse.urlparse(source).netloc
157 159
        for page in redirect_pages:
158
            if urlparse.urlparse(page.redirect_url).netloc == netloc:
160
            redirect_url = utils.get_templated_url(page.redirect_url)
161
            if urlparse.urlparse(redirect_url).netloc == netloc:
159 162
                selected_page = page
160 163
                break
161 164

  
......
289 292
        raise PermissionDenied()
290 293

  
291 294
    if page.redirect_url:
292
        return HttpResponseRedirect(page.redirect_url)
295
        return HttpResponseRedirect(page.get_redirect_url())
293 296

  
294 297
    cells = CellBase.get_cells(page_id=page.id)
295 298
    extend_with_parent_cells(cells)
combo/utils.py
19 19
import hmac
20 20
import hashlib
21 21
import binascii
22
import re
22 23

  
23 24
from HTMLParser import HTMLParser
24 25
import logging
......
169 170

  
170 171
requests = Requests()
171 172

  
173

  
174
def get_templated_url(url):
175
    template_vars = settings.TEMPLATE_VARS
176
    def repl(matchobj):
177
        if matchobj.group(0)[1:-1] in template_vars:
178
            return template_vars[matchobj.group(0)[1:-1]]
179
        return matchobj.group(0)
180
    return re.sub(r'(\[.*?\])', repl, url)
181

  
182

  
172 183
# Simple signature scheme for query strings
173 184

  
174 185
def sign_url(url, key, algo='sha256', timestamp=None, nonce=None):
tests/test_public.py
4 4
import urllib
5 5

  
6 6
from django.core.urlresolvers import reverse
7
from django.test import override_settings
8

  
7 9
from combo.wsgi import application
8 10
from combo.data.models import Page, CellBase, TextCell, ParentContentCell, FeedCell
9 11

  
......
75 77
    resp = app.get('/elsewhere/', status=302)
76 78
    assert resp.location == 'http://example.net'
77 79

  
80
def test_page_templated_redirect(app):
81
    Page.objects.all().delete()
82
    with override_settings(TEMPLATE_VARS={'test_url': 'http://example.net'}):
83
        page = Page(title='Elsewhere', slug='elsewhere', template_name='standard',
84
                redirect_url='[test_url]')
85
        page.save()
86
        resp = app.get('/elsewhere/', status=302)
87
        assert resp.location == 'http://example.net'
88

  
78 89
def test_page_private_unlogged(app):
79 90
    Page.objects.all().delete()
80 91
    page = Page(title='Home', slug='index', template_name='standard', public=False)
tests/test_utils.py
1
from combo.utils import aes_hex_decrypt, aes_hex_encrypt
1
from combo.utils import aes_hex_decrypt, aes_hex_encrypt, get_templated_url
2 2
from django.conf import settings
3
from django.test import override_settings
3 4

  
4 5

  
5 6
def test_crypto_url():
6 7
    invoice_id = '12-1234'
7 8
    key = settings.SECRET_KEY
8
    assert aes_hex_decrypt(key, aes_hex_encrypt(key, invoice_id)) == invoice_id
9
    assert aes_hex_decrypt(key, aes_hex_encrypt(key, invoice_id)) == invoice_id
10

  
11

  
12
def test_templated_url():
13
    assert get_templated_url('[test_url]') == '[test_url]'
14
    with override_settings(TEMPLATE_VARS={'test_url': 'http://www.example.net'}):
15
        assert get_templated_url('[test_url]') == 'http://www.example.net'
16
        assert get_templated_url('[test_url]/hello') == 'http://www.example.net/hello'
9
-