# HG changeset patch # User Todd Larsen # Date 1222212615 0 # Node ID b1351bf810640927082e2ee566c2f6d58dc0d7da # Parent 1cf3e7531382c30199710b357bb187c5cf6eda63 Move isReferrerSelf() and replaceSuffix() into new request_helpers.py module, since they are (mainly) used to manipulate parts of an HTTP request. diff -r 1cf3e7531382 -r b1351bf81064 app/soc/views/helpers/request_helpers.py --- a/app/soc/views/helpers/request_helpers.py Tue Sep 23 23:20:23 2008 +0000 +++ b/app/soc/views/helpers/request_helpers.py Tue Sep 23 23:30:15 2008 +0000 @@ -85,3 +85,93 @@ # TODO(tlarsen): write getMultipleIndexParamValues() that returns a # list of values if present, omitting those values that are # out of range + + +def isReferrerSelf(request, + expected_prefix=None, suffix=None): + """Returns True if HTTP referrer path starts with the HTTP request path. + + Args: + request: the Django HTTP request object; request.path is used if + expected_path is not supplied (the most common usage) + expected_prefix: optional HTTP path to use instead of the one in + request.path; default is None (use request.path) + suffix: suffix to remove from the HTTP request path before comparing + it to the HTTP referrer path in the HTTP request object headers + (this is often an link name, for example, that may be changing from + a POST referrer to a GET redirect target) + + Returns: + True if HTTP referrer path begins with the HTTP request path (either + request.path or expected_prefix instead if it was supplied), after + any suffix was removed from that request path + False otherwise + + """ + http_from = request.META.get('HTTP_REFERER') + + if not http_from: + # no HTTP referrer, so cannot possibly start with expected prefix + return False + + from_path = urlparse.urlparse(http_from).path + + if not expected_prefix: + # use HTTP request path, since expected_prefix was not supplied + expected_prefix = request.path + + if suffix: + # remove suffix (such as a link name) before comparison + chars_to_remove = len(suffix) + + if not suffix.startswith('/'): + chars_to_remove = chars_to_remove + 1 + + expected_prefix = expected_prefix[:-chars_to_remove] + + if not from_path.startswith(expected_prefix): + # expected prefix did not match first part of HTTP referrer path + return False + + # HTTP referrer started with (possibly truncated) expected prefix + return True + + +def replaceSuffix(path, old_suffix, new_suffix=None, params=None): + """Replace the last part of a URL path with something else. + + Also appends an optional list of query parameters. Used for + replacing, for example, one link name at the end of a relative + URL path with another. + + Args: + path: HTTP request relative URL path (with no query arguments) + old_suffix: expected suffix at the end of request.path component; + if any False value (such as None), the empty string '' is used + new_suffix: if non-False, appended to request.path along with a + '/' separator (after removing old_suffix if necessary) + params: an optional dictionary of query parameters to append to + the redirect target; appended as ?=&=... + + Returns: + /path/with/new_suffix?a=1&b=2 + """ + if not old_suffix: + old_suffix = '' + + old_suffix = '/' + old_suffix + + if path.endswith(old_suffix): + # also removes any trailing '/' if old_suffix was empty + path = path[:-len(old_suffix)] + + if new_suffix: + # if present, appends new_suffix, after '/' separator + path = '%s/%s' % (path, new_suffix) + + if params: + # appends any query parameters, after a '?' and separated by '&' + path = '%s?%s' % (path, '&'.join( + ['%s=%s' % (p,v) for p,v in params.iteritems()])) + + return path diff -r 1cf3e7531382 -r b1351bf81064 app/soc/views/helpers/response_helpers.py --- a/app/soc/views/helpers/response_helpers.py Tue Sep 23 23:20:23 2008 +0000 +++ b/app/soc/views/helpers/response_helpers.py Tue Sep 23 23:30:15 2008 +0000 @@ -42,6 +42,9 @@ from soc.logic import system from soc.logic.site import id_user +from soc.views.helpers import request_helpers +from soc.views.helpers import template_helpers + def respond(request, template, context=None, response_args=None): """Helper to render a response, passing standard stuff to the response. @@ -125,46 +128,6 @@ return context -def replaceSuffix(path, old_suffix, new_suffix=None, params=None): - """Replace the last part of a URL path with something else. - - Also appends an optional list of query parameters. Used for - replacing, for example, one link name at the end of a relative - URL path with another. - - Args: - path: HTTP request relative URL path (with no query arguments) - old_suffix: expected suffix at the end of request.path component; - if any False value (such as None), the empty string '' is used - new_suffix: if non-False, appended to request.path along with a - '/' separator (after removing old_suffix if necessary) - params: an optional dictionary of query parameters to append to - the redirect target; appended as ?=&=... - - Returns: - /path/with/new_suffix?a=1&b=2 - """ - if not old_suffix: - old_suffix = '' - - old_suffix = '/' + old_suffix - - if path.endswith(old_suffix): - # also removes any trailing '/' if old_suffix was empty - path = path[:-len(old_suffix)] - - if new_suffix: - # if present, appends new_suffix, after '/' separator - path = '%s/%s' % (path, new_suffix) - - if params: - # appends any query parameters, after a '?' and separated by '&' - path = '%s?%s' % (path, '&'.join( - ['%s=%s' % (p,v) for p,v in params.iteritems()])) - - return path - - def redirectToChangedSuffix( request, old_suffix, new_suffix=None, params=None): """Changes suffix of URL path and returns an HTTP redirect response. @@ -172,60 +135,11 @@ Args: request: the Django HTTP request object; redirect path is derived from request.path - old_suffix, new_suffix, params: see replaceSuffix() + old_suffix, new_suffix, params: see request_helpers.replaceSuffix() Returns: a Django HTTP redirect response pointing to the altered path """ - path = replaceSuffix(request.path, old_suffix, new_suffix, params=params) + path = request_helpers.replaceSuffix(request.path, old_suffix, new_suffix, + params=params) return http.HttpResponseRedirect(path) - - -def isReferrerSelf(request, - expected_prefix=None, suffix=None): - """Returns True if HTTP referrer path starts with the HTTP request path. - - Args: - request: the Django HTTP request object; request.path is used if - expected_path is not supplied (the most common usage) - expected_prefix: optional HTTP path to use instead of the one in - request.path; default is None (use request.path) - suffix: suffix to remove from the HTTP request path before comparing - it to the HTTP referrer path in the HTTP request object headers - (this is often an link name, for example, that may be changing from - a POST referrer to a GET redirect target) - - Returns: - True if HTTP referrer path begins with the HTTP request path (either - request.path or expected_prefix instead if it was supplied), after - any suffix was removed from that request path - False otherwise - - """ - http_from = request.META.get('HTTP_REFERER') - - if not http_from: - # no HTTP referrer, so cannot possibly start with expected prefix - return False - - from_path = urlparse.urlparse(http_from).path - - if not expected_prefix: - # use HTTP request path, since expected_prefix was not supplied - expected_prefix = request.path - - if suffix: - # remove suffix (such as a link name) before comparison - chars_to_remove = len(suffix) - - if not suffix.startswith('/'): - chars_to_remove = chars_to_remove + 1 - - expected_prefix = expected_prefix[:-chars_to_remove] - - if not from_path.startswith(expected_prefix): - # expected prefix did not match first part of HTTP referrer path - return False - - # HTTP referrer started with (possibly truncated) expected prefix - return True diff -r 1cf3e7531382 -r b1351bf81064 app/soc/views/site/user/profile.py --- a/app/soc/views/site/user/profile.py Tue Sep 23 23:20:23 2008 +0000 +++ b/app/soc/views/site/user/profile.py Tue Sep 23 23:30:15 2008 +0000 @@ -153,7 +153,7 @@ if request.path.endswith('lookup'): # convert /lookup path into /profile/link_name path - context['edit_link'] = response_helpers.replaceSuffix( + context['edit_link'] = request_helpers.replaceSuffix( request.path, 'lookup', 'profile/%s' % user.link_name) # else: URL is not one that was expected, so do not display edit link elif not form: @@ -283,7 +283,7 @@ # is 'Profile saved' parameter present, but referrer was not ourself? # (e.g. someone bookmarked the GET that followed the POST submit) if (request.GET.get(profile.SUBMIT_MSG_PARAM_NAME) - and (not response_helpers.isReferrerSelf(request, + and (not request_helpers.isReferrerSelf(request, suffix=linkname))): # redirect to aggressively remove 'Profile saved' query parameter return http.HttpResponseRedirect(request.path)