import, import calendarfrom base64importb64encode urlsafe_b64encode import import hmac logging import logging math import math import os import pprint import re import sys import time
import six
from .exc import (
BadHeaderValue,
HawkFail,
InvalidCredentials)
def validate_credentials(creds): ifnot hasattr(creds, '__getitem__'): raise InvalidCredentials('credentials must be a dict-like object') try:
creds['id']
creds['key']
creds['algorithm'] except KeyError:
etype, val, tb = sys.exc_info() raise InvalidCredentials('{etype}: {val}'
.format(etype=etype, val=val))
def random_string(length): """Generates a random string for a given length.""" # this conservatively gets 8*length bits and then returns 6*length of # them. Grabbing (6/8)*length bits could lose some entropy off the ends. return urlsafe_b64encode(os.urandom(length))[:length]
def calculate_payload_hash(payload, algorithm, content_type, block_size=1024): """Calculates a hash for a given payload."""
p_hash = hashlib.new(algorithm)
for i, p in enumerate(parts): # Make sure we are about to hash binary strings. if hasattr(p, "read"):
log.debug("part %i being handled as a file object", i) whileTrue:
block = p.read(block_size) ifnot block: break
p_hash.update(block) elifnot isinstance(p, six.binary_type):
p = p.encode('utf8')
p_hash.update(p) else:
p_hash.update(p)
parts[i] = p
if scheme.lower() != 'hawk': raise HawkFail("Unknown scheme '{scheme}' when parsing header"
.format(scheme=scheme))
attributes = {}
def replace_attribute(match): """Extract the next key="value"-pair in the header."""
key = match.group('key')
value = match.group('value') if key notin allowable_header_keys: raise HawkFail("Unknown Hawk key '{key}' when parsing header"
.format(key=key))
validate_header_attr(value, name=key) if key in attributes: raise BadHeaderValue('Duplicate key in header: {key}'.format(key=key))
attributes[key] = value
# Iterate over all the key="value"-pairs in the header, replace them with # an empty string, and store the extracted attribute in the attributes # dict. Correctly formed headers will then leave nothing unparsed ('').
unparsed_header = HAWK_HEADER_RE.sub(replace_attribute, attributes_string) if unparsed_header != '': raise BadHeaderValue("Couldn't parse Hawk header", unparsed_header)
def strings_match(a, b): # Constant time string comparision, mitigates side channel attacks. if len(a) != len(b): returnFalse
result = 0
def byte_ints(buf): for ch in buf: # In Python 3, if we have a bytes object, iterating it will # already get the integer value. In older pythons, we need # to use ord(). ifnot isinstance(ch, int):
ch = ord(ch) yield ch
for x, y in zip(byte_ints(a), byte_ints(b)):
result |= x ^ y return result == 0
def utc_now(offset_in_seconds=0.0): # TODO: add support for SNTP server? See ntplib module. return int(math.floor(calendar.timegm(time.gmtime()) +
float(offset_in_seconds)))
# Allowed value characters: # !#$%&'()*+,-./:;<=>?@[]^_`{|}~ and space, a-z, A-Z, 0-9, \, "
_header_attribute_chars = re.compile(
r"^[ a-zA-Z0-9_\!#\$%&'\(\)\*\+,\-\./\:;<\=>\?@\[\]\^`\{\|\}~]*$")
def validate_header_attr(val, name=None): ifnot _header_attribute_chars.match(val): raise BadHeaderValue('header value name={name} value={val} ' 'contained an illegal character'
.format(name=name or'?', val=repr(val)))
def prepare_header_val(val): if isinstance(val, six.binary_type):
val = val.decode('utf-8')
validate_header_attr(val) return val
def normalize_header_attr(val): if isinstance(val, six.binary_type): return val.decode('utf-8') return val
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.