def includeme(config): if hasattr(config.registry, "tonnikala_renderer_factory"): return config.registry.tonnikala_renderer_factory = TonnikalaRendererFactory() config.add_directive("add_tonnikala_extensions", add_tonnikala_extensions) config.add_directive("add_tonnikala_search_paths", add_tonnikala_search_paths) config.add_directive("set_tonnikala_reload", set_tonnikala_reload) settings = config.registry.settings if "tonnikala.extensions" in settings: extensions = settings["tonnikala.extensions"] if not is_nonstr_iter(extensions): extensions = aslist(extensions, flatten=True) config.add_tonnikala_extensions(*extensions) if "tonnikala.search_paths" in settings: paths = settings["tonnikala.search_paths"] if not is_nonstr_iter(paths): paths = aslist(paths, flatten=True) config.add_tonnikala_search_paths(*paths) tk_reload = settings.get("tonnikala.reload") if tk_reload is None: tk_reload = settings.get("pyramid.reload_templates") config.set_tonnikala_reload(asbool(tk_reload))
def principals_allowed_by_permission(self, context, permission): allowed = set() acls_to_examine = self._collect_acls_to_examine(context) permissions = self.permission_parser(permission) for location, acl in acls_to_examine: for ace_action, ace_principal, ace_permissions in reversed(acl): if not is_nonstr_iter(ace_principals): ace_principals = [ace_principals] ace_principals = set(ace_principals) if not is_nonstr_iter(ace_permissions): ace_permissions = [ace_permissions] if ace_permissions.issuperset(permissions): if ace_action == Allow: allowed.update(ace_principals) elif ace_action == Deny: if Everyone in ace_principals: allowed.clear() else: allowed.difference_update(ace_principals) return allowed
def parse_options_from_settings(settings, settings_prefix, maybe_dotted): """ Parse options for use with Mako's TemplateLookup from settings.""" def sget(name, default=None): return settings.get(settings_prefix + name, default) reload_templates = sget('reload_templates', None) if reload_templates is None: reload_templates = settings.get('pyramid.reload_templates', None) reload_templates = asbool(reload_templates) directories = sget('directories', []) module_directory = sget('module_directory', None) input_encoding = sget('input_encoding', 'utf-8') error_handler = sget('error_handler', None) default_filters = sget('default_filters', 'h') imports = sget('imports', None) future_imports = sget('future_imports', None) strict_undefined = asbool(sget('strict_undefined', False)) preprocessor = sget('preprocessor', None) if not is_nonstr_iter(directories): # Since we parse a value that comes from an .ini config, # we treat whitespaces and newline characters equally as list item separators. directories = aslist(directories, flatten=True) directories = [abspath_from_asset_spec(d) for d in directories] if module_directory is not None: module_directory = abspath_from_asset_spec(module_directory) if error_handler is not None: error_handler = maybe_dotted(error_handler) if default_filters is not None: if not is_nonstr_iter(default_filters): default_filters = aslist(default_filters) if imports is not None: if not is_nonstr_iter(imports): imports = aslist(imports, flatten=False) if future_imports is not None: if not is_nonstr_iter(future_imports): future_imports = aslist(future_imports) if preprocessor is not None: preprocessor = maybe_dotted(preprocessor) return dict( directories=directories, module_directory=module_directory, input_encoding=input_encoding, error_handler=error_handler, default_filters=default_filters, imports=imports, future_imports=future_imports, filesystem_checks=reload_templates, strict_undefined=strict_undefined, preprocessor=preprocessor, )
def _add_tween(self, tween_factory, under=None, over=None, explicit=False): if not isinstance(tween_factory, string_types): raise ConfigurationError( 'The "tween_factory" argument to add_tween must be a ' 'dotted name to a globally importable object, not %r' % tween_factory) name = tween_factory if name in (MAIN, INGRESS): raise ConfigurationError('%s is a reserved tween name' % name) tween_factory = self.maybe_dotted(tween_factory) for t, p in [('over', over), ('under', under)]: if p is not None: if not is_string_or_iterable(p): raise ConfigurationError( '"%s" must be a string or iterable, not %s' % (t, p)) if over is INGRESS or is_nonstr_iter(over) and INGRESS in over: raise ConfigurationError('%s cannot be over INGRESS' % name) if under is MAIN or is_nonstr_iter(under) and MAIN in under: raise ConfigurationError('%s cannot be under MAIN' % name) registry = self.registry introspectables = [] tweens = registry.queryUtility(ITweens) if tweens is None: tweens = Tweens() registry.registerUtility(tweens, ITweens) def register(): if explicit: tweens.add_explicit(name, tween_factory) else: tweens.add_implicit(name, tween_factory, under=under, over=over) discriminator = ('tween', name, explicit) tween_type = explicit and 'explicit' or 'implicit' intr = self.introspectable('tweens', discriminator, name, '%s tween' % tween_type) intr['name'] = name intr['factory'] = tween_factory intr['type'] = tween_type intr['under'] = under intr['over'] = over introspectables.append(intr) self.action(discriminator, register, introspectables=introspectables)
def renderer_factory(info): path = info.name registry = info.registry settings = info.settings lookup = registry.queryUtility(IMakoLookup) if lookup is None: reload_templates = settings.get('reload_templates', False) directories = settings.get('mako.directories', None) module_directory = settings.get('mako.module_directory', None) input_encoding = settings.get('mako.input_encoding', 'utf-8') error_handler = settings.get('mako.error_handler', None) default_filters = settings.get('mako.default_filters', 'h') imports = settings.get('mako.imports', None) strict_undefined = settings.get('mako.strict_undefined', 'false') preprocessor = settings.get('mako.preprocessor', None) if directories is None: raise ConfigurationError( 'Mako template used without a ``mako.directories`` setting') if not is_nonstr_iter(directories): directories = list(filter(None, directories.splitlines())) directories = [ abspath_from_asset_spec(d) for d in directories ] if module_directory is not None: module_directory = abspath_from_asset_spec(module_directory) if error_handler is not None: dotted = DottedNameResolver(info.package) error_handler = dotted.maybe_resolve(error_handler) if default_filters is not None: if not is_nonstr_iter(default_filters): default_filters = list(filter( None, default_filters.splitlines())) if imports is not None: if not is_nonstr_iter(imports): imports = list(filter(None, imports.splitlines())) strict_undefined = asbool(strict_undefined) if preprocessor is not None: dotted = DottedNameResolver(info.package) preprocessor = dotted.maybe_resolve(preprocessor) lookup = PkgResourceTemplateLookup(directories=directories, module_directory=module_directory, input_encoding=input_encoding, error_handler=error_handler, default_filters=default_filters, imports=imports, filesystem_checks=reload_templates, strict_undefined=strict_undefined, preprocessor=preprocessor) registry_lock.acquire() try: registry.registerUtility(lookup, IMakoLookup) finally: registry_lock.release() return MakoLookupTemplateRenderer(path, lookup)
def renderer_factory(info): path = info.name registry = info.registry settings = info.settings lookup = registry.queryUtility(IMakoLookup) if lookup is None: reload_templates = settings.get('reload_templates', False) directories = settings.get('mako.directories', []) module_directory = settings.get('mako.module_directory', None) input_encoding = settings.get('mako.input_encoding', 'utf-8') error_handler = settings.get('mako.error_handler', None) default_filters = settings.get('mako.default_filters', 'h') imports = settings.get('mako.imports', None) strict_undefined = settings.get('mako.strict_undefined', 'false') preprocessor = settings.get('mako.preprocessor', None) if not is_nonstr_iter(directories): directories = list(filter(None, directories.splitlines())) directories = [ abspath_from_asset_spec(d) for d in directories ] if module_directory is not None: module_directory = abspath_from_asset_spec(module_directory) if error_handler is not None: dotted = DottedNameResolver(info.package) error_handler = dotted.maybe_resolve(error_handler) if default_filters is not None: if not is_nonstr_iter(default_filters): default_filters = list(filter( None, default_filters.splitlines())) if imports is not None: if not is_nonstr_iter(imports): imports = list(filter(None, imports.splitlines())) strict_undefined = asbool(strict_undefined) if preprocessor is not None: dotted = DottedNameResolver(info.package) preprocessor = dotted.maybe_resolve(preprocessor) lookup = PkgResourceTemplateLookup(directories=directories, module_directory=module_directory, input_encoding=input_encoding, error_handler=error_handler, default_filters=default_filters, imports=imports, filesystem_checks=reload_templates, strict_undefined=strict_undefined, preprocessor=preprocessor) registry_lock.acquire() try: registry.registerUtility(lookup, IMakoLookup) finally: registry_lock.release() return MakoLookupTemplateRenderer(path, lookup)
def add_implicit(self, name, factory, under=None, over=None): self.names.append(name) self.factories[name] = factory if under is None and over is None: under = INGRESS if under is not None: if not is_nonstr_iter(under): under = (under,) self.order += [(u, name) for u in under] self.req_under.add(name) if over is not None: if not is_nonstr_iter(over): #hasattr(over, '__iter__'): over = (over,) self.order += [(name, o) for o in over] self.req_over.add(name)
def add_implicit(self, name, factory, under=None, over=None): self.names.append(name) self.factories[name] = factory if under is None and over is None: under = INGRESS if under is not None: if not is_nonstr_iter(under): under = (under, ) self.order += [(u, name) for u in under] self.req_under.add(name) if over is not None: if not is_nonstr_iter(over): over = (over, ) self.order += [(name, o) for o in over] self.req_over.add(name)
def _add_tween(self, tween_factory, under=None, over=None, explicit=False): if not isinstance(tween_factory, string_types): raise ConfigurationError( 'The "tween_factory" argument to add_tween must be a ' 'dotted name to a globally importable object, not %r' % tween_factory) name = tween_factory if name in (MAIN, INGRESS): raise ConfigurationError('%s is a reserved tween name' % name) tween_factory = self.maybe_dotted(tween_factory) def is_string_or_iterable(v): if isinstance(v, string_types): return True if hasattr(v, '__iter__'): return True for t, p in [('over', over), ('under', under)]: if p is not None: if not is_string_or_iterable(p): raise ConfigurationError( '"%s" must be a string or iterable, not %s' % (t, p)) if over is INGRESS or is_nonstr_iter(over) and INGRESS in over: raise ConfigurationError('%s cannot be over INGRESS' % name) if under is MAIN or is_nonstr_iter(under) and MAIN in under: raise ConfigurationError('%s cannot be under MAIN' % name) registry = self.registry tweens = registry.queryUtility(ITweens) if tweens is None: tweens = Tweens() registry.registerUtility(tweens, ITweens) tweens.add_implicit(EXCVIEW, excview_tween_factory, over=MAIN) def register(): if explicit: tweens.add_explicit(name, tween_factory) else: tweens.add_implicit(name, tween_factory, under=under, over=over) self.action(('tween', name, explicit), register)
def allowed(self, oids, principals, permission): """ For the set of oids present in ``oids``, return a sequence of oids that are permitted ``permission`` against each oid if the implied user is a member of the set of principals implied by ``principals``. This method uses the data collected via the ``set_acl`` method of this class.""" if self.path_to_acl is None: # bw compat raise StopIteration for oid in oids: path_tuple = self.objectid_to_path.get(oid) if path_tuple is None: continue try: for idx in reversed(range(len(path_tuple))): acl = self.path_to_acl.get(path_tuple[:idx+1]) if acl is None: continue for ace in acl: ace_action, ace_principal, ace_permissions = ace if ace_principal in principals: if not is_nonstr_iter(ace_permissions): ace_permissions = [ace_permissions] if permission in ace_permissions: if ace_action == Allow: yield oid raise _Break() except _Break: pass
def permits(self, context, principals, permission): """ Return an instance of :class:`pyramid.security.ACLAllowed` instance if the policy permits access, return an instance of :class:`pyramid.security.ACLDenied` if not.""" acl = '<No ACL found on any object in resource lineage>' for location in lineage(context): try: acl = location.__acl__ except AttributeError: continue for ace in acl: ace_action, ace_principal, ace_permissions = ace if ace_principal in principals: if not is_nonstr_iter(ace_permissions): ace_permissions = [ace_permissions] if permission in ace_permissions: if ace_action == Allow: return ACLAllowed(ace, acl, permission, principals, location) else: return ACLDenied(ace, acl, permission, principals, location) # default deny (if no ACL in lineage at all, or if none of the # principals were mentioned in any ACE we found) return ACLDenied( '<default deny>', acl, permission, principals, context)
def allows(self, principals, permission=None): """ ``principals`` may either be 1) a sequence of principal indentifiers, 2) a single principal identifier, or 3) a Pyramid request, which indicates that all the effective principals implied by the request are used. ``permission`` may be ``None`` if this index is configured with only a single permission. Otherwise a permission name must be passed or an error will be raised. """ permissions = self.discriminator.permissions if permission is None: if len(permissions) > 1: raise ValueError('Must pass a permission') else: permission = list(permissions)[0] else: if permissions is not None and not permission in permissions: raise ValueError( 'This index does not support the %s ' 'permission' % (permission,) ) if IRequest.providedBy(principals): principals = effective_principals(principals) elif not is_nonstr_iter(principals): principals = (principals,) principals = [ get_principal_repr(p) for p in principals ] values = [(principal, permission) for principal in principals] return hypatia.query.Any(self, values)
def _set(self, oids): if oids == colander.null: # fbo dump/load return if not is_nonstr_iter(oids): raise ValueError('Must be a sequence') iterable = _del(self) iterable.connect(oids)
def merged_local_principals(context, principals): # XXX Possibly limit to prefix like 'role.' set_principals = frozenset(principals) local_principals = set() block = False for location in lineage(context): if block: break block = getattr(location, '__ac_local_roles_block__', False) local_roles = getattr(location, '__ac_local_roles__', None) if local_roles and callable(local_roles): local_roles = local_roles() if not local_roles: continue for principal, roles in local_roles.iteritems(): if not is_nonstr_iter(roles): roles = [roles] if not set_principals.isdisjoint(roles): local_principals.add(principal) if not local_principals: return principals local_principals.update(principals) return list(local_principals)
def local_principals(context, principals): local_principals = set() block = False for location in lineage(context): if block: break block = getattr(location, '__ac_local_roles_block__', False) local_roles = getattr(location, '__ac_local_roles__', None) if local_roles and callable(local_roles): local_roles = local_roles() if not local_roles: continue for principal in principals: try: roles = local_roles[principal] except KeyError: pass else: if not is_nonstr_iter(roles): roles = [roles] local_principals.update(roles) if not local_principals: return principals local_principals.update(principals) return local_principals
def hashvalues(self): values = IndexFactory.hashvalues(self) permissions = values.get('permissions', None) if not is_nonstr_iter(permissions): permissions = (permissions, ) values['permissions'] = tuple(sorted(permissions)) return values
def create(self, content_type, *arg, **kw): """ Create an instance of ``content_type`` by calling its factory with ``*arg`` and ``**kw``. If the meta of the content type has an ``after_create`` value, call it (if it's a string, it's assumed to be a method of the created object, and if it's a sequence, each value should be a string or a callable, which will be called in turn); then send a :class:`substanced.event.ContentCreatedEvent`. Return the created object. If the key ``__oid`` is in the ``kw`` arguments, it will be used as the created object's oid. """ factory = self.content_types[content_type] oid = kw.pop('__oid', None) # FBO dump system loader inst = factory(*arg, **kw) if oid is not None: set_oid(inst, oid) meta = self.meta[content_type].copy() aftercreate = meta.get('after_create') if aftercreate is not None: if not is_nonstr_iter(aftercreate): aftercreate = [aftercreate] for callback in aftercreate: if isinstance(callback, STRING_TYPES): callback = getattr(inst, callback) callback(inst, self.registry) self.registry.subscribers( (ContentCreated(inst, content_type, meta), inst), None) return inst
def make(self, config, **kw): # Given a configurator and a list of keywords, a predicate list is # computed. Elsewhere in the code, we evaluate predicates using a # generator expression. All predicates associated with a view or # route must evaluate true for the view or route to "match" during a # request. The fastest predicate should be evaluated first, then the # next fastest, and so on, as if one returns false, the remainder of # the predicates won't need to be evaluated. # # While we compute predicates, we also compute a predicate hash (aka # phash) that can be used by a caller to identify identical predicate # lists. ordered = self.sorter.sorted() phash = md5() weights = [] preds = [] for n, (name, predicate_factory) in enumerate(ordered): vals = kw.pop(name, None) if vals is None: # XXX should this be a sentinel other than None? continue if not isinstance(vals, predvalseq): vals = (vals,) for val in vals: pred = predicate_factory(val, config) hashes = pred.phash() if not is_nonstr_iter(hashes): hashes = [hashes] for h in hashes: phash.update(bytes_(h)) weights.append(1 << n + 1) preds.append(pred) if kw: raise ConfigurationError("Unknown predicate values: %r" % (kw,)) # A "order" is computed for the predicate list. An order is # a scoring. # # Each predicate is associated with a weight value. The weight of a # predicate symbolizes the relative potential "importance" of the # predicate to all other predicates. A larger weight indicates # greater importance. # # All weights for a given predicate list are bitwise ORed together # to create a "score"; this score is then subtracted from # MAX_ORDER and divided by an integer representing the number of # predicates+1 to determine the order. # # For views, the order represents the ordering in which a "multiview" # ( a collection of views that share the same context/request/name # triad but differ in other ways via predicates) will attempt to call # its set of views. Views with lower orders will be tried first. # The intent is to a) ensure that views with more predicates are # always evaluated before views with fewer predicates and b) to # ensure a stable call ordering of views that share the same number # of predicates. Views which do not have any predicates get an order # of MAX_ORDER, meaning that they will be tried very last. score = 0 for bit in weights: score = score | bit order = (MAX_ORDER - score) / (len(preds) + 1) return order, preds, phash.hexdigest()
def allowed(self, oids, principals, permission): """ For the set of oids present in ``oids``, return a sequence of oids that are permitted ``permission`` against each oid if the implied user is a member of the set of principals implied by ``principals``. This method uses the data collected via the ``set_acl`` method of this class.""" if self.path_to_acl is None: # bw compat return for oid in oids: path_tuple = self.objectid_to_path.get(oid) if path_tuple is None: continue try: for idx in reversed(range(len(path_tuple))): acl = self.path_to_acl.get(path_tuple[:idx+1]) if acl is None: continue for ace in acl: ace_action, ace_principal, ace_permissions = ace if ace_principal in principals: if not is_nonstr_iter(ace_permissions): ace_permissions = [ace_permissions] if permission in ace_permissions: if ace_action == Allow: yield oid raise _Break() except _Break: pass
def prepare_for_json(value, minify=False): if value is None: if minify: return '' else: return None elif hasattr(value, '__json__'): return value.__json__() elif isinstance(value, bool): if minify: return value and 1 or 0 else: return value elif isinstance(value, (float, int)): return value elif isinstance(value, dict): return prepare_dict_for_json(value, minify) elif is_nonstr_iter(value): return prepare_iter_for_json(value, minify) elif isinstance(value, (DATE, DATETIME)): if minify: return int(mktime(value.timetuple())) else: return value.isoformat() else: return to_string(value)
def hashvalues(self): values = IndexFactory.hashvalues(self) permissions = values.get('permissions', None) if not is_nonstr_iter(permissions): permissions = (permissions,) values['permissions'] = tuple(sorted(permissions)) return values
def principals_allowed_by_permission(self, context, permission): allowed = set() for location in reversed(list(lineage(context))): # NB: we're walking *up* the object graph from the root try: acl = location.__acl__ except AttributeError: continue allowed_here = set() denied_here = set() if acl and callable(acl): acl = acl(request=context.request) for ace_action, ace_principal, ace_permissions in acl: if not is_nonstr_iter(ace_permissions): ace_permissions = [ace_permissions] if (ace_action == Allow) and (permission in ace_permissions): if ace_principal not in denied_here: allowed_here.add(ace_principal) if (ace_action == Deny) and (permission in ace_permissions): denied_here.add(ace_principal) if ace_principal == Everyone: # clear the entire allowed set, as we've hit a # deny of Everyone ala (Deny, Everyone, ALL) allowed = set() break elif ace_principal in allowed: allowed.remove(ace_principal) allowed.update(allowed_here) return allowed
def permits(self, context, principals, permission): acl = '<No ACL found on any object in resource lineage>' for location in lineage(context): try: acl = location.__acl__ except AttributeError: continue if acl and callable(acl): acl = acl(request=context.request) for ace in acl: ace_action, ace_principal, ace_permissions = ace if ace_principal in principals: if not is_nonstr_iter(ace_permissions): ace_permissions = [ace_permissions] if permission in ace_permissions: if ace_action == Allow: return ACLAllowed(ace, acl, permission, principals, location) return ACLDenied( ace, acl, permission, principals, location) return ACLDenied( '<default deny>', acl, permission, principals, context)
def maybe_list(value): if value is None: return [] elif not is_nonstr_iter(value): return [value] else: return list(value)
def maybe_set(value): if value is None: return set() elif not is_nonstr_iter(value): return set([value]) else: return set(value)
def create_order_by(table, maybe_column, descendant=False): if isinstance(maybe_column, basestring): column = getattr(table, maybe_column, None) return create_order_by(table, column, descendant) elif isinstance(maybe_column, OrderBy): return create_order_by(table, maybe_column.column_name, maybe_column.descendant) elif is_nonstr_iter(maybe_column): if (len(maybe_column) == 2 and not isinstance(maybe_column[1], OrderBy) and maybe_column[1].lower() == 'desc'): return create_order_by(table, maybe_column[0], descendant=True) else: return [ create_order_by(table, ob, descendant) for ob in maybe_column ] elif maybe_column is not None: if isinstance(maybe_column, CoreColumnParent): maybe_column = maybe_column.get_core_column() if descendant: return maybe_column.desc() else: return maybe_column
def generator(dict): newdict = {} for k, v in dict.items(): if PY3: # pragma: no cover if v.__class__ is binary_type: # url_quote below needs a native string, not bytes on Py3 v = v.decode('utf-8') else: if v.__class__ is text_type: # url_quote below needs bytes, not unicode on Py2 v = v.encode('utf-8') if k == remainder: # a stararg argument if is_nonstr_iter(v): v = '/'.join([quote_path_segment(x, safe='/') for x in v]) # native else: if v.__class__ not in string_types: v = str(v) v = quote_path_segment(v, safe='/') else: if v.__class__ not in string_types: v = str(v) # v may be bytes (py2) or native string (py3) v = quote_path_segment(v, safe='/') # at this point, the value will be a native string newdict[k] = v result = gen % newdict # native string result return result
def make_param_predicates(param_type, param, params_attr, weights, weight, predicates, hash): if not is_nonstr_iter(param): param = (param,) param = sorted(param) text = "%s_param %r" % (param_type, param) reqs = [] for p in param: pair = p.split('=', 1) if len(pair) == 1: pair = pair+[None] reqs.append(pair) if len(reqs) == 1 and reqs[0][1] is None: text = "%s_param %s" % (param_type, param[0]) def param_predicate(context, request): params = getattr(request, params_attr) for k, v in reqs: if v is None: return k in params if params.get(k) != v: return False return True param_predicate.__text__ = text weights.append(1 << weight) predicates.append(param_predicate) for p in param: hash.update(bytes_('%s_param:%r' % (param_type, p)))
def generator(dict): newdict = {} for k, v in dict.items(): if PY3: # pragma: no cover if v.__class__ is binary_type: # url_quote below needs a native string, not bytes on Py3 v = v.decode('utf-8') else: if v.__class__ is text_type: # url_quote below needs bytes, not unicode on Py2 v = v.encode('utf-8') if k == remainder: # a stararg argument if is_nonstr_iter(v): v = '/'.join([quote_path_segment(x) for x in v]) # native else: if v.__class__ not in string_types: v = str(v) v = quote_path_segment(v, safe='/') else: if v.__class__ not in string_types: v = str(v) # v may be bytes (py2) or native string (py3) v = quote_path_segment(v) # at this point, the value will be a native string newdict[k] = v result = gen % newdict # native string result return result
def make(self, config, **kw): # Given a configurator and a list of keywords, a predicate list is # computed. Elsewhere in the code, we evaluate predicates using a # generator expression. All predicates associated with a view or # route must evaluate true for the view or route to "match" during a # request. The fastest predicate should be evaluated first, then the # next fastest, and so on, as if one returns false, the remainder of # the predicates won't need to be evaluated. # # While we compute predicates, we also compute a predicate hash (aka # phash) that can be used by a caller to identify identical predicate # lists. ordered = self.sorter.sorted() phash = md5() weights = [] preds = [] for n, (name, predicate_factory) in enumerate(ordered): vals = kw.pop(name, None) if vals is None: # XXX should this be a sentinel other than None? continue if not isinstance(vals, predvalseq): vals = (vals, ) for val in vals: pred = predicate_factory(val, config) hashes = pred.phash() if not is_nonstr_iter(hashes): hashes = [hashes] for h in hashes: phash.update(bytes_(h)) weights.append(1 << n + 1) preds.append(pred) if kw: raise ConfigurationError('Unknown predicate values: %r' % (kw, )) # A "order" is computed for the predicate list. An order is # a scoring. # # Each predicate is associated with a weight value. The weight of a # predicate symbolizes the relative potential "importance" of the # predicate to all other predicates. A larger weight indicates # greater importance. # # All weights for a given predicate list are bitwise ORed together # to create a "score"; this score is then subtracted from # MAX_ORDER and divided by an integer representing the number of # predicates+1 to determine the order. # # For views, the order represents the ordering in which a "multiview" # ( a collection of views that share the same context/request/name # triad but differ in other ways via predicates) will attempt to call # its set of views. Views with lower orders will be tried first. # The intent is to a) ensure that views with more predicates are # always evaluated before views with fewer predicates and b) to # ensure a stable call ordering of views that share the same number # of predicates. Views which do not have any predicates get an order # of MAX_ORDER, meaning that they will be tried very last. score = 0 for bit in weights: score = score | bit order = (MAX_ORDER - score) / (len(preds) + 1) return order, preds, phash.hexdigest()
def create(self, content_type, *arg, **kw): """ Create an instance of ``content_type`` by calling its factory with ``*arg`` and ``**kw``. If the meta of the content type has an ``after_create`` value, call it (if it's a string, it's assumed to be a method of the created object, and if it's a sequence, each value should be a string or a callable, which will be called in turn); then send a :class:`substanced.event.ContentCreatedEvent`. Return the created object.""" factory = self.content_types[content_type] inst = factory(*arg, **kw) inst.__created__ = self._utcnow() meta = self.meta[content_type].copy() aftercreate = meta.get('after_create') if aftercreate is not None: if not is_nonstr_iter(aftercreate): aftercreate = [aftercreate] for callback in aftercreate: if isinstance(callback, basestring): callback = getattr(inst, callback) callback(inst, self.registry) self.registry.subscribers( (ContentCreated(inst, content_type, meta), inst), None ) return inst
def newer(self, generation, index_id, oids=None): if oids and not is_nonstr_iter(oids): oids = [oids] items = self.entries.newer(generation, index_id) for gen, idx, entry in items: if (not oids) or entry.oid in oids: yield gen, idx, entry
def wrapper(self, *arg, **kw): if self._ainfo is None: self._ainfo = [] info = kw.pop('_info', None) # backframes for outer decorators to actionmethods backframes = kw.pop('_backframes', 0) + 2 if is_nonstr_iter(info) and len(info) == 4: # _info permitted as extract_stack tuple info = ActionInfo(*info) if info is None: try: f = traceback.extract_stack(limit=4) # Work around a Python 3.5 issue whereby it would insert an # extra stack frame. This should no longer be necessary in # Python 3.5.1 last_frame = ActionInfo(*f[-1]) if last_frame.function == 'extract_stack': # pragma: no cover f.pop() info = ActionInfo(*f[-backframes]) except: # pragma: no cover info = ActionInfo(None, 0, '', '') self._ainfo.append(info) try: result = wrapped(self, *arg, **kw) finally: self._ainfo.pop() return result
def __call__(self, context, request): req_principals = effective_principals(request) if is_nonstr_iter(req_principals): rpset = set(req_principals) if self.val.issubset(rpset): return True return False
def set_deform_translation(self, path=None, production_path=None, base_static_path=None): def translator(term): return get_localizer(get_current_request()).translate(term) deform = _import_module('deform') path = self.is_production_environ and production_path or path if path: deform_template_dir = resource_filename(*path.split(':', 1)) zpt_renderer = deform.ZPTRendererFactory( [deform_template_dir], translator=translator) deform.Form.set_default_renderer(zpt_renderer) if base_static_path: if not base_static_path.endswith('/'): base_static_path += '/' for versions in deform.widget.default_resources.values(): for resources in versions.values(): for resource_type, resource in resources.items(): new_resources = [ r.replace('deform:static/', base_static_path, 1) for r in maybe_list(resource)] if not is_nonstr_iter(resource): resources[resource_type] = new_resources[0] else: resources[resource_type] = tuple(new_resources) self.add_translation_dirs('deform:locale') if not base_static_path: self.add_static_view('deform', 'deform:static')
def permits(self, context, principals, permission): """ Return an instance of :class:`pyramid.security.ACLAllowed` instance if the policy permits access, return an instance of :class:`pyramid.security.ACLDenied` if not.""" acl = '<No ACL found on any object in resource lineage>' for location in lineage(context): try: acl = location.__acl__ except AttributeError: continue if acl and callable(acl): acl = acl() for ace in acl: ace_action, ace_principal, ace_permissions = ace if ace_principal in principals: if not is_nonstr_iter(ace_permissions): ace_permissions = [ace_permissions] if permission in ace_permissions: if ace_action == Allow: return ACLAllowed(ace, acl, permission, principals, location) else: return ACLDenied(ace, acl, permission, principals, location) # default deny (if no ACL in lineage at all, or if none of the # principals were mentioned in any ACE we found) return ACLDenied('<default deny>', acl, permission, principals, context)
def create(self, content_type, *arg, **kw): """ Create an instance of ``content_type`` by calling its factory with ``*arg`` and ``**kw``. If the meta of the content type has an ``after_create`` value, call it (if it's a string, it's assumed to be a method of the created object, and if it's a sequence, each value should be a string or a callable, which will be called in turn); then send a :class:`substanced.event.ContentCreatedEvent`. Return the created object. If the key ``__oid`` is in the ``kw`` arguments, it will be used as the created object's oid. """ factory = self.content_types[content_type] oid = kw.pop('__oid', None) # FBO dump system loader inst = factory(*arg, **kw) if oid is not None: set_oid(inst, oid) set_created(inst, self._utcnow()) meta = self.meta[content_type].copy() aftercreate = meta.get('after_create') if aftercreate is not None: if not is_nonstr_iter(aftercreate): aftercreate = [aftercreate] for callback in aftercreate: if isinstance(callback, basestring): callback = getattr(inst, callback) callback(inst, self.registry) self.registry.subscribers( (ContentCreated(inst, content_type, meta), inst), None ) return inst
def __call__(self, context, request): req_principals = request.effective_principals if is_nonstr_iter(req_principals): rpset = set(req_principals) if self.val.issubset(rpset): return True return False
def __init__(self, val, config): if not is_nonstr_iter(val): val = (val,) val = sorted(val) self.val = val reqs = [ p.split('=', 1) for p in val ] self.reqs = [ (x.strip(), y.strip()) for x, y in reqs ]
def permits(self, context, principals, permission): acls_to_examine = self._collect_acls_to_examine(context) applicable_aces = [] granted_permissions = set() for location, acl in acls_to_examine: for ace in reversed(acl): ace_action, ace_principals, ace_permissions = ace if not is_nonstr_iter(ace_principals): ace_principals = [ace_principals] everyone = False if Everyone in ace_principals: ace_principals = [Everyone] everyone = True ace_principals = set(ace_principals) if not is_nonstr_iter(ace_permissions): ace_permissions = [ace_permissions] if everyone or ace_principals.issubset(principals): applicable_aces.append( ( (location, acl), ACE(ace_action, ace_principals, ace_permissions, ace) ) ) if ace_action == Allow: granted_permissions.update(ace_permissions) else: granted_permissions.difference_update(ace_permissions) required_permissions = self.permission_parser(permission) if granted_permissions.issuperset(required_permissions): return ExtendedACLAllowed( applicable_aces, required_permissions, principals ) else: return ExtendedACLDenied( applicable_aces, required_permissions, principals )
def urlencode(query, doseq=True, quote_via=quote_plus): """ An alternate implementation of Python's stdlib :func:`urllib.parse.urlencode` function which accepts unicode keys and values within the ``query`` dict/sequence; all Unicode keys and values are first converted to UTF-8 before being used to compose the query string. The value of ``query`` must be a sequence of two-tuples representing key/value pairs *or* an object (often a dictionary) with an ``.items()`` method that returns a sequence of two-tuples representing key/value pairs. For minimal calling convention backwards compatibility, this version of urlencode accepts *but ignores* a second argument conventionally named ``doseq``. The Python stdlib version behaves differently when ``doseq`` is False and when a sequence is presented as one of the values. This version always behaves in the ``doseq=True`` mode, no matter what the value of the second argument. Both the key and value are encoded using the ``quote_via`` function which by default is using a similar algorithm to :func:`urllib.parse.quote_plus` which converts spaces into '+' characters and '/' into '%2F'. .. versionchanged:: 1.5 In a key/value pair, if the value is ``None`` then it will be dropped from the resulting output. .. versionchanged:: 1.9 Added the ``quote_via`` argument to allow alternate quoting algorithms to be used. """ try: # presumed to be a dictionary query = query.items() except AttributeError: pass result = '' prefix = '' for (k, v) in query: k = quote_via(k) if is_nonstr_iter(v): for x in v: x = quote_via(x) result += '%s%s=%s' % (prefix, k, x) prefix = '&' elif v is None: result += '%s%s=' % (prefix, k) else: v = quote_via(v) result += '%s%s=%s' % (prefix, k, v) prefix = '&' return result
def __init__(self, values, config): if not is_nonstr_iter(values): values = (values, ) # deprecated media ranges were only supported in versions of the # predicate that didn't support lists, so check it here if len(values) == 1 and '*' in values[0]: self._is_using_deprecated_ranges = True self.values = values
def __init__(self, info): self.info = info self.mustache_directories = self.info.settings.get('mustache.directories') if not is_nonstr_iter(self.mustache_directories): self.mustache_directories = aslist( self.mustache_directories or '', flatten=True, )
def parse_options_from_settings(settings, settings_prefix, maybe_dotted): """ Parse options for use with Mako's TemplateLookup from settings.""" def sget(name, default=None): return settings.get(settings_prefix + name, default) reload_templates = settings.get('pyramid.reload_templates', None) if reload_templates is None: reload_templates = settings.get('reload_templates', False) reload_templates = asbool(reload_templates) directories = sget('directories', []) module_directory = sget('module_directory', None) input_encoding = sget('input_encoding', 'utf-8') error_handler = sget('error_handler', None) default_filters = sget('default_filters', 'h') imports = sget('imports', None) strict_undefined = asbool(sget('strict_undefined', False)) preprocessor = sget('preprocessor', None) if not is_nonstr_iter(directories): directories = list(filter(None, directories.splitlines())) directories = [abspath_from_asset_spec(d) for d in directories] if module_directory is not None: module_directory = abspath_from_asset_spec(module_directory) if error_handler is not None: error_handler = maybe_dotted(error_handler) if default_filters is not None: if not is_nonstr_iter(default_filters): default_filters = list(filter( None, default_filters.splitlines())) if imports is not None: if not is_nonstr_iter(imports): imports = list(filter(None, imports.splitlines())) if preprocessor is not None: preprocessor = maybe_dotted(preprocessor) return dict( directories=directories, module_directory=module_directory, input_encoding=input_encoding, error_handler=error_handler, default_filters=default_filters, imports=imports, filesystem_checks=reload_templates, strict_undefined=strict_undefined, preprocessor=preprocessor, )
def newer(self, generation, index_id, oids=None): """ Return the events newer than the combination of ``generation`` and ``oid``. Filter using ``oids`` if supplied. """ if oids and not is_nonstr_iter(oids): oids = [oids] items = self.entries.newer(generation, index_id) for gen, idx, entry in items: if (not oids) or entry.oid in oids: yield gen, idx, entry
def parse_options_from_settings(settings, settings_prefix, maybe_dotted): """ Parse options for use with Mako's TemplateLookup from settings.""" def sget(name, default=None): return settings.get(settings_prefix + name, default) reload_templates = settings.get('pyramid.reload_templates', None) if reload_templates is None: reload_templates = settings.get('reload_templates', False) reload_templates = asbool(reload_templates) directories = sget('directories', []) module_directory = sget('module_directory', None) input_encoding = sget('input_encoding', 'utf-8') error_handler = sget('error_handler', None) default_filters = sget('default_filters', 'h') imports = sget('imports', None) strict_undefined = asbool(sget('strict_undefined', False)) preprocessor = sget('preprocessor', None) if not is_nonstr_iter(directories): directories = list(filter(None, directories.splitlines())) directories = [abspath_from_asset_spec(d) for d in directories] if module_directory is not None: module_directory = abspath_from_asset_spec(module_directory) if error_handler is not None: error_handler = maybe_dotted(error_handler) if default_filters is not None: if not is_nonstr_iter(default_filters): default_filters = list(filter(None, default_filters.splitlines())) if imports is not None: if not is_nonstr_iter(imports): imports = list(filter(None, imports.splitlines())) if preprocessor is not None: preprocessor = maybe_dotted(preprocessor) return dict( directories=directories, module_directory=module_directory, input_encoding=input_encoding, error_handler=error_handler, default_filters=default_filters, imports=imports, filesystem_checks=reload_templates, strict_undefined=strict_undefined, preprocessor=preprocessor, )
def query_order_by(query, table, maybe_column): order = create_order_by(table, maybe_column) if order is not None: if is_nonstr_iter(order): order = [ob for ob in order if ob is not None] if order: return query.order_by(*order) else: return query.order_by(order) return query
def add(self, name, val, after=None, before=None): if name in self.names: self.remove(name) self.names.append(name) self.name2val[name] = val if after is None and before is None: before = self.default_before after = self.default_after if after is not None: if not is_nonstr_iter(after): after = (after, ) self.name2after[name] = after self.order += [(u, name) for u in after] self.req_after.add(name) if before is not None: if not is_nonstr_iter(before): before = (before, ) self.name2before[name] = before self.order += [(name, o) for o in before] self.req_before.add(name)