Beispiel #1
0
    def remove_member(self, team_id, user_id):
        """Remove the given user as member of the given team. Raises error if
        the team is unknown or if the user is the team owner. No error is raised
        if the user is unknown or not a team member.

        Parameters
        ----------
        team_id: string
            Unique team identifier
        user_id: string
            Unique user identifier

        Raises
        ------
        benchengine.error.ConstraintViolationError
        benchengine.error.UnknownTeamError
        """
        # Ensure that the team exists. Raises error if team does not exist.
        # If the user is the team owner the constraint that the owner has to be
        # a team member is violated.
        sql = 'SELECT owner_id FROM team WHERE id = ?'
        team = self.con.execute(sql, (team_id, )).fetchone()
        if team is None:
            raise err.UnknownTeamError(team_id)
        elif team['owner_id'] == user_id:
            raise err.ConstraintViolationError('cannot remove team owner')
        sql = 'DELETE FROM team_member WHERE team_id = ? AND user_id = ?'
        self.con.execute(sql, (team_id, user_id))
        self.con.commit()
Beispiel #2
0
    def insert_results(self, run_id, results):
        """Insert the results of a benchmark run into the results table. Expects
        a dictionary that contains result values for all mandatory results.

        Parameters
        ----------
        run_id: string
            Unique run identifier
        results: dict
                Dictionary containing run result values

        Raises
        ------
        benchengine.error.ConstraintViolationError
        """
        columns = list(['run_id'])
        values = list([run_id])
        for col in self.template.schema.columns:
            if col.identifier in results:
                values.append(results[col.identifier])
            elif col.required:
                raise err.ConstraintViolationError(
                    'missing result for \'{}\''.format(col.identifier))
            else:
                values.append(None)
            columns.append(col.identifier)
        sql = 'INSERT INTO {}({}) VALUES({})'.format(
            self.result_table_name, ','.join(columns),
            ','.join(['?'] * len(columns)))
        self.con.execute(sql, values)
        self.con.commit()
Beispiel #3
0
    def register_user(self, username, password, verify=False):
        """Create a new user for the given username. Raises an error if a user
        with that name already is registered. Returns the internal unique
        identifier for the created user.

        The verify flag allows to create active or inactive users. An inactive
        user cannot login until they have been activated. This option is
        intended for scenarios where the user receives an email after they
        register that contains a verification/activation link to ensure that
        the provided email address is valid.

        Parameters
        ----------
        username: string
            User email address that is used as the username
        password: string
            Password used to authenticate the user
        verify: bool, optional
            Determines whether the created user is active or inactive

        Returns
        -------
        string

        Raises
        ------
        benchengine.error.ConstraintViolationError
        benchengine.error.DuplicateUserError
        """
        # Ensure that the username does not contain more than 255 characters
        # and that the password has at least one (non-space) character
        if len(username) > 255:
            raise err.ConstraintViolationError('username too long')
        self.validate_password(password)
        # If a user with the given username already exists raise an error
        sql = 'SELECT id FROM registered_user WHERE email = ?'
        if not self.con.execute(sql, (username, )).fetchone() is None:
            raise err.DuplicateUserError(username)
        # Insert new user into database after creating an unique user identifier
        # and the password hash.
        user_id = util.get_unique_identifier()
        hash = pbkdf2_sha256.hash(password.strip())
        active = 0 if verify else 1
        sql = 'INSERT INTO registered_user(id, email, secret, active) '
        sql += 'VALUES(?, ?, ?, ?)'
        self.con.execute(sql, (user_id, username, hash, active))
        self.con.commit()
        # Log user in after successful registration and return API key
        return user_id
Beispiel #4
0
    def update_team_name(self, team_id, name):
        """Update the name of the team with the given identifier. Will raise
        errors if the team is unknown or the name is invalid or not unique.

        Parameters
        ----------
        team_id: string
            Unique team identifier
        name: string
            New unique team name

        Returns
        -------
        benchengine.user.team.base.TeamHandle

        Raises
        ------
        benchengine.error.ConstraintViolationError
        benchengine.error.UnknownTeamError
        """
        # Ensure that the team exists. Raises error if team does not exist.
        self.assert_team_exists(team_id)
        # Ensure that no other team has the same name
        sql = 'SELECT * FROM team WHERE id <> ? AND name = ?'
        if len(name.strip()) > 255:
            raise err.ConstraintViolationError(
                'team name contains more than 255 character')
        elif not self.con.execute(sql, (team_id, name)).fetchone() is None:
            raise err.ConstraintViolationError(
                'team name \'{}\' exists'.format(name.strip()))
        # Update the team name
        sql = 'UPDATE team SET name = ? WHERE id = ?'
        self.con.execute(sql, (name, team_id))
        self.con.commit()
        # Return the handle for the team
        return self.get_team(team_id)
Beispiel #5
0
    def validate_password(self, password):
        """Validate a given password. Raises constraint violation error if an
        invalid password is given.

        Currently, the only constraint for passwords is that they are not empty

        Parameters
        ----------
        password: string
            User password for authentication

        Raises
        ------
        benchengine.error.ConstraintViolationError
        """
        # Raise error if password is invalid
        if password is None or len(password.strip()) == 0:
            raise err.ConstraintViolationError('empty password')
Beispiel #6
0
    def add_benchmark(
        self, name, description=None, instructions=None, src_dir=None,
        src_repo_url=None, template_spec_file=None
    ):
        """Add a benchmark to the repository. The associated workflow template
        is created in the template repository from either the given source
        directory or Git repository. The template repository will raise an
        error if neither or both arguments are given.

        Raises an error if the given benchmark name is not unique.

        Parameters
        ----------
        name: string
            Unique benchmark headline name
        description: string, optional
            Optional short description for display in benchmark listings
        instructions: string, optional
            Text containing detailed instructions for benchmark participants
        src_dir: string, optional
            Directory containing the benchmark components, i.e., the fixed
            files and the template specification (optional).
        src_repo_url: string, optional
            Git repository that contains the the benchmark components
        template_spec_file: string, optional
            Path to the workflow template specification file (absolute or
            relative to the workflow directory)

        Returns
        -------
        benchengine.benchmark.base.BenchmarkHandle

        Raises
        ------
        benchengine.error.ConstraintViolationError
        benchtmpl.error.InvalidParameterError
        benchtmpl.error.InvalidTemplateError
        ValueError
        """
        # Ensure that the benchmark name is not empty, not longer than 255
        # character and unique.
        if name is None:
            raise err.ConstraintViolationError('missing benchmark name')
        name = name.strip()
        if name == '' or len(name) > 255:
            raise err.ConstraintViolationError('invalid benchmark name')
        sql = 'SELECT id FROM benchmark WHERE name = ?'
        if not self.con.execute(sql, (name,)).fetchone() is None:
            raise err.ConstraintViolationError('benchmark \'{}\' exists'.format(name))
        # Create the workflow template in the associated template repository
        template = self.template_store.add_template(
            src_dir=src_dir,
            src_repo_url=src_repo_url,
            template_spec_file=template_spec_file
        )
        # Insert benchmark into database and return descriptor
        sql = 'INSERT INTO benchmark'
        sql += '(id, name, description, instructions) '
        sql += 'VALUES(?, ?, ?, ?)'
        self.con.execute(
            sql,
            (template.identifier, name, description, instructions)
        )
        self.con.commit()
        handle = BenchmarkHandle(
            con=self.con,
            template=template,
            name=name,
            description=description,
            instructions=instructions
        )
        handle.create_result_table()
        return handle
Beispiel #7
0
    def create_team(self, name, owner_id, members=None):
        """Create a new team with the given name. Ensures that at least the team
        owner is added as a member to the new team.

        Parameters
        ----------
        name: string
            Unique team name
        owner_id: string
            Unique user identifier for team owner
        members: list(string), optional
            List of team members

        Returns
        -------
        benchengine.user.team.base.TeamDescriptor

        Raises
        ------
        benchengine.error.ConstraintViolationError
        benchengine.error.UnknownUserError
        """
        # Ensure that the owner exists and all team members exist. Will raise
        # exception if user is unknown.
        self.assert_user_exists(owner_id)
        if not members is None:
            for user_id in set(members):
                if not user_id == owner_id:
                    self.assert_user_exists(user_id)
        # Ensure that the given team name is uniqe and does not contain too many
        # characters
        sql = 'SELECT * FROM team WHERE name = ?'
        if name is None or name.strip() == '':
            raise err.ConstraintViolationError('missing team name')
        elif len(name.strip()) > 255:
            raise err.ConstraintViolationError(
                'team name contains more than 255 character')
        elif not self.con.execute(sql, (name.strip(), )).fetchone() is None:
            raise err.ConstraintViolationError(
                'team name \'{}\' exists'.format(name.strip()))
        # Get unique identifier for the new team.
        team_id = util.get_unique_identifier()
        # Create the new team and add team members. Ensure that at least the
        # team owner is added as a team member.
        sql = 'INSERT INTO team_member(team_id, user_id) VALUES(?, ?)'
        self.con.execute(
            'INSERT INTO team(id, name, owner_id) VALUES(?, ?, ?)',
            (team_id, name.strip(), owner_id))
        self.con.execute(sql, (team_id, owner_id))
        member_count = 1
        if not members is None:
            for user_id in set(members):
                if not user_id == owner_id:
                    self.con.execute(sql, (team_id, user_id))
                    member_count += 1
        self.con.commit()
        # Return team descriptor
        return TeamDescriptor(identifier=team_id,
                              name=name,
                              owner_id=owner_id,
                              member_count=member_count)