def deactivate_project(requested_by_user: int, project_id: int) -> bool: """ Deactivates an active project :param requested_by_user: ID of the user that requested modification of the user :param project_id: ID of the project that should be deactivated :return: Success or failure """ connection = DatabaseInterface.create_connection() try: success = connection.begin_transaction() # Start a new revision revision_id = None if success: revision_id = DatabaseInterface.tables().revision.insert_row( connection, datetime.datetime.utcnow(), requested_by_user) if revision_id is None: success = False # Read project project = None if success: project = ProjectManagementInterface.__read_project_by_id(connection, project_id, revision_id) if project is None: success = False elif not project["active"]: # Error, project is already inactive success = False # Deactivate project if success: success = DatabaseInterface.tables().project_information.insert_row( connection, project_id, project["short_name"], project["full_name"], project["description"], False, revision_id) if success: connection.commit_transaction() else: connection.rollback_transaction() except: connection.rollback_transaction() raise return success
def _initialize_system(): # Authentication AuthenticationInterface.remove_all_authentication_methods() AuthenticationInterface.add_authentication_method(AuthenticationMethodBasic()) # Database DatabaseInterface.load_database_plugin(DatabaseSqlite("database.db"))
def read_all_tracker_field_ids(tracker_id: int, tracker_field_selection=TrackerFieldSelection.Active, max_revision_id=None) -> List[int]: """ Reads all tracker field IDs from the database :param tracker_id: ID of the tracker :param tracker_field_selection: Search for active, inactive or all tracker :param max_revision_id: Maximum revision ID for the search ("None" for latest revision) :return: List of tracker field IDs """ connection = DatabaseInterface.create_connection() if max_revision_id is None: max_revision_id = DatabaseInterface.tables().revision.read_current_revision_id( connection) # Reads all tracker field IDs from the database tracker_fields = None if max_revision_id is not None: tracker_fields = \ DatabaseInterface.tables().tracker_field_information.read_all_tracker_field_ids( connection, tracker_id, tracker_field_selection, max_revision_id) return tracker_fields
def read_tracker_by_id(tracker_id: int, max_revision_id=None) -> Optional[dict]: """ Reads a tracker (active or inactive) that matches the specified tracker ID :param tracker_id: ID of the tracker :param max_revision_id: Maximum revision ID for the search ("None" for latest revision) :return: Tracker information object Returned dictionary contains items: - id - project_id - short_name - full_name - description - active - revision_id """ connection = DatabaseInterface.create_connection() if max_revision_id is None: max_revision_id = DatabaseInterface.tables().revision.read_current_revision_id( connection) # Read a tracker that matches the specified tracker ID tracker = None if max_revision_id is not None: tracker = TrackerManagementInterface.__read_tracker_by_id(connection, tracker_id, max_revision_id) return tracker
def read_all_tracker_ids(project_id: int, tracker_selection=TrackerSelection.Active, max_revision_id=None) -> List[int]: """ Reads all tracker IDs from the database :param project_id: ID of the project :param tracker_selection: Search for active, inactive or all tracker :param max_revision_id: Maximum revision ID for the search ("None" for latest revision) :return: List of tracker IDs """ connection = DatabaseInterface.create_connection() if max_revision_id is None: max_revision_id = DatabaseInterface.tables( ).revision.read_current_revision_id(connection) # Reads all tracker IDs from the database trackers = None if max_revision_id is not None: trackers = DatabaseInterface.tables( ).tracker_information.read_all_tracker_ids(connection, project_id, tracker_selection, max_revision_id) return trackers
def read_tracker_by_id(tracker_id: int, max_revision_id=None) -> Optional[dict]: """ Reads a tracker (active or inactive) that matches the specified tracker ID :param tracker_id: ID of the tracker :param max_revision_id: Maximum revision ID for the search ("None" for latest revision) :return: Tracker information object Returned dictionary contains items: - id - project_id - short_name - full_name - description - active - revision_id """ connection = DatabaseInterface.create_connection() if max_revision_id is None: max_revision_id = DatabaseInterface.tables( ).revision.read_current_revision_id(connection) # Read a tracker that matches the specified tracker ID tracker = None if max_revision_id is not None: tracker = TrackerManagementInterface.__read_tracker_by_id( connection, tracker_id, max_revision_id) return tracker
def read_project_by_id(project_id: int, max_revision_id=None) -> Optional[dict]: """ Reads a project (active or inactive) that matches the specified project ID :param project_id: ID of the project :param max_revision_id: Maximum revision ID for the search ("None" for latest revision) :return: Project information object Returned dictionary contains items: - id - short_name - full_name - description - active - revision_id """ connection = DatabaseInterface.create_connection() if max_revision_id is None: max_revision_id = DatabaseInterface.tables( ).revision.read_current_revision_id(connection) # Read a project that matches the specified project ID project = None if max_revision_id is not None: project = ProjectManagementInterface.__read_project_by_id( connection, project_id, max_revision_id) return project
def activate_tracker(requested_by_user: int, tracker_id: int) -> bool: """ Activates an inactive tracker :param requested_by_user: ID of the user that requested modification of the user :param tracker_id: ID of the tracker that should be activated :return: Success or failure """ connection = DatabaseInterface.create_connection() try: success = connection.begin_transaction() # Start a new revision revision_id = None if success: revision_id = DatabaseInterface.tables().revision.insert_row( connection, datetime.datetime.utcnow(), requested_by_user) if revision_id is None: success = False # Read tracker tracker = None if success: tracker = TrackerManagementInterface.__read_tracker_by_id(connection, tracker_id, revision_id) if tracker is None: success = False elif tracker["active"]: # Error, tracker is already active success = False # Activate tracker if success: success = DatabaseInterface.tables().tracker_information.insert_row( connection, tracker_id, tracker["short_name"], tracker["full_name"], tracker["description"], True, revision_id) if success: connection.commit_transaction() else: connection.rollback_transaction() except: connection.rollback_transaction() raise return success
def read_all_project_ids(project_selection=ProjectSelection.Active, max_revision_id=None) -> List[int]: """ Reads all project IDs from the database :param project_selection: Search for active, inactive or all project :param max_revision_id: Maximum revision ID for the search ("None" for latest revision) :return: List of project IDs """ connection = DatabaseInterface.create_connection() if max_revision_id is None: max_revision_id = DatabaseInterface.tables().revision.read_current_revision_id( connection) # Reads all project IDs from the database projects = None if max_revision_id is not None: projects = DatabaseInterface.tables().project_information.read_all_project_ids( connection, project_selection, max_revision_id) return projects
def read_project_by_id(project_id: int, max_revision_id=None) -> Optional[dict]: """ Reads a project (active or inactive) that matches the specified project ID :param project_id: ID of the project :param max_revision_id: Maximum revision ID for the search ("None" for latest revision) :return: Project information object Returned dictionary contains items: - id - short_name - full_name - description - active - revision_id """ connection = DatabaseInterface.create_connection() if max_revision_id is None: max_revision_id = DatabaseInterface.tables().revision.read_current_revision_id( connection) # Read a project that matches the specified project ID project = None if max_revision_id is not None: project = ProjectManagementInterface.__read_project_by_id(connection, project_id, max_revision_id) return project
def read_all_project_ids(project_selection=ProjectSelection.Active, max_revision_id=None) -> List[int]: """ Reads all project IDs from the database :param project_selection: Search for active, inactive or all project :param max_revision_id: Maximum revision ID for the search ("None" for latest revision) :return: List of project IDs """ connection = DatabaseInterface.create_connection() if max_revision_id is None: max_revision_id = DatabaseInterface.tables( ).revision.read_current_revision_id(connection) # Reads all project IDs from the database projects = None if max_revision_id is not None: projects = DatabaseInterface.tables( ).project_information.read_all_project_ids(connection, project_selection, max_revision_id) return projects
def _initialize_system(): # Authentication AuthenticationInterface.remove_all_authentication_methods() AuthenticationInterface.add_authentication_method( AuthenticationMethodBasic()) # Database DatabaseInterface.load_database_plugin(DatabaseSqlite("database.db"))
def update_user_information(user_to_modify: int, user_name: str, display_name: str, email: str, active: bool) -> bool: """ Updates user's information :param user_to_modify: ID of the user that should be modified :param user_name: User's new user name :param display_name: User's new display name :param email: User's new email address :param active: User's new state (active or inactive) :return: Success or failure """ connection = DatabaseInterface.create_connection() try: success = connection.begin_transaction() # Check if there is already an existing user with the same user name if success: user = UserManagementInterface.__read_user_by_user_name(connection, user_name) if user is not None: if user["id"] != user_to_modify: success = False # Check if there is already an existing user with the same display name if success: user = UserManagementInterface.__read_user_by_display_name(connection, display_name) if user is not None: if user["id"] != user_to_modify: success = False # Update user's information if success: success = DatabaseInterface.tables().user.update_row(connection, user_to_modify, user_name, display_name, email, active) if success: connection.commit_transaction() else: connection.rollback_transaction() except: connection.rollback_transaction() raise return success
def deactivate_tracker_field(requested_by_user: int, tracker_field_id: int) -> bool: """ Deactivates an active tracker field :param requested_by_user: ID of the user that requested modification of the user :param tracker_field_id: ID of the tracker field that should be deactivated :return: Success or failure """ connection = DatabaseInterface.create_connection() try: success = connection.begin_transaction() # Start a new revision revision_id = None if success: revision_id = DatabaseInterface.tables().revision.insert_row( connection, datetime.datetime.utcnow(), requested_by_user) if revision_id is None: success = False # Read tracker field tracker_field = None if success: tracker_field = TrackerFieldManagementInterface.__read_tracker_field_by_id( connection, tracker_field_id, revision_id) if tracker_field is None: success = False elif not tracker_field["active"]: # Error, tracker field is already inactive success = False # Deactivate tracker field if success: success = DatabaseInterface.tables( ).tracker_field_information.insert_row( connection, tracker_field_id, tracker_field["name"], tracker_field["display_name"], tracker_field["description"], tracker_field["field_type"], tracker_field["required"], False, revision_id) if success: connection.commit_transaction() else: connection.rollback_transaction() except: connection.rollback_transaction() raise return success
def __create_tracker_field(connection: Connection, tracker_id: int, name: str, display_name: str, description: str, field_type: str, required: bool, revision_id: int) -> Optional[int]: """ Creates a new tracker field :param connection: Database connection :param tracker_id: ID of the tracker :param name: Tracker field's name :param display_name: Tracker field's display name :param description: Tracker field's description :param field_type: Tracker field's type :param required: Necessity of the tracker field (required or not) :param revision_id: Revision ID :return: Tracker field ID of the newly created tracker field """ # Check if a tracker field with the same name already exists tracker_field = TrackerFieldManagementInterface.__read_tracker_field_by_name( connection, name, revision_id) if tracker_field is not None: return None # Check if a tracker field with the same display name already exists tracker_field = TrackerFieldManagementInterface.__read_tracker_field_by_display_name( connection, display_name, revision_id) if tracker_field is not None: return None # Create the tracker field in the new revision tracker_field_id = DatabaseInterface.tables().tracker_field.insert_row( connection, tracker_id) if tracker_field_id is None: return None # Add tracker field information to the tracker field tracker_field_information_id = \ DatabaseInterface.tables().tracker_field_information.insert_row( connection, tracker_field_id, name, display_name, description, field_type, required, True, revision_id) if tracker_field_information_id is None: return None return tracker_field_id
def read_all_user_ids(user_selection=UserSelection.Active) -> List[int]: """ Reads all user IDs from the database :param user_selection: Search for active, inactive or all users :return: List of user IDs """ connection = DatabaseInterface.create_connection() return DatabaseInterface.tables().user.read_all_ids(connection, user_selection)
def deactivate_project(requested_by_user: int, project_id: int) -> bool: """ Deactivates an active project :param requested_by_user: ID of the user that requested modification of the user :param project_id: ID of the project that should be deactivated :return: Success or failure """ connection = DatabaseInterface.create_connection() try: success = connection.begin_transaction() # Start a new revision revision_id = None if success: revision_id = DatabaseInterface.tables().revision.insert_row( connection, datetime.datetime.utcnow(), requested_by_user) if revision_id is None: success = False # Read project project = None if success: project = ProjectManagementInterface.__read_project_by_id( connection, project_id, revision_id) if project is None: success = False elif not project["active"]: # Error, project is already inactive success = False # Deactivate project if success: success = DatabaseInterface.tables( ).project_information.insert_row(connection, project_id, project["short_name"], project["full_name"], project["description"], False, revision_id) if success: connection.commit_transaction() else: connection.rollback_transaction() except: connection.rollback_transaction() raise return success
def create_tracker_fields(requested_by_user: int, tracker_id: int, fields: List[dict]) -> bool: """ Creates a new tracker :param requested_by_user: ID of the user that requested creation of the new tracker field :param tracker_id: ID of the tracker :param fields: Tracker fields :return: Success or failure Fields parameter needs to contain a list of dictionaries with the following items: - name: Tracker field's name - display_name: Tracker field's display name - description: Tracker field's description - field_type: Tracker field's type - required: Necessity of the tracker field (required or not) """ connection = DatabaseInterface.create_connection() try: success = connection.begin_transaction() # Start a new revision revision_id = None if success: revision_id = DatabaseInterface.tables().revision.insert_row( connection, datetime.datetime.utcnow(), requested_by_user) if revision_id is None: success = False # Create the tracker if success: for field in fields: tracker_field_id = TrackerFieldManagementInterface.__create_tracker_field( connection, tracker_id, field["name"], field["display_name"], field["description"], field["field_type"], field["required"], revision_id) if tracker_field_id is None: success = False break if success: connection.commit_transaction() else: connection.rollback_transaction() except: connection.rollback_transaction() raise return success
def activate_tracker(requested_by_user: int, tracker_id: int) -> bool: """ Activates an inactive tracker :param requested_by_user: ID of the user that requested modification of the user :param tracker_id: ID of the tracker that should be activated :return: Success or failure """ connection = DatabaseInterface.create_connection() try: success = connection.begin_transaction() # Start a new revision revision_id = None if success: revision_id = DatabaseInterface.tables().revision.insert_row( connection, datetime.datetime.utcnow(), requested_by_user) if revision_id is None: success = False # Read tracker tracker = None if success: tracker = TrackerManagementInterface.__read_tracker_by_id( connection, tracker_id, revision_id) if tracker is None: success = False elif tracker["active"]: # Error, tracker is already active success = False # Activate tracker if success: success = DatabaseInterface.tables( ).tracker_information.insert_row(connection, tracker_id, tracker["short_name"], tracker["full_name"], tracker["description"], True, revision_id) if success: connection.commit_transaction() else: connection.rollback_transaction() except: connection.rollback_transaction() raise return success
def create_tracker(requested_by_user: int, project_id: int, short_name: str, full_name: str, description: str) -> Optional[int]: """ Creates a new tracker :param requested_by_user: ID of the user that requested creation of the new tracker :param project_id: ID of the project :param short_name: Tracker's short name :param full_name: Tracker's full name :param description: Tracker's description :return: Tracker ID of the new tracker """ tracker_id = None connection = DatabaseInterface.create_connection() try: success = connection.begin_transaction() # Start a new revision revision_id = None if success: revision_id = DatabaseInterface.tables().revision.insert_row( connection, datetime.datetime.utcnow(), requested_by_user) if revision_id is None: success = False # Create the tracker if success: tracker_id = TrackerManagementInterface.__create_tracker(connection, project_id, short_name, full_name, description, revision_id) if tracker_id is None: success = False if success: connection.commit_transaction() else: connection.rollback_transaction() except: connection.rollback_transaction() raise return tracker_id
def setUp(self): # Authentication AuthenticationInterface.remove_all_authentication_methods() AuthenticationInterface.add_authentication_method(AuthenticationMethodBasic()) # Database DatabaseInterface.load_database_plugin(DatabaseSqlite("database.db")) DatabaseInterface.create_new_database() # Data members self.__admin_user_id = 1
def __create_tracker(connection: Connection, project_id: int, short_name: str, full_name: str, description: str, revision_id: int) -> Optional[int]: """ Creates a new tracker :param connection: Database connection :param project_id: ID of the project :param short_name: Tracker's short name :param full_name: Tracker's full name :param description: Tracker's description :param revision_id: Revision ID :return: Tracker ID of the newly created tracker """ # Check if a tracker with the same short name already exists tracker = TrackerManagementInterface.__read_tracker_by_short_name(connection, short_name, revision_id) if tracker is not None: return None # Check if a tracker with the same full name already exists tracker = TrackerManagementInterface.__read_tracker_by_full_name(connection, full_name, revision_id) if tracker is not None: return None # Create the tracker in the new revision tracker_id = DatabaseInterface.tables().tracker.insert_row(connection, project_id) if tracker_id is None: return None # Add tracker information to the tracker tracker_information_id = DatabaseInterface.tables().tracker_information.insert_row( connection, tracker_id, short_name, full_name, description, True, revision_id) if tracker_information_id is None: return None return tracker_id
def read_all_user_ids(user_selection=UserSelection.Active) -> List[int]: """ Reads all user IDs from the database :param user_selection: Search for active, inactive or all users :return: List of user IDs """ connection = DatabaseInterface.create_connection() return DatabaseInterface.tables().user.read_all_ids( connection, user_selection)
def setUp(self): # Authentication AuthenticationInterface.remove_all_authentication_methods() AuthenticationInterface.add_authentication_method( AuthenticationMethodBasic()) # Database DatabaseInterface.load_database_plugin(DatabaseSqlite("database.db")) DatabaseInterface.create_new_database() # Data members self.__admin_user_id = 1
def update_user_information(user_to_modify: int, user_name: str, display_name: str, email: str, active: bool) -> bool: """ Updates user's information :param user_to_modify: ID of the user that should be modified :param user_name: User's new user name :param display_name: User's new display name :param email: User's new email address :param active: User's new state (active or inactive) :return: Success or failure """ connection = DatabaseInterface.create_connection() try: success = connection.begin_transaction() # Check if there is already an existing user with the same user name if success: user = UserManagementInterface.__read_user_by_user_name( connection, user_name) if user is not None: if user["id"] != user_to_modify: success = False # Check if there is already an existing user with the same display name if success: user = UserManagementInterface.__read_user_by_display_name( connection, display_name) if user is not None: if user["id"] != user_to_modify: success = False # Update user's information if success: success = DatabaseInterface.tables().user.update_row( connection, user_to_modify, user_name, display_name, email, active) if success: connection.commit_transaction() else: connection.rollback_transaction() except: connection.rollback_transaction() raise return success
def __create_project(connection: Connection, short_name: str, full_name: str, description: str, revision_id: int) -> Optional[int]: """ Creates a new project :param connection: Database connection :param short_name: Project's short name :param full_name: Project's full name :param description: Project's description :param revision_id: Revision ID :return: Project ID of the newly created project """ # Check if a project with the same short name already exists project = ProjectManagementInterface.__read_project_by_short_name(connection, short_name, revision_id) if project is not None: return None # Check if a project with the same full name already exists project = ProjectManagementInterface.__read_project_by_full_name(connection, full_name, revision_id) if project is not None: return None # Create the project in the new revision project_id = DatabaseInterface.tables().project.insert_row(connection) if project_id is None: return None # Add project information to the project project_information_id = DatabaseInterface.tables().project_information.insert_row( connection, project_id, short_name, full_name, description, True, revision_id) if project_information_id is None: return None return project_id
def create_tracker_field(requested_by_user: int, tracker_id: int, name: str, display_name: str, description: str, field_type: str, required: bool) -> Optional[int]: """ Creates a new tracker :param requested_by_user: ID of the user that requested creation of the new tracker field :param tracker_id: ID of the tracker :param name: Tracker field's name :param display_name: Tracker field's display name :param description: Tracker field's description :param field_type: Tracker field's type :param required: Necessity of the tracker field (required or not) :return: Tracker field ID of the new tracker field """ tracker_field_id = None connection = DatabaseInterface.create_connection() try: success = connection.begin_transaction() # Start a new revision revision_id = None if success: revision_id = DatabaseInterface.tables().revision.insert_row( connection, datetime.datetime.utcnow(), requested_by_user) if revision_id is None: success = False # Create the tracker if success: tracker_field_id = TrackerFieldManagementInterface.__create_tracker_field( connection, tracker_id, name, display_name, description, field_type, required, revision_id) if tracker_field_id is None: success = False if success: connection.commit_transaction() else: connection.rollback_transaction() except: connection.rollback_transaction() raise return tracker_field_id
def read_tracker_fields_by_display_name(display_name: str, max_revision_id=None ) -> List[dict]: """ Reads all active and inactive tracker fields that match the specified display name :param display_name: Tracker field's display name :param max_revision_id: Maximum revision ID for the search ("None" for latest revision) :return: Tracker field information of all tracker fields that match the search attribute Each dictionary in the returned list contains items: - id - tracker_id - name - display_name - description - field_type - required - active - revision_id """ connection = DatabaseInterface.create_connection() if max_revision_id is None: max_revision_id = DatabaseInterface.tables( ).revision.read_current_revision_id(connection) # Read tracker fields that match the specified display name tracker_fields = list() if max_revision_id is not None: tracker_field_information_list = \ DatabaseInterface.tables().tracker_field_information.read_information( connection, "display_name", display_name, TrackerFieldSelection.All, max_revision_id) for tracker_field_information in tracker_field_information_list: tracker_fields.append( TrackerFieldManagementInterface. __parse_tracker_field_information( tracker_field_information)) return tracker_fields
def create_tracker(requested_by_user: int, project_id: int, short_name: str, full_name: str, description: str) -> Optional[int]: """ Creates a new tracker :param requested_by_user: ID of the user that requested creation of the new tracker :param project_id: ID of the project :param short_name: Tracker's short name :param full_name: Tracker's full name :param description: Tracker's description :return: Tracker ID of the new tracker """ tracker_id = None connection = DatabaseInterface.create_connection() try: success = connection.begin_transaction() # Start a new revision revision_id = None if success: revision_id = DatabaseInterface.tables().revision.insert_row( connection, datetime.datetime.utcnow(), requested_by_user) if revision_id is None: success = False # Create the tracker if success: tracker_id = TrackerManagementInterface.__create_tracker( connection, project_id, short_name, full_name, description, revision_id) if tracker_id is None: success = False if success: connection.commit_transaction() else: connection.rollback_transaction() except: connection.rollback_transaction() raise return tracker_id
def __read_user_by_display_name(token: str, display_name: str) -> dict: """ Reads current user's information :param token: Session token which contains the current user's information :param display_name: Display name :return: User information object Returned dictionary contains items: - id - user_name - display_name - email - active """ user = None success = False error_code = None error_message = None connection = DatabaseInterface.create_connection() try: success = connection.begin_transaction() # Extract session user if success: session_user = RestrictedResource._read_session_user( connection, token) if session_user is None: success = False error_code = 400 error_message = "Invalid session token" # Read requested user if success: user = UserManagementInterface.read_user_by_display_name( connection, display_name) if user is None: success = False error_code = 400 error_message = "Invalid user name" connection.rollback_transaction() except: connection.rollback_transaction() abort(500, message="Internal error, please try again") # Return user if success: return jsonify(user) else: if (error_code is not None) and (error_message is not None): abort(error_code, message=error_message) else: abort(500, message="Internal error")
def __read_user_by_display_name(connection: Connection, display_name: str) -> Optional[dict]: """ Reads an active user that matches the specified display name :param display_name: User's display name :return: User information object Returned dictionary contains items: - id - user_name - display_name - email - active """ # Read the users that match the search attribute users = DatabaseInterface.tables().user.read_users_by_attribute( connection, "display_name", display_name, UserSelection.Active) # Return a user only if exactly one was found user = None if users is not None: if len(users) == 1: user = users[0] return user
def read_user_by_id(connection: Connection, user_id: int) -> Optional[dict]: """ Reads a user (active or inactive) that matches the specified user ID :param connection: Database connection :param user_id: ID of the user :return: User information object Returned dictionary contains items: - id - user_name - display_name - email - active """ # Read the users that match the search attribute users = DatabaseInterface.tables().user.read_users_by_attribute( connection, "id", user_id, UserSelection.All) # Return a user only if exactly one was found user = None if users is not None: if len(users) == 1: user = users[0] return user
def read_user_by_id(connection: Connection, user_id: int) -> Optional[dict]: """ Reads a user (active or inactive) that matches the specified user ID :param connection: Database connection :param user_id: ID of the user :return: User information object Returned dictionary contains items: - id - user_name - display_name - email - active """ # Read the users that match the search attribute users = DatabaseInterface.tables().user.read_users_by_attribute(connection, "id", user_id, UserSelection.All) # Return a user only if exactly one was found user = None if users is not None: if len(users) == 1: user = users[0] return user
def __read_user_by_display_name(connection: Connection, display_name: str) -> Optional[dict]: """ Reads an active user that matches the specified display name :param display_name: User's display name :return: User information object Returned dictionary contains items: - id - user_name - display_name - email - active """ # Read the users that match the search attribute users = DatabaseInterface.tables().user.read_users_by_attribute(connection, "display_name", display_name, UserSelection.Active) # Return a user only if exactly one was found user = None if users is not None: if len(users) == 1: user = users[0] return user
def create_session_token(connection: Connection, user_id: int) -> Optional[str]: """ Creates a session token :param connection: Database connection :param user_id: ID of the user :return: Token value """ # Generate a token token = None for i in range(10): # Generate a random UUID (up to 10 tries) random_uuid = uuid.uuid4() # Check if this token already exists in the database existing_session_token = UserManagementInterface.read_session_token( connection, random_uuid.hex) if existing_session_token is None: token = random_uuid.hex break # Store the token in the database if token is not None: row_id = DatabaseInterface.tables().session_token.insert_row( connection, user_id, datetime.datetime.utcnow(), token) # In case of an error invalidate the generated token if row_id is None: token = None return token
def __create_tracker(connection: Connection, project_id: int, short_name: str, full_name: str, description: str, revision_id: int) -> Optional[int]: """ Creates a new tracker :param connection: Database connection :param project_id: ID of the project :param short_name: Tracker's short name :param full_name: Tracker's full name :param description: Tracker's description :param revision_id: Revision ID :return: Tracker ID of the newly created tracker """ # Check if a tracker with the same short name already exists tracker = TrackerManagementInterface.__read_tracker_by_short_name( connection, short_name, revision_id) if tracker is not None: return None # Check if a tracker with the same full name already exists tracker = TrackerManagementInterface.__read_tracker_by_full_name( connection, full_name, revision_id) if tracker is not None: return None # Create the tracker in the new revision tracker_id = DatabaseInterface.tables().tracker.insert_row( connection, project_id) if tracker_id is None: return None # Add tracker information to the tracker tracker_information_id = DatabaseInterface.tables( ).tracker_information.insert_row(connection, tracker_id, short_name, full_name, description, True, revision_id) if tracker_information_id is None: return None return tracker_id
def read_tracker_fields_by_display_name(display_name: str, max_revision_id=None) -> List[dict]: """ Reads all active and inactive tracker fields that match the specified display name :param display_name: Tracker field's display name :param max_revision_id: Maximum revision ID for the search ("None" for latest revision) :return: Tracker field information of all tracker fields that match the search attribute Each dictionary in the returned list contains items: - id - tracker_id - name - display_name - description - field_type - required - active - revision_id """ connection = DatabaseInterface.create_connection() if max_revision_id is None: max_revision_id = DatabaseInterface.tables().revision.read_current_revision_id( connection) # Read tracker fields that match the specified display name tracker_fields = list() if max_revision_id is not None: tracker_field_information_list = \ DatabaseInterface.tables().tracker_field_information.read_information( connection, "display_name", display_name, TrackerFieldSelection.All, max_revision_id) for tracker_field_information in tracker_field_information_list: tracker_fields.append( TrackerFieldManagementInterface.__parse_tracker_field_information( tracker_field_information)) return tracker_fields
def __read_user_by_display_name(token: str, display_name: str) -> dict: """ Reads current user's information :param token: Session token which contains the current user's information :param display_name: Display name :return: User information object Returned dictionary contains items: - id - user_name - display_name - email - active """ user = None success = False error_code = None error_message = None connection = DatabaseInterface.create_connection() try: success = connection.begin_transaction() # Extract session user if success: session_user = RestrictedResource._read_session_user(connection, token) if session_user is None: success = False error_code = 400 error_message = "Invalid session token" # Read requested user if success: user = UserManagementInterface.read_user_by_display_name(connection, display_name) if user is None: success = False error_code = 400 error_message = "Invalid user name" connection.rollback_transaction() except: connection.rollback_transaction() abort(500, message="Internal error, please try again") # Return user if success: return jsonify(user) else: if (error_code is not None) and (error_message is not None): abort(error_code, message=error_message) else: abort(500, message="Internal error")
def read_trackers_by_full_name(full_name: str, max_revision_id=None) -> List[dict]: """ Reads all active and inactive trackers that match the specified full name :param full_name: Tracker's full name :param max_revision_id: Maximum revision ID for the search ("None" for latest revision) :return: Tracker information of all trackers that match the search attribute Each dictionary in the returned list contains items: - id - project_id - short_name - full_name - description - active - revision_id """ connection = DatabaseInterface.create_connection() if max_revision_id is None: max_revision_id = DatabaseInterface.tables( ).revision.read_current_revision_id(connection) # Read trackers that match the specified full name trackers = list() if max_revision_id is not None: tracker_information_list = \ DatabaseInterface.tables().tracker_information.read_information( connection, "full_name", full_name, TrackerSelection.All, max_revision_id) for tracker_information in tracker_information_list: trackers.append( TrackerManagementInterface.__parse_tracker_information( tracker_information)) return trackers
def __create_project(connection: Connection, short_name: str, full_name: str, description: str, revision_id: int) -> Optional[int]: """ Creates a new project :param connection: Database connection :param short_name: Project's short name :param full_name: Project's full name :param description: Project's description :param revision_id: Revision ID :return: Project ID of the newly created project """ # Check if a project with the same short name already exists project = ProjectManagementInterface.__read_project_by_short_name( connection, short_name, revision_id) if project is not None: return None # Check if a project with the same full name already exists project = ProjectManagementInterface.__read_project_by_full_name( connection, full_name, revision_id) if project is not None: return None # Create the project in the new revision project_id = DatabaseInterface.tables().project.insert_row(connection) if project_id is None: return None # Add project information to the project project_information_id = DatabaseInterface.tables( ).project_information.insert_row(connection, project_id, short_name, full_name, description, True, revision_id) if project_information_id is None: return None return project_id
def read_trackers_by_full_name(full_name: str, max_revision_id=None) -> List[dict]: """ Reads all active and inactive trackers that match the specified full name :param full_name: Tracker's full name :param max_revision_id: Maximum revision ID for the search ("None" for latest revision) :return: Tracker information of all trackers that match the search attribute Each dictionary in the returned list contains items: - id - project_id - short_name - full_name - description - active - revision_id """ connection = DatabaseInterface.create_connection() if max_revision_id is None: max_revision_id = DatabaseInterface.tables().revision.read_current_revision_id( connection) # Read trackers that match the specified full name trackers = list() if max_revision_id is not None: tracker_information_list = \ DatabaseInterface.tables().tracker_information.read_information( connection, "full_name", full_name, TrackerSelection.All, max_revision_id) for tracker_information in tracker_information_list: trackers.append(TrackerManagementInterface.__parse_tracker_information( tracker_information)) return trackers
def deactivate_user(user_id: int) -> bool: """ Deactivates an active user :param user_id: ID of the user that should be deactivated :return: Success or failure """ connection = DatabaseInterface.create_connection() try: success = connection.begin_transaction() # Read user user = None if success: user = UserManagementInterface.read_user_by_id(connection, user_id) if user is None: success = False elif not user["active"]: # Error, user is already inactive success = False # Deactivate user if success: success = DatabaseInterface.tables().user.update_row(connection, user_id, user["user_name"], user["display_name"], user["email"], False) if success: connection.commit_transaction() else: connection.rollback_transaction() except: connection.rollback_transaction() raise return success
def read_projects_by_short_name(short_name: str, max_revision_id=None) -> List[dict]: """ Reads all active and inactive projects that match the specified short name :param short_name: Project's short name :param max_revision_id: Maximum revision ID for the search ("None" for latest revision) :return: Project information of all projects that match the search attribute Each dictionary in the returned list contains items: - id - short_name - full_name - description - active - revision_id """ connection = DatabaseInterface.create_connection() if max_revision_id is None: max_revision_id = DatabaseInterface.tables( ).revision.read_current_revision_id(connection) # Read projects that match the specified short name projects = list() if max_revision_id is not None: project_information_list = \ DatabaseInterface.tables().project_information.read_information( connection, "short_name", short_name, ProjectSelection.All, max_revision_id) for project_information in project_information_list: projects.append( ProjectManagementInterface.__parse_project_information( project_information)) return projects
def delete_session_token(connection: Connection, token: str) -> bool: """ Deletes the specified session token :param connection: Database connection :param token: Session's token value :return: Success or failure """ # Check if the specified token is valid existing_session_token = UserManagementInterface.read_session_token(connection, token) if existing_session_token is None: # Error, invalid token return False # Delete the token from the database DatabaseInterface.tables().session_token.delete_row_by_token(connection, token) return True
def read_projects_by_short_name(short_name: str, max_revision_id=None) -> List[dict]: """ Reads all active and inactive projects that match the specified short name :param short_name: Project's short name :param max_revision_id: Maximum revision ID for the search ("None" for latest revision) :return: Project information of all projects that match the search attribute Each dictionary in the returned list contains items: - id - short_name - full_name - description - active - revision_id """ connection = DatabaseInterface.create_connection() if max_revision_id is None: max_revision_id = DatabaseInterface.tables().revision.read_current_revision_id( connection) # Read projects that match the specified short name projects = list() if max_revision_id is not None: project_information_list = \ DatabaseInterface.tables().project_information.read_information( connection, "short_name", short_name, ProjectSelection.All, max_revision_id) for project_information in project_information_list: projects.append(ProjectManagementInterface.__parse_project_information( project_information)) return projects
def deactivate_user(user_id: int) -> bool: """ Deactivates an active user :param user_id: ID of the user that should be deactivated :return: Success or failure """ connection = DatabaseInterface.create_connection() try: success = connection.begin_transaction() # Read user user = None if success: user = UserManagementInterface.read_user_by_id( connection, user_id) if user is None: success = False elif not user["active"]: # Error, user is already inactive success = False # Deactivate user if success: success = DatabaseInterface.tables().user.update_row( connection, user_id, user["user_name"], user["display_name"], user["email"], False) if success: connection.commit_transaction() else: connection.rollback_transaction() except: connection.rollback_transaction() raise return success
def delete_session_token(connection: Connection, token: str) -> bool: """ Deletes the specified session token :param connection: Database connection :param token: Session's token value :return: Success or failure """ # Check if the specified token is valid existing_session_token = UserManagementInterface.read_session_token( connection, token) if existing_session_token is None: # Error, invalid token return False # Delete the token from the database DatabaseInterface.tables().session_token.delete_row_by_token( connection, token) return True
def post(self): """ Logs out the user """ # Extract session token from the request token = self._read_session_token() # Log out success = False error_code = None error_message = None connection = DatabaseInterface.create_connection() try: success = connection.begin_transaction() # Get the session token session_token = None if success: session_token = UserManagementInterface.read_session_token(connection, token) if session_token is None: success = False error_code = 400 error_message = "Invalid session token" # Delete session token if success: success = UserManagementInterface.delete_session_token(connection, token) if not success: error_code = 500 error_message = "Failed to log out, please try again" if success: connection.commit_transaction() else: connection.rollback_transaction() except: connection.rollback_transaction() abort(500, message="Internal error, please try again") # Return response if success: return None else: if (error_code is not None) and (error_message is not None): abort(error_code, message=error_message) else: abort(500, message="Internal error")
def __read_user_authentication(connection: Connection, user_id: int) -> Optional[dict]: """ Reads user's authentication :param connection: Database connection :param user_id: ID of the user :return: User authentication object Returned dictionary contains items: - authentication_type - authentication_parameters """ # Read the user's authentication user_authentication = DatabaseInterface.tables( ).user_authentication.read_authentication(connection, user_id) if user_authentication is None: return None # Read the user's authentication parameters authentication_parameters = \ DatabaseInterface.tables().user_authentication_parameter.read_authentication_parameters( connection, user_id) if authentication_parameters is None: return None # Create authentication object authentication_object = dict() authentication_object["authentication_type"] = user_authentication[ "authentication_type"] authentication_object[ "authentication_parameters"] = authentication_parameters return authentication_object
def read_tracker_field_by_display_name(display_name: str, max_revision_id=None) -> Optional[dict]: """ Reads an active tracker field that matches the specified display name :param display_name: Tracker field's display name :param max_revision_id: Maximum revision ID for the search ("None" for latest revision) :return: Tracker field information object Returned dictionary contains items: - id - tracker_id - name - display_name - description - field_type - required - active - revision_id """ connection = DatabaseInterface.create_connection() if max_revision_id is None: max_revision_id = DatabaseInterface.tables().revision.read_current_revision_id( connection) # Read a tracker field that matches the specified display name tracker_field = None if max_revision_id is not None: tracker_field = TrackerFieldManagementInterface.__read_tracker_field_by_display_name( connection, display_name, max_revision_id) return tracker_field
def __read_tracker_field_by_id(connection: Connection, tracker_field_id: int, max_revision_id: int) -> Optional[dict]: """ Reads a tracker field (active or inactive) that matches the search parameters :param connection: Database connection :param tracker_field_id: ID of the tracker :param max_revision_id: Maximum revision ID for the search :return: Tracker field information object Returned dictionary contains items: - id - tracker_id - name - display_name - description - field_type - required - active - revision_id """ # Read the tracker fields that match the search attribute tracker_fields = DatabaseInterface.tables( ).tracker_field_information.read_information(connection, "tracker_field_id", tracker_field_id, TrackerFieldSelection.All, max_revision_id) # Return a tracker field only if exactly one was found tracker_field = None if tracker_fields is not None: if len(tracker_fields) == 1: tracker_field = { "id": tracker_fields[0]["tracker_field_id"], "tracker_id": tracker_fields[0]["tracker_id"], "name": tracker_fields[0]["name"], "display_name": tracker_fields[0]["display_name"], "description": tracker_fields[0]["description"], "field_type": tracker_fields[0]["field_type"], "required": tracker_fields[0]["required"], "active": tracker_fields[0]["active"], "revision_id": tracker_fields[0]["revision_id"] } return tracker_field
def read_tracker_field_by_display_name(display_name: str, max_revision_id=None ) -> Optional[dict]: """ Reads an active tracker field that matches the specified display name :param display_name: Tracker field's display name :param max_revision_id: Maximum revision ID for the search ("None" for latest revision) :return: Tracker field information object Returned dictionary contains items: - id - tracker_id - name - display_name - description - field_type - required - active - revision_id """ connection = DatabaseInterface.create_connection() if max_revision_id is None: max_revision_id = DatabaseInterface.tables( ).revision.read_current_revision_id(connection) # Read a tracker field that matches the specified display name tracker_field = None if max_revision_id is not None: tracker_field = TrackerFieldManagementInterface.__read_tracker_field_by_display_name( connection, display_name, max_revision_id) return tracker_field
def __read_user_authentication(connection: Connection, user_id: int) -> Optional[dict]: """ Reads user's authentication :param connection: Database connection :param user_id: ID of the user :return: User authentication object Returned dictionary contains items: - authentication_type - authentication_parameters """ # Read the user's authentication user_authentication = DatabaseInterface.tables().user_authentication.read_authentication( connection, user_id) if user_authentication is None: return None # Read the user's authentication parameters authentication_parameters = \ DatabaseInterface.tables().user_authentication_parameter.read_authentication_parameters( connection, user_id) if authentication_parameters is None: return None # Create authentication object authentication_object = dict() authentication_object["authentication_type"] = user_authentication["authentication_type"] authentication_object["authentication_parameters"] = authentication_parameters return authentication_object
def __read_tracker_field_by_display_name(connection: Connection, display_name: str, max_revision_id: int) -> Optional[dict]: """ Reads an active tracker that matches the specified full name :param connection: Database connection :param display_name: Tracker's display name :param max_revision_id: Maximum revision ID for the search :return: Tracker field information object Returned dictionary contains items: - id - tracker_id - name - display_name - description - field_type - required - active - revision_id """ # Read the tracker fields that match the search attribute tracker_fields = DatabaseInterface.tables().tracker_field_information.read_information( connection, "display_name", display_name, TrackerFieldSelection.Active, max_revision_id) # Return a tracker field only if exactly one was found tracker_field = None if tracker_fields is not None: if len(tracker_fields) == 1: tracker_field = {"id": tracker_fields[0]["tracker_field_id"], "tracker_id": tracker_fields[0]["tracker_id"], "name": tracker_fields[0]["name"], "display_name": tracker_fields[0]["display_name"], "description": tracker_fields[0]["description"], "field_type": tracker_fields[0]["field_type"], "required": tracker_fields[0]["required"], "active": tracker_fields[0]["active"], "revision_id": tracker_fields[0]["revision_id"]} return tracker_field
def __read_tracker_by_full_name(connection: Connection, full_name: str, max_revision_id: int) -> Optional[dict]: """ Reads an active tracker that matches the specified full name :param connection: Database connection :param full_name: Tracker's full name :param max_revision_id: Maximum revision ID for the search :return: Tracker information object Returned dictionary contains items: - id - project_id - short_name - full_name - description - active - revision_id """ # Read the trackers that match the search attribute trackers = DatabaseInterface.tables().tracker_information.read_information( connection, "full_name", full_name, TrackerSelection.Active, max_revision_id) # Return a tracker only if exactly one was found tracker = None if trackers is not None: if len(trackers) == 1: tracker = {"id": trackers[0]["tracker_id"], "project_id": trackers[0]["project_id"], "short_name": trackers[0]["short_name"], "full_name": trackers[0]["full_name"], "description": trackers[0]["description"], "active": trackers[0]["active"], "revision_id": trackers[0]["revision_id"]} return tracker
def read_session_token(connection: Connection, token: str) -> Optional[dict]: """ Reads a session token from the database :param connection: Database connection :param token: Session's token value :return: Session token object Returned dictionary contains items: - id - user_id - created_on - token """ session_token = DatabaseInterface.tables().session_token.read_token(connection, token) return session_token
def create_user(user_name: str, display_name: str, email: str, authentication_type: str, authentication_parameters: dict) -> Optional[int]: """ Creates a new user :param user_name: User's user name :param display_name: User's display name :param email: Email address of the user :param authentication_type: User's authentication type :param authentication_parameters: User's authentication parameters :return: User ID of the new user """ user_id = None connection = DatabaseInterface.create_connection() try: success = connection.begin_transaction() # Create the user if success: user_id = UserManagementInterface.__create_user(connection, user_name, display_name, email, authentication_type, authentication_parameters) if user_id is None: success = False if success: connection.commit_transaction() else: connection.rollback_transaction() except: connection.rollback_transaction() raise return user_id
def __read_project_by_full_name(connection: Connection, full_name: str, max_revision_id: int) -> Optional[dict]: """ Reads an active project that matches the specified full name :param connection: Database connection :param full_name: Projects's full name :param max_revision_id: Maximum revision ID for the search :return: Project information object Returned dictionary contains items: - id - short_name - full_name - description - active - revision_id """ # Read the projects that match the search attribute projects = DatabaseInterface.tables().project_information.read_information( connection, "full_name", full_name, ProjectSelection.Active, max_revision_id) # Return a project only if exactly one was found project = None if projects is not None: if len(projects) == 1: project = {"id": projects[0]["project_id"], "short_name": projects[0]["short_name"], "full_name": projects[0]["full_name"], "description": projects[0]["description"], "active": projects[0]["active"], "revision_id": projects[0]["revision_id"]} return project
def read_users_by_display_name(connection: Connection, display_name: str) -> List[dict]: """ Reads all active and inactive users that match the specified display name :param connection: Database connection :param display_name: User's display name :return: User information of all users that match the search attribute Each dictionary in the returned list contains items: - id - user_name - display_name - email - active """ return DatabaseInterface.tables().user.read_users_by_attribute(connection, "display_name", display_name, UserSelection.All)