예제 #1
0
def get_entities_for_reindex(tags):
    """Collect entities for theses tags."""
    if isinstance(tags, Tag):
        tags = (tags,)

    session = db.session()
    indexing = get_service("indexing")
    tbl = Entity.__table__
    tag_ids = [t.id for t in tags]
    query = (
        sa.sql.select([tbl.c.entity_type, tbl.c.id])
        .select_from(tbl.join(entity_tag_tbl, entity_tag_tbl.c.entity_id == tbl.c.id))
        .where(entity_tag_tbl.c.tag_id.in_(tag_ids))
    )

    entities = set()

    with session.no_autoflush:
        for entity_type, entity_id in session.execute(query):
            if entity_type not in indexing.adapted:
                logger.debug("%r is not indexed, skipping", entity_type)

            item = ("changed", entity_type, entity_id, ())
            entities.add(item)

    return entities
예제 #2
0
def is_admin(group):
    security = get_service("security")
    is_admin = current_user in group.admins
    if not is_admin and "security" in current_app.extensions:
        is_admin = security.has_role(current_user, "admin")

    return is_admin
예제 #3
0
    def url_value_preprocess(self, endpoint, view_args):
        model_name = view_args.pop("Model", None)
        group = view_args.pop("group", _MARKER)

        if group == "_":
            # "General" group
            group = ""

        if group is not _MARKER:
            view_args["group"] = group

        if model_name is not None:
            svc = get_service("vocabularies")
            Model = svc.get_vocabulary(name=model_name, group=group)
            g.breadcrumb.append(
                BreadcrumbItem(
                    label=Model.Meta.group if group else _("Global"),
                    url=url_for(".vocabularies_group", group=group or "_"),
                ))
            g.breadcrumb.append(
                BreadcrumbItem(
                    label=Model.Meta.label,
                    url=url_for(".vocabularies_model",
                                group=group or "_",
                                Model=Model.Meta.name),
                ))
            view_args["Model"] = Model
예제 #4
0
def get_attachments_from_dms(community):
    index_service = get_service("indexing")
    filters = wq.And(
        [
            wq.Term("community_id", community.id),
            wq.Term("object_type", Document.entity_type),
        ]
    )
    sortedby = whoosh.sorting.FieldFacet("created_at", reverse=True)
    documents = index_service.search("", filter=filters, sortedby=sortedby, limit=50)

    attachments = []
    for doc in documents:
        url = url_for(doc)
        attachment = Attachment(
            url,
            doc["name"],
            doc["owner_name"],
            doc["created_at"],
            doc.get("content_length"),
            doc.get("content_type", ""),
        )
        attachments.append(attachment)

    return attachments
예제 #5
0
    def get_results(self, q, *args, **kwargs):
        svc = get_service("indexing")
        search_kwargs = {"limit": 50, "Models": (self.Model, )}
        results = svc.search(q, **search_kwargs)

        itemkey = None
        try:
            # 'nom' doesn't always exist but for Contacts, sorting on
            # the last name ('nom') feels more natural than 'name',
            # which starts with the first name ('prenom').
            if not results.is_empty():
                res = results[0]
                fields = res.fields()
                if "nom" in fields:
                    itemkey = "nom"
                elif "name" in fields:
                    itemkey = "name"
                if itemkey:
                    results.sort(key=lambda it: it.fields().get(itemkey))
        except Exception:
            if itemkey is not None:
                msg = "we could not sort whoosh results on fields' key {}.".format(
                    itemkey)
                logger.warning(msg)

        return results
예제 #6
0
def can_edit(user):
    security = get_service("security")
    if not security:
        return True

    # TODO: introduce a "self" role?
    return (user == current_user) or security.has_role(current_user, "admin")
예제 #7
0
    def url_value_preprocess(self, endpoint, view_args):
        Model = view_args.pop('Model', None)
        group = view_args.pop('group', _MARKER)

        if group == '_':
            # "General" group
            group = None

        if group is not _MARKER:
            view_args['group'] = group

        if Model is not None:
            svc = get_service('vocabularies')
            Model = svc.get_vocabulary(name=Model, group=group)
            g.breadcrumb.append(BreadcrumbItem(
                label=Model.Meta.group if group else _('Global'),
                url=url_for('.vocabularies_group', group=group or '_'),
            ))
            g.breadcrumb.append(
                BreadcrumbItem(
                    label=Model.Meta.label,
                    url=url_for(
                        '.vocabularies_model',
                        group=group or '_',
                        Model=Model.Meta.name,
                    ),
                ),
            )
            view_args['Model'] = Model
예제 #8
0
def is_admin(group):
    security = get_service("security")
    is_admin = current_user in group.admins
    if not is_admin and "security" in current_app.extensions:
        is_admin = security.has_role(current_user, "admin")

    return is_admin
예제 #9
0
    def data(self, *args, **kw) -> Dict:
        security = get_service("security")
        length = int(kw.get("iDisplayLength", 0))
        start = int(kw.get("iDisplayStart", 0))
        sort_dir = kw.get("sSortDir_0", "asc")
        echo = int(kw.get("sEcho", 0))
        search = kw.get("sSearch", "").replace("%", "").strip().lower()

        end = start + length
        # pyre-fixme[16]: `Group` has no attribute `query`.
        query = Group.query.options(sa.orm.noload("*"))
        total_count = query.count()

        if search:
            # TODO: gérer les accents
            query = query.filter(
                func.lower(Group.name).like("%" + search + "%"))

        count = query.count()
        columns = [func.lower(Group.name)]
        direction = asc if sort_dir == "asc" else desc
        order_by = list(map(direction, columns))

        # sqlite does not support 'NULLS FIRST|LAST' in ORDER BY clauses
        # pyre-fixme[16]: `Group` has no attribute `__mapper__`.
        engine = query.session.get_bind(Group.__mapper__)
        if engine.name != "sqlite":
            order_by[0] = nullslast(order_by[0])

        query = query.order_by(*order_by).add_columns(Group.members_count)
        groups = query.slice(start, end).all()
        data = []

        for group, members_count in groups:
            # TODO: this should be done on the browser.
            group_url = url_for(".groups_group", group_id=group.id)
            name = html.escape(group.name or "")
            # pyre-fixme[16]: `Service` has no attribute `get_roles`.
            roles = [r for r in security.get_roles(group) if r.assignable]

            columns = [
                f'<a href="{group_url}">{name}</a>',
                str(members_count or 0),
                render_template_string(
                    """{%- for role in roles %}
                        <span class="badge badge-default">{{ role }}</span>
                        {%- endfor %}""",
                    roles=roles,
                ),
                "\u2713" if group.public else "",
            ]

            data.append(columns)

        return {
            "sEcho": echo,
            "iTotalRecords": total_count,
            "iTotalDisplayRecords": count,
            "aaData": data,
        }
예제 #10
0
    def data(self, *args, **kw):
        security = get_service('security')
        length = int(kw.get("iDisplayLength", 0))
        start = int(kw.get("iDisplayStart", 0))
        sort_dir = kw.get("sSortDir_0", "asc")
        echo = int(kw.get("sEcho", 0))
        search = kw.get("sSearch", "").replace("%", "").strip().lower()

        end = start + length
        query = Group.query \
            .options(sa.orm.noload('*'))
        total_count = query.count()

        if search:
            # TODO: gérer les accents
            query = query.filter(
                func.lower(Group.name).like("%" + search + "%"),
            )

        count = query.count()
        columns = [func.lower(Group.name)]
        direction = asc if sort_dir == 'asc' else desc
        order_by = list(map(direction, columns))

        # sqlite does not support 'NULLS FIRST|LAST' in ORDER BY clauses
        engine = query.session.get_bind(Group.__mapper__)
        if engine.name != 'sqlite':
            order_by[0] = nullslast(order_by[0])

        query = query.order_by(*order_by) \
            .add_columns(Group.members_count)
        groups = query.slice(start, end).all()
        data = []

        for group, members_count in groups:
            # TODO: this should be done on the browser.
            group_url = url_for(".groups_group", group_id=group.id)
            name = escape(getattr(group, "name") or "")
            roles = [r for r in security.get_roles(group) if r.assignable]

            columns = [
                '<a href="{url}">{name}</a>'.format(url=group_url, name=name),
                text_type(members_count or 0),
                render_template_string(
                    '''{%- for role in roles %}
                        <span class="badge badge-default">{{ role }}</span>
                        {%- endfor %}''',
                    roles=roles,
                ),
                '\u2713' if group.public else '',
            ]

            data.append(columns)

        return {
            "sEcho": echo,
            "iTotalRecords": total_count,
            "iTotalDisplayRecords": count,
            "aaData": data,
        }
예제 #11
0
    def data(self, q="", page=None, *args, **kwargs):
        if not q:
            q = ""
        svc = get_service("indexing")
        url_for_hit = svc.app_state.url_for_hit
        search_kwargs = {"facet_by_type": 5}
        response = {}
        results = svc.search(q, **search_kwargs)
        datasets = {}

        for typename, docs in results.items():
            dataset = []
            for doc in docs:
                # Because it happens sometimes
                try:
                    name = doc["name"]
                except KeyError:
                    continue

                d = {"name": name}
                url = url_for_hit(doc, None)
                if url is not None:
                    d["url"] = url
                    dataset.append(d)
            datasets[typename] = dataset

        response["results"] = datasets
        return response
예제 #12
0
    def data(self, q="", page=None, *args, **kwargs):
        if not q:
            q = ""
        svc = get_service("indexing")
        url_for_hit = svc.app_state.url_for_hit
        search_kwargs = {"facet_by_type": 5}
        response = {}
        results = svc.search(q, **search_kwargs)
        datasets = {}

        for typename, docs in results.items():
            dataset = []
            for doc in docs:
                # Because it happens sometimes
                try:
                    name = doc["name"]
                except KeyError:
                    continue

                d = {"name": name}
                url = url_for_hit(doc, None)
                if url is not None:
                    d["url"] = url
                    dataset.append(d)
            datasets[typename] = dataset

        response["results"] = datasets
        return response
예제 #13
0
    def get_results(self, q, *args, **kwargs):
        svc = get_service("indexing")
        search_kwargs = {"limit": 50, "Models": (self.Model,)}
        results = svc.search(q, **search_kwargs)

        itemkey = None
        try:
            # 'nom' doesn't always exist but for Contacts, sorting on
            # the last name ('nom') feels more natural than 'name',
            # which starts with the first name ('prenom').
            if not results.is_empty():
                res = results[0]
                fields = res.fields()
                if "nom" in fields:
                    itemkey = "nom"
                elif "name" in fields:
                    itemkey = "name"
                if itemkey:
                    results.sort(key=lambda it: it.fields().get(itemkey))
        except Exception:
            if itemkey is not None:
                msg = "we could not sort whoosh results on fields' key {}.".format(
                    itemkey
                )
                logger.warning(msg)

        return results
예제 #14
0
def get_entities_for_reindex(tags):
    """Collect entities for theses tags."""
    if isinstance(tags, Tag):
        tags = (tags, )

    session = db.session()
    indexing = get_service("indexing")
    tbl = Entity.__table__
    tag_ids = [t.id for t in tags]
    query = (sa.sql.select([tbl.c.entity_type, tbl.c.id]).select_from(
        tbl.join(entity_tag_tbl,
                 entity_tag_tbl.c.entity_id == tbl.c.id)).where(
                     entity_tag_tbl.c.tag_id.in_(tag_ids)))

    entities = set()

    with session.no_autoflush:
        for entity_type, entity_id in session.execute(query):
            if entity_type not in indexing.adapted:
                logger.debug("%r is not indexed, skipping", entity_type)

            item = ("changed", entity_type, entity_id, ())
            entities.add(item)

    return entities
예제 #15
0
    def content(self):
        obj = self.current_obj

        index_service = get_service("indexing")
        index = index_service.app_state.indexes["default"]
        schema = index.schema
        context = self.context.copy()
        context["schema"] = schema
        context["sorted_fields"] = sorted(schema.names())

        adapter = index_service.adapted.get(fqcn(obj.__class__))
        if adapter and adapter.indexable:
            doc = context["current_document"] = index_service.get_document(
                obj, adapter)
            indexed = {}
            for name, field in schema.items():
                value = doc.get(name)
                indexed[name] = None
                if value and field.analyzer and field.format:
                    indexed[name] = list(field.process_text(value))
            context["current_indexed"] = indexed
            context["current_keys"] = sorted(set(doc) | set(indexed))

        with index.searcher() as search:
            document = search.document(object_key=obj.object_key)

        sorted_keys = sorted(document) if document is not None else None

        context.update({"document": document, "sorted_keys": sorted_keys})

        jinja_env = current_app.jinja_env
        jinja_env.filters.update(self.jinja_env.filters)
        template = jinja_env.get_or_select_template(
            "debug_panels/indexing_panel.html")
        return template.render(context)
예제 #16
0
def user(user_id):
    security = get_service("security")
    user = User.query.get(user_id)

    # FIXME: use user profiles
    view_form = UserProfileViewForm(obj=user)

    communities = [m.community for m in user.communautes_membership]
    if current_user != user and (not security.has_role(current_user,
                                                       "manager")):
        # filter visible communautes (ticket 165)
        communities = [c for c in communities if c.has_member(current_user)]

    view_form.communautes._set_data(communities)

    # FIXME
    contact = user
    entries = get_recent_entries(user=user)
    entries = ActivityEntryPresenter.wrap_collection(entries)
    ctx = {
        "user": user,
        "contact": contact,
        "view_form": view_form,
        "can_edit": can_edit(user),
        "tabs": make_tabs(user),
        "activity_entries": entries,
    }
    return render_template("social/user.html", **ctx)
예제 #17
0
def createuser(email, password, role=None, name=None, first_name=None):
    """Create new user."""

    if User.query.filter(User.email == email).count() > 0:
        print(f"A user with email '{email}' already exists, aborting.")
        return

    # if password is None:
    #     password = prompt_pass("Password")

    user = User(
        email=email,
        password=password,
        last_name=name,
        first_name=first_name,
        can_login=True,
    )
    db.session.add(user)

    if role in ("admin",):
        # FIXME: add other valid roles
        security = get_service("security")
        security.grant_role(user, role)

    db.session.commit()
    print(f"User {email} added")
예제 #18
0
    def content(self):
        obj = self.current_obj

        index_service = get_service("indexing")
        index = index_service.app_state.indexes["default"]
        schema = index.schema
        context = self.context.copy()
        context["schema"] = schema
        context["sorted_fields"] = sorted(schema.names())

        adapter = index_service.adapted.get(fqcn(obj.__class__))
        if adapter and adapter.indexable:
            doc = context["current_document"] = index_service.get_document(obj, adapter)
            indexed = {}
            for name, field in schema.items():
                value = doc.get(name)
                indexed[name] = None
                if value and field.analyzer and field.format:
                    indexed[name] = list(field.process_text(value))
            context["current_indexed"] = indexed
            context["current_keys"] = sorted(set(doc) | set(indexed))

        with index.searcher() as search:
            document = search.document(object_key=obj.object_key)

        sorted_keys = sorted(document) if document is not None else None

        context.update({"document": document, "sorted_keys": sorted_keys})

        jinja_env = current_app.jinja_env
        jinja_env.filters.update(self.jinja_env.filters)
        template = jinja_env.get_or_select_template("debug_panels/indexing_panel.html")
        return template.render(context)
예제 #19
0
def createuser(email, password, role=None, name=None, first_name=None):
    """Create new user."""
    email = text_type(email)
    if User.query.filter(User.email == email).count() > 0:
        print("A user with email '{}' already exists, aborting.".format(email))
        return

    if password is None:
        password = prompt_pass('Password')

    user = User(
        email=email,
        password=password,
        last_name=name,
        first_name=first_name,
        can_login=True,
    )
    db.session.add(user)

    if role in ('admin',):
        # FIXME: add other valid roles
        security = get_service('security')
        security.grant_role(user, role)

    db.session.commit()
    print("User {} added".format(email))
예제 #20
0
  def __call__(self, form, field):
    svc = get_service('antivirus')
    if not svc:
      return

    res = svc.scan(field.data)
    if res is False:
      raise ValidationError(_(u'Virus detected!'))
예제 #21
0
    def __call__(self, form, field):
        svc = get_service("antivirus")
        if not svc:
            return

        res = svc.scan(field.data)
        if res is False:
            raise validators.ValidationError(_("Virus detected!"))
예제 #22
0
    def __call__(self, form, field):
        svc = get_service('antivirus')
        if not svc:
            return

        res = svc.scan(field.data)
        if res is False:
            raise ValidationError(_(u'Virus detected!'))
예제 #23
0
 def get_form_kwargs(self):
     kw = super().get_form_kwargs()
     security = get_service("security")
     roles = [
         r for r in security.get_roles(self.obj, no_group_roles=True) if r.assignable
     ]
     kw["roles"] = [role.name for role in roles]
     return kw
예제 #24
0
def _run_antivirus(document):
    antivirus = get_service("antivirus")
    if antivirus and antivirus.running:
        is_clean = antivirus.scan(document.content_blob)
        if "antivirus_task" in document.content_blob.meta:
            del document.content_blob.meta["antivirus_task"]
        return is_clean
    return None
예제 #25
0
    def __call__(self, form, field):
        svc = get_service("antivirus")
        if not svc:
            return

        res = svc.scan(field.data)
        if res is False:
            raise validators.ValidationError(_("Virus detected!"))
예제 #26
0
def _run_antivirus(document):
    antivirus = get_service('antivirus')
    if antivirus and antivirus.running:
        is_clean = antivirus.scan(document.content_blob)
        if 'antivirus_task' in document.content_blob.meta:
            del document.content_blob.meta['antivirus_task']
        return is_clean
    return None
예제 #27
0
 def get(self):
     svc = get_service('vocabularies')
     ctx = {
         'service': svc,
         'url_for_voc_edit': self.voc_edit_url,
         'icon_checked': Glyphicon('check'),
         'vocabularies': svc.grouped_vocabularies,
     }
     return render_template('admin/vocabularies.html', **ctx)
예제 #28
0
 def decorated_view(*args, **kwargs):
     community = g.community
     if community and community.has_permission(current_user, MANAGE):
         return func(*args, **kwargs)
     security = get_service("security")
     is_admin = security.has_role(current_user, "admin")
     if not is_admin:
         raise Forbidden()
     return func(*args, **kwargs)
예제 #29
0
 def decorated_view(*args, **kwargs):
     community = getattr(g, "community")
     if community and community.has_permission(current_user, MANAGE):
         return func(*args, **kwargs)
     security = get_service("security")
     is_admin = security.has_role(current_user, "admin")
     if not is_admin:
         raise Forbidden()
     return func(*args, **kwargs)
예제 #30
0
 def get_form_kwargs(self):
     kw = super().get_form_kwargs()
     security = get_service("security")
     roles = [
         r for r in security.get_roles(self.obj, no_group_roles=True)
         if r.assignable
     ]
     kw["roles"] = [role.name for role in roles]
     return kw
예제 #31
0
def finalize_validate():
    config_file = Path(current_app.instance_path) / "config.py"
    logging_file = Path(current_app.instance_path) / "logging.yml"

    assert not config_file.exists()
    config = cmd_config.DefaultConfig(logging_file="logging.yml")
    config.SQLALCHEMY_DATABASE_URI = session_get("db")["uri"]

    redis_uri = session_get("redis")["uri"]
    config.REDIS_URI = redis_uri
    config.BROKER_URL = redis_uri
    config.CELERY_RESULT_BACKEND = redis_uri

    d = session_get("site_info")
    config.SITE_NAME = d["sitename"]
    config.MAIL_SENDER = d["mailsender"]

    is_production = d["server_mode"] == "production"
    config.PRODUCTION = is_production
    config.DEBUG = not is_production
    config.DEBUG_TB_ENABLED = config.DEBUG
    config.CELERY_ALWAYS_EAGER = not is_production

    cmd_config.write_config(config_file, config)
    cmd_config.maybe_write_logging(logging_file)

    admin_account = session_get("admin_account")
    # create a new app that will be configured with new config,
    # to create database and admin_user
    setup_app = unwrap(current_app)
    app = setup_app.__class__(
        setup_app.import_name,
        static_url_path=setup_app.static_url_path,
        static_folder=setup_app.static_folder,
        template_folder=setup_app.template_folder,
        instance_path=setup_app.instance_path,
    )
    with app.test_request_context("/setup/finalize"):
        app.create_db()
        db_session = db.session()
        admin = User(
            email=admin_account["email"],
            password=admin_account["password"],
            last_name=admin_account["name"],
            first_name=admin_account["firstname"],
            can_login=True,
        )
        db_session.add(admin)
        security = get_service("security")
        security.grant_role(admin, Admin)
        db_session.commit()

    session_clear()

    return render_template("setupwizard/done.html",
                           config_file=config_file,
                           logging_file=logging_file)
예제 #32
0
def finalize_validate():
    config_file = Path(current_app.instance_path) / "config.py"
    logging_file = Path(current_app.instance_path) / "logging.yml"

    assert not config_file.exists()
    config = cmd_config.DefaultConfig(logging_file="logging.yml")
    config.SQLALCHEMY_DATABASE_URI = session_get("db")["uri"]

    redis_uri = session_get("redis")["uri"]
    config.REDIS_URI = redis_uri
    config.BROKER_URL = redis_uri
    config.CELERY_RESULT_BACKEND = redis_uri

    d = session_get("site_info")
    config.SITE_NAME = d["sitename"]
    config.MAIL_SENDER = d["mailsender"]

    is_production = d["server_mode"] == "production"
    config.PRODUCTION = is_production
    config.DEBUG = not is_production
    config.DEBUG_TB_ENABLED = config.DEBUG
    config.CELERY_ALWAYS_EAGER = not is_production

    cmd_config.write_config(config_file, config)
    cmd_config.maybe_write_logging(logging_file)

    admin_account = session_get("admin_account")
    # create a new app that will be configured with new config,
    # to create database and admin_user
    setup_app = unwrap(current_app)
    app = setup_app.__class__(
        setup_app.import_name,
        static_url_path=setup_app.static_url_path,
        static_folder=setup_app.static_folder,
        template_folder=setup_app.template_folder,
        instance_path=setup_app.instance_path,
    )
    with app.test_request_context("/setup/finalize"):
        app.create_db()
        db_session = db.session()
        admin = User(
            email=admin_account["email"],
            password=admin_account["password"],
            last_name=admin_account["name"],
            first_name=admin_account["firstname"],
            can_login=True,
        )
        db_session.add(admin)
        security = get_service("security")
        security.grant_role(admin, Admin)
        db_session.commit()

    session_clear()

    return render_template(
        "setupwizard/done.html", config_file=config_file, logging_file=logging_file
    )
예제 #33
0
def finalize_validate():
    config_file = os.path.join(current_app.instance_path, 'config.py')
    logging_file = os.path.join(current_app.instance_path, 'logging.yml')

    assert not os.path.exists(config_file)
    config = cmd_config.DefaultConfig(logging_file='logging.yml')
    config.SQLALCHEMY_DATABASE_URI = session_get('db')['uri']

    redis_uri = session_get('redis')['uri']
    config.REDIS_URI = redis_uri
    config.BROKER_URL = redis_uri
    config.CELERY_RESULT_BACKEND = redis_uri

    d = session_get('site_info')
    config.SITE_NAME = d['sitename']
    config.MAIL_SENDER = d['mailsender']

    is_production = d['server_mode'] == u'production'
    config.PRODUCTION = is_production
    config.DEBUG = not is_production
    config.DEBUG_TB_ENABLED = config.DEBUG
    config.CELERY_ALWAYS_EAGER = not is_production

    cmd_config.write_config(config_file, config)
    cmd_config.maybe_write_logging(logging_file)

    admin_account = session_get('admin_account')
    # create a new app that will be configured with new config, to create database
    # and admin_user
    setup_app = current_app._get_current_object()
    app = setup_app.__class__(
        setup_app.import_name,
        static_url_path=setup_app.static_url_path,
        static_folder=setup_app.static_folder,
        template_folder=setup_app.template_folder,
        instance_path=setup_app.instance_path,
    )
    with app.test_request_context('/setup/finalize'):
        app.create_db()
        db_session = app.db.session()
        admin = User(email=admin_account['email'],
                     password=admin_account['password'],
                     last_name=admin_account['name'],
                     first_name=admin_account['firstname'],
                     can_login=True)
        db_session.add(admin)
        security = get_service('security')
        security.grant_role(admin, Admin)
        db_session.commit()

    session_clear()

    response = make_response(
        render_template('setupwizard/done.html',
                        config_file=config_file,
                        logging_file=logging_file), 200)
    return response
예제 #34
0
 def get_form_kwargs(self):
     kw = super(GroupEdit, self).get_form_kwargs()
     security = get_service('security')
     roles = [
         r for r in security.get_roles(self.obj, no_group_roles=True)
         if r.assignable
     ]
     kw['roles'] = [r.name for r in roles]
     return kw
예제 #35
0
def finalize_validate():
  config_file = os.path.join(current_app.instance_path, 'config.py')
  logging_file = os.path.join(current_app.instance_path, 'logging.yml')

  assert not os.path.exists(config_file)
  config = cmd_config.DefaultConfig(logging_file='logging.yml')
  config.SQLALCHEMY_DATABASE_URI = session_get('db')['uri']

  redis_uri = session_get('redis')['uri']
  config.REDIS_URI = redis_uri
  config.BROKER_URL = redis_uri
  config.CELERY_RESULT_BACKEND = redis_uri

  d = session_get('site_info')
  config.SITE_NAME = d['sitename']
  config.MAIL_SENDER = d['mailsender']

  is_production = d['server_mode'] == u'production'
  config.PRODUCTION = is_production
  config.DEBUG = not is_production
  config.DEBUG_TB_ENABLED = config.DEBUG
  config.CELERY_ALWAYS_EAGER = not is_production

  cmd_config.write_config(config_file, config)
  cmd_config.maybe_write_logging(logging_file)

  admin_account = session_get('admin_account')
  # create a new app that will be configured with new config, to create database
  # and admin_user
  setup_app = current_app._get_current_object()
  app = setup_app.__class__(
      setup_app.import_name,
      static_url_path=setup_app.static_url_path,
      static_folder=setup_app.static_folder,
      template_folder=setup_app.template_folder,
      instance_path=setup_app.instance_path,
  )
  with app.test_request_context('/setup/finalize'):
    app.create_db()
    db_session = app.db.session()
    admin = User(email=admin_account['email'],
                 password=admin_account['password'],
                 last_name=admin_account['name'],
                 first_name=admin_account['firstname'],
                 can_login=True)
    db_session.add(admin)
    security = get_service('security')
    security.grant_role(admin, Admin)
    db_session.commit()

  session_clear()

  response = make_response(
    render_template('setupwizard/done.html', config_file=config_file,
                    logging_file=logging_file),
    200)
  return response
예제 #36
0
    def data(self, *args, **kw):
        security = get_service("security")
        length = int(kw.get("iDisplayLength", 0))
        start = int(kw.get("iDisplayStart", 0))
        sort_dir = kw.get("sSortDir_0", "asc")
        echo = int(kw.get("sEcho", 0))
        search = kw.get("sSearch", "").replace("%", "").strip().lower()

        end = start + length
        query = Group.query.options(sa.orm.noload("*"))
        total_count = query.count()

        if search:
            # TODO: gérer les accents
            query = query.filter(func.lower(Group.name).like("%" + search + "%"))

        count = query.count()
        columns = [func.lower(Group.name)]
        direction = asc if sort_dir == "asc" else desc
        order_by = list(map(direction, columns))

        # sqlite does not support 'NULLS FIRST|LAST' in ORDER BY clauses
        engine = query.session.get_bind(Group.__mapper__)
        if engine.name != "sqlite":
            order_by[0] = nullslast(order_by[0])

        query = query.order_by(*order_by).add_columns(Group.members_count)
        groups = query.slice(start, end).all()
        data = []

        for group, members_count in groups:
            # TODO: this should be done on the browser.
            group_url = url_for(".groups_group", group_id=group.id)
            name = html.escape(group.name or "")
            roles = [r for r in security.get_roles(group) if r.assignable]

            columns = [
                f'<a href="{group_url}">{name}</a>',
                str(members_count or 0),
                render_template_string(
                    """{%- for role in roles %}
                        <span class="badge badge-default">{{ role }}</span>
                        {%- endfor %}""",
                    roles=roles,
                ),
                "\u2713" if group.public else "",
            ]

            data.append(columns)

        return {
            "sEcho": echo,
            "iTotalRecords": total_count,
            "iTotalDisplayRecords": count,
            "aaData": data,
        }
예제 #37
0
 def get(self):
     svc = get_service("vocabularies")
     vocabularies = svc.grouped_vocabularies
     ctx = {
         "service": svc,
         "url_for_voc_edit": self.voc_edit_url,
         "icon_checked": Glyphicon("check"),
         "vocabularies": vocabularies,
     }
     return render_template("admin/vocabularies.html", **ctx)
예제 #38
0
    def with_permission(self, permission, user=None):
        from abilian.services import get_service

        security = get_service("security")
        if hasattr(self, "_query_entity_zero"):
            # SQLAlchemy 1.1+
            model = self._query_entity_zero().entity_zero.entity
        else:
            # SQLAlchemy 1.0
            model = self._entity_zero().entity_zero.entity
        expr = security.query_entity_with_permission(permission, user, Model=model)
        return self.filter(expr)
예제 #39
0
 def template_kwargs(self):
     security = get_service("security")
     kw = super().template_kwargs
     members = list(self.obj.members)
     members.sort(key=lambda u: (u.last_name, u.first_name))
     kw["members"] = members
     kw["roles"] = sorted(
         r for r in security.get_roles(self.obj, no_group_roles=True)
         if r.assignable)
     kw["ADD_USER_BUTTON"] = ADD_USER_BUTTON
     kw["REMOVE_USER_BUTTON"] = REMOVE_USER_BUTTON
     return kw
예제 #40
0
 def template_kwargs(self):
     security = get_service("security")
     kw = super().template_kwargs
     members = list(self.obj.members)
     members.sort(key=lambda u: (u.last_name, u.first_name))
     kw["members"] = members
     kw["roles"] = sorted(
         r for r in security.get_roles(self.obj, no_group_roles=True) if r.assignable
     )
     kw["ADD_USER_BUTTON"] = ADD_USER_BUTTON
     kw["REMOVE_USER_BUTTON"] = REMOVE_USER_BUTTON
     return kw
예제 #41
0
    def model_view(self, Model, group=None):
        svc = get_service('vocabularies')

        ctx = {
            'service': svc,
            'url_for_voc_edit': self.voc_edit_url,
            'icon_checked': Glyphicon('check'),
            'vocabularies': {
                Model.Meta.group: [Model],
            },
            'edit_return_to': 'model',
        }
        return render_template('admin/vocabularies.html', **ctx)
예제 #42
0
    def after_populate_obj(self):
        security = get_service('security')
        current_roles = security.get_roles(self.obj, no_group_roles=True)
        current_roles = {r for r in current_roles if r.assignable}
        new_roles = {Role(r) for r in self.form.roles.data}

        for r in (current_roles - new_roles):
            security.ungrant_role(self.obj, r)

        for r in (new_roles - current_roles):
            security.grant_role(self.obj, r)

        return super(GroupEdit, self).after_populate_obj()
예제 #43
0
 def template_kwargs(self):
     security = get_service('security')
     kw = super(GroupView, self).template_kwargs
     members = list(self.obj.members)
     members.sort(key=lambda u: (u.last_name, u.first_name))
     kw['members'] = members
     kw['roles'] = sorted(
         r for r in security.get_roles(self.obj, no_group_roles=True)
         if r.assignable
     )
     kw['ADD_USER_BUTTON'] = ADD_USER_BUTTON
     kw['REMOVE_USER_BUTTON'] = REMOVE_USER_BUTTON
     return kw
예제 #44
0
    def after_populate_obj(self):
        security = get_service("security")
        current_roles = security.get_roles(self.obj, no_group_roles=True)
        current_roles = {r for r in current_roles if r.assignable}
        new_roles = {Role(r) for r in self.form.roles.data}

        for r in current_roles - new_roles:
            security.ungrant_role(self.obj, r)

        for r in new_roles - current_roles:
            security.grant_role(self.obj, r)

        return super().after_populate_obj()
예제 #45
0
    def model_view(self, Model, group=None):
        svc = get_service("vocabularies")

        ctx = {
            "service": svc,
            "url_for_voc_edit": self.voc_edit_url,
            "icon_checked": Glyphicon("check"),
            "vocabularies": {
                Model.Meta.group: [Model]
            },
            "edit_return_to": "model",
        }
        return render_template("admin/vocabularies.html", **ctx)
예제 #46
0
def _setup_default_permissions(instance):
    """Separate method to conveniently call it from scripts for example."""
    from abilian.services import get_service

    security = get_service("security")
    for permission, roles in instance.__default_permissions__:
        if permission == "create":
            # use str for comparison instead of `abilian.services.security.CREATE`
            # symbol to avoid imports that quickly become circular.
            #
            # FIXME: put roles and permissions in a separate, isolated module.
            continue
        for role in roles:
            security.add_permission(permission, role, obj=instance)
예제 #47
0
    def with_permission(self, permission, user=None):
        from abilian.services import get_service

        security = get_service("security")
        if hasattr(self, "_query_entity_zero"):
            # SQLAlchemy 1.1+
            model = self._query_entity_zero().entity_zero.entity
        else:
            # SQLAlchemy 1.0
            model = self._entity_zero().entity_zero.entity
        expr = security.query_entity_with_permission(permission,
                                                     user,
                                                     Model=model)
        return self.filter(expr)
예제 #48
0
def _setup_default_permissions(instance):
    """Separate method to conveniently call it from scripts for example."""
    from abilian.services import get_service

    security = get_service("security")
    for permission, roles in instance.__default_permissions__:
        if permission == "create":
            # use str for comparison instead of `abilian.services.security.CREATE`
            # symbol to avoid imports that quickly become circular.
            #
            # FIXME: put roles and permissions in a separate, isolated module.
            continue
        for role in roles:
            security.add_permission(permission, role, obj=instance)
예제 #49
0
    def can_create(self):
        create_cls = self.module.create_cls
        permission = create_cls.permission
        cls_permissions = dict(self.Model.__default_permissions__)

        if self.permission in cls_permissions:
            security = get_service("security")
            return security.has_permission(
                current_user,
                create_cls.permission,
                obj=self.obj,
                roles=cls_permissions[permission],
            )
        return False
예제 #50
0
    def __init__(self, clear, progressive, batch_size):
        # type: (bool, bool, int) -> None
        self.clear = clear
        self.progressive = progressive
        self.batch_size = int(batch_size or 0)

        self.index_service = get_service("indexing")
        self.index = self.index_service.app_state.indexes["default"]
        self.adapted = self.index_service.adapted
        self.session = Session(bind=db.session.get_bind(None, None), autocommit=True)
        self.indexed = set()  # type: Set[str]
        self.cleared = set()  # type: Set[str]

        strategy = progressive_mode if self.progressive else single_transaction
        self.strategy = strategy(self.index, clear=self.clear)
예제 #51
0
def send_daily_social_digest():
    for user in User.query.filter(User.can_login == True).all():
        preferences = get_service("preferences")
        prefs = preferences.get_preferences(user)

        if not prefs.get("sbe:notifications:daily", False):
            continue

        # Defensive programming.
        if not validate_email(user.email):
            continue

        try:
            send_daily_social_digest_to(user)
        except BaseException:
            current_app.logger.error("Error sending daily social digest", exc_info=True)
예제 #52
0
def createuser(email, password, role=None, name=None, first_name=None):
  """
  Adds an admin user with given email and password.
  """
  user = User(email=email, password=password,
              last_name=name, first_name=first_name,
              can_login=True)
  db.session.add(user)

  if role in ('admin',):
    # FIXME: add other valid roles
    security = get_service('security')
    security.grant_role(user, role)

  db.session.commit()
  print "User {} added".format(email)
예제 #53
0
    def do_access_control(self):
        """`before_request` handler to check if user should be redirected to
        login page."""
        from abilian.services import get_service

        if current_app.testing and current_app.config.get("NO_LOGIN"):
            # Special case for tests
            user = User.query.get(0)
            login_user(user, force=True)
            return

        state = self.app_state
        user = unwrap(current_user)

        # Another special case for tests
        if current_app.testing and getattr(user, "is_admin", False):
            return

        security = get_service("security")
        user_roles = frozenset(security.get_roles(user))
        endpoint = request.endpoint
        blueprint = request.blueprint

        access_controllers = []
        access_controllers.extend(state.bp_access_controllers.get(None, []))

        if blueprint and blueprint in state.bp_access_controllers:
            access_controllers.extend(state.bp_access_controllers[blueprint])

        if endpoint and endpoint in state.endpoint_access_controllers:
            access_controllers.extend(state.endpoint_access_controllers[endpoint])

        for access_controller in reversed(access_controllers):
            verdict = access_controller(user=user, roles=user_roles)
            if verdict is None:
                continue
            elif verdict is True:
                return
            else:
                if user.is_anonymous:
                    return self.redirect_to_login()
                raise Forbidden()

        # default policy
        if current_app.config.get("PRIVATE_SITE") and user.is_anonymous:
            return self.redirect_to_login()
예제 #54
0
def has_access(community=None, user=None):
    if not user:
        user = current_user
    if user.is_anonymous:
        return False

    security = get_service("security")
    is_admin = security.has_role(user, "admin")
    if is_admin:
        return True

    if not community:
        community = getattr(g, "community", None)

    if community is not None:
        return community.get_role(user) is not None

    return False
예제 #55
0
def reindex_tree(obj):
    """Schedule reindexing `obj` and all of its descendants.

    Generally needed to update indexed security.
    """
    assert isinstance(obj, CmisObject)

    index_service = get_service("indexing")
    if not index_service.running:
        return

    descendants = (
        sa.select([CmisObject.id, CmisObject._parent_id])
        .where(CmisObject._parent_id == sa.bindparam("ancestor_id"))
        .cte(name="descendants", recursive=True)
    )
    da = descendants.alias()
    CA = sa.orm.aliased(CmisObject)
    d_ids = sa.select([CA.id, CA._parent_id])
    descendants = descendants.union_all(d_ids.where(CA._parent_id == da.c.id))
    session = sa.orm.object_session(obj) or db.session()

    # including ancestor_id in entity_ids_q will garantee at least 1 value for the
    # "IN" predicate; otherwise when using sqlite (as during tests...)
    # 'ResourceClosedError' will be raised.
    #
    # as an added bonus, "obj" will also be in query results, thus will be added
    # in "to_update" without needing to do it apart.
    entity_ids_q = sa.union(
        sa.select([descendants.c.id]), sa.select([sa.bindparam("ancestor_id")])
    )
    query = (
        session.query(Entity)
        .filter(Entity.id.in_(entity_ids_q))
        .options(sa.orm.noload("*"))
        .params(ancestor_id=obj.id)
    )

    to_update = index_service.app_state.to_update
    key = "changed"

    for item in query.yield_per(1000):
        to_update.append((key, item))
예제 #56
0
def is_manager(context=None, user=None):
    security = get_service("security")

    if not user:
        user = current_user
    if user.is_anonymous:
        return False

    if context:
        community = context.get("object").community
    else:
        community = g.community

    if community.has_permission(user, MANAGE) or user == community.creator:
        return True

    if security.has_role(user, "admin"):
        return True

    return False
예제 #57
0
    def content(self):
        obj = self.current_obj
        security = get_service("security")
        context = self.context.copy()

        context["permissions"] = security.get_permissions_assignments(obj=obj)
        context["roles"] = roles = {}

        for principal, r in security.get_role_assignements(obj=obj):
            if r not in roles:
                roles[r] = {"anonymous": False, "users": set(), "groups": set()}

            info = roles[r]
            if principal is Anonymous:
                info["anonymous"] = True
            elif isinstance(principal, Group):
                info["groups"].add(principal)
            else:
                info["users"].add(principal)

        for r in roles:
            info = roles[r]
            info["groups"] = [
                "{g} (id={g.id})".format(g=g)
                for g in sorted(info["groups"], key=lambda g: g.name)
            ]
            users = sorted(
                info["users"], key=lambda u: (u.last_name.lower(), u.first_name.lower())
            )
            info["users"] = [
                '{u} (id={u.id}, email="{u.email}")'.format(u=u) for u in users
            ]

        jinja_env = current_app.jinja_env
        jinja_env.filters.update(self.jinja_env.filters)
        template = jinja_env.get_or_select_template(
            "debug_panels/security_info_panel.html"
        )

        return template.render(context)
예제 #58
0
    def _indexable_roles_and_users(self):
        """Return a string made for indexing roles having :any:`READ`
        permission on this object."""
        from abilian.services.indexing import indexable_role
        from abilian.services.security import READ, Admin, Anonymous, Creator, Owner
        from abilian.services import get_service

        result = []
        security = get_service("security")

        # roles - required to match when user has a global role
        assignments = security.get_permissions_assignments(permission=READ, obj=self)
        allowed_roles = assignments.get(READ, set())
        allowed_roles.add(Admin)

        for r in allowed_roles:
            result.append(indexable_role(r))

        for role, attr in ((Creator, "creator"), (Owner, "owner")):
            if role in allowed_roles:
                user = getattr(self, attr)
                if user:
                    result.append(indexable_role(user))

        # users and groups
        principals = set()
        for user, role in security.get_role_assignements(self):
            if role in allowed_roles:
                principals.add(user)

        if Anonymous in principals:
            # it's a role listed in role assignments - legacy when there wasn't
            # permission-role assignments
            principals.remove(Anonymous)

        for p in principals:
            result.append(indexable_role(p))

        return " ".join(result)
예제 #59
0
파일: base.py 프로젝트: debon/abilian-core
def createuser(email, password, role=None, name=None, first_name=None):
  """
  Create new user.
  """
  email = unicode(email)
  if User.query.filter(User.email == email).count() > 0:
    print("A user with email '{}' already exists, aborting.".format(email))
    return

  if password is None:
    password = prompt_pass(u'Password')

  user = User(email=email, password=password,
              last_name=name, first_name=first_name,
              can_login=True)
  db.session.add(user)

  if role in ('admin',):
    # FIXME: add other valid roles
    security = get_service('security')
    security.grant_role(user, role)

  db.session.commit()
  print("User {} added".format(email))
예제 #60
0
def is_admin(context):
    security = get_service("security")
    return security.has_role(current_user, Admin, object=context.get("object"))