def _prepare_artifacts(self, attributes): """Converts the request and attributes into an artifacts dict.""" artifacts = { "method": self.req["method"], "host": self.req["host"], "port": self.req["port"], "resource": util.parse_normalized_url(self.req["url"])["resource"], } artifact_keys = ["ts", "nonce", "hash", "ext", "app", "dlg", "mac", "id"] attrs = attributes.keys() for key in artifact_keys: if key in attrs: artifacts[key] = attributes[key] else: # I think we want empty strings in normalized header mac artifacts[key] = "" return artifacts
def _prepare_artifacts(self, attributes): """Converts the request and attributes into an artifacts dict.""" artifacts = { 'method': self.req['method'], 'host': self.req['host'], 'port': self.req['port'], 'resource': util.parse_normalized_url(self.req['url'])['resource'], } artifact_keys = ['ts', 'nonce', 'hash', 'ext', 'app', 'dlg', 'mac', 'id'] attrs = attributes.keys() for key in artifact_keys: if key in attrs: artifacts[key] = attributes[key] else: # I think we want empty strings in normalized header mac artifacts[key] = '' return artifacts
def _prepare_artifacts(self, attributes): """Converts the request and attributes into an artifacts dict.""" artifacts = { 'method': self.req['method'], 'host': self.req['host'], 'port': self.req['port'], 'resource': util.parse_normalized_url(self.req['url'])['resource'], } artifact_keys = [ 'ts', 'nonce', 'hash', 'ext', 'app', 'dlg', 'mac', 'id' ] attrs = attributes.keys() for key in artifact_keys: if key in attrs: artifacts[key] = attributes[key] else: # I think we want empty strings in normalized header mac artifacts[key] = '' return artifacts
def get_bewit(uri, options=None): # XXX Where is credentials here? """ Generate a bewit value for a given URI Compatibility Note: HAWK exposes this as hawk.uri.getBewit credentials is an object with the following keys: 'id, 'key', 'algorithm'. options is an object with the following optional keys: 'ext', 'localtime_offset_msec' uri: 'http://example.com/resource?a=b' or object from Url.parse() options: { Required credentials: { id: 'dh37fgj492je', key: 'aoijedoaijsdlaksjdl', algorithm: 'sha256' // 'sha1', 'sha256' }, ttl_sec: 60 * 60, // TTL in seconds Optional ext: 'application-specific', // Application specific data // sent via the ext attribute. localtime_offset_msec: 400 // Time offset to sync with // server time } """ if not valid_bewit_args(uri, options): return '' now = time.time() + int(options['localtime_offset_msec']) creds = options['credentials'] if 'id' not in creds or 'key' not in creds or 'algorithm' not in creds: raise BadRequest url_parts = util.parse_normalized_url(uri) exp = now + int(options['ttl_sec']) resource = url_parts['path'] if len(url_parts['query']) > 0: resource += '?' + url_parts['query'] artifacts = { 'ts': int(exp), 'nonce': '', 'method': 'GET', 'resource': resource, 'host': url_parts['hostname'], 'port': str(url_parts['port']), 'ext': options['ext'] } return hcrypto.calculate_bewit(creds, artifacts, exp)
def header(url, method, options=None): """ :param uri: 'http://example.com/resource?a=b' :param method: HTTP verb ('GET', 'POST', etc) :param options: Required Options: credentials (id, key, algorithm) Optional: ext: Application specific data (string) timestamp: A pre-calculated timestamp nonce: '2334f34f': A pre-generated nonce localtimeOffsetMsec: Time offset to sync with server time (ignored if timestamp provided) (Example 400) payload: UTF-8 encoded string for body hash generation (ignored if hash provided) (Example '{"some":"payload"}') contentType: Payload content-type (ignored if hash provided) (Example 'application/json') hash: Pre-calculated payload hash (Example 'U4MKKSmiVxk37JCCrAVIjV=') app: Oz application id ('24s23423f34dx') dlg: Oz delegated-by application id - '234sz34tww3sd' """ result = {'field': '', 'artifacts': {}} if url is None or len(url) == 0: log.info("Bad URL skipping") return result if method is None or len(method) == 0: log.info("Bad method skipping") return result if not isinstance(options, dict): log.info("Bad options skipping") return result if 'credentials' not in options: log.info("Bad credentials skipping") return result cred = options['credentials'] if 'id' not in cred or 'key' not in cred or 'algorithm' not in cred: log.info("Bad credentail elements skipping") return result timestamp = math.floor(time.time()) if 'timestamp' in options: offset = 0 if 'localtimeOffsetMsec' in options: offset = int(options['localtimeOffsetMsec']) timestamp = math.floor(options['timestamp'] + offset) if 'nonce' not in options: options['nonce'] = hcrypto.random_string(6) url_parts = util.parse_normalized_url(url) # TODO use None or '' for these optional artifacts? if 'hash' not in options: options['hash'] = None if 'ext' not in options: options['ext'] = None if 'app' not in options: options['app'] = None if 'dlg' not in options: options['dlg'] = None resource = url_parts['resource'] log.debug('parsed URL parts: %s' % pprint.pformat(url_parts)) artifacts = { 'ts': int(timestamp), 'nonce': options['nonce'], 'method': method, 'resource': resource, 'host': url_parts['hostname'], 'port': url_parts['port'], 'hash': options['hash'], 'ext': options['ext'], 'app': options['app'], 'dlg': options['dlg'] } result['artifacts'] = artifacts if artifacts['hash'] is None and 'payload' in options: if 'contentType' not in options: options['contentType'] = 'text/plain' log.debug('about to hash payload: %s' % options['payload']) log.debug('algorithm=%s, contentType=%s' % (cred['algorithm'], options['contentType'])) artifacts['hash'] = hcrypto.calculate_payload_hash( options['payload'], cred['algorithm'], options['contentType']) log.debug('artifacts=%s' % pprint.pformat(artifacts)) mac = hcrypto.calculate_mac('header', cred, artifacts) _header = ''.join([ 'Hawk id="', cred['id'], '"', ', ts="', str(artifacts['ts']), '"', ', nonce="', artifacts['nonce'], '"', ]) if len(artifacts['hash']) > 0: _header += ', hash="' + artifacts['hash'] + '"' if artifacts['ext'] is not None and len(artifacts['ext']) > 0: util.check_header_attribute(artifacts['ext']) h_ext = artifacts['ext'].replace('\\', '\\\\').replace('\n', '\\n') _header += ', ext="' + h_ext + '"' _header += ', mac="' + mac + '"' if artifacts['app'] is not None: _header += ', app="' + artifacts['app'] + '"' if artifacts['dlg'] is not None: _header += ', dlg="' + artifacts['dlg'] + '"' result['field'] = _header return result