Exemplo n.º 1
0
class ProjectInviteKeys(db.Model):
    """
    Many-to-many association table between projects and invites.

    Primary key(s):
    - project_id
    - invite_id

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

    # Table setup
    __tablename__ = "projectinvitekeys"

    # 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_invite_keys")
    # ---
    invite_id = db.Column(db.Integer,
                          db.ForeignKey("invites.id", ondelete="CASCADE"),
                          primary_key=True)
    invite = db.relationship("Invite", back_populates="project_invite_keys")
    # ---

    # Additional columns
    key = db.Column(db.LargeBinary(300), nullable=False, unique=True)
    owner = db.Column(db.Boolean, nullable=False, default=False, unique=False)
Exemplo n.º 2
0
class ProjectUserKeys(db.Model):
    """
    Many-to-many association table between projects and users (all).

    Primary key(s):
    - project_id
    - user_id

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

    # Table setup
    __tablename__ = "projectuserkeys"

    # 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_user_keys")
    # ---
    user_id = db.Column(db.String(50),
                        db.ForeignKey("users.username", ondelete="CASCADE"),
                        primary_key=True)
    user = db.relationship("User", back_populates="project_user_keys")
    # ---

    # Additional columns
    key = db.Column(db.LargeBinary(300), nullable=False, unique=True)
Exemplo n.º 3
0
class ProjectUsers(db.Model):
    """
    Many-to-many association table between projects and research users.

    Primary key(s):
    - project_id
    - user_id

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

    # Table setup
    __tablename__ = "projectusers"

    # Foreign keys & relationships
    project_id = db.Column(db.Integer,
                           db.ForeignKey("projects.id", ondelete="CASCADE"),
                           primary_key=True)
    project = db.relationship("Project", back_populates="researchusers")
    # ---
    user_id = db.Column(db.String(50),
                        db.ForeignKey("researchusers.username",
                                      ondelete="CASCADE"),
                        primary_key=True)
    researchuser = db.relationship("ResearchUser",
                                   back_populates="project_associations")
    # ---

    # Additional columns
    owner = db.Column(db.Boolean, nullable=False, default=False, unique=False)
Exemplo n.º 4
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}>"
Exemplo n.º 5
0
class Identifier(db.Model):
    """
    Data model for user identifiers for login.

    Elixir identifiers consists of 58 characters (40 hex + "@elixir-europe.org").

    Primary key(s):
    - username
    - identifier

    Foreign key(s):
    - username
    """

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

    # Foreign keys & relationships
    username = db.Column(db.String(50),
                         db.ForeignKey("users.username", ondelete="CASCADE"),
                         primary_key=True)
    user = db.relationship("User", back_populates="identifiers")
    # ---

    # Additional columns
    identifier = db.Column(db.String(58),
                           primary_key=True,
                           unique=True,
                           nullable=False)

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

        return f"<Identifier {self.identifier}>"
Exemplo n.º 6
0
class SuperAdmin(User):
    """
    Data model for super admin user accounts (Data Centre).

    Primary key(s):
    - username

    Foreign key(s):
    - username
    """

    __tablename__ = "superadmins"
    __mapper_args__ = {"polymorphic_identity": "superadmin"}

    # Foreign keys & relationships
    username = db.Column(db.String(50),
                         db.ForeignKey("users.username"),
                         primary_key=True)

    @property
    def role(self):
        """Get user role."""

        return "Super Admin"

    @property
    def projects(self):
        """Get list of projects: Super admins can access all projects."""

        return Project.query.all()
Exemplo n.º 7
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)
Exemplo n.º 8
0
class UnitUser(User):
    """
    Data model for unit user accounts.

    Primary key(s):
    - username

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

    __tablename__ = "unitusers"
    __mapper_args__ = {"polymorphic_identity": "unituser"}

    # Foreign keys & relationships
    username = db.Column(db.String(50),
                         db.ForeignKey("users.username", ondelete="CASCADE"),
                         primary_key=True)
    # ---
    unit_id = db.Column(db.Integer,
                        db.ForeignKey("units.id", ondelete="RESTRICT"),
                        nullable=False)
    unit = db.relationship("Unit", back_populates="users")

    # Additional columns
    is_admin = db.Column(db.Boolean, nullable=False, default=False)

    @property
    def role(self):
        """User role is Unit Admin if the unit user has admin rights."""

        if self.is_admin:
            return "Unit Admin"

        return "Unit Personnel"

    @property
    def projects(self):
        """Get the unit projects."""

        return self.unit.projects
Exemplo n.º 9
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}>"
Exemplo n.º 10
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}>"
Exemplo n.º 11
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)
Exemplo n.º 12
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}>"
Exemplo n.º 13
0
class Email(db.Model):
    """
    Data model for user email addresses.

    Primary key:
    - id

    Foreign key(s):
    - user_id
    """

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

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

    # Foreign keys & relationships
    user_id = db.Column(db.String(50),
                        db.ForeignKey("users.username", ondelete="CASCADE"),
                        nullable=False)
    user = db.relationship("User", back_populates="emails")
    # ---

    # Additional columns
    email = db.Column(db.String(254), unique=True, nullable=False)
    primary = db.Column(db.Boolean,
                        unique=False,
                        nullable=False,
                        default=False)

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

        return f"<Email {self.email}>"
Exemplo n.º 14
0
class ResearchUser(User):
    """
    Data model for research user accounts.

    Primary key(s):
    - username

    Foreign key(s):
    - username
    """

    __tablename__ = "researchusers"
    __mapper_args__ = {"polymorphic_identity": "researchuser"}

    # Foreign keys
    username = db.Column(db.String(50),
                         db.ForeignKey("users.username", ondelete="CASCADE"),
                         primary_key=True)

    # Relationships
    project_associations = db.relationship("ProjectUsers",
                                           back_populates="researchuser",
                                           passive_deletes=True,
                                           cascade="all, delete")

    @property
    def role(self):
        """Get user role."""

        return "Researcher"

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

        return [proj.project for proj in self.project_associations]
Exemplo n.º 15
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}>"