def get_current_jwt_token(request): """Get current JWT token for authenticated principal""" manager = query_utility(ISecurityManager) if manager is None: raise HTTPServiceUnavailable() configuration = IJWTSecurityConfiguration(manager) if not configuration.enabled: raise HTTPServiceUnavailable() if Authenticated not in request.effective_principals: raise HTTPForbidden() custom_claims = request.params.get('claims', {}) request.response.cache_expires(configuration.refresh_expiration) return { 'status': 'success', configuration.access_token_name: create_jwt_token(request, request.authenticated_userid, expiration=configuration.access_expiration, obj=ACCESS_OBJECT, **custom_claims), configuration.refresh_token_name: create_jwt_token(request, request.authenticated_userid, expiration=configuration.refresh_expiration, obj=REFRESH_OBJECT) }
def __call__(self): """ Return a response with a 200 or 503 status, including a JSON body listing the status and timing information for most outbound connections. """ services = { 'database': check_database, 'geoip': check_geoip, 'redis': check_redis, } failed = False result = {} for name, check in services.items(): try: service_result = check(self.request) except Exception: # pragma: no cover result[name] = {'up': None, 'time': -1} failed = True else: result[name] = service_result if not service_result['up']: failed = True if failed: response = HTTPServiceUnavailable() response.content_type = 'application/json' response.json = result return response return result
def monitor_view(request): services = { 'database': check_database, 'geoip': check_geoip, 'redis': check_redis, 'stats': check_stats, } failed = False result = {} for name, check in services.items(): try: service_result = check(request) except Exception: # pragma: no cover result[name] = {'up': None, 'time': -1} failed = True else: result[name] = service_result if not service_result['up']: failed = True if failed: response = HTTPServiceUnavailable() response.content_type = 'application/json' response.json = result return response return result
def __call__(self): services = { 'database': check_database, 'geoip': check_geoip, 'redis': check_redis, 'stats': check_stats, } failed = False result = {} for name, check in services.items(): try: service_result = check(self.request) except Exception: # pragma: no cover result[name] = {'up': None, 'time': -1} failed = True else: result[name] = service_result if not service_result['up']: failed = True if failed: response = HTTPServiceUnavailable() response.content_type = 'application/json' response.json = result return response return result
def refresh_jwt_token(request): """JWT token refresh service""" sm = query_utility(ISecurityManager) # pylint: disable=invalid-name if sm is None: raise HTTPServiceUnavailable() configuration = IJWTSecurityConfiguration(sm) if not configuration.enabled: raise HTTPServiceUnavailable() # user remote authentication authority if configuration.proxy_mode: handler = IJWTProxyHandler(sm, None) if handler is not None: status_code, token = handler.refresh_token(request) # pylint: disable=assignment-from-no-return request.response.status_code = status_code return token # refresh token locally claims = get_jwt_claims(request) if not claims: raise HTTPForbidden() principal_id = claims.get('sub') if not principal_id: raise HTTPUnauthorized() params = request.params if TEST_MODE else request.validated custom_claims = params.get('claims', {}) return { 'status': 'success', configuration.access_token_name: create_jwt_token(request, principal_id, expiration=configuration.access_expiration, obj=ACCESS_OBJECT, **custom_claims) }
def heartbeat_view(request): try: session = request.db_slave_session conn = session.connection() if conn.execute(select([func.now()])).first() is None: return HTTPServiceUnavailable() else: return {'status': 'OK', 'hostname': LOCAL_FQDN} except Exception: return HTTPServiceUnavailable()
def heartbeat_view(request): success = request.registry.cache.ping(request.registry.raven) if not success: response = HTTPServiceUnavailable() response.content_type = 'application/json' response.json = {'redis': {'up': False}} return response return {'redis': {'up': True}}
def authenticate(request, **kwargs): _api_key = request.headers['X-Api-Key'] # api key not set serverside if 'api.c3smembership.api_key' not in request.registry.settings: raise HTTPServiceUnavailable() if not request.registry.settings['api.c3smembership.api_key']: raise HTTPServiceUnavailable() # api key not valid if _api_key != request.registry.settings['api.c3smembership.api_key']: raise HTTPUnauthorized()
def verify_jwt_token(request): """JWT token verification view""" manager = query_utility(ISecurityManager) if manager is None: raise HTTPServiceUnavailable() configuration = IJWTSecurityConfiguration(manager) if not configuration.enabled: raise HTTPServiceUnavailable() claims = get_jwt_claims(request) if not claims: raise HTTPForbidden() request.response.status_code = HTTPAccepted.code return {'status': 'success'}
def heartbeat_view(request): raven = request.registry.raven kinesis_success = request.registry.kinesis.ping(raven) if not kinesis_success: response = HTTPServiceUnavailable() response.content_type = 'application/json' response.json = { 'queue': {'up': kinesis_success}, } return response return {'queue': {'up': True}}
def heartbeat_view(request): raven = request.registry.raven kinesis_success = request.registry.kinesis.ping(raven) if not kinesis_success: response = HTTPServiceUnavailable() response.content_type = 'application/json' response.json = { 'queue': { 'up': kinesis_success }, } return response return {'queue': {'up': True}}
def master_feed(self, request): """View callable that returns an atom feed for all boards.""" if not self.feeds: # Tell the user to come back later. raise HTTPServiceUnavailable(headers={'Retry-After': '60'}) return Response(self.feeds['master'], content_type='application/atom+xml')
def process_batch(request, data, errors): stats_client = request.registry.stats_client nickname = request.headers.get('X-Nickname', u'') email = request.headers.get('X-Email', u'') upload_items = flatten_items(data) errors = process_upload( nickname, email, upload_items, stats_client, api_key_log=getattr(request, 'api_key_log', False), api_key_name=getattr(request, 'api_key_name', None), ) if errors is SENTINEL: # pragma: no cover return HTTPServiceUnavailable() if errors: # pragma: no cover stats_client.incr('geosubmit.upload.errors', len(errors)) result = HTTPOk() result.content_type = 'application/json' result.body = '{}' return result
def convert_storage_errors(viewfunc, request): """View decorator to convert storage errors into HTTP error responses. This decorator intercepts any storage-backend exceptions and translates them into a matching HTTPError subclass. """ try: return viewfunc(request) except ConflictError: # NOTE: the protocol specification states that we should return # a "409 Conflict" response here, but clients currently do not # handle these respones very well: # * desktop bug: https://bugzilla.mozilla.org/show_bug.cgi?id=959034 # * android bug: https://bugzilla.mozilla.org/show_bug.cgi?id=959032 headers = {"Retry-After": str(RETRY_AFTER)} raise HTTPServiceUnavailable(headers=headers) except NotFoundError: raise HTTPNotFound except InvalidOffsetError: raise json_error(400, "error", [{ "location": "querystring", "name": "offset", "description": "Invalid value for offset", }]) except InvalidBatch, e: raise HTTPBadRequest("Invalid batch: %s" % e)
def __call__(self): if self._get_target_client().is_in_maintenance_mode(): raise HTTPServiceUnavailable() params = dict(self.request.params) replace_placeholder_in_data(params, self._get_source_client().get_public_url()) kwargs = {'headers': self.request.headers} if self.request.method.lower() == 'get': kwargs['params'] = params else: kwargs['data'] = params response = requests.request(self.request.method.lower(), self._get_target_url(), **kwargs) body = response.raw.read().replace( PORTAL_URL_PLACEHOLDER, self._get_target_client().get_public_url()) headers = dict(response.headers) if 'content-length' in headers: del headers['content-length'] proxy_response = Response(body=body, status=response.status_code) proxy_response.headers.update(headers) return proxy_response
def render(self): master = self.isDBMaster() if master: return master try: check_interval = 0.5 timeout = 5 writeDB = app.db.dbWriteInstance() readDB = app.db.dbReadInstance() writeLoc = app.db.getWriteLocation(writeDB) i = 0 while i <= timeout / check_interval: readLoc = app.db.getReadLocation(readDB) assert readLoc if readLoc >= writeLoc: return "This node is in sync, delay = %fs" % ( i * check_interval) time.sleep(check_interval) i += 1 return HTTPServiceUnavailable() finally: writeDB.rollback() writeDB.close() readDB.rollback() readDB.close()
def __call__(self): body = self.request.body if not body: return HTTPBadRequest('Empty body.') if len(body) > self._max_size: return HTTPBadRequest('Encrypted body too large.') try: text = body.decode('ascii') except UnicodeDecodeError: return HTTPBadRequest('Invalid character encoding.') if not self.request.registry.crypto.validate(text): return HTTPBadRequest('Invalid JWE structure.') # Random partition key, as all client data is encrypted. partition_key = '%05d' % random.randint(0, 2**16) kinesis = self.request.registry.kinesis try: kinesis.client.put_record( Data=body, PartitionKey=partition_key, StreamName=kinesis.frontend_stream, ) except botocore.exceptions.ClientError: self.request.registry.raven.captureException() return HTTPServiceUnavailable('Data queue backend unavailable.') return {'status': 'success'}
def __call__(self): """ Return a response with a 200 or 503 status, including a JSON body listing the status and timing information for most outbound connections. """ services = { 'database': check_database, 'geoip': check_geoip, 'redis': check_redis, } failed = False result = {} for name, check in services.items(): try: service_result = check(self.request) except Exception: # pragma: no cover result[name] = {'up': None, 'time': -1} failed = True else: result[name] = service_result if not service_result['up']: failed = True if failed: response = self.prepare_exception(HTTPServiceUnavailable()) response.content_type = 'application/json' response.json = result return response return result
def catch_backend_errors_tween(request): try: return handler(request) except BackendError as err: logger = get_logger(request) err_info = str(err) err_trace = traceback.format_exc() try: extra_info = "user: %s" % (request.user, ) except Exception: extra_info = "user: -" error_log = "%s\n%s\n%s" % (err_info, err_trace, extra_info) hash = create_hash(error_log) logger.error(hash) logger.error(error_log) msg = json.dumps("application error: crash id %s" % hash) if err.retry_after is not None: if err.retry_after == 0: retry_after = None else: retry_after = err.retry_after else: settings = request.registry.settings retry_after = settings.get("mozsvc.retry_after", 1800) return HTTPServiceUnavailable(body=msg, retry_after=retry_after, content_type="application/json")
def maintenance_message(request): _ = TranslationStringFactory('assembl') localizer = request.localizer raise HTTPServiceUnavailable(localizer.translate( _("IdeaLoom is down for maintenance. We'll be back in a few minutes.") ), body_template=maintenance_template)
def convert_storage_errors(viewfunc, request): """View decorator to convert storage errors into HTTP error responses. This decorator intercepts any storage-backend exceptions and translates them into a matching HTTPError subclass. """ try: return viewfunc(request) except ConflictError: # NOTE: the protocol specification states that we should return # a "409 Conflict" response here, but clients currently do not # handle these respones very well: # * desktop bug: https://bugzilla.mozilla.org/show_bug.cgi?id=959034 # * android bug: https://bugzilla.mozilla.org/show_bug.cgi?id=959032 if request.method != "POST" or "bsos" not in request.validated: # For most requests we instead return a "503 Service Unavailable" # gives approximately the right client retry behaviour. headers = {"Retry-After": str(RETRY_AFTER)} raise HTTPServiceUnavailable(headers=headers) else: # For bulk POST operations we can report the error in the response # body, and let the client continue with the rest of its sync. logger.error("ConflictError on POST request") res = {'success': [], 'failed': {}} for bso in request.validated["bsos"]: res["failed"][bso["id"]] = "conflict" return res except NotFoundError: raise HTTPNotFound except InvalidOffsetError: raise json_error(400, "error", [{ "location": "querystring", "name": "offset", "description": "Invalid value for offset", }])
def get_jwt_token(request): """REST login endpoint for JWT authentication""" # check security manager utility sm = query_utility(ISecurityManager) # pylint: disable=invalid-name if sm is None: raise HTTPServiceUnavailable() configuration = IJWTSecurityConfiguration(sm) if not configuration.enabled: raise HTTPServiceUnavailable() # check request params params = request.params if TEST_MODE else request.validated login = params.get('login') if not login: raise HTTPBadRequest() credentials = Credentials('jwt', id=login, **params) # use remote authentication authority if configuration.proxy_mode: handler = IJWTProxyHandler(sm, None) if handler is not None: status_code, tokens = handler.get_tokens(request, credentials) # pylint: disable=assignment-from-no-return request.response.status_code = status_code return tokens # authenticate principal in security manager principal_id = sm.authenticate(credentials, request) if principal_id is not None: custom_claims = params.get('claims', {}) request.response.cache_expires(configuration.refresh_expiration) return { 'status': 'success', configuration.access_token_name: create_jwt_token(request, principal_id, expiration=configuration.access_expiration, obj=ACCESS_OBJECT, **custom_claims), configuration.refresh_token_name: create_jwt_token(request, principal_id, expiration=configuration.refresh_expiration, obj=REFRESH_OBJECT) } request.response.status_code = HTTPUnauthorized.code return { 'status': 'error', 'message': request.localizer.translate(_("Invalid credentials!")) }
def get_ldh_data(request): try: variant_id = request.matchdict['variant_id'] except (ValueError, TypeError, KeyError) as e: return http_error(HTTPBadRequest(), request) try: ldh_url = 'https://ldh.clinicalgenome.org/ldh/Variant/id/' + variant_id ldh_data = requests.get(ldh_url, timeout=10) ldh_data.raise_for_status() ldh_data = ldh_data.json() return ldh_data['data'] except HTTPError as e: if (e.response.status_code == 404): return {} return http_error(HTTPServiceUnavailable(), request) except Exception as e: return http_error(HTTPServiceUnavailable(), request)
def redirect_breaker(request): current_breaker = request.registry.cachebreaker breaker = request.matchdict['breaker'] path = request.matchdict['path'] if breaker < current_breaker: return HTTPMovedPermanently(request.route_url(redirected_route, breaker=current_breaker, path=path)) # too recent breaker if breaker > current_breaker: # return 503 Service Unavailable - retry after 3 seconds rv = HTTPServiceUnavailable() rv.retry_after = 3 return rv # finally come here, if no match found in static assets return HTTPNotFound("No such asset")
def get_jwt_claims(request): """Extract claims from provided JWT token""" sm = query_utility(ISecurityManager) # pylint: disable=invalid-name if sm is None: raise HTTPServiceUnavailable() configuration = IJWTSecurityConfiguration(sm) if not configuration.enabled: raise HTTPServiceUnavailable() params = request.params if TEST_MODE else request.validated obj = params.get('obj') if configuration.proxy_mode: handler = IJWTProxyHandler(sm, None) if handler is not None: status_code, claims = handler.get_claims(request, obj) # pylint: disable=assignment-from-no-return request.response.status_code = status_code return claims return get_request_claims(request, obj)
def geosubmit_view(request): stats_client = request.registry.stats_client api_key_log = getattr(request, 'api_key_log', False) api_key_name = getattr(request, 'api_key_name', None) try: data, errors = preprocess_request( request, schema=GeoSubmitBatchSchema(), response=JSONParseError, ) except JSONParseError: # capture JSON exceptions for submit calls request.registry.heka_client.raven(RAVEN_ERROR) raise items = map_items(data['items']) nickname = request.headers.get('X-Nickname', u'') if isinstance(nickname, str): nickname = nickname.decode('utf-8', 'ignore') email = request.headers.get('X-Email', u'') if isinstance(email, str): email = email.decode('utf-8', 'ignore') # count the number of batches and emit a pseudo-timer to capture # the number of reports per batch length = len(items) stats_client.incr('items.uploaded.batches') stats_client.timing('items.uploaded.batch_size', length) if api_key_log: stats_client.incr('items.api_log.%s.uploaded.batches' % api_key_name) stats_client.timing( 'items.api_log.%s.uploaded.batch_size' % api_key_name, length) # batch incoming data into multiple tasks, in case someone # manages to submit us a huge single request for i in range(0, length, 100): batch = kombu_dumps(items[i:i + 100]) # insert observations, expire the task if it wasn't processed # after six hours to avoid queue overload try: insert_measures.apply_async(kwargs={ 'email': email, 'items': batch, 'nickname': nickname, 'api_key_log': api_key_log, 'api_key_name': api_key_name, }, expires=21600) except ConnectionError: # pragma: no cover return HTTPServiceUnavailable() result = HTTPOk() result.content_type = 'application/json' result.body = '{}' return result
def is_healthy(self, request): try: if request.activity.is_healthy(): return { "status": "healthy", } except: logger.exception("Failed health check") raise HTTPServiceUnavailable()
def get_departures(self): try: results = self.ot_api.get_departures(self.id, self.limit) except opentransapi.OpenTransRateLimitException as e: raise HTTPTooManyRequests(str(e)) # limit API exceeded except opentransapi.OpenTransNoStationException as e: raise HTTPNotFound(str(e)) # no station for this request except (RequestException, opentransapi.OpenTransException) as e: raise HTTPServiceUnavailable(str(e)) return results
def redirect_breaker(request): current_breaker = request.registry.cachebreaker breaker = request.matchdict['breaker'] path = request.matchdict['path'] if breaker < current_breaker: return HTTPMovedPermanently( request.route_url(redirected_route, breaker=current_breaker, path=path)) # too recent breaker if breaker > current_breaker: # return 503 Service Unavailable - retry after 3 seconds rv = HTTPServiceUnavailable() rv.retry_after = 3 return rv # finally come here, if no match found in static assets return HTTPNotFound("No such asset")
def board_feed(self, request): """View callable that returns an atom feed for a particular board.""" board = request.matchdict['board_command'].lower() if board not in self.board_names: raise HTTPNotFound("No such board found.") elif not self.feeds: # Tell the user to come back later. raise HTTPServiceUnavailable(headers={'Retry-After': '60'}) elif board not in self.feeds: raise HTTPNotFound("No such board found.") return Response(self.feeds[board], content_type='application/atom+xml')
def raise500Error(request, reason): outputDir = request.getWorkSpace('outputCsv') zipFilePath = '%s/json2csv.zip' % outputDir errmsg = 'failed to create zipfile : %s\n reason : %s' errmsg = errmsg % (zipFilePath, reason) log.error(errmsg) raise HTTPServiceUnavailable({'status':'error', 'reason': 'failed to create zipfile'})
def get(self): """Returns Article document manifest.""" try: article_document = managers.get_article_document( article_id=self.request.matchdict['id'], **self.request.db_settings ) return Response(status_code=200, json=article_document.manifest) except managers.article_manager.ArticleManagerException as e: raise HTTPNotFound(detail=e.message) except: raise HTTPServiceUnavailable()
def get_allele_frequency_impact_statements(request): try: afis_id = request.matchdict['afis_id'] except (ValueError, TypeError, KeyError) as e: return http_error(HTTPBadRequest(), request) try: afis_url = 'https://ldh.clinicalgenome.org/fdr/AlleleFunctionalImpactStatement/id/' + afis_id afis_record = requests.get(afis_url, timeout=10) afis_record = afis_record.json() return afis_record['data'] except Exception as e: return http_error(HTTPServiceUnavailable(), request)
def synchronize(request, imported=None, deleted=None): """Synchronize documents to remote container""" container = get_utility(IDocumentContainer) synchronizer = IDocumentSynchronizer(container) if not synchronizer.target: raise HTTPServiceUnavailable() result = {} for oid in (imported or ()): result[oid] = synchronizer.synchronize(oid, IMPORT_MODE, request) # pylint: disable=assignment-from-no-return for oid in (deleted or ()): result[oid] = synchronizer.synchronize(oid, DELETE_MODE, request) # pylint: disable=assignment-from-no-return return result
def desk_signin(request): import requests req = request.json_body settings = request.registry.settings try: path = settings['desktop']['central_server'] + 'signin' session = requests.Session() session.headers.update({'Connection': 'Keep-Alive'}) adapter = requests.adapters.HTTPAdapter(pool_connections=1, pool_maxsize=1, max_retries=10) session.mount('http://', adapter) status = session.post(path, json=req) client_id = status.json()['client_id'] cookies = status.cookies.get_dict() with open('authentication_data.json', 'w') as f: f.write(json.dumps(cookies)) if status.status_code == 200: path = request.route_url('basic_sync') subreq = Request.blank(path) subreq.method = 'POST' sub_headers = {'Cookie': request.headers['Cookie']} subreq.headers = sub_headers resp = request.invoke_subrequest(subreq) if resp.status_code == 200: headers = remember(request, principal=client_id, max_age=315360000) response = Response() response.headers = headers locale_id = cookies['locale_id'] response.set_cookie(key='locale_id', value=str(locale_id), max_age=datetime.timedelta(days=3650)) response.set_cookie(key='client_id', value=str(client_id), max_age=datetime.timedelta(days=3650)) result = dict() result['client_id'] = client_id request.response.status = HTTPOk.code # request.response.headers = headers # return response return HTTPOk(headers=response.headers, json_body=result) # return result except HTTPUnauthorized: return HTTPUnauthorized( json_body={'error': 'Login or password is wrong, please retry'}) except Exception: return HTTPServiceUnavailable( json_body={ 'error': 'You have no internet connection or Lingvodoc server is unavailable; please retry later.' })