X-Git-Url: https://code.grnet.gr/git/astakos/blobdiff_plain/678b2236de5d9cd11bf4cc65519d57b95ffa053b..217994f8661305ac61e040041a84cd246f9765bd:/snf-astakos-app/astakos/im/util.py diff --git a/snf-astakos-app/astakos/im/util.py b/snf-astakos-app/astakos/im/util.py index 926ec3c..eb9d759 100644 --- a/snf-astakos-app/astakos/im/util.py +++ b/snf-astakos-app/astakos/im/util.py @@ -36,7 +36,7 @@ import datetime import time from urllib import quote -from urlparse import urlsplit, urlunsplit +from urlparse import urlsplit, urlunsplit, urlparse from datetime import tzinfo, timedelta from django.http import HttpResponse, HttpResponseBadRequest, urlencode @@ -47,8 +47,10 @@ from django.core.urlresolvers import reverse from django.core.exceptions import ValidationError from astakos.im.models import AstakosUser, Invitation, ApprovalTerms -from astakos.im.settings import INVITATIONS_PER_LEVEL, COOKIE_NAME, \ - COOKIE_DOMAIN, COOKIE_SECURE, FORCE_PROFILE_UPDATE, LOGGING_LEVEL +from astakos.im.settings import ( + INVITATIONS_PER_LEVEL, COOKIE_NAME, COOKIE_DOMAIN, COOKIE_SECURE, + FORCE_PROFILE_UPDATE, LOGGING_LEVEL +) from astakos.im.functions import login logger = logging.getLogger(__name__) @@ -96,6 +98,51 @@ def get_invitation(request): raise ValueError(_('Email: %s is reserved' % invitation.username)) return invitation +def restrict_next(url, domain=None, allowed_schemes=()): + """ + Return url if having the supplied ``domain`` (if present) or one of the ``allowed_schemes``. + Otherwise return None. + + >>> print restrict_next('/im/feedback', '.okeanos.grnet.gr') + /im/feedback + >>> print restrict_next('pithos.okeanos.grnet.gr/im/feedback', '.okeanos.grnet.gr') + pithos.okeanos.grnet.gr/im/feedback + >>> print restrict_next('https://pithos.okeanos.grnet.gr/im/feedback', '.okeanos.grnet.gr') + https://pithos.okeanos.grnet.gr/im/feedback + >>> print restrict_next('pithos://127.0.0,1', '.okeanos.grnet.gr') + None + >>> print restrict_next('pithos://127.0.0,1', '.okeanos.grnet.gr', allowed_schemes=('pithos')) + pithos://127.0.0,1 + >>> print restrict_next('node1.example.com', '.okeanos.grnet.gr') + None + >>> print restrict_next('//node1.example.com', '.okeanos.grnet.gr') + None + >>> print restrict_next('https://node1.example.com', '.okeanos.grnet.gr') + None + >>> print restrict_next('https://node1.example.com') + https://node1.example.com + >>> print restrict_next('//node1.example.com') + //node1.example.com + >>> print restrict_next('node1.example.com') + node1.example.com + """ + if not url: + return + parts = urlparse(url, scheme='http') + if not parts.netloc: + # fix url if does not conforms RFC 1808 + url = '//%s' % url + parts = urlparse(url, scheme='http') + # TODO more scientific checks? + if not parts.netloc: # internal url + return url + elif not domain: + return url + elif parts.netloc.endswith(domain): + return url + elif parts.scheme in allowed_schemes: + return url + def prepare_response(request, user, next='', renew=False): """Return the unique username and the token as 'X-Auth-User' and 'X-Auth-Token' headers, @@ -115,6 +162,8 @@ def prepare_response(request, user, next='', renew=False): except ValidationError, e: return HttpResponseBadRequest(e) + next = restrict_next(next, domain=COOKIE_DOMAIN) + if FORCE_PROFILE_UPDATE and not user.is_verified and not user.is_superuser: params = '' if next: