def test_default_bucket_exists_and_has_user_id(self): bucket = self.app.get(self.bucket_url, headers=self.headers) result = bucket.json settings = self.app.app.registry.settings hmac_secret = settings["userid_hmac_secret"] bucket_id = hmac_digest(hmac_secret, self.principal)[:32] self.assertEqual(result["data"]["id"], text_type(UUID(bucket_id))) self.assertEqual(result["permissions"]["write"], [self.principal])
def test_default_bucket_exists_and_has_user_id(self): bucket = self.app.get(self.bucket_url, headers=self.headers) result = bucket.json settings = self.app.app.registry.settings hmac_secret = settings['cliquet.userid_hmac_secret'] bucket_id = hmac_digest(hmac_secret, self.principal)[:32] self.assertEqual(result['data']['id'], text_type(UUID(bucket_id))) self.assertEqual(result['permissions']['write'], [self.principal])
def test_default_bucket_exists_and_has_user_id(self): bucket = self.app.get(self.bucket_url, headers=self.headers) result = bucket.json settings = self.app.app.registry.settings hmac_secret = settings['userid_hmac_secret'] bucket_id = hmac_digest(hmac_secret, self.principal)[:32] self.assertEqual(result['data']['id'], text_type(UUID(bucket_id))) self.assertEqual(result['permissions']['write'], [self.principal])
def unauthenticated_userid(self, request): settings = request.registry.settings credentials = self._get_credentials(request) if credentials: username, password = credentials if not username: return hmac_secret = settings['userid_hmac_secret'] credentials = '%s:%s' % credentials userid = utils.hmac_digest(hmac_secret, credentials) return userid
def default_bucket(request): if request.method.lower() == 'options': path = request.path.replace('default', 'unknown') subrequest = build_request(request, { 'method': 'OPTIONS', 'path': path }) return request.invoke_subrequest(subrequest) if getattr(request, 'prefixed_userid', None) is None: # Pass through the forbidden_view_config raise httpexceptions.HTTPForbidden() settings = request.registry.settings if asbool(settings['readonly']): raise httpexceptions.HTTPMethodNotAllowed() hmac_secret = settings['userid_hmac_secret'] # Build the user unguessable bucket_id UUID from its user_id digest = hmac_digest(hmac_secret, request.prefixed_userid) bucket_id = text_type(UUID(digest[:32])) path = request.path.replace('/buckets/default', '/buckets/%s' % bucket_id) querystring = request.url[(request.url.index(request.path) + len(request.path)):] # Make sure bucket exists create_bucket(request, bucket_id) # Make sure the collection exists create_collection(request, bucket_id) subrequest = build_request(request, { 'method': request.method, 'path': path + querystring, 'body': request.body }) subrequest.bound_data = request.bound_data try: response = request.invoke_subrequest(subrequest) except httpexceptions.HTTPException as error: if error.content_type == 'application/json': response = reapply_cors(subrequest, error) else: # Ask the upper level to format the error. raise error return response
def default_bucket(request): if request.method.lower() == 'options': path = request.path.replace('default', 'unknown') subrequest = build_request(request, { 'method': 'OPTIONS', 'path': path }) return request.invoke_subrequest(subrequest) if getattr(request, 'prefixed_userid', None) is None: raise HTTPForbidden() # Pass through the forbidden_view_config settings = request.registry.settings hmac_secret = settings['userid_hmac_secret'] # Build the user unguessable bucket_id UUID from its user_id digest = hmac_digest(hmac_secret, request.prefixed_userid) bucket_id = text_type(UUID(digest[:32])) path = request.path.replace('/buckets/default', '/buckets/%s' % bucket_id) querystring = request.url[(request.url.index(request.path) + len(request.path)):] # Make sure bucket exists create_bucket(request, bucket_id) # Make sure the collection exists create_collection(request, bucket_id) subrequest = build_request(request, { 'method': request.method, 'path': path + querystring, 'body': request.body }) subrequest.bound_data = request.bound_data try: response = request.invoke_subrequest(subrequest) except HTTPException as error: if error.content_type == 'application/json': response = reapply_cors(subrequest, error) else: # Ask the upper level to format the error. raise error return response
def default_bucket(request): if request.method.lower() == 'options': path = request.path.replace('default', 'unknown') subrequest = build_request(request, { 'method': 'OPTIONS', 'path': path }) return request.invoke_subrequest(subrequest) if getattr(request, 'prefixed_userid', None) is None: raise HTTPForbidden # Pass through the forbidden_view_config settings = request.registry.settings hmac_secret = settings['userid_hmac_secret'] # Build the user unguessable bucket_id UUID from its user_id digest = hmac_digest(hmac_secret, request.prefixed_userid) bucket_id = text_type(UUID(digest[:32])) path = request.path.replace('/buckets/default', '/buckets/%s' % bucket_id) querystring = request.url[(request.url.index(request.path) + len(request.path)):] # Make sure bucket exists create_bucket(request, bucket_id) # Make sure the collection exists create_collection(request, bucket_id) subrequest = build_request(request, { 'method': request.method, 'path': path + querystring, 'body': request.body }) subrequest.bound_data = request.bound_data try: response = request.invoke_subrequest(subrequest) except HTTPException as error: response = reapply_cors(subrequest, error) return response
def default_bucket(request): if getattr(request, 'prefixed_userid', None) is None: raise HTTPForbidden # Pass through the forbidden_view_config settings = request.registry.settings hmac_secret = settings['cliquet.userid_hmac_secret'] # Build the user unguessable bucket_id UUID from its user_id bucket_id = hmac_digest(hmac_secret, request.prefixed_userid)[:32] path = request.path.replace('default', bucket_id) # Make sure bucket exists create_bucket(request, bucket_id) # Make sure the collection exists create_collection(request, bucket_id) subrequest = build_request(request, { 'method': request.method, 'path': path, 'body': request.body }) return request.invoke_subrequest(subrequest)
def get_user_id(self, credentials): hmac_secret = self.config.get("app:main", "kinto.userid_hmac_secret") credentials = "%s:%s" % credentials digest = cliquet_utils.hmac_digest(hmac_secret, credentials) return "basicauth:%s" % digest
def default_bucket_id(request): settings = request.registry.settings secret = settings['userid_hmac_secret'] # Build the user unguessable bucket_id UUID from its user_id digest = hmac_digest(secret, request.prefixed_userid) return six.text_type(uuid.UUID(digest[:32]))
def build_sync_client(request): # Get the BID assertion is_authorization_defined = AUTHORIZATION_HEADER in request.headers starts_with_browser_id = False if is_authorization_defined: authorization = request.headers[AUTHORIZATION_HEADER].lower() starts_with_browser_id = authorization.startswith("browserid ") if not is_authorization_defined or not starts_with_browser_id: msg = "Provide a BID assertion %s header." % AUTHORIZATION_HEADER response = http_error(httpexceptions.HTTPUnauthorized(), errno=ERRORS.MISSING_AUTH_TOKEN, message=msg) response.headers.extend(forget(request)) raise response bucket_id = request.matchdict["bucket_id"] is_client_state_header_defined = CLIENT_STATE_HEADER in request.headers if bucket_id == "syncto": if not is_client_state_header_defined: msg = "Provide the tokenserver %s header." % CLIENT_STATE_HEADER response = http_error(httpexceptions.HTTPUnauthorized(), errno=ERRORS.MISSING_AUTH_TOKEN, message=msg) response.headers.extend(forget(request)) raise response client_state = request.headers[CLIENT_STATE_HEADER] elif len(bucket_id) != CLIENT_STATE_LENGTH: msg = "The provided bucket ID is incorrect." response = http_error(httpexceptions.HTTPUnauthorized(), errno=ERRORS.MISSING_AUTH_TOKEN, message=msg) response.headers.extend(forget(request)) raise response else: client_state = bucket_id if is_client_state_header_defined: send_alert(request, "%s header is deprecated and should not be " "provided anymore." % CLIENT_STATE_HEADER) authorization_header = request.headers[AUTHORIZATION_HEADER] bid_assertion = authorization_header.split(" ", 1)[1] settings = request.registry.settings cache = request.registry.cache statsd = request.registry.statsd token_server_url = settings["token_server_url"] hmac_secret = settings["cache_hmac_secret"] cache_key = "credentials_%s" % utils.hmac_digest(hmac_secret, bid_assertion) ca_bundle = settings["certificate_ca_bundle"] encrypted_credentials = cache.get(cache_key) if not encrypted_credentials: settings_ttl = int(settings["cache_credentials_ttl_seconds"]) bid_ttl = _extract_bid_assertion_ttl(bid_assertion) ttl = min(settings_ttl, bid_ttl or settings_ttl) tokenserver = TokenserverClient(bid_assertion, client_state, token_server_url, verify=ca_bundle) if statsd: statsd.watch_execution_time(tokenserver, prefix="tokenserver") credentials = tokenserver.get_hawk_credentials(duration=ttl) encrypted = encrypt(json.dumps(credentials), client_state, hmac_secret) cache.set(cache_key, encrypted, ttl) else: credentials = json.loads(decrypt(encrypted_credentials, client_state, hmac_secret)) if statsd: timer = statsd.timer("syncclient.start_time") timer.start() sync_client = SyncClient(verify=ca_bundle, **credentials) if statsd: timer.stop() statsd.watch_execution_time(sync_client, prefix="syncclient") return sync_client
def get_user_id(self, credentials): hmac_secret = self.config.get('app:main', 'cliquet.userid_hmac_secret') credentials = '%s:%s' % credentials digest = cliquet_utils.hmac_digest(hmac_secret, credentials) return 'basicauth:%s' % digest
def build_sync_client(request): # Get the BID assertion is_authorization_defined = AUTHORIZATION_HEADER in request.headers starts_with_browser_id = False if is_authorization_defined: authorization = request.headers[AUTHORIZATION_HEADER].lower() starts_with_browser_id = authorization.startswith("browserid ") if not is_authorization_defined or not starts_with_browser_id: msg = "Provide a BID assertion %s header." % AUTHORIZATION_HEADER response = http_error(httpexceptions.HTTPUnauthorized(), errno=ERRORS.MISSING_AUTH_TOKEN, message=msg) response.headers.extend(forget(request)) raise response is_client_state_defined = CLIENT_STATE_HEADER in request.headers if not is_client_state_defined: msg = "Provide the tokenserver %s header." % CLIENT_STATE_HEADER response = http_error(httpexceptions.HTTPUnauthorized(), errno=ERRORS.MISSING_AUTH_TOKEN, message=msg) response.headers.extend(forget(request)) raise response authorization_header = request.headers[AUTHORIZATION_HEADER] bid_assertion = authorization_header.split(" ", 1)[1] client_state = request.headers[CLIENT_STATE_HEADER] settings = request.registry.settings cache = request.registry.cache statsd = request.registry.statsd token_server_url = settings['token_server_url'] hmac_secret = settings['cache_hmac_secret'] cache_key = 'credentials_%s' % utils.hmac_digest(hmac_secret, bid_assertion) encrypted_credentials = cache.get(cache_key) if not encrypted_credentials: settings_ttl = int(settings['cache_credentials_ttl_seconds']) bid_ttl = _extract_bid_assertion_ttl(bid_assertion) ttl = min(settings_ttl, bid_ttl or settings_ttl) tokenserver = TokenserverClient(bid_assertion, client_state, token_server_url) if statsd: statsd.watch_execution_time(tokenserver, prefix="tokenserver") credentials = tokenserver.get_hawk_credentials(duration=ttl) encrypted = encrypt(json.dumps(credentials), client_state, hmac_secret) cache.set(cache_key, encrypted, ttl) else: credentials = json.loads( decrypt(encrypted_credentials, client_state, hmac_secret)) if statsd: timer = statsd.timer("syncclient.start_time") timer.start() sync_client = SyncClient(**credentials) if statsd: timer.stop() statsd.watch_execution_time(sync_client, prefix="syncclient") return sync_client
def test_supports_secret_as_text(self): value = hmac_digest("blah", "input data") self.assertTrue(value.startswith("d4f5c51db246c7faeb42240545b47274b6"))
def test_supports_secret_as_bytes(self): value = hmac_digest(b"blah", "input data") self.assertTrue(value.startswith("d4f5c51db246c7faeb42240545b47274b6"))
def get_user_id(self, credentials): hmac_secret = self.config.get('app:main', 'kinto.userid_hmac_secret') credentials = '%s:%s' % credentials digest = cliquet_utils.hmac_digest(hmac_secret, credentials) return 'basicauth:%s' % digest