Skip to content

Commit

Permalink
Merge pull request #62 from geoadmin/develop
Browse files Browse the repository at this point in the history
New Release v1.2.2 - #patch
  • Loading branch information
ltshb authored Jun 9, 2022
2 parents f4add80 + 306131e commit 5b91ef9
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 62 deletions.
2 changes: 1 addition & 1 deletion .env.test
Original file line number Diff line number Diff line change
@@ -1 +1 @@
ALLOWED_DOMAINS=some_random_domain,http://localhost
ALLOWED_DOMAINS=some_random_domain,.*\.geo\.admin\.ch,http://localhost
30 changes: 19 additions & 11 deletions app/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,26 @@ def validate_origin():
origin = request.headers.get('Origin', None)
referrer = request.headers.get('Referer', None)

if origin is None and referrer is None and sec_fetch_site is None:
logger.error('Referer and/or Origin and/or Sec-Fetch-Site headers not set')
abort(403, 'Not allowed')
if origin is not None and not is_domain_allowed(origin):
logger.error('Origin=%s is not allowed', origin)
abort(403, 'Not allowed')
if referrer is not None and not is_domain_allowed(referrer):
logger.error('Referer=%s is not allowed', referrer)
abort(403, 'Not allowed')
if sec_fetch_site is not None and sec_fetch_site != 'same-origin':
if origin is not None:
if is_domain_allowed(origin):
return
logger.error('Origin=%s does not match %s', origin, ALLOWED_DOMAINS_PATTERN)
abort(403, 'Permission denied')

if sec_fetch_site is not None:
if sec_fetch_site in ['same-origin', 'same-site']:
return
logger.error('Sec-Fetch-Site=%s is not allowed', sec_fetch_site)
abort(403, 'Not allowed')
abort(403, 'Permission denied')

if referrer is not None:
if is_domain_allowed(referrer):
return
logger.error('Referer=%s does not match %s', referrer, ALLOWED_DOMAINS_PATTERN)
abort(403, 'Permission denied')

logger.error('Referer and/or Origin and/or Sec-Fetch-Site headers not set')
abort(403, 'Permission denied')


@app.after_request
Expand Down
2 changes: 1 addition & 1 deletion tests/unit_tests/base_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ def check_response_not_allowed(self, response, msg, is_checker=False):
self.assertEqual(
response.json, {
"error": {
"code": 403, "message": "Not allowed"
"code": 403, "message": "Permission denied"
}, "success": False
}
)
109 changes: 60 additions & 49 deletions tests/unit_tests/test_all_icons.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import logging
import os

from nose2.tools import params
from PIL import Image

from flask import url_for
Expand Down Expand Up @@ -108,42 +109,50 @@ def check_image(
blue, average_color[2], delta=acceptable_color_delta, msg=error_message
)

def test_icon_set_origin_validation(self):
url = url_for('all_icon_sets')
response = self.app.get(url, headers={'Sec-Fetch-Site': 'same-origin'})
self.assertEqual(response.status_code, 200)
self.assertCors(response)
response = self.app.get(url, headers={'Origin': self.origin_for_testing})
self.assertEqual(response.status_code, 200)
self.assertCors(response)
response = self.app.get(url, headers={'Referer': self.origin_for_testing})
self.assertEqual(response.status_code, 200)
@params(
None,
{'Origin': 'www.example'},
{
'Origin': 'www.example', 'Sec-Fetch-Site': 'cross-site'
},
{
'Origin': 'www.example', 'Sec-Fetch-Site': 'same-site'
},
{
'Origin': 'www.example', 'Sec-Fetch-Site': 'same-origin'
},
{'Referer': 'http://www.example'},
)
def test_icon_set_origin_not_allowed(self, headers):
response = self.app.get(url_for('all_icon_sets'), headers=headers)
self.assertEqual(response.status_code, 403, msg="Domain restriction not applied")
self.assertCors(response)

response = self.app.get(url, headers={'Origin': 'dummy'})
self.assertEqual(response.status_code, 403)
self.assertCors(response)
response = self.app.get(url, headers={'Referer': 'dummy'})
self.assertEqual(response.status_code, 403)
self.assertCors(response)
response = self.app.get(url, headers={'Origin': ''})
self.assertEqual(response.status_code, 403)
self.assertCors(response)
response = self.app.get(url, headers={'Referer': ''})
self.assertEqual(response.status_code, 403)
self.assertCors(response)
response = self.app.get(url, headers={'Sec-Fetch-Site': 'cross-site'})
self.assertEqual(response.status_code, 403)
self.assertCors(response)
response = self.app.get(url, headers={'Sec-Fetch-Site': 'none'})
self.assertEqual(response.status_code, 403)
self.assertCors(response)
response = self.app.get(url, headers={'Sec-Fetch-Site': ''})
self.assertEqual(response.status_code, 403)
self.assertCors(response)
response = self.app.get(url)
self.assertEqual(response.status_code, 403)
@params(
{'Origin': 'map.geo.admin.ch'},
{
'Origin': 'map.geo.admin.ch', 'Sec-Fetch-Site': 'same-site'
},
{
'Origin': 'public.geo.admin.ch', 'Sec-Fetch-Site': 'same-origin'
},
{
'Origin': 'http://localhost', 'Sec-Fetch-Site': 'cross-site'
},
{'Sec-Fetch-Site': 'same-origin'},
{'Referer': 'https://map.geo.admin.ch'},
)
def test_icon_set_origin_allowed(self, headers):
response = self.app.get(url_for('all_icon_sets'), headers=headers)
self.assertEqual(response.status_code, 200)
self.assertCors(response)
self.assertEqual(response.content_type, "application/json")
self.assertIn('Cache-Control', response.headers, msg="Cache control header missing")
self.assertIn(
'max-age=', response.headers['Cache-Control'], msg="Cache Control max-age not set"
)
self.assertIn('success', response.json)
self.assertIn('items', response.json)

def test_all_icon_sets_endpoint(self):
"""
Expand All @@ -156,8 +165,8 @@ def test_all_icon_sets_endpoint(self):
self.assertIn('Cache-Control', response.headers)
self.assertIn('max-age=', response.headers['Cache-Control'])
self.assertIn('success', response.json)
self.assertTrue(response.json['items'])
self.assertIn('items', response.json)
self.assertTrue(response.json['items'])
icon_sets_from_endpoint = response.json['items']
self.assertEqual(len(icon_sets_from_endpoint), len(self.all_icon_sets))
for icon_set in icon_sets_from_endpoint:
Expand Down Expand Up @@ -318,12 +327,12 @@ def test_all_icons_colorized(self):
for icon_name in icon_set:
with self.subTest(icon_set_name=icon_set_name, icon_name=icon_name):
icon_set = get_icon_set(icon_set_name)
params = {"icon_set_name": icon_set_name, "icon_name": icon_name}
url_params = {"icon_set_name": icon_set_name, "icon_name": icon_name}
if icon_set.colorable:
params["red"] = 0
params["green"] = 255
params["blue"] = 255
colored_url = url_for('colorized_icon', **params)
url_params["red"] = 0
url_params["green"] = 255
url_params["blue"] = 255
colored_url = url_for('colorized_icon', **url_params)
self.check_image(
icon_name,
colored_url,
Expand All @@ -341,12 +350,14 @@ def test_all_icons_colorized_and_double_size(self):
for icon_name in icon_set:
with self.subTest(icon_set_name=icon_set_name, icon_name=icon_name):
icon_set = get_icon_set(icon_set_name)
params = {"icon_set_name": icon_set_name, "icon_name": icon_name, "scale": '2x'}
url_params = {
"icon_set_name": icon_set_name, "icon_name": icon_name, "scale": '2x'
}
if icon_set.colorable:
params["red"] = 0
params["green"] = 0
params["blue"] = 255
colored_url = url_for('colorized_icon', **params)
url_params["red"] = 0
url_params["green"] = 0
url_params["blue"] = 255
colored_url = url_for('colorized_icon', **url_params)
self.check_image(
icon_name,
colored_url,
Expand All @@ -365,14 +376,14 @@ def test_all_icons_colorized_and_half_size(self):
for icon_name in icon_set:
with self.subTest(icon_set_name=icon_set_name, icon_name=icon_name):
icon_set = get_icon_set(icon_set_name)
params = {
url_params = {
"icon_set_name": icon_set_name, "icon_name": icon_name, "scale": '0.5x'
}
if icon_set.colorable:
params["red"] = 0
params["green"] = 255
params["blue"] = 0
colored_url = url_for('colorized_icon', **params)
url_params["red"] = 0
url_params["green"] = 255
url_params["blue"] = 0
colored_url = url_for('colorized_icon', **url_params)
self.check_image(
icon_name,
colored_url,
Expand Down

0 comments on commit 5b91ef9

Please sign in to comment.