def get_blob_from_credential(credential): try: blob = jsonutils.loads(credential.blob) except (ValueError, TypeError): raise exception.ValidationError( message=_('Invalid blob in credential')) if not blob or not isinstance(blob, dict): raise exception.ValidationError(attribute='blob', target='credential') return blob
def check_length(property_name, value, min_length=1, max_length=64): if len(value) < min_length: if min_length == 1: msg = _("%s cannot be empty.") % property_name else: msg = (_("%(property_name)s cannot be less than " "%(min_length)s characters.") % dict(property_name=property_name, min_length=min_length)) raise exception.ValidationError(msg) if len(value) > max_length: msg = (_("%(property_name)s should not be greater than " "%(max_length)s characters.") % dict(property_name=property_name, max_length=max_length)) raise exception.ValidationError(msg)
def _ssl_cert_req_type(self, req_type): try: import ssl except ImportError: raise exception.ValidationError(_('no ssl support available')) req_type = req_type.upper() try: return { 'NONE': ssl.CERT_NONE, 'OPTIONAL': ssl.CERT_OPTIONAL, 'REQUIRED': ssl.CERT_REQUIRED }[req_type] except KeyError: msg = _('Invalid ssl_cert_reqs value of %s, must be one of ' '"NONE", "OPTIONAL", "REQUIRED"') % (req_type) raise exception.ValidationError(message=msg)
def check_type(property_name, value, expected_type, display_expected_type): if not isinstance(value, expected_type): msg = (_("%(property_name)s is not a " "%(display_expected_type)s") % dict(property_name=property_name, display_expected_type=display_expected_type)) raise exception.ValidationError(msg)
def _require_attribute(self, ref, attribute): """Ensures the reference contains the specified attribute. Raise a ValidationError if the given attribute is not present """ if self._attribute_is_empty(ref, attribute): msg = _('%s field is required and cannot be empty') % attribute raise exception.ValidationError(message=msg)
def _require_attributes(self, ref, attrs): """Ensures the reference contains the specified attributes. Raise a ValidationError if any of the given attributes is not present """ missing_attrs = [attribute for attribute in attrs if self._attribute_is_empty(ref, attribute)] if missing_attrs: msg = _('%s field(s) cannot be empty') % ', '.join(missing_attrs) raise exception.ValidationError(message=msg)
def process_request(self, request): # Abort early if we don't have any work to do params_json = request.body if not params_json: return # Reject unrecognized content types. Empty string indicates # the client did not explicitly set the header if request.content_type not in ('application/json', ''): e = exception.ValidationError(attribute='application/json', target='Content-Type header') return wsgi.render_exception(e, request=request) params_parsed = {} try: params_parsed = jsonutils.loads(params_json) except ValueError: e = exception.ValidationError(attribute='valid JSON', target='request body') return wsgi.render_exception(e, request=request) finally: if not params_parsed: params_parsed = {} if not isinstance(params_parsed, dict): e = exception.ValidationError(attribute='valid JSON object', target='request body') return wsgi.render_exception(e, request=request) params = {} for k, v in six.iteritems(params_parsed): if k in ('self', 'context'): continue if k.startswith('_'): continue params[k] = v request.environ[PARAMS_ENV] = params
def verify_length_and_trunc_password(password): """Verify and truncate the provided password to the max_password_length.""" max_length = CONF.identity.max_password_length try: if len(password) > max_length: if CONF.strict_password_check: raise exception.PasswordVerificationError(size=max_length) else: LOG.warning( _LW('Truncating user password to ' '%d characters.'), max_length) return password[:max_length] else: return password except TypeError: raise exception.ValidationError(attribute='string', target='password')
def configure_cache_region(region): """Configure a cache region. :param region: optional CacheRegion object, if not provided a new region will be instantiated :raises: exception.ValidationError :returns: dogpile.cache.CacheRegion """ if not isinstance(region, dogpile.cache.CacheRegion): raise exception.ValidationError( _('region not type dogpile.cache.CacheRegion')) if not region.is_configured: # NOTE(morganfainberg): this is how you tell if a region is configured. # There is a request logged with dogpile.cache upstream to make this # easier / less ugly. config_dict = build_cache_config() region.configure_from_config(config_dict, '%s.' % CONF.cache.config_prefix) if CONF.cache.debug_cache_backend: region.wrap(DebugProxy) # NOTE(morganfainberg): if the backend requests the use of a # key_mangler, we should respect that key_mangler function. If a # key_mangler is not defined by the backend, use the sha1_mangle_key # mangler provided by dogpile.cache. This ensures we always use a fixed # size cache-key. if region.key_mangler is None: region.key_mangler = util.sha1_mangle_key for class_path in CONF.cache.proxies: # NOTE(morganfainberg): if we have any proxy wrappers, we should # ensure they are added to the cache region's backend. Since # configure_from_config doesn't handle the wrap argument, we need # to manually add the Proxies. For information on how the # ProxyBackends work, see the dogpile.cache documents on # "changing-backend-behavior" cls = importutils.import_class(class_path) LOG.debug("Adding cache-proxy '%s' to backend.", class_path) region.wrap(cls) return region
def __call__(self, request): try: response = self.process_request(request) if response: return response response = request.get_response(self.application) return self.process_response(request, response) except exception.Error as e: LOG.warning(six.text_type(e)) return render_exception(e, request=request, user_locale=best_match_language(request)) except TypeError as e: LOG.exception(six.text_type(e)) return render_exception(exception.ValidationError(e), request=request, user_locale=best_match_language(request)) except Exception as e: LOG.exception(six.text_type(e)) return render_exception(exception.UnexpectedError(exception=e), request=request, user_locale=best_match_language(request))
def __call__(self, req): arg_dict = req.environ['wsgiorg.routing_args'][1] action = arg_dict.pop('action') del arg_dict['controller'] # allow middleware up the stack to provide context, params and headers. context = req.environ.get(CONTEXT_ENV, {}) context['query_string'] = dict(six.iteritems(req.params)) context['headers'] = dict(six.iteritems(req.headers)) context['path'] = req.environ['PATH_INFO'] scheme = (None if not CONF.secure_proxy_ssl_header else req.environ.get(CONF.secure_proxy_ssl_header)) if scheme: # NOTE(andrey-mp): "wsgi.url_scheme" contains the protocol used # before the proxy removed it ('https' usually). So if # the webob.Request instance is modified in order to use this # scheme instead of the one defined by API, the call to # webob.Request.relative_url() will return a URL with the correct # scheme. req.environ['wsgi.url_scheme'] = scheme context['host_url'] = req.host_url params = req.environ.get(PARAMS_ENV, {}) # authentication and authorization attributes are set as environment # values by the container and processed by the pipeline. the complete # set is not yet know. context['environment'] = req.environ context['accept_header'] = req.accept req.environ = None params.update(arg_dict) context.setdefault('is_admin', False) # TODO(termie): do some basic normalization on methods method = getattr(self, action) # NOTE(morganfainberg): use the request method to normalize the # response code between GET and HEAD requests. The HTTP status should # be the same. req_method = req.environ['REQUEST_METHOD'].upper() LOG.info('%(req_method)s %(path)s?%(params)s', { 'req_method': req_method, 'path': context['path'], 'params': urllib.urlencode(req.params)}) params = self._normalize_dict(params) try: result = method(context, **params) except exception.Unauthorized as e: LOG.warning( _LW("Authorization failed. %(exception)s from " "%(remote_addr)s"), {'exception': e, 'remote_addr': req.environ['REMOTE_ADDR']}) return render_exception(e, context=context, user_locale=best_match_language(req)) except exception.Error as e: LOG.warning(six.text_type(e)) return render_exception(e, context=context, user_locale=best_match_language(req)) except TypeError as e: LOG.exception(six.text_type(e)) return render_exception(exception.ValidationError(e), context=context, user_locale=best_match_language(req)) except Exception as e: LOG.exception(six.text_type(e)) return render_exception(exception.UnexpectedError(exception=e), context=context, user_locale=best_match_language(req)) if result is None: return render_response(status=(204, 'No Content')) elif isinstance(result, six.string_types): return result elif isinstance(result, webob.Response): return result elif isinstance(result, webob.exc.WSGIHTTPException): return result response_code = self._get_response_code(req) return render_response(body=result, status=response_code, method=req_method)
def _init_args(self, arguments): """Helper logic for collecting and parsing MongoDB specific arguments. The arguments passed in are separated out in connection specific setting and rest of arguments are passed to create/update/delete db operations. """ self.conn_kwargs = {} # connection specific arguments self.hosts = arguments.pop('db_hosts', None) if self.hosts is None: msg = _('db_hosts value is required') raise exception.ValidationError(message=msg) self.db_name = arguments.pop('db_name', None) if self.db_name is None: msg = _('database db_name is required') raise exception.ValidationError(message=msg) self.cache_collection = arguments.pop('cache_collection', None) if self.cache_collection is None: msg = _('cache_collection name is required') raise exception.ValidationError(message=msg) self.username = arguments.pop('username', None) self.password = arguments.pop('password', None) self.max_pool_size = arguments.pop('max_pool_size', 10) self.w = arguments.pop('w', -1) try: self.w = int(self.w) except ValueError: msg = _('integer value expected for w (write concern attribute)') raise exception.ValidationError(message=msg) self.read_preference = arguments.pop('read_preference', None) self.use_replica = arguments.pop('use_replica', False) if self.use_replica: if arguments.get('replicaset_name') is None: msg = _('replicaset_name required when use_replica is True') raise exception.ValidationError(message=msg) self.replicaset_name = arguments.get('replicaset_name') self.son_manipulator = arguments.pop('son_manipulator', None) # set if mongo collection needs to be TTL type. # This needs to be max ttl for any cache entry. # By default, -1 means don't use TTL collection. # With ttl set, it creates related index and have doc_date field with # needed expiration interval self.ttl_seconds = arguments.pop('mongo_ttl_seconds', -1) try: self.ttl_seconds = int(self.ttl_seconds) except ValueError: msg = _('integer value expected for mongo_ttl_seconds') raise exception.ValidationError(message=msg) self.conn_kwargs['ssl'] = arguments.pop('ssl', False) if self.conn_kwargs['ssl']: ssl_keyfile = arguments.pop('ssl_keyfile', None) ssl_certfile = arguments.pop('ssl_certfile', None) ssl_ca_certs = arguments.pop('ssl_ca_certs', None) ssl_cert_reqs = arguments.pop('ssl_cert_reqs', None) if ssl_keyfile: self.conn_kwargs['ssl_keyfile'] = ssl_keyfile if ssl_certfile: self.conn_kwargs['ssl_certfile'] = ssl_certfile if ssl_ca_certs: self.conn_kwargs['ssl_ca_certs'] = ssl_ca_certs if ssl_cert_reqs: self.conn_kwargs['ssl_cert_reqs'] = ( self._ssl_cert_req_type(ssl_cert_reqs)) # rest of arguments are passed to mongo crud calls self.meth_kwargs = arguments