예제 #1
0
def toargs(context, schema, data):
    """Marshal data to an argument dictionary using a schema

    Names that are python keywords have an underscore added as a
    suffix in the schema and in the argument list, but are used
    without the underscore in the data.

    The fields in the schema must all implement IFromUnicode.

    All of the items in the data must have corresponding fields in the
    schema unless the schema has a true tagged value named
    'keyword_arguments'.
    """
    data = dict(data)
    args = {}
    for name, field in schema.namesAndDescriptions(True):
        field = field.bind(context)
        n = name
        if n.endswith('_') and iskeyword(n[:-1]):
            n = n[:-1]

        s = data.get(n, data)
        if s is not data:
            s = str(s)
            del data[n]

            try:
                args[str(name)] = field.from_unicode(s)
            except ValidationError as v:
                reraise(ConfigurationError("Invalid value for", n, str(v)),
                        None,
                        sys.exc_info()[2])
        elif field.required:
            # if the default is valid, we can use that:
            default = field.default
            try:
                field.validate(default)
            except ValidationError:
                raise ConfigurationError("Missing parameter:", n)
            args[str(name)] = default

    if data:
        # we had data left over
        try:
            keyword_arguments = schema.getTaggedValue('keyword_arguments')
        except KeyError:
            keyword_arguments = False
        if not keyword_arguments:
            raise ConfigurationError("Unrecognized parameters:", *data)

        for name in data:
            args[str(name)] = data[name]

    return args
예제 #2
0
    def factory(self, context, name):
        r = self._registry.get(name)
        if r is None:
            # Try namespace-independent name
            ns, n = name
            r = self._registry.get(n)
            if r is None:
                raise ConfigurationError("Unknown directive", ns, n)

        f = r.lookup1(providedBy(context), Interface)
        if f is None:
            raise ConfigurationError(
                "The directive %s cannot be used in this context" % (name, ))
        return f
예제 #3
0
def grantAll_directive(_context, principal=None, role=None):  # noqa: N802
    """Grant all permissions to a role or principal
    """
    from guillotina.security.security_code import role_permission_manager
    from guillotina.security.security_code import principal_permission_manager
    nspecified = (
        (principal is not None) +
        (role is not None))

    if nspecified != 1:
        raise ConfigurationError(
            "Exactly one of the principal and role attributes "
            "must be specified")

    if principal:
        _context.action(
            discriminator=('grantAllPermissionsToPrincipal',
                           principal),
            callable=principal_permission_manager.grantAllPermissionsToPrincipal,
            args=(principal, ),
        )
    else:
        _context.action(
            discriminator=('grantAllPermissionsToRole', role),
            callable=role_permission_manager.grantAllPermissionsToRole,
            args=(role, ),
        )
예제 #4
0
 def contained(self, name, data, info):
     """Handle a subdirective
     """
     # Look up the subdirective meta data on our meta object
     ns, name = name
     schema = self.meta.get(name)
     if schema is None:
         raise ConfigurationError("Invalid directive", name)
     schema = schema[0]  # strip off info
     handler = getattr(self.handler, name)
     return SimpleStackItem(self.context, handler, info, schema, data)
예제 #5
0
    def contained(self, name, data, info):
        """Handle a contained directive

        We have to compute a new stack item by getting a named adapter
        for the current context object.
        """
        factory = self.context.factory(self.context, name)
        if factory is None:
            raise ConfigurationError("Invalid directive", name)
        adapter = factory(self.context, data, info)
        return adapter
예제 #6
0
def grant_directive(
        _context, principal=None, role=None, permission=None,
        permissions=None):
    from guillotina.security.security_code import role_permission_manager as role_perm_mgr
    from guillotina.security.security_code import principal_permission_manager as principal_perm_mgr
    from guillotina.security.security_code import principal_role_manager as principal_role_mgr

    nspecified = (
        (principal is not None) +
        (role is not None) +
        (permission is not None) +
        (permissions is not None))
    permspecified = (
        (permission is not None) +
        (permissions is not None))

    if nspecified != 2 or permspecified == 2:
        raise ConfigurationError(
            "Exactly two of the principal, role, and permission resp. "
            "permissions attributes must be specified")

    if permission:
        permissions = [permission]

    if principal and role:
        _context.action(
            discriminator=('grantRoleToPrincipal', role, principal),
            callable=principal_role_mgr.assign_role_to_principal,
            args=(role, principal),
        )
    elif principal and permissions:
        for permission in permissions:
            _context.action(
                discriminator=('grantPermissionToPrincipal',
                               permission,
                               principal),
                callable=principal_perm_mgr.grant_permission_to_principal,
                args=(permission, principal),
            )
    elif role and permissions:
        for permission in permissions:
            _context.action(
                discriminator=('grantPermissionToRole', permission, role),
                callable=role_perm_mgr.grant_permission_to_role,
                args=(permission, role),
            )
예제 #7
0
def load_behavior(_context, behavior):
    conf = behavior['config']
    klass = resolve_dotted_name(behavior['klass'])
    factory = conf.get('factory') or klass
    real_factory = resolve_dotted_name(factory)
    if IInterface.providedBy(real_factory):
        # create concret class to register for behavior
        schema = real_factory
        from guillotina.behaviors.instance import AnnotationBehavior

        class real_factory(AnnotationBehavior):
            __annotations_data_key__ = conf.get('data_key', 'default')
            auto_serialize = conf.get('auto_serialize', True)
    else:
        schema = resolve_dotted_name(conf['provides'])
    classImplements(real_factory, schema)

    name = conf.get('name')
    name_only = conf.get('name_only', False)
    title = conf.get('title', '')
    for_ = resolve_dotted_name(conf.get('for_'))
    marker = resolve_dotted_name(conf.get('marker'))

    if marker is None and real_factory is None:
        marker = schema

    if marker is not None and real_factory is None and marker is not schema:
        raise ConfigurationError(
            u"You cannot specify a different 'marker' and 'provides' if "
            u"there is no adapter factory for the provided interface."
        )
    if name_only and name is None:
        raise ConfigurationError(
            u"If you decide to only register by 'name', a name must be given."
        )

    # Instantiate the real factory if it's the schema-aware type. We do
    # this here so that the for_ interface may take this into account.
    if factory is not None and IBehaviorSchemaAwareFactory.providedBy(factory):
        factory = factory(schema)

    registration = BehaviorRegistration(
        title=conf.get('title', ''),
        description=conf.get('description', ''),
        interface=schema,
        marker=marker,
        factory=real_factory,
        name=name,
        for_=for_
    )
    if not name_only:
        # behavior registration by provides interface identifier
        component.utility(
            _context,
            provides=IBehavior,
            name=schema.__identifier__,
            component=registration
        )

    if name is not None:
        # for convinience we register with a given name
        component.utility(
            _context,
            provides=IBehavior,
            name=name,
            component=registration
        )

    if factory is None:
        if for_ is not None:
            logger.warning(
                u"Specifying 'for' in behavior '{0}' if no 'factory' is given "
                u"has no effect and is superfluous.".format(title)
            )
        # w/o factory we're done here
        return

    if for_ is None:
        # Attempt to guess the factory's adapted interface and use it as
        # the 'for_'.
        # Fallback to '*' (=Interface).
        adapts = getattr(factory, '__component_adapts__', None) or [Interface]
        if len(adapts) != 1:
            raise ConfigurationError(
                u"The factory can not be declared as multi-adapter."
            )
        for_ = adapts[0]

    adapter_factory = BehaviorAdapterFactory(registration)

    component.adapter(
        _context,
        factory=(adapter_factory,),
        provides=schema,
        for_=(for_,)
    )
예제 #8
0
 def contained(self, name, data, info):
     raise ConfigurationError("Invalid directive %s" % str(name))
예제 #9
0
 def contained(self, name, data):
     raise ConfigurationError('Invalid directive %s' % str(name))