def test_encode_decode(string_num): """Check if querystringsafe_base64.encode can be reverted by querystringsafe_base64.decode.""" original = test_strings[string_num] encoded = querystringsafe_base64.encode(original) decoded = querystringsafe_base64.decode(encoded) assert decoded == original
def test_encode_decode_unpad(string_num): """Check if querystringsafe_base64.encode can be reverted by querystringsafe_base64.decode with padding removed.""" original = test_strings[string_num] encoded = querystringsafe_base64.encode(original) assert len(encoded) % 4 != 0 # make sure it would end with padding decoded = querystringsafe_base64.decode(encoded.rstrip()) assert decoded == original
def stub_attribution_code(request): """Return a JSON response containing the HMAC signed stub attribution value""" if not request.is_ajax(): return HttpResponseJSON({'error': 'Resource only available via XHR'}, status=400) response = None rate = settings.STUB_ATTRIBUTION_RATE key = settings.STUB_ATTRIBUTION_HMAC_KEY if not rate: # return as though it was rate limited, since it was response = HttpResponseJSON({'error': 'rate limited'}, status=429) elif not key: response = HttpResponseJSON({'error': 'service not configured'}, status=403) if response: patch_response_headers(response, 300) # 5 min return response data = request.GET codes = OrderedDict() has_value = False for name, default_value in STUB_VALUE_NAMES: val = data.get(name, '') # remove utm_ name = name[4:] if val and STUB_VALUE_RE.match(val): codes[name] = val has_value = True else: codes[name] = default_value if codes['source'] == '(not set)' and 'referrer' in data: try: domain = urlparse(data['referrer']).netloc if domain and STUB_VALUE_RE.match(domain): codes['source'] = domain codes['medium'] = 'referral' has_value = True except Exception: # any problems and we should just ignore it pass if not has_value: codes['source'] = 'www.mozilla.org' codes['medium'] = '(none)' codes['timestamp'] = str(int(time())) code = '&'.join('='.join(attr) for attr in codes.items()) code = querystringsafe_base64.encode(code) sig = hmac.new(key, code, hashlib.sha256).hexdigest() response = HttpResponseJSON({ 'attribution_code': code, 'attribution_sig': sig, }) patch_response_headers(response, 300) # 5 min return response
def test_encode_result_is_agnostic_to_url_quoting(string_num): """Test if querystringsafe_base64.encode returns a string that does not have characters that must be quoted.""" original = test_strings[string_num] # quoting and unquoting has no impact on base64dotted: safe_encoded = querystringsafe_base64.encode(original).decode('ascii') assert safe_encoded == quote_plus(safe_encoded) assert safe_encoded == unquote_plus(safe_encoded) # base64 has to be quoted: url_encoded = b64encode(original) assert url_encoded != quote_plus(url_encoded)
def test_encode_result_is_agnostic_to_url_quoting(string_num): """Test if querystringsafe_base64.encode returns a string that does not have characters that must be quoted.""" original = test_strings[string_num] # quoting and unquoting has no impact on base64dotted: safe_encoded = querystringsafe_base64.encode(original) assert safe_encoded == quote_plus(safe_encoded) assert safe_encoded == unquote_plus(safe_encoded) # base64 has to be quoted: url_encoded = b64encode(original) assert url_encoded != quote_plus(url_encoded)
def sign_attribution_codes(codes): """ Take the attribution codes and return the base64 encoded string respecting max length and HMAC signature. """ key = settings.STUB_ATTRIBUTION_HMAC_KEY code = get_attrribution_code(codes) if len(code) > settings.STUB_ATTRIBUTION_MAX_LEN: return None code = querystringsafe_base64.encode(code.encode()) sig = hmac.new(key.encode(), code, hashlib.sha256).hexdigest() return {'attribution_code': code.decode(), 'attribution_sig': sig}
def signed_codes(): # random data codes = ( ('source', 'google'), ('medium', str(uuid4())), ('campaign', '(not set)'), ('content', '(not set)'), ('timestamp', str(int(time()))), ) code = '&'.join('='.join(attr) for attr in codes) code = querystringsafe_base64.encode(code.encode()) sig = hmac.new(_HMAC_KEY.encode(), code.encode(), hashlib.sha256).hexdigest() return code, sig
def sign_attribution_codes(codes): """ Take the attribution codes and return the base64 encoded string respecting max length and HMAC signature. """ key = settings.STUB_ATTRIBUTION_HMAC_KEY code = get_attrribution_code(codes) if len(code) > settings.STUB_ATTRIBUTION_MAX_LEN: return None code = querystringsafe_base64.encode(code) sig = hmac.new(key, code, hashlib.sha256).hexdigest() return { 'attribution_code': code, 'attribution_sig': sig, }