Esempio n. 1
0
def before_compile(query):
    """A query compilation rule that will add limiting criteria for every
    subclass of OrgBase"""

    show_all = getattr(g, "show_all", False) or query._execution_options.get("show_all", False)
    if show_all:
        return query

    for ent in query.column_descriptions:
        entity = ent['entity']
        if entity is None:
            continue
        insp = inspect(ent['entity'])
        mapper = getattr(insp, 'mapper', None)

        # if the subclass OrgBase exists, then filter by organisations - else, return default query
        if mapper:
            if issubclass(mapper.class_, ManyOrgBase) or issubclass(mapper.class_, OneOrgBase):

                try:
                    # member_organisations = getattr(g, "member_organisations", [])
                    active_organisation = getattr(g, "active_organisation", None)
                    active_organisation_id = getattr(active_organisation, "id", None)
                    member_organisation_ids = [active_organisation_id] if active_organisation_id else []

                    if issubclass(mapper.class_, ManyOrgBase):
                        # filters many-to-many
                        query = query.enable_assertions(False).filter(or_(
                            ent['entity'].organisations.any(
                                server.models.organisation.Organisation.id.in_(member_organisation_ids)),
                            ent['entity'].is_public == True,
                        ))
                    else:
                        query = query.enable_assertions(False).filter(or_(
                            ent['entity'].organisation_id == active_organisation_id,
                            ent['entity'].is_public == True,
                        ))

                except AttributeError:
                    raise

                except TypeError:
                    raise OrganisationNotProvidedException('Must provide organisation ID or specify SHOW_ALL flag')

            elif issubclass(mapper.class_, OneOrgBase):
                # must filter directly on query
                raise OrganisationNotProvidedException('{} has a custom org base. Must filter directly on query'.format(ent['entity']))

    return query
Esempio n. 2
0
def filter_by_org(query):
    """A query compilation rule that will add limiting criteria for every
    subclass of OrgBase"""
    show_deleted = query._execution_options.get("show_deleted", False)
    show_all = getattr(g, "show_all", False) or query._execution_options.get(
        "show_all", False)
    # We want to support multiple active organizations, but only for select GET requets.
    # This is done through a multi_org flag, very similar to the show_all flag
    multi_org = getattr(g, "multi_org", False) or query._execution_options.get(
        "multi_org", False)

    if show_all and show_deleted:
        return query

    for ent in query.column_descriptions:
        entity = ent['entity']
        if entity is None:
            continue
        insp = inspect(ent['entity'])
        mapper = getattr(insp, 'mapper', None)

        if mapper:
            # if subclass SoftDelete exists and not show_deleted, return non-deleted items, else show deleted
            if issubclass(mapper.class_, SoftDelete) and not show_deleted:
                query = query.enable_assertions(False).filter(
                    ent['entity'].deleted == None)

            if show_all and not show_deleted:
                return query

            # if the subclass OrgBase exists, then filter by organisations - else, return default query
            if issubclass(mapper.class_, ManyOrgBase) or issubclass(
                    mapper.class_, OneOrgBase):

                try:
                    # member_organisations = getattr(g, "member_organisations", [])
                    active_organisation = getattr(g, "active_organisation",
                                                  None)
                    active_organisation_id = getattr(active_organisation, "id",
                                                     None)
                    # If we're operating on a query supporting multi_org, AND the application
                    # context has query_organisations set from the HTTP request, use those
                    # organizations. Otherwise, use a singleton of the current active org
                    query_organisations = [active_organisation_id
                                           ] if active_organisation_id else []
                    if getattr(g, 'query_organisations', None):
                        if not multi_org:
                            raise Exception(
                                'Multiple organizations not supported for this operation'
                            )
                        query_organisations = g.query_organisations

                    if issubclass(mapper.class_, ManyOrgBase):
                        # filters many-to-many
                        query = query.enable_assertions(False).filter(
                            or_(
                                ent['entity'].organisations.any(
                                    server.models.organisation.Organisation.id.
                                    in_(query_organisations)),
                                ent['entity'].is_public == True,
                            ))
                    else:
                        query = query.enable_assertions(False).filter(
                            or_(
                                ent['entity'].organisation_id ==
                                active_organisation_id,
                                ent['entity'].is_public == True,
                            ))

                except AttributeError:
                    raise

                except TypeError:
                    raise OrganisationNotProvidedException(
                        'Must provide organisation ID or specify SHOW_ALL flag'
                    )

            elif issubclass(mapper.class_, OneOrgBase):
                # must filter directly on query
                raise OrganisationNotProvidedException(
                    '{} has a custom org base. Must filter directly on query'.
                    format(ent['entity']))

    return query