Example #1
0
    def __get_product(self, session, product):
        """
        Retrieve the product connection object and create a Thrift Product
        object for the given product record in the database.
        """

        server_product = self.__server.get_product(product.endpoint)
        if not server_product:
            LOG.info("Product '{0}' was found in the configuration "
                     "database but no database connection was "
                     "present. Mounting analysis run database...".format(
                         product.endpoint))
            self.__server.add_product(product)
            server_product = self.__server.get_product(product.endpoint)

        name = base64.b64encode(product.display_name.encode('utf-8'))
        descr = base64.b64encode(product.description.encode('utf-8')) \
            if product.description else None

        args = {'config_db_session': session, 'productID': product.id}
        product_access = permissions.require_permission(
            permissions.PRODUCT_ACCESS, args, self.__auth_session)
        product_admin = permissions.require_permission(
            permissions.PRODUCT_ADMIN, args, self.__auth_session)

        return server_product, ttypes.Product(
            id=product.id,
            endpoint=product.endpoint,
            displayedName_b64=name,
            description_b64=descr,
            connected=server_product.db_status == shared.ttypes.DBStatus.OK,
            accessible=product_access,
            administrating=product_admin,
            databaseStatus=server_product.db_status)
Example #2
0
    def getCurrentProduct(self):
        """
        Return information about the current product.

        The request MUST be routed as /product-name/ProductService!
        """

        if not self.__product:
            msg = "Requested current product from ProductService but the " \
                  "request came through the main endpoint."
            LOG.error(msg)
            raise shared.ttypes.RequestFailed(shared.ttypes.ErrorCode.IOERROR,
                                              msg)

        try:
            session = self.__session()
            prod = session.query(Product).get(self.__product.id)

            server_product = self.__server.get_product(prod.endpoint)
            if not server_product:
                # TODO: Like above, better support this.
                LOG.error("Product '{0}' was found in the configuration "
                          "database, but no database connection is "
                          "present. Was the configuration database "
                          "connected to multiple servers?"
                          .format(prod.endpoint))
                LOG.info("Please restart the server to make this "
                         "product available.")
                raise shared.ttypes.RequestFailed(
                    shared.ttypes.ErrorCode.DATABASE,
                    "Product exists, but was not connected to this server.")

            name = base64.b64encode(prod.display_name.encode('utf-8'))
            descr = base64.b64encode(prod.description.encode('utf-8')) \
                if prod.description else None

            args = {'config_db_session': session,
                    'productID': prod.id}
            product_access = permissions.require_permission(
                permissions.PRODUCT_ACCESS, args, self.__auth_session)
            product_admin = permissions.require_permission(
                permissions.PRODUCT_ADMIN, args, self.__auth_session)

            return ttypes.Product(
                id=prod.id,
                endpoint=prod.endpoint,
                displayedName_b64=name,
                description_b64=descr,
                connected=server_product.connected,
                accessible=product_access,
                administrating=product_admin)

        except sqlalchemy.exc.SQLAlchemyError as alchemy_ex:
            msg = str(alchemy_ex)
            LOG.error(msg)
            raise shared.ttypes.RequestFailed(shared.ttypes.ErrorCode.DATABASE,
                                              msg)
        finally:
            session.close()
Example #3
0
    def __get_product(self, session, product):
        """
        Retrieve the product connection object and create a Thrift Product
        object for the given product record in the database.
        """

        server_product = self.__server.get_product(product.endpoint)
        if not server_product:
            LOG.info("Product '{0}' was found in the configuration "
                     "database but no database connection was "
                     "present. Mounting analysis run database..."
                     .format(product.endpoint))
            self.__server.add_product(product)
            server_product = self.__server.get_product(product.endpoint)

        server_product.connect()
        num_of_runs = 0
        latest_store_to_product = ""
        if server_product.db_status == shared.ttypes.DBStatus.OK:
            run_db_session = server_product.session_factory()
            num_of_runs = run_db_session.query(Run).count()
            if num_of_runs:
                last_updated_run = run_db_session.query(Run) \
                    .order_by(Run.date.desc()) \
                    .limit(1) \
                    .one_or_none()

                latest_store_to_product = last_updated_run.date

        name = base64.b64encode(product.display_name.encode('utf-8'))
        descr = base64.b64encode(product.description.encode('utf-8')) \
            if product.description else None

        args = {'config_db_session': session,
                'productID': product.id}
        product_access = permissions.require_permission(
            permissions.PRODUCT_ACCESS, args, self.__auth_session)
        product_admin = permissions.require_permission(
            permissions.PRODUCT_ADMIN, args, self.__auth_session)

        admin_perm_name = permissions.PRODUCT_ADMIN.name
        admins = session.query(ProductPermission). \
            filter(and_(ProductPermission.permission == admin_perm_name,
                        ProductPermission.product_id == product.id)) \
            .all()

        return server_product, ttypes.Product(
            id=product.id,
            endpoint=product.endpoint,
            displayedName_b64=name,
            description_b64=descr,
            runCount=num_of_runs,
            latestStoreToProduct=str(latest_store_to_product),
            connected=server_product.db_status == shared.ttypes.DBStatus.OK,
            accessible=product_access,
            administrating=product_admin,
            databaseStatus=server_product.db_status,
            admins=[admin.name for admin in admins])
Example #4
0
    def __require_permission(self, required, args=None):
        """
        Helper method to raise an UNAUTHORIZED exception if the user does not
        have any of the given permissions.
        """

        try:
            if args is None:
                args = dict(self.__permission_args)
                session = self.__session()
                args['config_db_session'] = session

            if not any([
                    permissions.require_permission(
                        perm, args, self.__auth_session) for perm in required
            ]):
                raise shared.ttypes.RequestFailed(
                    shared.ttypes.ErrorCode.UNAUTHORIZED,
                    "You are not authorized to execute this action.")

            return True

        except sqlalchemy.exc.SQLAlchemyError as alchemy_ex:
            msg = str(alchemy_ex)
            LOG.error(msg)
            raise shared.ttypes.RequestFailed(shared.ttypes.ErrorCode.DATABASE,
                                              msg)
        finally:
            if session:
                session.close()
Example #5
0
    def hasPermission(self, permission, extra_params):
        """
        Returns whether or not the current logged-in user (or guest, if
        authentication is disabled) is granted the given permission.

        This method observes permission inheritance.
        """

        with DBSession(self.__config_db) as session:
            perm, params = ThriftAuthHandler.__create_permission_args(
                permission, extra_params, session)

            return require_permission(perm, params, self.__auth_session)
Example #6
0
    def isAdministratorOfAnyProduct(self):
        try:
            session = self.__session()
            prods = session.query(Product).all()

            for prod in prods:
                args = {'config_db_session': session, 'productID': prod.id}
                if permissions.require_permission(permissions.PRODUCT_ADMIN,
                                                  args, self.__auth_session):
                    return True

            return False

        except sqlalchemy.exc.SQLAlchemyError as alchemy_ex:
            msg = str(alchemy_ex)
            LOG.error(msg)
            raise shared.ttypes.RequestFailed(shared.ttypes.ErrorCode.DATABASE,
                                              msg)
        finally:
            session.close()
Example #7
0
    def hasPermission(self, permission, extra_params):
        """
        Returns whether or not the current logged-in user (or guest, if
        authentication is disabled) is granted the given permission.

        This method observes permission inheritance.
        """

        try:
            session = self.__config_db()
            perm, params = ThriftAuthHandler.__create_permission_args(
                permission, extra_params, session)

            return require_permission(perm, params, self.__auth_session)

        except sqlalchemy.exc.SQLAlchemyError as alchemy_ex:
            msg = str(alchemy_ex)
            LOG.error(msg)
            raise shared.ttypes.RequestFailed(shared.ttypes.ErrorCode.DATABASE,
                                              msg)
        finally:
            session.close()
Example #8
0
    def getProducts(self, product_endpoint_filter, product_name_filter):
        """
        Get the list of products configured on the server.
        """

        result = []

        try:
            session = self.__session()
            prods = session.query(Product)

            if product_endpoint_filter:
                prods = prods.filter(Product.endpoint.ilike('%{0}%'.format(
                    util.escape_like(product_endpoint_filter)), escape='*'))

            if product_name_filter:
                prods = prods.filter(Product.display_name.ilike('%{0}%'.format(
                    util.escape_like(product_name_filter)), escape='*'))

            prods = prods.all()

            for prod in prods:
                server_product = self.__server.get_product(prod.endpoint)

                if not server_product:
                    # TODO: Better support this, if the configuration database
                    # is mounted to multiple servers?
                    LOG.error("Product '{0}' was found in the configuration "
                              "database, but no database connection is "
                              "present. Was the configuration database "
                              "connected to multiple servers?"
                              .format(prod.endpoint))
                    LOG.info("Please restart the server to make this "
                             "product available.")
                    continue

                # Clients are expected to use this method to query if
                # the product exists and usable. Usability sometimes requires
                # "updating" the "is connected" status of the database.
                if not server_product.connected:
                    server_product.connect()

                name = base64.b64encode(prod.display_name.encode('utf-8'))
                descr = base64.b64encode(prod.description.encode('utf-8')) \
                    if prod.description else None

                args = {'config_db_session': session,
                        'productID': prod.id}
                product_access = permissions.require_permission(
                    permissions.PRODUCT_ACCESS, args, self.__auth_session)
                product_admin = permissions.require_permission(
                    permissions.PRODUCT_ADMIN, args, self.__auth_session)

                result.append(ttypes.Product(
                    id=prod.id,
                    endpoint=prod.endpoint,
                    displayedName_b64=name,
                    description_b64=descr,
                    connected=server_product.connected,
                    accessible=product_access,
                    administrating=product_admin))

            return result

        except sqlalchemy.exc.SQLAlchemyError as alchemy_ex:
            msg = str(alchemy_ex)
            LOG.error(msg)
            raise shared.ttypes.RequestFailed(shared.ttypes.ErrorCode.DATABASE,
                                              msg)
        finally:
            session.close()