예제 #1
0
    def getProductConfiguration(self, product_id):
        """
        Get the product configuration --- WITHOUT THE DB PASSWORD --- of the
        given product.
        """

        with DBSession(self.__session) as session:
            product = session.query(Product).get(product_id)
            if product is None:
                msg = "Product with ID {0} does not exist!".format(product_id)
                LOG.error(msg)

                raise codechecker_api_shared.ttypes.RequestFailed(
                    codechecker_api_shared.ttypes.ErrorCode.DATABASE, msg)

            # Put together the database connection's descriptor.
            args = SQLServer.connection_string_to_args(product.connection)
            if args['postgresql']:
                db_engine = 'postgresql'
                db_host = args['dbaddress']
                db_port = args['dbport']
                db_user = args['dbusername']
                db_name = args['dbname']
            else:
                db_engine = 'sqlite'
                db_host = ""
                db_port = 0
                db_user = ""
                db_name = args['sqlite']

            dbc = ttypes.DatabaseConnection(
                engine=db_engine,
                host=db_host,
                port=db_port,
                username_b64=convert.to_b64(db_user),
                # DO NOT TRANSPORT PASSWORD BACK TO THE USER!
                database=db_name)

            # Put together the product configuration.
            descr = convert.to_b64(product.description) \
                if product.description else None

            is_review_status_change_disabled = \
                product.is_review_status_change_disabled

            prod = ttypes.ProductConfiguration(
                id=product.id,
                endpoint=product.endpoint,
                displayedName_b64=convert.to_b64(product.display_name),
                description_b64=descr,
                connection=dbc,
                runLimit=product.run_limit,
                isReviewStatusChangeDisabled=is_review_status_change_disabled)

            return prod
예제 #2
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 '%s' was found in the configuration "
                "database but no database connection was "
                "present. Mounting analysis run database...", product.endpoint)
            self.__server.add_product(product)
            server_product = self.__server.get_product(product.endpoint)

        descr = convert.to_b64(product.description) \
            if product.description else None

        args = {'config_db_session': session, 'productID': product.id}
        product_access = permissions.require_permission(
            permissions.PRODUCT_VIEW, 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()

        connected = server_product.db_status ==\
            codechecker_api_shared.ttypes.DBStatus.OK

        latest_storage_date = str(product.latest_storage_date) \
            if product.latest_storage_date else None

        if product.confidentiality is None:
            confidentiality = ttypes.Confidentiality.CONFIDENTIAL
        else:
            confidentiality = \
                    confidentiality_enum(product.confidentiality)

        return server_product, ttypes.Product(
            id=product.id,
            endpoint=product.endpoint,
            displayedName_b64=convert.to_b64(product.display_name),
            description_b64=descr,
            runCount=product.num_of_runs,
            latestStoreToProduct=latest_storage_date,
            connected=connected,
            accessible=product_access,
            administrating=self.__administrating(args),
            databaseStatus=server_product.db_status,
            admins=[admin.name for admin in admins],
            confidentiality=confidentiality)
예제 #3
0
def handle_add_product(args):

    init_logger(args.verbose if 'verbose' in args else None)

    protocol, host, port = split_server_url(args.server_url)
    client = setup_product_client(protocol, host, port)

    # Put together the database connection's descriptor.
    if 'postgresql' in args:
        db_engine = 'postgresql'
        db_host = args.dbaddress
        db_port = args.dbport
        db_user = args.dbusername
        db_pass = args.dbpassword
        db_name = args.dbname
    else:
        db_engine = 'sqlite'
        db_host = ""
        db_port = 0
        db_user = ""
        db_pass = ""
        db_name = args.sqlite

    dbc = DatabaseConnection(
        engine=db_engine,
        host=db_host,
        port=db_port,
        username_b64=convert.to_b64(db_user),
        password_b64=convert.to_b64(db_pass),
        database=db_name)

    # Put together the product configuration.
    name = convert.to_b64(args.display_name) \
        if 'display_name' in args else None
    desc = convert.to_b64(args.description) \
        if 'description' in args else None

    prod = ProductConfiguration(
        endpoint=args.endpoint,
        displayedName_b64=name,
        description_b64=desc,
        connection=dbc)

    LOG.debug("Sending request to add product...")
    success = client.addProduct(prod)
    if success:
        LOG.info("Product added successfully.")
    else:
        LOG.error("Adding the product has failed.")
        sys.exit(1)
    def test_auth_su_notification_edit(self):
        """
        Test that SUPERADMINS can edit the notification text.
        """
        # Create a SUPERUSER login.
        self.sessionToken = self.auth_client.performLogin(
            "Username:Password", "root:root")

        ret = self.auth_client.addPermission(Permission.SUPERUSER, "root",
                                             False, "")
        self.assertTrue(ret)
        # we got the permission

        su_auth_client = \
            env.setup_auth_client(self._test_workspace,
                                  session_token=self.sessionToken)

        su_config_client = \
            env.setup_config_client(self._test_workspace,
                                    session_token=self.sessionToken)

        user = su_auth_client.getLoggedInUser()
        self.assertEqual(user, "root")
        # we are root

        su_config_client.setNotificationBannerText(
            convert.to_b64('su notification'))
        self.assertEqual(
            convert.from_b64(su_config_client.getNotificationBannerText()),
            'su notification')
예제 #5
0
 def create_test_product(product_name, product_endpoint):
     # Create a new product on the secondary server.
     name = convert.to_b64(product_name)
     return ProductConfiguration(endpoint=product_endpoint,
                                 displayedName_b64=name,
                                 description_b64=name,
                                 connection=DatabaseConnection(
                                     engine='sqlite',
                                     host='',
                                     port=0,
                                     username_b64='',
                                     password_b64='',
                                     database=os.path.join(
                                         self.test_workspace_secondary,
                                         'data.sqlite')))
    def test_noauth_notification_edit(self):
        """
        Test for editing the notification text on a non authenting server.
        """

        # A non-authenticated session should return an empty user.
        user = self.auth_client.getLoggedInUser()
        self.assertEqual(user, "")

        # Server without authentication should allow notification setting.
        self.config_client.setNotificationBannerText(
            convert.to_b64('noAuth notif'))
        self.assertEqual(
            convert.from_b64(self.config_client.getNotificationBannerText()),
            'noAuth notif')
예제 #7
0
    def getNotificationBannerText(self):
        """
        Retrieves the notification banner text.
        """

        notificationString = ''
        with DBSession(self.__session) as session:
            notificationQuery = session.query(Configuration) \
                .filter(
                    Configuration.config_key == 'notification_banner_text') \
                .one_or_none()

            if notificationQuery is not None:
                notificationString = notificationQuery.config_value

        return convert.to_b64(notificationString)
    def test_unicode_string(self):
        """
        Test for non ascii strings. Needed because the used Thrift
        version won't eat them.
        """

        # A non-authenticated session should return an empty user.
        user = self.auth_client.getLoggedInUser()
        self.assertEqual(user, "")

        # Check if utf-8 encoded strings are okay.
        self.config_client.setNotificationBannerText(
            convert.to_b64('árvíztűrő tükörfúrógép'))
        self.assertEqual(
            convert.from_b64(self.config_client.getNotificationBannerText()),
            'árvíztűrő tükörfúrógép')
    def test_auth_non_su_notification_edit(self):
        """
        Test that non SUPERADMINS can't edit the notification text.
        """
        self.sessionToken = self.auth_client.performLogin(
            "Username:Password", "cc:test")

        authd_auth_client = \
            env.setup_auth_client(self._test_workspace,
                                  session_token=self.sessionToken)

        authd_config_client = \
            env.setup_config_client(self._test_workspace,
                                    session_token=self.sessionToken)

        user = authd_auth_client.getLoggedInUser()
        self.assertEqual(user, "cc")

        with self.assertRaises(RequestFailed):
            authd_config_client.setNotificationBannerText(
                convert.to_b64('non su notification'))

            print("You are not authorized to modify notifications!")
예제 #10
0
    def test_editing(self):
        """
        Test editing the product details (without reconnecting it).
        """

        pr_client = env.setup_product_client(self.test_workspace,
                                             product=self.product_name)
        product_id = pr_client.getCurrentProduct().id
        config = self._pr_client.getProductConfiguration(product_id)

        old_name = config.displayedName_b64

        new_name = convert.to_b64("edited product name")
        config.displayedName_b64 = new_name
        with self.assertRaises(RequestFailed):
            self._pr_client.editProduct(product_id, config)
            print("Product was edited through non-superuser!")

        self.assertTrue(self._root_client.editProduct(product_id, config),
                        "Product edit didn't conclude.")

        config = self._pr_client.getProductConfiguration(product_id)
        self.assertEqual(
            config.endpoint, self.product_name,
            "The product edit changed the endpoint, when it "
            "shouldn't have!")
        self.assertEqual(config.displayedName_b64, new_name,
                         "The product edit didn't change the name.")

        # Restore the configuration of the product.
        config.displayedName_b64 = old_name
        self.assertTrue(self._root_client.editProduct(product_id, config),
                        "Product config restore didn't conclude.")

        config = self._pr_client.getProductConfiguration(product_id)
        self.assertEqual(config.displayedName_b64, old_name,
                         "The product edit didn't change the name back.")
예제 #11
0
    def test_add_invalid_product(self):
        """
        Test the server prohibiting the addition of bogus product configs.
        """
        error = convert.to_b64("bogus")
        product_cfg = ProductConfiguration(displayedName_b64=error,
                                           description_b64=error)

        # Test setting up product with valid endpoint but no database
        # connection.
        with self.assertRaises(RequestFailed):
            cfg = deepcopy(product_cfg)
            cfg.endpoint = "valid"
            self._root_client.addProduct(cfg)

        # Test some invalid strings based on pattern.
        dbc = DatabaseConnection(engine='sqlite',
                                 host='',
                                 port=0,
                                 username_b64='',
                                 password_b64='',
                                 database="valid.sqlite")
        product_cfg.connection = dbc

        with self.assertRaises(RequestFailed):
            product_cfg.endpoint = "$$$$$$$"
            self._root_client.addProduct(product_cfg)

        # Test some forbidden URI parts.
        with self.assertRaises(RequestFailed):
            product_cfg.endpoint = "index.html"
            self._root_client.addProduct(product_cfg)

        with self.assertRaises(RequestFailed):
            product_cfg.endpoint = "CodeCheckerService"
            self._root_client.addProduct(product_cfg)
예제 #12
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 '%s' was found in the configuration "
                "database but no database connection was "
                "present. Mounting analysis run database...", product.endpoint)
            self.__server.add_product(product)
            server_product = self.__server.get_product(product.endpoint)

        num_of_runs = 0
        runs_in_progress = set()
        latest_store_to_product = ""

        # Try to get product details. It may throw different error messages
        # depending on the used SQL driver adapter in case of connection error,
        # so we should try to connect to the database and get the results
        # again on failure.
        try:
            num_of_runs, runs_in_progress, latest_store_to_product = \
                server_product.get_details()
        except Exception:
            # Try to connect to the product and try to get details again.
            server_product.connect()

            if server_product.db_status ==\
                    codechecker_api_shared.ttypes.DBStatus.OK:
                num_of_runs, runs_in_progress, latest_store_to_product = \
                    server_product.get_details()

        descr = convert.to_b64(product.description) \
            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()

        connected = server_product.db_status ==\
            codechecker_api_shared.ttypes.DBStatus.OK

        return server_product, ttypes.Product(
            id=product.id,
            endpoint=product.endpoint,
            displayedName_b64=convert.to_b64(product.display_name),
            description_b64=descr,
            runCount=num_of_runs,
            latestStoreToProduct=str(latest_store_to_product),
            connected=connected,
            accessible=product_access,
            administrating=product_admin,
            databaseStatus=server_product.db_status,
            admins=[admin.name for admin in admins],
            runStoreInProgress=runs_in_progress)