Exemple #1
0
    def user_groups(self, userdn):
        """Get the groups the user belongs to.

        Given a user DN, return a sequence of LDAP attribute dictionaries
        matching the groups of which the DN is a member.  If the DN does not
        exist, return ``None``.

        In a return value ``[(dn, attrdict), ...]``, ``dn`` will be the
        distinguished name of the group.  Attrdict will be a dictionary
        mapping LDAP group attributes to sequences of values.

        If :meth:`pyramid.config.Configurator.ldap_set_groups_query` was not
        called, using this function will raise an
        :exc:`pyramid.exceptions.ConfiguratorError`

        """
        search = getattr(self.registry, 'ldap_groups_query', None)
        if search is None:
            raise ConfigurationError(
                'set_ldap_groups_query was not called during setup')
        login = re.match("^uid=(.*),.*$", userdn).groups()[0]
        with self.manager.connection() as conn:
            try:
                result = search.execute(conn,
                                        userdn=escape_for_search(userdn),
                                        login=login)
            except LDAPException:
                logger.debug('Exception in user_groups with userdn %r',
                             userdn,
                             exc_info=True)
                return None

        return result
Exemple #2
0
        def register():
            directories = []
            resolver = AssetResolver(self.package_name)

            # defer spec resolution until register to allow for asset
            # overrides to take place in an earlier config phase
            for spec in specs:
                # the trailing slash helps match asset overrides for folders
                if not spec.endswith('/'):
                    spec += '/'
                asset = resolver.resolve(spec)
                directory = asset.abspath()
                if not asset.isdir():
                    raise ConfigurationError('"%s" is not a directory' %
                                             directory)
                intr = self.introspectable(
                    'translation directories',
                    directory,
                    spec,
                    'translation directory',
                )
                intr['directory'] = directory
                intr['spec'] = spec
                introspectables.append(intr)
                directories.append(directory)

            tdirs = self.registry.queryUtility(ITranslationDirectories)
            if tdirs is None:
                tdirs = []
                self.registry.registerUtility(tdirs, ITranslationDirectories)
            if override:
                tdirs.extend(directories)
            else:
                for directory in reversed(directories):
                    tdirs.insert(0, directory)
Exemple #3
0
 def _get_resource(resource):
     parts = resource.split('/')
     if len(parts) == 2:
         bucket, collection = parts
     elif len(parts) == 5:
         _, _, bucket, _, collection = parts
     else:
         raise ConfigurationError(error_msg)
     valid_ids = (name_generator.match(bucket) and
                  name_generator.match(collection))
     if not valid_ids:
         raise ConfigurationError(error_msg)
     return {
         'bucket': bucket,
         'collection': collection
     }
Exemple #4
0
def includeme(config):  # pragma: no cover
    settings = config.registry.settings
    YEAR = 86400 * 365
    config.add_directive('add_mgmt_view', add_mgmt_view, action_wrap=False)
    config.add_static_view('deformstatic', 'deform:static', cache_max_age=YEAR)
    config.add_static_view('sdistatic',
                           'substanced.sdi:static',
                           cache_max_age=YEAR)
    # b/c alias for template lookups
    config.override_asset(to_override='substanced.sdi:templates/',
                          override_with='substanced.sdi.views:templates/')
    manage_prefix = settings.get('substanced.manage_prefix', '/manage')
    manage_pattern = manage_prefix + '*traverse'
    config.add_route(MANAGE_ROUTE_NAME, manage_pattern)
    config.add_request_method(mgmt_path)
    config.add_request_method(mgmt_url)
    config.add_request_method(get_user, name='user', reify=True)
    config.add_request_method(FlashUndo, name='flash_with_undo', reify=True)
    config.include('deform_bootstrap')
    secret = settings.get('substanced.secret')
    if secret is None:
        raise ConfigurationError(
            'You must set a substanced.secret key in your .ini file')
    session_factory = UnencryptedCookieSessionFactoryConfig(secret)
    config.set_session_factory(session_factory)
    from ..principal import groupfinder
    authn_policy = SessionAuthenticationPolicy(callback=groupfinder)
    authz_policy = ACLAuthorizationPolicy()
    config.set_authentication_policy(authn_policy)
    config.set_authorization_policy(authz_policy)
    config.add_permission('sdi.edit-properties')  # used by property machinery
Exemple #5
0
def get_beat_config(parser, section):
    get = partial(parser.get, section)
    has_option = partial(parser.has_option, section)

    schedule_type = get('type')
    schedule_value = safe_json(get, section, 'schedule')

    scheduler_cls = SCHEDULE_TYPE_MAP.get(schedule_type)

    if scheduler_cls is None:
        raise ConfigurationError('schedule type %s in section %s is invalid' %
                                 (schedule_type, section))

    schedule = scheduler_cls(schedule_value)

    config = {
        'task': get('task'),
        'schedule': schedule,
    }

    if has_option('args'):
        config['args'] = safe_json(get, section, 'args')

    if has_option('kwargs'):
        config['kwargs'] = safe_json(get, section, 'kwargs')

    return config
Exemple #6
0
def authtktauthenticationpolicy(_context,
                                secret,
                                callback=None,
                                cookie_name='auth_tkt',
                                secure=False,
                                include_ip=False,
                                timeout=None,
                                reissue_time=None,
                                max_age=None,
                                http_only=False,
                                path='/',
                                wild_domain=True):
    try:
        policy = AuthTktAuthenticationPolicy(secret,
                                             callback=callback,
                                             cookie_name=cookie_name,
                                             secure=secure,
                                             include_ip=include_ip,
                                             timeout=timeout,
                                             reissue_time=reissue_time,
                                             max_age=max_age,
                                             http_only=http_only,
                                             path=path,
                                             wild_domain=wild_domain)
    except ValueError, why:  # pragma: no cover
        raise ConfigurationError(str(why))
Exemple #7
0
def parse_resource(resource):
    parts = resource.split('/')
    if len(parts) == 5:
        _, _, bucket, _, collection = parts
    else:
        raise ConfigurationError(ERROR_MSG % resource)
    return {'bucket': bucket, 'collection': collection}
Exemple #8
0
def includeme(config):
    settings = config.registry.settings

    config.include('.models')

    # Security policies
    # a default authorization policy is mandatory
    authz_policy = ACLAuthorizationPolicy()
    config.set_authorization_policy(authz_policy)

    if not config.registry.queryUtility(IAuthenticationPolicy):
        config.set_authentication_policy(OauthAuthenticationPolicy())

    auth_check = settings.get('oauth2_provider.auth_checker')
    if not auth_check:
        raise ConfigurationError(
            'You must provide an implementation of the '
            'authentication check interface that is included with '
            'pyramid_oauth2_provider for verifying usernames and passwords')

    policy = config.maybe_dotted(auth_check)
    config.registry.registerUtility(policy, IAuthCheck)

    config.add_route('oauth2_provider_authorize', '/oauth2/authorize')
    config.add_route('oauth2_provider_token', '/oauth2/token')
    config.scan()
Exemple #9
0
def authtktauthenticationpolicy(_context,
                                secret,
                                callback=None,
                                cookie_name='auth_tkt',
                                secure=False,
                                include_ip=False,
                                timeout=None,
                                reissue_time=None,
                                max_age=None,
                                http_only=False,
                                path='/',
                                wild_domain=True):
    try:
        policy = AuthTktAuthenticationPolicy(
            secret,
            callback=callback,
            cookie_name=cookie_name,
            secure=secure,
            include_ip=include_ip,
            timeout=timeout,
            reissue_time=reissue_time,
            max_age=max_age,
            http_only=http_only,
            path=path,
            wild_domain=wild_domain,
            hashalg='sha512',
        )
    except ValueError as why:  # pragma: no cover
        raise ConfigurationError(str(why))
    # authentication policies must be registered eagerly so they can
    # be found by the view registration machinery
    config = with_context(_context)
    set_authentication_policy(config, policy)
Exemple #10
0
def includeme(config):
    config.add_api_capability(
        'accounts',
        description='Manage user accounts.',
        url='https://kinto.readthedocs.io/en/latest/api/1.x/accounts.html')

    config.scan('kinto.plugins.accounts.views')

    PERMISSIONS_INHERITANCE_TREE[''].update({'account:create': {}})
    PERMISSIONS_INHERITANCE_TREE['account'] = {
        'write': {
            'account': ['write']
        },
        'read': {
            'account': ['write', 'read']
        }
    }

    # Add some safety to avoid weird behaviour with basicauth default policy.
    settings = config.get_settings()
    auth_policies = settings['multiauth.policies']
    if 'basicauth' in auth_policies and 'account' in auth_policies:
        if auth_policies.index('basicauth') < auth_policies.index('account'):
            error_msg = (
                "'basicauth' should not be mentioned before 'account' "
                "in 'multiauth.policies' setting.")
            raise ConfigurationError(error_msg)
    def register_context():
        bad_config = ""
        constructed_context = None
        try:
            if context:
                if isinstance(context, CryptContext):
                    constructed_context = context
                else:
                    msg = "'context' must be an instance of passlib.CryptContext"
                    bad_config = msg
            elif ini_string:
                constructed_context = CryptContext.from_string(ini_string)
            elif ini_file:
                constructed_context = CryptContext.from_path(ini_file)
            elif context_dict:
                constructed_context = CryptContext(**context_dict)
            else:
                # no required arguments have been passed, error
                bad_config = 'requires a CryptContext or configuration data'
        except IOError:
            bad_config = "unable to open %s" % ini_file
        except ValueError:
            bad_config = "received invalid or incompatible configuration options"
        except KeyError:
            bad_config = "received unknown or forbidden configuration options"
        except TypeError:
            bad_config = "received configuration options of the wrong type"

        if bad_config:
            raise ConfigurationError("set_password_context %s" % bad_config)

        config.registry.password_context = constructed_context
Exemple #12
0
 def __init__(self, *args, **settings):
     if 'context' not in settings and len(args) > 0:
         exception, args = args[0], args[1:]
         settings['context'] = exception
     if len(args) > 0:
         raise ConfigurationError('unknown positional arguments')
     self.__dict__.update(settings)
Exemple #13
0
def setup_storage(config):
    settings = config.get_settings()

    # Id generators by resource name.
    config.registry.id_generators = {}
    for key, value in settings.items():
        m = re.match(r'^([^_]*)_?id_generator', key)
        if m is None:
            continue
        resource_name = m.group(1)
        id_generator = config.maybe_dotted(value)
        config.registry.id_generators[resource_name] = id_generator()

    storage_mod = settings['storage_backend']
    if not storage_mod:
        return

    storage_mod = config.maybe_dotted(storage_mod)
    backend = storage_mod.load_from_config(config)
    if not isinstance(backend, storage.StorageBase):
        raise ConfigurationError("Invalid storage backend: %s" % backend)
    config.registry.storage = backend

    heartbeat = storage.heartbeat(backend)
    config.registry.heartbeats['storage'] = heartbeat
Exemple #14
0
 def register():
     self._set_authentication_policy(policy)
     if self.registry.queryUtility(IAuthorizationPolicy) is None:
         raise ConfigurationError(
             'Cannot configure an authentication policy without '
             'also configuring an authorization policy '
             '(use the set_authorization_policy method)')
Exemple #15
0
def http_cached_view(view, info):
    if info.settings.get('prevent_http_cache', False):
        return view

    seconds = info.options.get('http_cache')

    if seconds is None:
        return view

    options = {}

    if isinstance(seconds, (tuple, list)):
        try:
            seconds, options = seconds
        except ValueError:
            raise ConfigurationError(
                'If http_cache parameter is a tuple or list, it must be '
                'in the form (seconds, options); not %s' % (seconds, ))

    def wrapper(context, request):
        response = view(context, request)
        prevent_caching = getattr(response.cache_control, 'prevent_auto',
                                  False)
        if not prevent_caching:
            response.cache_expires(seconds, **options)
        return response

    return wrapper
Exemple #16
0
 def __init__(self, **settings):
     if not settings.get('name'):
         raise ConfigurationError("You must provide a name for a viewlet")
     if 'for_' in settings:
         if settings.get('context') is None:
             settings['context'] = settings['for_']
     self.__dict__.update(settings)
Exemple #17
0
def includeme(config):
    """Add the Velruse standalone app configuration to a Pyramid app."""
    settings = config.registry.settings
    config.add_directive('register_velruse_store', register_velruse_store)

    # setup application
    setup = settings.get('setup') or default_setup
    if setup:
        config.include(setup)

    # include supported providers
    for provider in settings_adapter:
        config.include('velruse.providers.%s' % provider)

    # configure requested providers
    for provider in find_providers(settings):
        load_provider(config, provider)

    # check for required settings
    if not settings.get('endpoint'):
        raise ConfigurationError('missing required setting "endpoint"')

    # add views
    config.add_view(auth_complete_view,
                    context='velruse.AuthenticationComplete')
    config.add_view(auth_denied_view, context='velruse.AuthenticationDenied')
    config.add_view(auth_info_view,
                    name='auth_info',
                    request_param='format=json',
                    renderer='json')
Exemple #18
0
 def __init__(self, val, config):
     self.orig = val
     try:
         val = re.compile(val)
     except re.error as why:
         raise ConfigurationError(why.args[0])
     self.val = val
Exemple #19
0
    def user_groups(self, userdn):
        """ Given a user DN, return a sequence of LDAP attribute dictionaries
        matching the groups of which the DN is a member.  If the DN does not
        exist, return ``None``.

        In a return value ``[(dn, attrdict), ...]``, ``dn`` will be the
        distinguished name of the group.  Attrdict will be a dictionary
        mapping LDAP group attributes to sequences of values.  The keys and
        values in the dictionary values provided will be decoded from UTF-8,
        recursively, where possible.  The dictionary returned is a
        case-insensitive dictionary implemenation.

        If :meth:`pyramid.config.Configurator.ldap_set_groups_query` was not
        called, using this function will raise an
        :exc:`pyramid.exceptions.ConfiguratorError`
        """
        with self.manager.connection() as conn:
            search = getattr(self.registry, 'ldap_groups_query', None)
            if search is None:
                raise ConfigurationError(
                    'set_ldap_groups_query was not called during setup')
            try:
                result = search.execute(conn, userdn=userdn)
                return _ldap_decode(result)
            except ldap.LDAPError:
                logger.debug('Exception in user_groups with userdn %r' %
                             userdn,
                             exc_info=True)
                return None
Exemple #20
0
def prepare(request=None, registry=None):
    """ This function pushes data onto the Pyramid threadlocal stack
    (request and registry), making those objects 'current'.  It
    returns a dictionary useful for bootstrapping a Pyramid
    application in a scripting environment.

    ``request`` is passed to the :app:`Pyramid` application root
    factory to compute the root. If ``request`` is None, a default
    will be constructed using the registry's :term:`Request Factory`
    via the :meth:`pyramid.interfaces.IRequestFactory.blank` method.

    If ``registry`` is not supplied, the last registry loaded from
    :attr:`pyramid.config.global_registries` will be used. If you
    have loaded more than one :app:`Pyramid` application in the
    current process, you may not want to use the last registry
    loaded, thus you can search the ``global_registries`` and supply
    the appropriate one based on your own criteria.

    The function returns a dictionary composed of ``root``,
    ``closer``, ``registry``, ``request`` and ``root_factory``.  The
    ``root`` returned is the application's root resource object.  The
    ``closer`` returned is a callable (accepting no arguments) that
    should be called when your scripting application is finished
    using the root.  ``registry`` is the registry object passed or
    the last registry loaded into
    :attr:`pyramid.config.global_registries` if no registry is passed.
    ``request`` is the request object passed or the constructed request
    if no request is passed.  ``root_factory`` is the root factory used
    to construct the root.
    """
    if registry is None:
        registry = getattr(request, 'registry', global_registries.last)
    if registry is None:
        raise ConfigurationError('No valid Pyramid applications could be '
                                 'found, make sure one has been created '
                                 'before trying to activate it.')
    if request is None:
        request = _make_request('/', registry)
    threadlocals = {'registry': registry, 'request': request}
    threadlocal_manager.push(threadlocals)
    extensions = registry.queryUtility(IRequestExtensions)
    if extensions is not None:
        request._set_extensions(extensions)

    def closer():
        threadlocal_manager.pop()

    root_factory = registry.queryUtility(IRootFactory,
                                         default=DefaultRootFactory)
    root = root_factory(request)
    if getattr(request, 'context', None) is None:
        request.context = root
    return {
        'root': root,
        'closer': closer,
        'registry': registry,
        'request': request,
        'root_factory': root_factory
    }
Exemple #21
0
 def add_authn_plugin(self, config, plugin):
     plugin_id = plugin.get_id()
     if plugin_id in self._plugins.keys():
         raise ConfigurationError(
             'Cannot register authentication plugin twice: "%s"', plugin_id)
     else:
         log.debug('Register authentication plugin: "%s"', plugin_id)
         self._plugins[plugin_id] = plugin
Exemple #22
0
 def __call__(self, view):
     if (asyncio.iscoroutinefunction(view)
             or asyncio.iscoroutinefunction(getattr(view, '__call__', None))
             or self.is_class_method_coroutine(view)):
         raise ConfigurationError(
             'Coroutine {} mapped to executor.'.format(view))
     view = super().__call__(view)
     return self.run_in_executor_view(view)
Exemple #23
0
def get_uris(settings):
    named = []
    for k, v in settings.items():
        if k.startswith(NAMED):
            name = k[len(NAMED):]
            if not name:
                raise ConfigurationError(
                    '%s is not a valid zodbconn identifier' % k)
            named.append((name, v))
    primary = settings.get('zodbconn.uri')
    if primary is None and named:
        raise ConfigurationError(
            'Must have primary zodbconn.uri in settings containing named uris')
    if primary:
        yield '', primary
        for name, uri in named:
            yield name, uri
Exemple #24
0
 def ensure():
     if self.autocommit:
         return
     if self.registry.queryUtility(IAuthenticationPolicy) is None:
         raise ConfigurationError(
             'Cannot configure an authorization policy without '
             'also configuring an authentication policy '
             '(use the set_authorization_policy method)')
Exemple #25
0
    def __init__(self, val: List[str], config):
        if not val:
            raise ConfigurationError(
                "Excpected at least one value in headers predicate")

        self.sub_predicates = [
            predicates.HeaderPredicate(subval, config) for subval in val
        ]
Exemple #26
0
def initialize(config,
               version=None,
               settings_prefix='',
               default_settings=None):
    """Initialize kinto.core with the given configuration, version and project
    name.

    This will basically include kinto.core in Pyramid and set route prefix
    based on the specified version.

    :param config: Pyramid configuration
    :type config: ~pyramid:pyramid.config.Configurator
    :param str version: Current project version (e.g. '0.0.1') if not defined
        in application settings.
    :param str settings_prefix: Project name if not defined
        in application settings.
    :param dict default_settings: Override kinto.core default settings values.
    """
    from kinto.core import DEFAULT_SETTINGS

    settings = config.get_settings()

    settings_prefix = settings.pop(
        'kinto.settings_prefix',
        settings.get('settings_prefix')) or settings_prefix
    settings['settings_prefix'] = settings_prefix
    if not settings_prefix:
        warnings.warn('No value specified for `settings_prefix`')

    kinto_core_defaults = {**DEFAULT_SETTINGS}

    if default_settings:
        kinto_core_defaults.update(default_settings)

    load_default_settings(config, kinto_core_defaults)

    http_scheme = settings['http_scheme']
    if http_scheme != 'https':
        warnings.warn('HTTPS is not enabled')

    # Override project version from settings.
    project_version = settings.get('project_version') or version
    if not project_version:
        error_msg = 'Invalid project version: {}'.format(project_version)
        raise ConfigurationError(error_msg)
    settings['project_version'] = project_version = str(project_version)

    # HTTP API version.
    http_api_version = settings.get('http_api_version')
    if http_api_version is None:
        # The API version is derivated from the module version if not provided.
        http_api_version = '.'.join(project_version.split('.')[0:2])
    settings['http_api_version'] = http_api_version = str(http_api_version)
    api_version = 'v{}'.format(http_api_version.split('.')[0])

    # Include kinto.core views with the correct api version prefix.
    config.include('kinto.core', route_prefix=api_version)
    config.route_prefix = api_version
Exemple #27
0
def initialize(config,
               version=None,
               settings_prefix="",
               default_settings=None):
    """Initialize kinto.core with the given configuration, version and project
    name.

    This will basically include kinto.core in Pyramid and set route prefix
    based on the specified version.

    :param config: Pyramid configuration
    :type config: ~pyramid:pyramid.config.Configurator
    :param str version: Current project version (e.g. '0.0.1') if not defined
        in application settings.
    :param str settings_prefix: Project name if not defined
        in application settings.
    :param dict default_settings: Override kinto.core default settings values.
    """
    from kinto.core import DEFAULT_SETTINGS

    settings = config.get_settings()

    settings_prefix = (settings.pop("kinto.settings_prefix",
                                    settings.get("settings_prefix"))
                       or settings_prefix)
    settings["settings_prefix"] = settings_prefix
    if not settings_prefix:
        warnings.warn("No value specified for `settings_prefix`")

    kinto_core_defaults = {**DEFAULT_SETTINGS}

    if default_settings:
        kinto_core_defaults.update(default_settings)

    load_default_settings(config, kinto_core_defaults)

    http_scheme = settings["http_scheme"]
    if http_scheme != "https":
        warnings.warn("HTTPS is not enabled")

    # Override project version from settings.
    project_version = settings.get("project_version") or version
    if not project_version:
        error_msg = f"Invalid project version: {project_version}"
        raise ConfigurationError(error_msg)
    settings["project_version"] = project_version = str(project_version)

    # HTTP API version.
    http_api_version = settings.get("http_api_version")
    if http_api_version is None:
        # The API version is derivated from the module version if not provided.
        http_api_version = ".".join(project_version.split(".")[0:2])
    settings["http_api_version"] = http_api_version = str(http_api_version)
    api_version = f"v{http_api_version.split('.')[0]}"

    # Include kinto.core views with the correct api version prefix.
    config.include("kinto.core", route_prefix=api_version)
    config.route_prefix = api_version
Exemple #28
0
    def add_translation_dirs(self, *specs):
        """ Add one or more :term:`translation directory` paths to the
        current configuration state.  The ``specs`` argument is a
        sequence that may contain absolute directory paths
        (e.g. ``/usr/share/locale``) or :term:`asset specification`
        names naming a directory path (e.g. ``some.package:locale``)
        or a combination of the two.

        Example:

        .. code-block:: python

           config.add_translation_dirs('/usr/share/locale',
                                       'some.package:locale')

        Later calls to ``add_translation_dir`` insert directories into the
        beginning of the list of translation directories created by earlier
        calls.  This means that the same translation found in a directory
        added later in the configuration process will be found before one
        added earlier in the configuration process.  However, if multiple
        specs are provided in a single call to ``add_translation_dirs``, the
        directories will be inserted into the beginning of the directory list
        in the order they're provided in the ``*specs`` list argument (items
        earlier in the list trump ones later in the list).
        """
        directories = []
        introspectables = []

        for spec in specs[::-1]:  # reversed
            package_name, filename = self._split_spec(spec)
            if package_name is None:  # absolute filename
                directory = filename
            else:
                __import__(package_name)
                package = sys.modules[package_name]
                directory = os.path.join(package_path(package), filename)

            if not os.path.isdir(os.path.realpath(directory)):
                raise ConfigurationError('"%s" is not a directory' % directory)
            intr = self.introspectable('translation directories', directory,
                                       spec, 'translation directory')
            intr['directory'] = directory
            intr['spec'] = spec
            introspectables.append(intr)
            directories.append(directory)

        def register():
            for directory in directories:

                tdirs = self.registry.queryUtility(ITranslationDirectories)
                if tdirs is None:
                    tdirs = []
                    self.registry.registerUtility(tdirs,
                                                  ITranslationDirectories)

                tdirs.insert(0, directory)

        self.action(None, register, introspectables=introspectables)
Exemple #29
0
    def _add_view_from_route(self,
                             route_name,
                             view,
                             context,
                             permission,
                             renderer,
                             attr,
                             ):
        if view:
            self.add_view(
                permission=permission,
                context=context,
                view=view,
                name='',
                route_name=route_name,
                renderer=renderer,
                attr=attr,
                )
        else:
            # prevent mistakes due to misunderstanding of how hybrid calls to
            # add_route and add_view interact
            if attr:
                raise ConfigurationError(
                    'view_attr argument not permitted without view '
                    'argument')
            if context:
                raise ConfigurationError(
                    'view_context argument not permitted without view '
                    'argument')
            if permission:
                raise ConfigurationError(
                    'view_permission argument not permitted without view '
                    'argument')
            if renderer:
                raise ConfigurationError(
                    'view_renderer argument not permitted without '
                    'view argument')

        warnings.warn(
            'Passing view-related arguments to add_route() is deprecated as of '
            'Pyramid 1.1.  Use add_view() to associate a view with a route '
            'instead.  See "Deprecations" in "What\'s New in Pyramid 1.1" '
            'within the general Pyramid documentation for further details.',
            DeprecationWarning,
            4)
Exemple #30
0
def includeme(config):
    config.add_api_capability(
        'accounts',
        description='Manage user accounts.',
        url='https://kinto.readthedocs.io/en/latest/api/1.x/accounts.html')

    config.scan('kinto.plugins.accounts.views')

    PERMISSIONS_INHERITANCE_TREE['root'].update({
        'account:create': {}
    })
    PERMISSIONS_INHERITANCE_TREE['account'] = {
        'write': {'account': ['write']},
        'read': {'account': ['write', 'read']}
    }

    # Add some safety to avoid weird behaviour with basicauth default policy.
    settings = config.get_settings()
    auth_policies = settings['multiauth.policies']
    if 'basicauth' in auth_policies and 'account' in auth_policies:
        if auth_policies.index('basicauth') < auth_policies.index('account'):
            error_msg = ("'basicauth' should not be mentioned before 'account' "
                         "in 'multiauth.policies' setting.")
            raise ConfigurationError(error_msg)

    # We assume anyone in account_create_principals is to create
    # accounts for other people.
    # No one can create accounts for other people unless they are an
    # "admin", defined as someone matching account_write_principals.
    # Therefore any account that is in account_create_principals
    # should be in account_write_principals too.
    creators = set(settings.get('account_create_principals', '').split())
    admins = set(settings.get('account_write_principals', '').split())
    cant_create_anything = creators.difference(admins)
    # system.Everyone isn't an account.
    cant_create_anything.discard('system.Everyone')
    if cant_create_anything:
        message = ('Configuration has some principals in account_create_principals '
                   'but not in account_write_principals. These principals will only be '
                   'able to create their own accounts. This may not be what you want.\n'
                   'If you want these users to be able to create accounts for other users, '
                   'add them to account_write_principals.\n'
                   'Affected users: {}'.format(list(cant_create_anything)))

        raise ConfigurationError(message)