def test_compare(self): """ Tests the compare funciton """ a, b = 'test123', 'test123' compare_result_true = compare(a, b) self.assertTrue(compare_result_true) a, b = 'test123', 'test456' compare_result_false = compare(a, b) self.assertFalse(compare_result_false)
def verifyURL(request, hmac_key=None, hash_vars=True, salt=None, user_signature=None): """ Verifies that a request's args & vars have not been tampered with by the user :param request: web2py's request object :param hmac_key: the key to authenticate with, must be the same one previously used when calling URL() :param hash_vars: which vars to include in our hashing. (Optional) Only uses the 1st value currently True (or undefined) means all, False none, an iterable just the specified keys do not call directly. Use instead: URL.verify(hmac_key='...') the key has to match the one used to generate the URL. >>> r = Storage() >>> gv = Storage(p=(1,3),q=2,_signature='a32530f0d0caa80964bb92aad2bedf8a4486a31f') >>> r.update(dict(application='a', controller='c', function='f', extension='html')) >>> r['args'] = ['x', 'y', 'z'] >>> r['get_vars'] = gv >>> verifyURL(r, 'key') True >>> verifyURL(r, 'kay') False >>> r.get_vars.p = (3, 1) >>> verifyURL(r, 'key') True >>> r.get_vars.p = (3, 2) >>> verifyURL(r, 'key') False """ if not '_signature' in request.get_vars: return False # no signature in the request URL # check if user_signature requires if user_signature: from globals import current if not current.session or not current.session.auth: return False hmac_key = current.session.auth.hmac_key if not hmac_key: return False # get our sig from request.get_vars for later comparison original_sig = request.get_vars._signature # now generate a new hmac for the remaining args & vars vars, args = request.get_vars, request.args # remove the signature var since it was not part of our signed message request.get_vars.pop('_signature') # join all the args & vars into one long string # always include all of the args other = args and urllib.quote('/' + '/'.join([str(x) for x in args])) or '' h_args = '/%s/%s/%s.%s%s' % (request.application, request.controller, request.function, request.extension, other) # but only include those vars specified (allows more flexibility for use with # forms or ajax) list_vars = [] for (key, vals) in sorted(vars.items()): if not isinstance(vals, (list, tuple)): vals = [vals] for val in vals: list_vars.append((key, val)) # which of the vars are to be included? if hash_vars is True: # include them all h_vars = list_vars elif hash_vars is False: # include none of them h_vars = '' else: # include just those specified # wrap in a try - if the desired vars have been removed it'll fail try: if hash_vars and not isinstance(hash_vars, (list, tuple)): hash_vars = [hash_vars] h_vars = [(k, v) for (k, v) in list_vars if k in hash_vars] except: # user has removed one of our vars! Immediate fail return False # build the full message string with both args & vars message = h_args + '?' + urllib.urlencode(sorted(h_vars)) # hash with the hmac_key provided sig = simple_hash(message, str(hmac_key), salt or '', digest_alg='sha1') # put _signature back in get_vars just in case a second call to URL.verify is performed # (otherwise it'll immediately return false) request.get_vars['_signature'] = original_sig # return whether or not the signature in the request matched the one we just generated # (I.E. was the message the same as the one we originally signed) return compare(original_sig, sig)