authentic/src/authentic2/cors.py

66 lines
2.2 KiB
Python

# authentic2 - versatile identity manager
# Copyright (C) 2010-2019 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import itertools
from django.apps import apps
from django.conf import settings
from django.utils.six.moves.urllib import parse as urlparse
from . import app_settings, plugins
from .decorators import SessionCache
def make_origin(url):
'''Build origin of an URL'''
parsed = urlparse.urlparse(url)
if ':' in parsed.netloc:
host, port = parsed.netloc.split(':', 1)
if parsed.scheme == 'http' and port == 80:
port = None
if parsed.scheme == 'https' and port == 443:
port = None
else:
host, port = parsed.netloc, None
result = '%s://%s' % (parsed.scheme, host)
if port:
result += ':%s' % port
return result
@SessionCache(timeout=60, args=(1,))
def check_origin(request, origin):
'''Decide if an origin is authorized to do a CORS request'''
if settings.DEBUG:
return True
request_origin = make_origin(request.build_absolute_uri())
if origin == 'null':
return False
if not origin:
return False
if origin == request_origin:
return True
# A2_CORS_WHITELIST must contain properly formatted origins (i.e. only
# scheme and netloc, no path and port must be normalized)
for whitelist_origin in app_settings.A2_CORS_WHITELIST:
if whitelist_origin == origin:
return True
for plugin in plugins.get_plugins():
if hasattr(plugin, 'check_origin'):
if plugin.check_origin(request, origin):
return True
return False