"""API utilities.""" import functools import bleach from flask import g from flask import request from marshmallow import ValidationError from owsrequest.flask_request import get_ows_headers from podcast import config from podcast.models import user as user_model from podcast.utils.exc import OwsError def validate_request_data(schema, partial=False): """Decorate requests' input data validation. Args: schema (marshmallow.Schema()): schema instance to apply partial (bool): validate only derived fields """ def validator(func): @functools.wraps(func) def wrapper(*args, **kwargs): data = request.get_json() try: validated = schema.load(data, partial=partial) except ValidationError as err: raise OwsError.bad_request(err.messages) else: return func(*args, data=validated, **kwargs) return wrapper return validator def validate_request_query(schema, partial=False): """Decorate requests' input query string validation. Args: schema (marshmallow.Schema()): schema instance to apply partial (bool): validate only derived fields """ def validator(func): @functools.wraps(func) def wrapper(*args, **kwargs): data = request.args try: validated = schema.load(data, partial=partial) except ValidationError as err: raise OwsError.bad_request(err.messages) else: return func(*args, data=validated, **kwargs) return wrapper return validator def clean_html(html): """Clean html tags.""" return bleach.clean( html, tags=['strong', 'p', 'em', 'u', 'ul', 'li', 'a', 'br'], attributes={'a': ['href']} ) def _get_request_context(): """Get global context.""" return g.request_context def get_current_user(): """Get current user.""" if 'current_user' not in g: g.current_user = user_model.get_user_by_uuid(_get_uuid()) return g.current_user def get_user_id(): """Get user_id from global context.""" return get_current_user()['id'] def _get_uuid(): """Get uuid from global context.""" context = _get_request_context() if context.identity_uuid: return context.identity_uuid # for cypress test elif context.context_type == 'account' and context.orchard_user_id: return context.orchard_user_id raise OwsError(message='Failed to identify user', status=401) def asset_url(filename): """Return full path to filename in output_bucket.""" return 'https://{}/{}'.format(config.OUTPUT_CDN_BASE_URL, filename) def utc_format(date): """Convert datetime to utc string.""" return date.isoformat() def utc_format_with_z(date): """Convert datetime to utc string.""" return utc_format(date) + '.000Z' def get_ows_json_headers(): """Get headers ready for ows calls as json.""" headers = get_ows_headers() headers['Content-Type'] = 'application/json' return headers