예제 #1
0
class ProjectStatuses(db.Model):
    """
    One-to-many table between projects and statuses. Contains all project status history.

    Primary key(s):
    - project_id
    - status

    Foreign key(s):
    - project_id
    """

    # Table setup
    __tablename__ = "projectstatuses"

    # Foreign keys & relationships
    project_id = db.Column(db.Integer,
                           db.ForeignKey("projects.id", ondelete="CASCADE"),
                           primary_key=True)
    project = db.relationship("Project", back_populates="project_statuses")
    # ---

    # Additional columns
    status = db.Column(db.String(50),
                       unique=False,
                       nullable=False,
                       primary_key=True)
    date_created = db.Column(db.DateTime(), nullable=False, primary_key=True)

    # Columns
    is_aborted = db.Column(db.Boolean,
                           nullable=True,
                           default=False,
                           unique=False)
    deadline = db.Column(db.DateTime(), nullable=True)
예제 #2
0
class Version(db.Model):
    """
    Data model for keeping track of all active and non active files. Used for invoicing.

    Primary key:
    - id

    Foreign key(s):
    - project_id
    - active_file
    """

    # Table setup
    __tablename__ = "versions"
    __table_args__ = {"extend_existing": True}

    # Columns
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)

    # Foreign keys & relationships
    project_id = db.Column(db.Integer,
                           db.ForeignKey("projects.id", ondelete="RESTRICT"),
                           nullable=False)
    project = db.relationship("Project", back_populates="file_versions")
    # ---
    active_file = db.Column(db.BigInteger,
                            db.ForeignKey("files.id", ondelete="SET NULL"),
                            nullable=True)
    file = db.relationship("File", back_populates="versions")
    # ---

    # Additional columns
    size_stored = db.Column(db.BigInteger, unique=False, nullable=False)
    time_uploaded = db.Column(db.DateTime(),
                              unique=False,
                              nullable=False,
                              default=dds_web.utils.current_time())
    time_deleted = db.Column(db.DateTime(),
                             unique=False,
                             nullable=True,
                             default=None)
    time_invoiced = db.Column(db.DateTime(),
                              unique=False,
                              nullable=True,
                              default=None)

    def __repr__(self):
        """Called by print, creates representation of object"""

        return f"<File Version {self.id}>"
예제 #3
0
class PasswordReset(db.Model):
    """Keep track of password resets."""

    # Table setup
    __tablename__ = "password_resets"
    __table_args__ = {"extend_existing": True}

    # Primary Key
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)

    user_id = db.Column(db.String(50),
                        db.ForeignKey("users.username", ondelete="CASCADE"))
    user = db.relationship("User", back_populates="password_reset")

    email = db.Column(db.String(254), unique=True, nullable=False)
    issued = db.Column(db.DateTime(), unique=False, nullable=False)
    changed = db.Column(db.DateTime(), unique=False, nullable=True)

    valid = db.Column(db.Boolean, unique=False, nullable=False, default=True)
예제 #4
0
class Invite(db.Model):
    """
    Invites for users not yet confirmed in DDS.

    Primary key:
    - id

    Foreign key(s):
    - unit_id
    """

    # Table setup
    __tablename__ = "invites"
    __table_args__ = {"extend_existing": True}

    # Primary Key
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)

    # Foreign keys & relationships
    unit_id = db.Column(db.Integer,
                        db.ForeignKey("units.id", ondelete="CASCADE"))
    unit = db.relationship("Unit", back_populates="invites")
    project_invite_keys = db.relationship("ProjectInviteKeys",
                                          back_populates="invite",
                                          passive_deletes=True,
                                          cascade="all, delete")
    # ---

    # Additional columns
    email = db.Column(db.String(254), unique=True, nullable=False)
    role = db.Column(db.String(20), unique=False, nullable=False)
    nonce = db.Column(db.LargeBinary(12), default=None)
    public_key = db.Column(db.LargeBinary(300), default=None)
    private_key = db.Column(db.LargeBinary(300), default=None)
    created_at = db.Column(db.DateTime(),
                           nullable=False,
                           default=dds_web.utils.current_time())

    @property
    def projects(self):
        """Return list of project items."""

        return [proj.project for proj in self.project_associations]

    def __str__(self):
        """Called by str(), creates representation of object"""

        return f"Pending invite for {self.email}"

    def __repr__(self):
        """Called by print, creates representation of object"""

        return f"<Invite {self.email}>"
예제 #5
0
class MOTD(db.Model):
    """
    Data model for keeping track of MOTD (message of the day).

    Primary key:
    - message
    """

    # Table setup
    __tablename__ = "motd"
    __table_args__ = {"extend_existing": True}

    # Columns
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    message = db.Column(db.Text, nullable=False, default=None)
    date_created = db.Column(db.DateTime(), nullable=False, default=None)
예제 #6
0
class File(db.Model):
    """
    Data model for files.

    Primary key:
    - id

    Foreign key(s):
    - project_id
    """

    # Table setup
    __tablename__ = "files"
    __table_args__ = {"extend_existing": True}

    # Columns
    id = db.Column(db.BigInteger, primary_key=True, autoincrement=True)

    # Foreign keys & relationships
    project_id = db.Column(db.Integer,
                           db.ForeignKey("projects.id", ondelete="RESTRICT"),
                           index=True,
                           nullable=False)
    project = db.relationship("Project", back_populates="files")
    # ---

    # Additional columns
    name = db.Column(db.Text, unique=False, nullable=False)
    name_in_bucket = db.Column(db.Text, unique=False, nullable=False)
    subpath = db.Column(db.Text, unique=False, nullable=False)
    size_original = db.Column(db.BigInteger, unique=False, nullable=False)
    size_stored = db.Column(db.BigInteger, unique=False, nullable=False)
    compressed = db.Column(db.Boolean, nullable=False)
    public_key = db.Column(db.String(64), unique=False, nullable=False)
    salt = db.Column(db.String(32), unique=False, nullable=False)
    checksum = db.Column(db.String(64), unique=False, nullable=False)
    time_latest_download = db.Column(db.DateTime(),
                                     unique=False,
                                     nullable=True)

    # Additional relationships
    versions = db.relationship("Version", back_populates="file")

    def __repr__(self):
        """Called by print, creates representation of object"""

        return f"<File {pathlib.Path(self.name).name}>"
예제 #7
0
class DeletionRequest(db.Model):
    """Table to collect self-deletion requests by users"""

    # Table setup
    __tablename__ = "deletions"
    __table_args__ = {"extend_existing": True}

    # Primary Key
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    requester_id = db.Column(
        db.String(50), db.ForeignKey("users.username", ondelete="CASCADE"))
    requester = db.relationship("User", back_populates="deletion_request")
    email = db.Column(db.String(254), unique=True, nullable=False)
    issued = db.Column(db.DateTime(), unique=False, nullable=False)

    def __repr__(self):
        """Called by print, creates representation of object"""

        return f"<DeletionRequest {self.email}>"
예제 #8
0
class Project(db.Model):
    """
    Data model for projects.

    Primary key(s):
    - id

    Foreign key(s):
    - unit_id
    - created_by
    """

    # Table setup
    __tablename__ = "projects"
    __table_args__ = {"extend_existing": True}

    # Columns
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    public_id = db.Column(db.String(255), unique=True, nullable=True)
    title = db.Column(db.Text, unique=False, nullable=True)
    date_created = db.Column(
        db.DateTime(),
        nullable=True,
        default=dds_web.utils.current_time(),
    )
    date_updated = db.Column(db.DateTime(), nullable=True)
    description = db.Column(db.Text)
    pi = db.Column(db.String(255), unique=False, nullable=True)
    bucket = db.Column(db.String(255), unique=True, nullable=False)
    public_key = db.Column(db.LargeBinary(100), nullable=True)

    non_sensitive = db.Column(db.Boolean,
                              unique=False,
                              default=False,
                              nullable=False)
    released = db.Column(db.DateTime(), nullable=True)
    is_active = db.Column(db.Boolean,
                          unique=False,
                          nullable=False,
                          default=True,
                          index=True)

    # Foreign keys & relationships
    unit_id = db.Column(db.Integer,
                        db.ForeignKey("units.id", ondelete="RESTRICT"),
                        nullable=True)
    responsible_unit = db.relationship("Unit", back_populates="projects")
    # ---
    created_by = db.Column(
        db.String(50), db.ForeignKey("users.username", ondelete="SET NULL"))
    creator = db.relationship("User",
                              backref="created_projects",
                              foreign_keys=[created_by])
    last_updated_by = db.Column(
        db.String(50), db.ForeignKey("users.username", ondelete="SET NULL"))
    updator = db.relationship("User",
                              backref="updated_projects",
                              foreign_keys=[last_updated_by])
    # ---

    # Additional relationships
    files = db.relationship("File", back_populates="project")
    file_versions = db.relationship("Version", back_populates="project")
    project_statuses = db.relationship("ProjectStatuses",
                                       back_populates="project",
                                       passive_deletes=True,
                                       cascade="all, delete")
    researchusers = db.relationship("ProjectUsers",
                                    back_populates="project",
                                    passive_deletes=True,
                                    cascade="all, delete")
    project_user_keys = db.relationship("ProjectUserKeys",
                                        back_populates="project",
                                        passive_deletes=True)
    project_invite_keys = db.relationship("ProjectInviteKeys",
                                          back_populates="project",
                                          passive_deletes=True)

    @property
    def current_status(self):
        """Return the current status of the project"""
        return max(self.project_statuses, key=lambda x: x.date_created).status

    @property
    def has_been_available(self):
        """Return True if the project has ever been in the status Available"""
        result = False
        if len([x for x in self.project_statuses if "Available" in x.status
                ]) > 0:
            result = True
        return result

    @property
    def times_expired(self):
        return len([x for x in self.project_statuses if "Expired" in x.status])

    @property
    def current_deadline(self):
        """Return deadline for statuses that have a deadline"""
        deadline = None
        if self.current_status in ["Available", "Expired"]:
            deadline = max(self.project_statuses,
                           key=lambda x: x.date_created).deadline
        elif self.current_status in ["In Progress"]:
            if self.has_been_available:
                list_available = list(
                    filter(lambda x: x.status == "Available",
                           self.project_statuses))
                latest_available = max(list_available,
                                       key=lambda x: x.date_created)
                deadline = latest_available.deadline
        return deadline

    @property
    def safespring_project(self):
        """Get the safespring project name from responsible unit."""

        return self.responsible_unit.safespring

    @property
    def size(self):
        """Calculate size of project."""

        return sum([f.size_stored for f in self.files])

    @property
    def num_files(self):
        """Get number of files in project."""

        return len(self.files)

    def __str__(self):
        """Called by str(), creates representation of object"""

        return f"Project {self.public_id}"

    def __repr__(self):
        """Called by print, creates representation of object"""

        return f"<Project {self.public_id}>"