예제 #1
0
class PageList(db.Model):
    """Represent association between page and list."""

    __versioned__ = {}

    __tablename__ = 'pages_pagelist'

    id = db.Column(db.Integer,
                   nullable=False,
                   primary_key=True,
                   autoincrement=True)
    """PageList identifier."""

    list_id = db.Column(db.Integer, db.ForeignKey(Page.id), nullable=False)
    """Id of a list."""

    page_id = db.Column(db.Integer, db.ForeignKey(Page.id), nullable=False)
    """Id of a page."""

    order = db.Column(db.Integer, nullable=False)

    list = db.relationship(Page,
                           backref=db.backref("pages",
                                              cascade="all, delete-orphan"),
                           foreign_keys=[list_id])
    """Relation to the list."""

    page = db.relationship(Page,
                           backref=db.backref("lists",
                                              cascade="all, delete-orphan"),
                           foreign_keys=[page_id])
    """Relation to the page."""
예제 #2
0
class FlowAction(db.Model, TimestampMixin):
    """Action list belong to Flow."""

    __tablename__ = 'workflow_flow_action'

    id = db.Column(db.Integer(),
                   nullable=False,
                   primary_key=True,
                   autoincrement=True)
    """FlowAction identifier."""

    flow_id = db.Column(UUIDType,
                        db.ForeignKey(FlowDefine.flow_id),
                        nullable=False,
                        unique=False,
                        index=True)
    """the id of flow."""

    action_id = db.Column(db.Integer(),
                          db.ForeignKey(Action.id),
                          nullable=False,
                          unique=False)
    """the id of action."""

    action_version = db.Column(db.String(64), nullable=True)
    """the version of used action."""

    action_order = db.Column(db.Integer(), nullable=False, unique=False)
    """the order of action."""

    action_condition = db.Column(db.String(255), nullable=True, unique=False)
    """the condition of transition."""

    TATUSPOLICY = [
        (AvailableStautsPolicy.USABLE,
         AvailableStautsPolicy.describe(AvailableStautsPolicy.USABLE)),
        (AvailableStautsPolicy.UNUSABLE,
         AvailableStautsPolicy.describe(AvailableStautsPolicy.UNUSABLE)),
    ]
    """Subscription policy choices."""

    action_status = db.Column(ChoiceType(TATUSPOLICY, impl=db.String(1)),
                              nullable=False,
                              default=AvailableStautsPolicy.USABLE)
    """the status of flow action."""

    action_date = db.Column(db.DateTime, nullable=False, default=datetime.now)
    """the use date of action."""

    action = db.relationship(Action, backref=db.backref('flow_action'))
    """flow action relationship."""

    action_roles = db.relationship('FlowActionRole',
                                   backref=db.backref('flow_action'))
    """flow action relationship."""
예제 #3
0
class TermSources(db.Model):
    __tablename__ = 'iroko_terms_sources'

    # TODO: Esta relacion deberia hacerse con los UUIDs y no con los IDs
    term_id = db.Column(db.Integer,
                        db.ForeignKey('iroko_terms.id'),
                        primary_key=True)
    sources_id = db.Column(db.Integer,
                           db.ForeignKey('iroko_sources.id'),
                           primary_key=True)
    data = db.Column(JSONType)

    source = db.relationship("Source", backref=db.backref("term_sources"))
    term = db.relationship("Term", backref=db.backref("term_sources"))
예제 #4
0
class WorkFlow(db.Model, TimestampMixin):
    """Define WorkFlow."""

    __tablename__ = 'workflow_workflow'

    id = db.Column(db.Integer(),
                   nullable=False,
                   primary_key=True,
                   autoincrement=True)
    """Flows identifier."""

    flows_id = db.Column(UUIDType,
                         nullable=False,
                         unique=True,
                         index=True,
                         default=uuid.uuid4())
    """the id of flows."""

    flows_name = db.Column(db.String(255),
                           nullable=True,
                           unique=False,
                           index=False)
    """the name of flows."""

    itemtype_id = db.Column(db.Integer(),
                            db.ForeignKey(ItemType.id),
                            nullable=False,
                            unique=False)
    """the id of itemtype."""

    itemtype = db.relationship(ItemType,
                               backref=db.backref(
                                   'workflow',
                                   lazy='dynamic',
                                   order_by=desc('item_type.tag')))

    index_tree_id = db.Column(db.BigInteger, nullable=True, unique=False)
    """Index tree id that this workflow will belong to"""

    flow_id = db.Column(db.Integer(),
                        db.ForeignKey(FlowDefine.id),
                        nullable=False,
                        unique=False)
    """the id of flow."""

    flow_define = db.relationship(FlowDefine,
                                  backref=db.backref('workflow',
                                                     lazy='dynamic'))
class GitSnapshot(db.Model):
    """Snapshot information for a Git repo."""

    __tablename__ = 'git_snapshot'

    id = db.Column(db.Integer, primary_key=True)

    # webhook payload / event
    payload = db.Column(json_type, default={}, nullable=True)

    # git specifics
    tag = db.Column(db.String(255), nullable=True)
    ref = db.Column(db.String(255), nullable=True)

    # foreign keys (connecting to repo and events)
    webhook_id = db.Column(db.Integer,
                           db.ForeignKey(GitWebhook.id),
                           nullable=False)
    webhook = db.relationship(GitWebhook,
                              backref=db.backref("snapshots",
                                                 cascade="all, delete-orphan"))
    created = db.Column(db.DateTime, server_default=db.func.now())

    @staticmethod
    def create(webhook, data):
        snapshot = GitSnapshot(payload=data,
                               webhook_id=webhook.id,
                               tag=data['commit'].get('tag'),
                               ref=data['commit']['id'])
        db.session.add(snapshot)
        db.session.commit()
예제 #6
0
class Term(db.Model):
    __tablename__ = 'iroko_terms'

    id = db.Column(db.Integer, primary_key=True)
    uuid = db.Column(UUIDType, default=uuid.uuid4)

    identifier = db.Column(db.String, nullable=False, unique=True)
    description = db.Column(db.String)

    vocabulary_id = db.Column(db.String(),
                              db.ForeignKey('iroko_vocab.identifier',
                                            ondelete='CASCADE'),
                              nullable=False,
                              index=True)
    vocabulary = db.relationship("Vocabulary",
                                 backref=db.backref(
                                     "terms",
                                     cascade="all, delete-orphan",
                                     lazy='dynamic'))

    parent_id = db.Column(db.Integer, db.ForeignKey('iroko_terms.id'))
    children = db.relationship("Term", lazy="joined", join_depth=2)

    # any data related to the term
    data = db.Column(JSONType)

    def __str__(self):
        """Representation."""
        return self.identifier
예제 #7
0
class RecordsBuckets(db.Model):
    """Relationship between Records and Buckets."""

    __tablename__ = 'records_buckets'

    record_id = db.Column(
        UUIDType,
        db.ForeignKey(RecordMetadata.id),
        primary_key=True,
        nullable=False,
        # NOTE no unique constrain for better future ...
    )

    bucket_id = db.Column(
        UUIDType,
        db.ForeignKey(Bucket.id),
        primary_key=True,
        nullable=False,
    )

    bucket = db.relationship(Bucket)
    record = db.relationship(
        RecordMetadata,
        backref=db.backref('records_buckets', uselist=False),
        uselist=False,
    )
예제 #8
0
class ActionRoles(ActionNeedMixin, db.Model):
    """ActionRoles data model.

    It relates an allowed action with a role.
    """

    __tablename__ = 'access_actionsroles'

    __table_args__ = (UniqueConstraint('action',
                                       'exclude',
                                       'argument',
                                       'role_id',
                                       name='access_actionsroles_unique'), )

    role_id = db.Column(db.Integer(),
                        db.ForeignKey(Role.id, ondelete='CASCADE'),
                        nullable=False,
                        index=True)

    role = db.relationship("Role",
                           backref=db.backref("actionusers",
                                              cascade="all, delete-orphan"))

    @property
    def need(self):
        """Return RoleNeed instance."""
        return RoleNeed(self.role.name)
예제 #9
0
class UserActor(UserMixin, Actor):
    """An actor matching a set of users identified by ID."""

    __tablename__ = 'explicit_acls_useractor'
    __mapper_args__ = {
        'polymorphic_identity': 'user',
    }

    id = db.Column(db.String(36),
                   db.ForeignKey('explicit_acls_actor.id'),
                   primary_key=True)
    """Id maps to base class' id"""

    users = db.relationship(User,
                            secondary=users_actors,
                            lazy='subquery',
                            backref=db.backref('actors', lazy=True))

    def __str__(self):
        """Returns the string representation of the actor."""
        return 'UserActor[%s]' % self.name

    def get_elasticsearch_representation(self,
                                         another=None,
                                         record=None,
                                         **kwargs):
        """
        Returns ES representation of this Actor.

        :param another: A serialized representation of the previous Actor of the same type.
                        The implementation should merge it with its own ES representation
        :return: The elasticsearch representation of the property on Record
        """
        return list(set([x.id for x in self.users] + (another or [])))

    def user_matches(self,
                     user: Union[User, AnonymousUser],
                     context: Dict,
                     record: Record = None) -> bool:
        """
        Checks if a user is allowed to perform any operation according to the ACL.

        :param user: user being checked against the ACL
        :param context:  any extra context carrying information about the user
        """
        if user.is_anonymous:
            return False
        for x in self.users:
            if x == user:
                return True
        return False

    def get_matching_users(self, record: Record = None) -> Iterable[int]:
        """
        Returns a list of users matching this Actor.

        :return: Iterable of a user ids
        """
        return [x.id for x in self.users]
class TemplateDefinition(db.Model, object):
    """Representation of a template definition."""

    __tablename__ = 'sequencegenerator_template'

    COUNTER_REGEX = re.compile(r'({counter(!.)?(:.*)?})')
    """Regular expression matching the counter inside the template string."""

    name = db.Column(db.String(255), primary_key=True)
    """The identifier of the template definition."""

    meta_template = db.Column(db.String(255), unique=True)
    """The template generator."""

    parent_name = db.Column(
        db.ForeignKey(name,
                      name='fk_seqgen_template_parent_name_seqgen_template'))
    """Indicate that the template depends on another one."""

    start = db.Column(db.Integer, default=0)
    """The starting counter of sequences generated from ``meta_template``."""

    step = db.Column(db.Integer, default=1)
    """The incremental step of sequences generated from ``meta_template``."""

    children = db.relationship('TemplateDefinition',
                               backref=db.backref('parent', remote_side=name))

    @validates('meta_template')
    def validate_meta_template(self, key, value):
        """Validate template string of template definition."""
        if not self.COUNTER_REGEX.search(value):
            raise InvalidTemplate('No counter placeholder')
        return value

    def counter(self, **kwargs):
        """Get counter of this template definition, based on given kwargs."""
        meta_template = double_counter(self.meta_template, self.COUNTER_REGEX)
        counter = Counter.get(meta_template, kwargs)
        if counter is None:
            with db.session.begin_nested():
                counter = Counter.create(
                    meta_template=meta_template,
                    ctx=kwargs,
                    counter=self.start,
                    template_definition=self,
                )
                db.session.add(counter)

        return counter

    def __repr__(self):
        """Canonical representation of ``TemplateDefinition``."""
        return ('TemplateDefinition('
                'name={0.name!r}, '
                'meta_template={0.meta_template!r}, '
                'start={0.start!r}, '
                'step={0.step!r})').format(self)
예제 #11
0
class FlowDefine(db.Model, TimestampMixin):
    """Define Flow."""

    __tablename__ = 'workflow_flow_define'

    id = db.Column(db.Integer(),
                   nullable=False,
                   primary_key=True,
                   autoincrement=True)
    """Flow identifier."""

    flow_id = db.Column(UUIDType,
                        nullable=False,
                        unique=True,
                        index=True,
                        default=uuid.uuid4())
    """the id of flow."""

    flow_name = db.Column(db.String(255),
                          nullable=True,
                          unique=True,
                          index=True)
    """the name of flow."""

    flow_user = db.Column(db.Integer(),
                          db.ForeignKey(User.id),
                          nullable=True,
                          unique=False)
    """the user who update the flow."""

    user_profile = db.relationship(User)
    """User relationship"""

    FLOWSTATUSPOLICY = [
        (FlowStatusPolicy.AVAILABLE,
         FlowStatusPolicy.describe(FlowStatusPolicy.AVAILABLE)),
        (FlowStatusPolicy.INUSE,
         FlowStatusPolicy.describe(FlowStatusPolicy.INUSE)),
        (FlowStatusPolicy.MAKING,
         FlowStatusPolicy.describe(FlowStatusPolicy.MAKING)),
    ]
    """Subscription policy choices."""

    flow_status = db.Column(ChoiceType(FLOWSTATUSPOLICY, impl=db.String(1)),
                            nullable=False,
                            default=FlowStatusPolicy.MAKING,
                            info=dict(
                                label=_('Subscription Policy'),
                                widget=RadioGroupWidget(
                                    FlowStatusPolicy.descriptions),
                            ))
    """the status of flow."""

    flow_actions = db.relationship('FlowAction', backref=db.backref('flow'))
    """flow action relationship."""
예제 #12
0
class GitWebhookSubscriber(db.Model):
    """Records subscribed to the git repository events."""

    __tablename__ = 'git_subscriber'
    __table_args__ = db.UniqueConstraint(
        'record_id',
        'webhook_id',
        name='uq_git_webhook_subscriber_unique_constraint'),

    id = db.Column(db.Integer, primary_key=True)

    status = db.Column(db.Enum('active', 'deleted', name='git_webhook_status'),
                       nullable=False,
                       default='active')

    record_id = db.Column(UUIDType,
                          db.ForeignKey(RecordMetadata.id),
                          nullable=False)
    record = db.relationship(RecordMetadata,
                             backref=db.backref("webhooks",
                                                cascade="all, delete-orphan"))

    webhook_id = db.Column(db.Integer,
                           db.ForeignKey(GitWebhook.id),
                           nullable=False)
    webhook = db.relationship(GitWebhook,
                              backref=db.backref("subscribers",
                                                 cascade="all, delete-orphan"))

    user_id = db.Column(db.Integer, db.ForeignKey(User.id), nullable=False)
    user = db.relationship(User)

    snapshots = db.relationship(GitSnapshot,
                                order_by="desc(GitSnapshot.created)",
                                secondary='git_subscriber_snapshots')

    @property
    def repo(self):
        return self.webhook.repo
예제 #13
0
class User(db.Model, UserMixin):
    """User data model."""

    __tablename__ = "accounts_user"

    id = db.Column(db.Integer, primary_key=True)

    email = db.Column(db.String(255), unique=True)
    """User email."""

    password = db.Column(db.String(255))
    """User password."""

    active = db.Column(db.Boolean(name='active'))
    """Flag to say if the user is active or not ."""

    confirmed_at = db.Column(db.DateTime)
    """When the user confirmed the email address."""

    last_login_at = db.Column(db.DateTime)
    """When the user logged-in for the last time."""

    current_login_at = db.Column(db.DateTime)
    """When user logged into the current session."""

    last_login_ip = db.Column(IPAddressType, nullable=True)
    """Last user IP address."""

    current_login_ip = db.Column(IPAddressType, nullable=True)
    """Current user IP address."""

    login_count = db.Column(db.Integer)
    """Count how many times the user logged in."""

    roles = db.relationship('Role',
                            secondary=userrole,
                            backref=db.backref('users', lazy='dynamic'))
    """List of the user's roles."""
    @validates('last_login_ip', 'current_login_ip')
    def validate_ip(self, key, value):
        """Hack untrackable IP addresses."""
        # NOTE Flask-Security stores 'untrackable' value to IPAddressType
        #      field. This incorrect value causes ValueError on loading
        #      user object.
        if value == 'untrackable':  # pragma: no cover
            value = None
        return value

    def __str__(self):
        """Representation."""
        return 'User <id={0.id}, email={0.email}>'.format(self)
예제 #14
0
class PropertyValue(db.Model, Timestamp):
    """Property and Value match to be used in Property based ACL queries."""

    __tablename__ = 'explicit_acls_propertyvalue'

    #
    # Fields
    #
    id = db.Column(db.String(36), default=gen_uuid_key, primary_key=True)
    """Primary key."""

    acl_id = db.Column(
        db.ForeignKey('explicit_acls_propertyvalueacl.id',
                      name='fk_explicit_acls_propertyvalue_acl_id'))
    acl = db.relationship('PropertyValueACL', back_populates='property_values')

    name = db.Column(db.String(64))
    """Name of the property in elasticsearch."""

    value = db.Column(db.String(128))
    """Value of the property in elasticsearch."""

    match_operation = db.Column(ChoiceType(MatchOperation,
                                           impl=db.String(length=10)),
                                default=MatchOperation.term)
    """Property value matching mode: can be either term or match."""

    bool_operation = db.Column(ChoiceType(BoolOperation,
                                          impl=db.String(length=10)),
                               default=BoolOperation.must)
    """Bool filter operation mode this property belongs to."""

    originator_id = db.Column(db.ForeignKey(
        User.id,
        ondelete='CASCADE',
    ),
                              nullable=False,
                              index=True)
    originator = db.relationship(User,
                                 backref=db.backref("authored_properties"))
    """The originator (person that last time modified the Property)"""
    def __str__(self):
        """Returns string representation of the class."""
        return '%s: %s(%s=%s)' % (
            self.bool_operation,
            self.match_operation,
            self.name,
            self.value,
        )
class GitWebhook(db.Model):
    """Webook for a Git repository."""

    __tablename__ = 'git_webhook'
    __table_args__ = db.UniqueConstraint(
        'event_type', 'repo_id', name='uq_git_webhook_unique_constraint'),

    id = db.Column(db.Integer, primary_key=True)
    event_type = db.Column(db.String(255), nullable=False)

    external_id = db.Column(db.String(255), nullable=False)
    secret = db.Column(db.String(32), nullable=True)

    repo_id = db.Column(db.Integer, db.ForeignKey(GitRepository.id))
    repo = db.relationship(GitRepository,
                           backref=db.backref("webhooks",
                                              cascade="all, delete-orphan"))
예제 #16
0
class GitSnapshot(db.Model):
    """Snapshot information for a Git repo."""

    __tablename__ = 'git_snapshot'

    id = db.Column(db.Integer, primary_key=True)

    # webhook payload / event
    payload = db.Column(json_type, default={}, nullable=True)

    webhook_id = db.Column(db.Integer,
                           db.ForeignKey(GitWebhook.id),
                           nullable=False)
    webhook = db.relationship(GitWebhook,
                              backref=db.backref("snapshots",
                                                 cascade="all, delete-orphan"))

    created = db.Column(db.DateTime, default=datetime.utcnow)
예제 #17
0
class User(db.Model, UserMixin):
    """User data model."""

    __tablename__ = "accounts_user"

    id = db.Column(db.Integer, primary_key=True)

    email = db.Column(db.String(255), unique=True)

    password = db.Column(db.String(255))

    active = db.Column(db.Boolean)

    confirmed_at = db.Column(db.DateTime)

    last_login_at = db.Column(db.DateTime)

    current_login_at = db.Column(db.DateTime)

    last_login_ip = db.Column(IPAddressType, nullable=True)

    current_login_ip = db.Column(IPAddressType, nullable=True)

    login_count = db.Column(db.Integer)

    roles = db.relationship('Role',
                            secondary=userrole,
                            backref=db.backref('users', lazy='dynamic'))

    @validates('last_login_ip', 'current_login_ip')
    def validate_ip(self, key, value):
        """Hack untrackable IP addresses."""
        # NOTE Flask-Security stores 'untrackable' value to IPAddressType
        #      field. This incorrect value causes ValueError on loading
        #      user object.
        if value == 'untrackable':  # pragma: no cover
            value = None
        return value

    def __str__(self):
        """Representation."""
        return 'User <id={0.id}, email={0.email}>'.format(self)
예제 #18
0
class Notification(db.Model):
    """Define a Notification"""

    __tablename__ = 'iroko_notification'

    id = db.Column(db.Integer, primary_key=True)
    classification = db.Column(db.Enum(NotificationType))
    description = db.Column(db.String)
    emiter = db.Column(db.String)
    viewed = db.Column(db.Boolean, default=False)
    receiver_id = db.Column(
        db.Integer,
        db.ForeignKey(User.id, name='fk_iroko_notifications_user_id'))

    receiver = db.relationship(User,
                               backref=db.backref(
                                   'notifications',
                                   cascade='all, delete-orphan'))
    # any data related to the notification
    data = db.Column(JSONType)
예제 #19
0
class ActivityHistory(db.Model, TimestampMixin):
    """Define ActivityHistory."""

    __tablename__ = 'workflow_action_history'

    id = db.Column(db.Integer(),
                   nullable=False,
                   primary_key=True,
                   autoincrement=True)
    """ActivityHistory identifier."""

    activity_id = db.Column(db.String(24),
                            nullable=False,
                            unique=False,
                            index=True)
    """activity id of Activity."""

    action_id = db.Column(db.Integer(), nullable=False, unique=False)
    """action id."""

    action_version = db.Column(db.String(24), nullable=True, unique=False)
    """the used version of action."""

    action_status = db.Column(db.String(1),
                              db.ForeignKey(ActionStatus.action_status_id),
                              nullable=True)
    """the status description of action."""

    action_user = db.Column(db.Integer(),
                            db.ForeignKey(User.id),
                            nullable=True)
    """the user of operate action."""

    action_date = db.Column(db.DateTime, nullable=False, default=datetime.now)
    """the date of operate action."""

    action_comment = db.Column(db.Text, nullable=True)
    """action comment."""

    user = db.relationship(User, backref=db.backref('activity_history'))
    """User relaionship."""
예제 #20
0
class HarvestedItem(db.Model):
    """The items harvested from a repository"""

    __tablename__ = 'iroko_harvest_items'
    __table_args__ = (db.UniqueConstraint(
        'source_uuid',
        'identifier',
        name='identifier_in_repository'
        ),
        )
    id = db.Column(db.Integer, primary_key=True)

    source_uuid = db.Column(
        UUIDType,
        db.ForeignKey(
            'iroko_source_repositories'
            '.source_uuid', ondelete='CASCADE'
            ),
        nullable=False, index=True
        )
    repository = db.relationship(
        "Repository", backref=db.backref(
            'harvested_items'
            )
        )

    """identifier in the repo"""
    identifier = db.Column(db.String, nullable=False)

    # el uuid del iroko record asociado
    record = db.Column(UUIDType, nullable=True)

    status = db.Column(db.Enum(HarvestedItemStatus))
    error_log = db.Column(db.String)

    data = db.Column(JSONType)
    """Any other relevant data to be used in the future could be here."""

    def __str__(self):
        """Representation."""
        return self.identifier
예제 #21
0
class Comment(db.Model, Timestamp):
    """Comment in a request."""

    __tablename__ = 'requests_comment'

    id = db.Column(
        UUIDType,
        default=uuid.uuid4,
        primary_key=True,
    )

    request_id = db.Column(
        UUIDType,
        db.ForeignKey(Request.id, ondelete="CASCADE"),
        nullable=False,
    )

    created_by = db.Column(db.Integer, db.ForeignKey(User.id), nullable=False)

    message = db.Column(db.Text)

    request = db.relationship(
        Request,
        backref=db.backref(
            'comments',
            cascade='all, delete-orphan',
            passive_deletes=True,
        ),
    )

    @classmethod
    def create(cls, request_id, created_by, message):
        with db.session.begin_nested():
            obj = cls(
                request_id=request_id,
                created_by=created_by,
                message=message,
            )
            db.session.add(obj)
        return obj
예제 #22
0
파일: models.py 프로젝트: weko3-dev35/weko
class UserProfile(db.Model):
    """User profile model.

    Stores a username, display name (case sensitive version of username) and a
    full name for a user.
    """

    __tablename__ = 'userprofiles_userprofile'

    user_id = db.Column(db.Integer, db.ForeignKey(User.id), primary_key=True)
    """Foreign key to :class:`~invenio_accounts.models.User`."""

    user = db.relationship(User,
                           backref=db.backref('profile',
                                              uselist=False,
                                              cascade='all, delete-orphan'))
    """User relationship."""

    _username = db.Column('username', db.String(255), unique=True)
    """Lower-case version of username to assert uniqueness."""

    _displayname = db.Column('displayname', db.String(255))
    """Case preserving version of username."""

    fullname = db.Column(db.String(100), nullable=False, default='')
    """Full name of person."""

    timezone = db.Column(db.String(255), nullable=False, default='')
    """Selected timezone."""

    language = db.Column(db.String(255), nullable=False, default='')
    """Selected language."""
    """University / Institution"""
    university = db.Column('university', db.String(100))
    """Affiliation department / Department"""
    department = db.Column('department', db.String(100))
    """Position"""
    position = db.Column('position', db.String(100))
    """Position"""
    otherPosition = db.Column('otherPosition', db.String(100))
    """Phone number"""
    phoneNumber = db.Column('phoneNumber', db.String(15))
    """Affiliation institute name 1"""
    """Affiliation institute name (n)"""
    instituteName = db.Column('instituteName', db.String(100))
    """Affiliation institute position (n)"""
    institutePosition = db.Column('institutePosition', db.String(255))
    """Affiliation institute name 2"""
    """Affiliation institute name (n)"""
    instituteName2 = db.Column('instituteName2', db.String(100))
    """Affiliation institute position (n)"""
    institutePosition2 = db.Column('institutePosition2', db.String(255))
    """Affiliation institute name 3"""
    """Affiliation institute name (n)"""
    instituteName3 = db.Column('instituteName3', db.String(100))
    """Affiliation institute position (n)"""
    institutePosition3 = db.Column('institutePosition3', db.String(255))
    """Affiliation institute name 4"""
    """Affiliation institute name (n)"""
    instituteName4 = db.Column('instituteName4', db.String(100))
    """Affiliation institute position (n)"""
    institutePosition4 = db.Column('institutePosition4', db.String(255))
    """Affiliation institute name 5"""
    """Affiliation institute name (n)"""
    instituteName5 = db.Column('instituteName5', db.String(100))
    """Affiliation institute position (n)"""
    institutePosition5 = db.Column('institutePosition5', db.String(255))

    @hybrid_property
    def username(self):
        """Get username."""
        return self._displayname

    @hybrid_property
    def get_username(self):
        """Get username."""
        return self._username

    @username.setter
    def username(self, username):
        """Set username.

        .. note:: The username will be converted to lowercase. The display name
            will contain the original version.
        """
        validate_username(username)
        self._username = username.lower()
        self._displayname = username

    @classmethod
    def get_by_username(cls, username):
        """Get profile by username.

        :param username: A username to query for (case insensitive).
        """
        return cls.query.filter(
            UserProfile._username == username.lower()).one()

    @classmethod
    def get_by_userid(cls, user_id):
        """Get profile by user identifier.

        :param user_id: Identifier of a :class:`~invenio_accounts.models.User`.
        :returns: A :class:`~invenio_userprofiles.models.UserProfile` instance
            or ``None``.
        """
        return cls.query.filter_by(user_id=user_id).one_or_none()

    @property
    def is_anonymous(self):
        """Return whether this UserProfile is anonymous."""
        return False

    def get_institute_data(self):
        """Get institute data.

        :return:
        """
        institute_dict = {
            1: {
                'subitem_affiliated_institution_name': self.instituteName,
                'subitem_affiliated_institution_position':
                self.institutePosition
            },
            2: {
                'subitem_affiliated_institution_name': self.instituteName2,
                'subitem_affiliated_institution_position':
                self.institutePosition2
            },
            3: {
                'subitem_affiliated_institution_name': self.instituteName3,
                'subitem_affiliated_institution_position':
                self.institutePosition3
            },
            4: {
                'subitem_affiliated_institution_name': self.instituteName4,
                'subitem_affiliated_institution_position':
                self.institutePosition4
            },
            5: {
                'subitem_affiliated_institution_name': self.instituteName5,
                'subitem_affiliated_institution_position':
                self.institutePosition5
            }
        }
        return institute_dict
예제 #23
0
class RoleActor(RoleMixin, Actor):
    """An actor matching set of invenio roles."""

    __tablename__ = 'explicit_acls_roleactor'
    __mapper_args__ = {
        'polymorphic_identity': 'role',
    }

    id = db.Column(db.String(36),
                   db.ForeignKey('explicit_acls_actor.id'),
                   primary_key=True)
    """Id maps to base class' id"""

    roles = db.relationship(Role,
                            secondary=roles_actors,
                            lazy='subquery',
                            backref=db.backref('actors', lazy=True))

    def __str__(self):
        """Returns the string representation of the actor."""
        return 'RoleActor[%s]' % self.name

    def get_elasticsearch_representation(self,
                                         others=None,
                                         record=None,
                                         **kwargs):
        """
        Returns ES representation of this Actor.

        :param another: A serialized representation of the previous Actor of the same type.
                        The implementation should merge it with its own ES representation
        :return: The elasticsearch representation of the property on Record
        """
        return list(set([x.id for x in self.roles] + (others or [])))

    def user_matches(self,
                     user: User,
                     context: Dict,
                     record: Record = None) -> bool:
        """
        Checks if a user is allowed to perform any operation according to the ACL.

        :param user: user being checked against the ACL
        :param context:  any extra context carrying information about the user
        """
        role_ids = set(x.id for x in self.roles)
        for role in user.roles:
            if role.id in role_ids:
                return True
        return False

    def get_matching_users(self, record: Record = None) -> Iterable[int]:
        """
        Returns a list of users matching this Actor.

        :return: Iterable of a user ids
        """
        ret = set()
        for r in self.roles:
            for u in r.users:
                ret.add(u.id)
        return ret
예제 #24
0
class Activity(db.Model, TimestampMixin):
    """Define Activety."""

    __tablename__ = 'workflow_activity'

    id = db.Column(db.Integer(),
                   nullable=False,
                   primary_key=True,
                   autoincrement=True)
    """Activity identifier."""

    activity_id = db.Column(db.String(24),
                            nullable=False,
                            unique=True,
                            index=True)
    """activity id of Activity."""

    activity_name = db.Column(db.String(255),
                              nullable=True,
                              unique=False,
                              index=False)
    """activity name of Activity."""

    item_id = db.Column(UUIDType, nullable=True, unique=False, index=True)
    """item id."""

    workflow_id = db.Column(db.Integer(),
                            db.ForeignKey(WorkFlow.id),
                            nullable=False,
                            unique=False)
    """workflow id."""

    workflow = db.relationship(WorkFlow,
                               backref=db.backref('activity', lazy='dynamic'))

    workflow_status = db.Column(db.Integer(), nullable=True, unique=False)
    """workflow status."""

    flow_id = db.Column(db.Integer(),
                        db.ForeignKey(FlowDefine.id),
                        nullable=True,
                        unique=False)
    """flow id."""

    flow_define = db.relationship(FlowDefine,
                                  backref=db.backref('activity',
                                                     lazy='dynamic'))

    action_id = db.Column(db.Integer(),
                          db.ForeignKey(Action.id),
                          nullable=True,
                          unique=False)
    """action id."""

    action = db.relationship(Action,
                             backref=db.backref('activity', lazy='dynamic'))

    # action_version = db.Column(
    #     db.String(24), nullable=True, unique=False)
    # """action version."""

    action_status = db.Column(db.String(1),
                              db.ForeignKey(ActionStatus.action_status_id),
                              nullable=True,
                              unique=False)
    """action status."""

    activity_login_user = db.Column(db.Integer(),
                                    db.ForeignKey(User.id),
                                    nullable=True,
                                    unique=False)
    """the user of create activity."""

    activity_update_user = db.Column(db.Integer(),
                                     db.ForeignKey(User.id),
                                     nullable=True,
                                     unique=False)
    """the user of update activity."""

    ACTIVITYSTATUSPOLICY = [
        (ActivityStatusPolicy.ACTIVITY_BEGIN,
         ActivityStatusPolicy.describe(ActivityStatusPolicy.ACTIVITY_BEGIN)),
        (ActivityStatusPolicy.ACTIVITY_FINALLY,
         ActivityStatusPolicy.describe(ActivityStatusPolicy.ACTIVITY_FINALLY)),
        (ActivityStatusPolicy.ACTIVITY_FORCE_END,
         ActivityStatusPolicy.describe(
             ActivityStatusPolicy.ACTIVITY_FORCE_END)),
        (ActivityStatusPolicy.ACTIVITY_CANCEL,
         ActivityStatusPolicy.describe(ActivityStatusPolicy.ACTIVITY_CANCEL)),
        (ActivityStatusPolicy.ACTIVITY_MAKING,
         ActivityStatusPolicy.describe(ActivityStatusPolicy.ACTIVITY_MAKING)),
        (ActivityStatusPolicy.ACTIVITY_ERROR,
         ActivityStatusPolicy.describe(ActivityStatusPolicy.ACTIVITY_ERROR)),
    ]
    """Subscription policy choices."""

    activity_status = db.Column(ChoiceType(ACTIVITYSTATUSPOLICY,
                                           impl=db.String(1)),
                                default=ActivityStatusPolicy.ACTIVITY_BEGIN,
                                nullable=True,
                                unique=False,
                                index=False)
    """activity status."""

    activity_start = db.Column(db.DateTime, nullable=False)
    """activity start date."""

    activity_end = db.Column(db.DateTime, nullable=True)
    """activity end date."""

    activity_community_id = db.Column(db.Text, nullable=True)
    """activity community id"""
예제 #25
0
class Token(db.Model):
    """A bearer token is the final token that can be used by the client."""

    __tablename__ = 'oauth2TOKEN'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    """Object ID."""

    client_id = db.Column(
        db.String(255),
        db.ForeignKey(Client.client_id),
        nullable=False,
    )
    """Foreign key to client application."""

    client = db.relationship('Client',
                             backref=db.backref('oauth2tokens',
                                                cascade="all, delete-orphan"))
    """SQLAlchemy relationship to client application."""

    user_id = db.Column(db.Integer, db.ForeignKey(User.id), nullable=True)
    """Foreign key to user."""

    user = db.relationship(User,
                           backref=db.backref(
                               "oauth2tokens",
                               cascade="all, delete-orphan",
                           ))
    """SQLAlchemy relationship to user."""

    token_type = db.Column(db.String(255), default='bearer')
    """Token type - only bearer is supported at the moment."""

    access_token = db.Column(String255EncryptedType(type_in=db.String(255),
                                                    key=secret_key),
                             unique=True)

    refresh_token = db.Column(String255EncryptedType(type_in=db.String(255),
                                                     key=secret_key,
                                                     engine=NoneAesEngine),
                              unique=True,
                              nullable=True)

    expires = db.Column(db.DateTime, nullable=True)

    _scopes = db.Column(db.Text)

    is_personal = db.Column(db.Boolean, default=False)
    """Personal accesss token."""

    is_internal = db.Column(db.Boolean, default=False)
    """Determines if token is an internally generated token."""
    @property
    def scopes(self):
        """Return all scopes."""
        if self._scopes:
            return self._scopes.split()
        return []

    @scopes.setter
    def scopes(self, scopes):
        """Set scopes."""
        validate_scopes(scopes)
        self._scopes = " ".join(set(scopes)) if scopes else ""

    def get_visible_scopes(self):
        """Get list of non-internal scopes for token."""
        return [
            k for k, s in current_oauth2server.scope_choices()
            if k in self.scopes
        ]

    @classmethod
    def create_personal(cls, name, user_id, scopes=None, is_internal=False):
        """Create a personal access token.

        A token that is bound to a specific user and which doesn't expire, i.e.
        similar to the concept of an API key.
        """
        with db.session.begin_nested():
            scopes = " ".join(scopes) if scopes else ""

            c = Client(name=name,
                       user_id=user_id,
                       is_internal=True,
                       is_confidential=False,
                       _default_scopes=scopes)
            c.gen_salt()

            t = Token(
                client_id=c.client_id,
                user_id=user_id,
                access_token=gen_salt(
                    current_app.config.get('OAUTH2_TOKEN_PERSONAL_SALT_LEN')),
                expires=None,
                _scopes=scopes,
                is_personal=True,
                is_internal=is_internal,
            )

            db.session.add(c)
            db.session.add(t)

        return t
예제 #26
0
class ItemType(db.Model, Timestamp):
    """Represent an item type.

    The ItemType object contains a ``created`` and  a ``updated``
    properties that are automatically updated.
    """

    # Enables SQLAlchemy-Continuum versioning
    __versioned__ = {}

    __tablename__ = 'item_type'

    id = db.Column(
        db.Integer(),
        primary_key=True,
        autoincrement=True
    )
    """Identifier of item type."""

    name_id = db.Column(
        db.Integer(),
        db.ForeignKey(
            'item_type_name.id',
            name='fk_item_type_name_id'
        ),
        nullable=False
    )
    """Name identifier of item type."""

    item_type_name = db.relationship(
        'ItemTypeName',
        backref=db.backref('item_type', lazy='dynamic',
                           order_by=desc('item_type.tag'))
    )
    """Name information from ItemTypeName class."""

    schema = db.Column(
        db.JSON().with_variant(
            postgresql.JSONB(none_as_null=True),
            'postgresql',
        ).with_variant(
            JSONType(),
            'sqlite',
        ).with_variant(
            JSONType(),
            'mysql',
        ),
        default=lambda: dict(),
        nullable=True
    )
    """Store schema in JSON format. When you create a new ``item type`` the 
    ``schema`` field value should never be ``NULL``. Default value is an 
    empty dict. ``NULL`` value means that the record metadata has been 
    deleted. """

    form = db.Column(
        db.JSON().with_variant(
            postgresql.JSONB(none_as_null=True),
            'postgresql',
        ).with_variant(
            JSONType(),
            'sqlite',
        ).with_variant(
            JSONType(),
            'mysql',
        ),
        default=lambda: dict(),
        nullable=True
    )
    """Store schema form in JSON format.
    When you create a new ``item type`` the ``form`` field value should never be
    ``NULL``. Default value is an empty dict. ``NULL`` value means that the
    record metadata has been deleted.
    """

    render = db.Column(
        db.JSON().with_variant(
            postgresql.JSONB(none_as_null=True),
            'postgresql',
        ).with_variant(
            JSONType(),
            'sqlite',
        ).with_variant(
            JSONType(),
            'mysql',
        ),
        default=lambda: dict(),
        nullable=True
    )
    """Store page render information in JSON format. When you create a new 
    ``item type`` the ``render`` field value should never be ``NULL``. 
    Default value is an empty dict. ``NULL`` value means that the record 
    metadata has been deleted. """

    tag = db.Column(db.Integer, nullable=False)
    """Tag of item type."""

    version_id = db.Column(db.Integer, nullable=False)
    """Used by SQLAlchemy for optimistic concurrency control."""

    __mapper_args__ = {
        'version_id_col': version_id
    }
예제 #27
0
class UserProfile(db.Model):
    """User profile model.

    Stores a username, display name (case sensitive version of username) and a
    full name for a user.
    """

    __tablename__ = 'userprofiles_userprofile'

    user_id = db.Column(db.Integer, db.ForeignKey(User.id), primary_key=True)
    """Foreign key to :class:`~invenio_accounts.models.User`."""

    user = db.relationship(User,
                           backref=db.backref('profile',
                                              uselist=False,
                                              cascade='all, delete-orphan'))
    """User relationship."""

    _username = db.Column('username', db.String(255), unique=True)
    """Lower-case version of username to assert uniqueness."""

    _displayname = db.Column('displayname', db.String(255))
    """Case preserving version of username."""

    full_name = db.Column(db.String(255), nullable=False, default='')
    """Full name of person."""
    @hybrid_property
    def username(self):
        """Get username."""
        return self._displayname

    @username.setter
    def username(self, username):
        """Set username.

        .. note:: The username will be converted to lowercase. The display name
            will contain the original version.
        """
        validate_username(username)
        self._username = username.lower()
        self._displayname = username

    @classmethod
    def get_by_username(cls, username):
        """Get profile by username.

        :param username: A username to query for (case insensitive).
        """
        return cls.query.filter(
            UserProfile._username == username.lower()).one()

    @classmethod
    def get_by_userid(cls, user_id):
        """Get profile by user identifier.

        :param user_id: Identifier of a :class:`~invenio_accounts.models.User`.
        :returns: A :class:`~invenio_userprofiles.models.UserProfile` instance
            or ``None``.
        """
        return cls.query.filter_by(user_id=user_id).one_or_none()

    @property
    def is_anonymous(self):
        """Return whether this UserProfile is anonymous."""
        return False
예제 #28
0
class User(db.Model, Timestamp, UserMixin):
    """User data model."""

    __tablename__ = "accounts_user"

    id = db.Column(db.Integer, primary_key=True)

    email = db.Column(db.String(255), unique=True)
    """User email."""

    password = db.Column(db.String(255))
    """User password."""

    active = db.Column(db.Boolean(name='active'))
    """Flag to say if the user is active or not ."""

    confirmed_at = db.Column(db.DateTime)
    """When the user confirmed the email address."""

    roles = db.relationship('Role',
                            secondary=userrole,
                            backref=db.backref('users', lazy='dynamic'))
    """List of the user's roles."""

    # Enables SQLAlchemy version counter
    version_id = db.Column(db.Integer, nullable=False)
    """Used by SQLAlchemy for optimistic concurrency control."""

    __mapper_args__ = {"version_id_col": version_id}

    login_info = db.relationship("LoginInformation",
                                 back_populates="user",
                                 uselist=False,
                                 lazy="joined")

    def _get_login_info_attr(self, attr_name):
        if self.login_info is None:
            return None
        return getattr(self.login_info, attr_name)

    def _set_login_info_attr(self, attr_name, value):
        if self.login_info is None:
            self.login_info = LoginInformation()
        setattr(self.login_info, attr_name, value)

    @property
    def current_login_at(self):
        """When user logged into the current session."""
        return self._get_login_info_attr("current_login_at")

    @property
    def current_login_ip(self):
        """Current user IP address."""
        return self._get_login_info_attr("current_login_ip")

    @property
    def last_login_at(self):
        """When the user logged-in for the last time."""
        return self._get_login_info_attr("last_login_at")

    @property
    def last_login_ip(self):
        """Last user IP address."""
        return self._get_login_info_attr("last_login_ip")

    @property
    def login_count(self):
        """Count how many times the user logged in."""
        return self._get_login_info_attr("login_count")

    @current_login_at.setter
    def current_login_at(self, value):
        return self._set_login_info_attr("current_login_at", value)

    @current_login_ip.setter
    def current_login_ip(self, value):
        return self._set_login_info_attr("current_login_ip", value)

    @last_login_at.setter
    def last_login_at(self, value):
        return self._set_login_info_attr("last_login_at", value)

    @last_login_ip.setter
    def last_login_ip(self, value):
        return self._set_login_info_attr("last_login_ip", value)

    @login_count.setter
    def login_count(self, value):
        return self._set_login_info_attr("login_count", value)

    def __str__(self):
        """Representation."""
        return 'User <id={0.id}, email={0.email}>'.format(self)
예제 #29
0
class Counter(db.Model):
    """Stores generated identifiers."""

    __tablename__ = 'sequencegenerator_counter'

    template_instance = db.Column(db.String(255),
                                  nullable=False,
                                  primary_key=True,
                                  index=True)
    """The template string to use."""

    definition_name = db.Column(db.ForeignKey(TemplateDefinition.name))
    """Link to the template definition."""

    counter = db.Column(db.Integer, nullable=False)
    """Running counter."""

    template_definition = db.relationship(TemplateDefinition,
                                          lazy='joined',
                                          backref=db.backref(
                                              'counters',
                                              cascade='all, delete-orphan'))

    # Optimistic concurrency control
    __mapper_args__ = {
        'version_id_col': counter,
        'version_id_generator': False
    }

    @classmethod
    def create(cls, meta_template, ctx=None, **kwargs):
        """Initialize a counter."""
        assert 'meta_template' not in kwargs
        return cls(template_instance=meta_template.format(**ctx or {}),
                   **kwargs)

    @classmethod
    def get(cls, definition, ctx=None):
        """Get a ``Counter``."""
        return cls.query.get(definition.format(**ctx or {}))

    def increment(self):
        """Generate next identifier."""
        next_identifier = self.template_instance.format(counter=self.counter)
        with db.session.begin_nested():
            self.counter += self.template_definition.step
            return next_identifier

    def reset(self, start=0):
        """Reset counter."""
        with db.session.begin_nested():
            # Ensure no children exist
            for child in self.template_definition.children:
                if child.counters:
                    raise InvalidResetCall()

            self.counter = start

    def __repr__(self):
        """Canonical representation of ``Counter``."""
        return ('Counter('
                'template_instance={0.template_instance!r}, '
                'definition_name={0.definition_name!r}, '
                'counter={0.counter!r}, '
                'template_definition={0.template_definition!r})').format(self)
예제 #30
0
class ReanaWorkflow(db.Model):
    """Model defining a REANA workflow."""

    __tablename__ = 'reana_workflows'

    id = db.Column(UUIDType,
                   primary_key=True,
                   default=uuid.uuid4,
                   nullable=False)
    rec_uuid = db.Column(UUIDType,
                         db.ForeignKey(RecordMetadata.id),
                         nullable=False)

    user_id = db.Column(db.Integer, db.ForeignKey(User.id), nullable=False)
    workflow_id = db.Column(UUIDType, unique=True, nullable=False)

    name = db.Column(db.String(100), unique=False, nullable=False)
    workflow_name = db.Column(db.String(100), unique=False, nullable=False)
    workflow_name_run = db.Column(db.String(100), unique=False, nullable=False)

    status = db.Column(db.Enum('created',
                               'queued',
                               'running',
                               'stopped',
                               'failed',
                               'finished',
                               'deleted',
                               name='status'),
                       unique=False,
                       nullable=False)

    # the following fields represent the creation part of a workflow
    workflow_json = db.Column(json_type, default=lambda: dict(), nullable=True)

    # logging after the workflow runs
    logs = db.Column(json_type, default=lambda: dict(), nullable=True)

    created = db.Column(db.DateTime, server_default=db.func.now())
    updated = db.Column(db.DateTime,
                        server_default=db.func.now(),
                        server_onupdate=db.func.now())

    user = db.relationship('User')
    record = db.relationship('RecordMetadata',
                             backref=db.backref('reana_workflows',
                                                cascade='all, delete-orphan'))

    @classmethod
    def get_user_workflows(cls, user_id):
        """Get user workflows."""
        workflows = cls.query \
            .filter_by(user_id=user_id) \
            .all()

        return workflows

    @classmethod
    def get_deposit_workflows(cls, depid):
        """Get deposit workflows."""
        workflows = cls.query \
            .filter_by(rec_uuid=depid) \
            .all()

        return workflows

    @classmethod
    def get_workflow_by_id(cls, workflow_id):
        """Get workflow by id."""
        return cls.query \
            .filter_by(workflow_id=workflow_id) \
            .one_or_none()

    def serialize(self):
        """Serialize schema model."""
        return reana_workflow_serializer.dump(self).data