class Subscription(db.Model): """ .. TODO:: A class docstring """ __tablename__ = 'candlepin_subscription' uuid = db.Column(db.Integer, primary_key=True) entitlement_id = db.Column(db.Integer, db.ForeignKey('candlepin_entitlement.uuid'), nullable=False) system_id = db.Column(db.String(36), db.ForeignKey('candlepin_system.uuid'), nullable=False) start_date = db.Column(db.DateTime, default=datetime.now) entitlement = db.relationship('Entitlement') system = db.relationship('System') def __init__(self, *args, **kwargs): super(Subscription, self).__init__(*args, **kwargs) uuid = generate_id() if db.session.query(Subscription).get(uuid) is not None: while db.session.query(Subscription).get(uuid) is not None: uuid = generate_id() self.uuid = uuid
class KBArticle(Translatable, db.Model): __tablename__ = 'kb_article' __translatable__ = {'locales': ['en', 'nl', 'de', 'da', 'fr']} locale = "en" _id = db.Column(db.Integer, primary_key=True) author_id = db.Column(db.Integer, db.ForeignKey('account.uuid')) @hybrid_property def votes(self): """ The total number of votes on this article. """ return db.session.query(KBVote).filter_by(article_id=self._id).count() @hybrid_property def votes_down(self): """ The number of non-positive votes on this article. """ return db.session.query(KBVote).filter_by(article_id=self._id, positive=False).count() @hybrid_property def votes_up(self): """ The number of positive votes on this article. """ return db.session.query(KBVote).filter_by(article_id=self._id, positive=True).count()
class TANToken(OTPToken, db.Model): """ Temporary Authorization Number (TAN) """ __tablename__ = 'otp_token_tan' #: The timestamp the challenge as issued. Relevant primarily for TOTP. issued = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow) phone_number = db.Column(db.Integer, nullable=False) tan = db.Column(db.Integer, nullable=False, default=-1) def __init__(self, *args, **kwargs): super(TANToken, self).__init__(*args, **kwargs) uuid = generate_id() if db.session.query(TANToken).get(uuid) is not None: while db.session.query(TANToken).get(uuid) is not None: uuid = generate_id() self.uuid = uuid
class TOTPToken(OTPToken, db.Model): """ A time-based OTP token. """ __tablename__ = 'otp_token_totp' secret = db.Column(db.String(16), nullable=False) #: The timestamp the challenge as issued. Relevant primarily for TOTP. issued = db.Column( db.DateTime, default=datetime.datetime.utcnow, nullable=False ) #: The timestamp the last (valid) TOTP as used. used = db.Column( db.DateTime, default=datetime.datetime.utcnow, nullable=False ) def __init__(self, *args, **kwargs): super(TOTPToken, self).__init__(*args, **kwargs) uuid = generate_id() if db.session.query(TOTPToken).get(uuid) is not None: while db.session.query(TOTPToken).get(uuid) is not None: uuid = generate_id() self.uuid = uuid def validate_token(self, token): """ Validate the token. """ auth = otpauth.OtpAuth(self.secret) result = auth.valid_totp(token) if result: self.used = datetime.datetime.utcnow() db.session.commit() return result def token_config_uri(self, name): """ Get the token configuration URL. """ auth = otpauth.OtpAuth(self.secret) result = auth.to_uri( 'totp', '%s:%s' % (urllib.quote(self.name), urllib.quote(name)), urllib.quote('piko') ) return result
class Group(db.Model): """ An abstract, digital representation of a group of :py:class:`Accounts <piko.db.model.Account>` or :py:class:`Persons <piko.db.model.Persons>`. A group can be a simple collection of Accounts, such that a family of "John" and "Jane" can be grouped as the "Doe Family". Both "John" and "Jane" would have accounts. """ __tablename__ = 'group' #: An automatically generated unique integer ID uuid = db.Column(db.Integer, primary_key=True) _name = db.Column(db.String(255), nullable=False) #: List of :py:class:`piko.db.model.Account` records associated #: with this :py:class:`Group`. accounts = db.relationship('Account') #: List of :py:class:`piko.db.model.Person` records associated #: with this :py:class:`Group`. persons = db.relationship('Person', secondary="person_groups", cascade="delete") def __init__(self, *args, **kwargs): """ When a group is created, assign it a unique integer ID. """ super(Group, self).__init__(*args, **kwargs) uuid = generate_id() if db.session.query(Group).get(uuid) is not None: while db.session.query(Group).get(uuid) is not None: uuid = generate_id() self.uuid = uuid @property def name(self): """ A display name such as 'Doe Family' or 'Example, Inc.'. """ return self._name @name.setter def name(self, value): self._name = value
class KBView(db.Model): __tablename__ = 'kb_view' _id = db.Column(db.Integer, primary_key=True) account_id = db.Column(db.Integer, db.ForeignKey('account.uuid', ondelete="CASCADE"), index=True) article_id = db.Column(db.Integer, db.ForeignKey('kb_article._id', ondelete="CASCADE"), index=True) article = db.relationship('KBArticle')
class Domain(db.Model): """ A domain. """ __tablename__ = "asp_domain" uuid = db.Column(db.Integer, primary_key=True) #: The namespace for this domain. namespace = db.Column(db.String(256), index=True, nullable=False) #: The state representation of the domain state = db.Column(db.Integer, default=False, nullable=False) #: Parent ID parent_id = db.Column(db.Integer, db.ForeignKey('asp_domain.uuid', ondelete='CASCADE'), nullable=True) parent = db.relationship('Domain') def __init__(self, *args, **kwargs): super(Domain, self).__init__(*args, **kwargs) uuid = generate_id() if db.session.query(Domain).get(uuid) is not None: while db.session.query(Domain).get(uuid) is not None: uuid = generate_id() self.uuid = uuid def parentdomain(self): """ Return the parent domain name space as a string, or None. """ if self.parent_id is not None: return self.parent.namespace else: return None def subdomains(self): """ Return a list of subdomains. """ return db.session.query(Domain).filter_by(parent_id=self.uuid).all()
class KBVote(db.Model): __tablename__ = 'kb_vote' _id = db.Column(db.Integer, primary_key=True) account_id = db.Column(db.Integer, db.ForeignKey('account.uuid', ondelete="CASCADE"), index=True) article_id = db.Column(db.Integer, db.ForeignKey('kb_article._id', ondelete="CASCADE"), index=True) positive = db.Column(db.Boolean, default=True, index=True) account = db.relationship('Account') article = db.relationship('KBArticle')
class Customer(db.Model): """ A customer. """ __tablename__ = 'candlepin_customer' #: The unique ID for the customer. Note that this ID cannot be predictable, #: and is generated. uuid = db.Column(db.Integer, primary_key=True) #: A name for the customer. Think along the lines of *Example, Inc.*. name = db.Column(db.String(128)) #: The date and time this customer was created -- GMT. created = db.Column(db.DateTime, default=datetime.utcnow) modified = db.Column(db.DateTime, default=datetime.utcnow) """ The date and time this customer was modified -- GMT. .. NOTE:: It should probably be linked with a 'whodunnit', and it should also be updated (automatically). """ entitlements = db.relationship('Entitlement') systems = db.relationship('System') def __init__(self, *args, **kwargs): """ Upon creation of the customer entity, ensure that the integer ID assigned to it is random as well as unique without trial and error. """ super(Customer, self).__init__(*args, **kwargs) uuid = generate_id() if db.session.query(Customer).get(uuid) is not None: while db.session.query(Customer).get(uuid) is not None: uuid = generate_id() self.uuid = uuid
class SessionTransaction(db.Model): """ A session-specific transaction. """ __tablename__ = "session_transaction" uuid = db.Column(db.String(32), primary_key=True) session_id = db.Column(db.String(32), db.ForeignKey('session.uuid', ondelete="CASCADE"), nullable=False) transaction_id = db.Column(db.String(32), nullable=False) task_id = db.Column(db.String(64), nullable=True) session = db.relationship('Session', backref='transactions') def __init__(self, *args, **kwargs): super(SessionTransaction, self).__init__(*args, **kwargs) query = db.session.query if 'uuid' in kwargs: uuid = kwargs['uuid'] else: uuid = generate_id() while query(SessionTransaction).get(uuid) is not None: uuid = generate_id() self.uuid = uuid if 'transaction_id' in kwargs: transaction_id = kwargs['transaction_id'] else: transaction_id = generate_id() while query(SessionTransaction).filter_by( transaction_id=transaction_id).first() is not None: transaction_id = generate_id() self.transaction_id = transaction_id
class Change(db.Model): """ This object represents an entry of a ChangeLog-type table. """ # __tablename__ = "changes" # Yearly # pylint: disable=eval-used # __tablename__ = eval( # '"changes_%s"' % (datetime.strftime(datetime.utcnow(), "%Y")) # ) # Monthly # pylint: disable=eval-used # __tablename__ = eval( # '"changes_%s"' % (datetime.strftime(datetime.utcnow(), "%Y_%m")) # ) # Daily # pylint: disable=eval-used __tablename__ = eval('"changes_%s"' % (datetime.strftime(datetime.utcnow(), "%Y_%m_%d"))) # Hourly # pylint: disable=eval-used # __tablename__ = eval( # '"changes_%s"' % ( # datetime.strftime(datetime.utcnow(), "%Y_%m_%d_%H") # ) # ) # Minutely # pylint: disable=eval-used # __tablename__ = eval( # '"changes_%s"' % ( # datetime.strftime(datetime.utcnow(), "%Y_%m_%d_%H_%M") # ) # ) # Secondly # pylint: disable=eval-used # __tablename__ = eval( # '"changes_%s"' % ( # datetime.strftime(datetime.utcnow(), "%Y_%m_%d_%H_%M_%S") # ) # ) uuid = db.Column(db.Integer, primary_key=True) object_name = db.Column(db.String(64)) object_id = db.Column(db.Integer) attribute_name = db.Column(db.String(64)) value_from = db.Column(db.Text, nullable=True) value_to = db.Column(db.Text, nullable=True) changed = db.Column(db.DateTime, default=datetime.utcnow) def __init__(self, *args, **kwargs): db.create_all() super(Change, self).__init__(*args, **kwargs)
class AccountLogin(db.Model): """ .. TODO:: A class docstring. """ __tablename__ = 'account_login' uuid = db.Column(db.Integer, primary_key=True) timestamp = db.Column( db.DateTime, default=datetime.datetime.utcnow, nullable=False ) success = db.Column(db.Boolean, default=False) account_id = db.Column( db.Integer, db.ForeignKey('account.uuid', ondelete="CASCADE"), nullable=True ) account = db.relationship('Account') person_id = db.Column( db.Integer, db.ForeignKey('person.uuid', ondelete="CASCADE"), nullable=True ) person = db.relationship('Person') def log_success(self, account_id): """ Log a successful login. """ pass def log_failure(self, account_id): """ Log a failed login attempt. """ pass
class OAuth2Client(db.Model): __tablename__ = 'oauth2_client' #: The Client ID. Distributed to application owners uuid = db.Column(db.String(36), primary_key=True) #: A human readable name, not required. name = db.Column(db.String(40)) #: A human readable description, not required. description = db.Column(db.String(400)) #: The secret the client application needs to use. secret = db.Column(db.String(55), unique=True, index=True, nullable=False) confidential = db.Column(db.Boolean, default=True) _redirect_uris = db.Column(db.Text) _default_scopes = db.Column(db.Text) @property def client_id(self): return self.uuid @property def client_secret(self): return self.secret @property def client_type(self): if self.confidential: return 'confidential' return 'public' @property def redirect_uris(self): if self._redirect_uris: result = self._redirect_uris.split() else: result = [] print "OAuth2Client.redirect_uris():", result return result @property def default_redirect_uri(self): if self._redirect_uris: return self.redirect_uris[0] @property def default_scopes(self): if self._default_scopes: return self._default_scopes.split() return []
class Certificate(db.Model): """ A client SSL Certificate """ __tablename__ = 'pki_certificate' id = db.Column(db.Integer, primary_key=True) cn = db.Column(db.String(36), nullable=False, index=True) certificate = db.Column(db.Text, nullable=False) private_key = db.Column(db.Text, nullable=False) not_before = db.Column(db.DateTime, nullable=True) not_after = db.Column(db.DateTime, nullable=True) def __init__(self, *args, **kwargs): super(Certificate, self).__init__(*args, **kwargs) cert = crypto.load_certificate(crypto.FILETYPE_PEM, kwargs['certificate']) self.not_before = datetime.datetime.strptime(cert.get_notBefore(), '%Y%m%d%H%M%SZ') self.not_after = datetime.datetime.strptime(cert.get_notAfter(), '%Y%m%d%H%M%SZ')
class Product(db.Model): """ A product released. """ __tablename__ = 'candlepin_product' #: The unique ID for this product uuid = db.Column(db.Integer, primary_key=True) #: A machine readable key key = db.Column(db.String(32), index=True) #: A human readable name or title name = db.Column(db.String(128)) #: The ID of a parent product ID, such as an additional opt-in repository #: with feature-specific packages that requires the base repository to be #: available as well. parent_id = db.Column( db.Integer, db.ForeignKey('candlepin_product.uuid', ondelete='CASCADE'), nullable=True ) #: End of Sales eos = db.Column(db.DateTime) #: End of Life eol = db.Column(db.DateTime) #: Proxy to the entitlements associated with this product. entitlements = db.relationship('Entitlement')
class OAuth2Token(db.Model): """ An OAuth2 Token """ __tablename__ = 'oauth2_token' uuid = db.Column(db.Integer, autoincrement=True, primary_key=True) #: Client ID, links to :py:attr:`piko.apps.oauth.db.model.Client.id` client_id = db.Column( db.String(40), db.ForeignKey('oauth2_client.uuid'), nullable=False ) client = db.relationship('OAuth2Client') account_id = db.Column( db.Integer, db.ForeignKey('account.uuid') ) account = db.relationship('Account') # currently only bearer is supported token_type = db.Column(db.String(40)) access_token = db.Column(db.String(255), unique=True) refresh_token = db.Column(db.String(255), unique=True) expires = db.Column(db.DateTime) _scopes = db.Column(db.Text) def delete(self): """ Remove this token. """ db.session.delete(self) db.session.commit() return self @property def scopes(self): """ Return the scopes this token is valid for. """ if self._scopes: return self._scopes.split() return []
class KBArticleLocale(translation_base(KBArticle)): __tablename__ = 'kb_article_i18n' translator_id = db.Column(db.Integer, db.ForeignKey('account.uuid')) title = db.Column(db.Unicode(120), nullable=False) href = db.Column(db.String(120), nullable=False) description = db.Column(db.Unicode(512), nullable=False) teaser = db.Column(db.UnicodeText, nullable=False) content = db.Column(db.UnicodeText, nullable=False)
class HOTPToken(OTPToken, db.Model): __tablename__ = 'otp_token_hotp' secret = db.Column(db.String(16), nullable=False) #: The counter counter = db.Column(db.Integer, default=1, nullable=False) def __init__(self, *args, **kwargs): super(HOTPToken, self).__init__(*args, **kwargs) uuid = generate_id() if db.session.query(HOTPToken).get(uuid) is not None: while db.session.query(HOTPToken).get(uuid) is not None: uuid = generate_id() self.uuid = uuid def validate_token(self, token): auth = otpauth.OtpAuth(self.secret) result = auth.valid_hotp(token, last=self.counter) if not result: return False self.counter = result db.session.commit() return True def token_config_uri(self, name): auth = otpauth.OtpAuth(self.secret) result = auth.to_uri('hotp', '%s:%s' % (urllib.quote(self.name), urllib.quote(name)), urllib.quote('Kolab Now'), counter=self.counter) return result
class System(db.Model): """ .. TODO:: A class docstring. """ __tablename__ = 'candlepin_system' uuid = db.Column(db.String(36), primary_key=True) customer_id = db.Column( db.Integer, db.ForeignKey('candlepin_customer.uuid', ondelete='CASCADE')) customer = db.relationship('Customer') def __init__(self, *args, **kwargs): super(System, self).__init__(*args, **kwargs) uuid = generate_uuid() if db.session.query(System).get(uuid) is not None: while db.session.query(System).get(uuid) is not None: uuid = generate_uuid() self.uuid = uuid
class OAuth2Grant(db.Model): """ A grant. """ __tablename__ = 'oauth2_grant' uuid = db.Column(db.Integer, primary_key=True) account_id = db.Column(db.Integer, db.ForeignKey('account.uuid', ondelete='CASCADE')) account = db.relationship('Account') client_id = db.Column(db.String(40), db.ForeignKey('oauth2_client.uuid'), nullable=False) client = db.relationship('OAuth2Client') code = db.Column(db.String(255), index=True, nullable=False) redirect_uri = db.Column(db.String(255)) expires = db.Column(db.DateTime) _scopes = db.Column(db.Text) def delete(self): """ .. TODO:: A docstring. """ db.session.delete(self) db.session.commit() return self @property def user(self): """ A proxy to ``self.account`` """ return self.account @property def scopes(self): """ .. TODO:: A docstring. """ if self._scopes: return self._scopes.split() return []
class Entitlement(db.Model): """ An entitlement for a customer """ __tablename__ = 'candlepin_entitlement' #: The ID for the entitlement uuid = db.Column(db.Integer, primary_key=True) #: The ID of the customer this entitlement is associated with. customer_id = db.Column( db.Integer, db.ForeignKey('candlepin_customer.uuid', ondelete='CASCADE'), nullable=False ) #: The product ID this entitlement allows the customer to install, #: if any one particular product in particular. product_id = db.Column( db.Integer, db.ForeignKey('candlepin_product.uuid', ondelete='CASCADE'), nullable=True ) #: The quantity quantity = db.Column(db.Integer, default=-1) #: The start date of the entitlement start_date = db.Column( db.DateTime, default=datetime.utcnow, nullable=False ) #: Validity ends this many days after the start date end_date = db.Column( db.DateTime, default=in_two_months, nullable=False ) #: Proxy attribute customer = db.relationship('Customer') def __init__(self, *args, **kwargs): super(Entitlement, self).__init__(*args, **kwargs) uuid = generate_id() if db.session.query(Entitlement).get(uuid) is not None: while db.session.query(Entitlement).get(uuid) is not None: uuid = generate_id() self.uuid = uuid
class Role(db.Model): """ A role. """ __tablename__ = "role" uuid = db.Column(db.Integer, primary_key=True) key = db.Column(db.String(16), nullable=False) name = db.Column(db.String(64), nullable=False) description = db.Column(db.Text, default='This role has no description set.') ldap_role = db.Column(db.Boolean, default=False) ldap_role_dn = db.Column(db.String(256), nullable=True, default=None)
def account_id(cls): return db.Column(db.Integer, db.ForeignKey('account.uuid', ondelete="CASCADE"))
def uuid(cls): return db.Column(db.Integer, primary_key=True)
def name(cls): return db.Column(db.Unicode(64))
def type_name(cls): return db.Column(db.Enum('hotp', 'tan', 'totp'), default='totp', nullable=False)
def confirmed(cls): return db.Column(db.Boolean, default=False)
""" .. TODO:: A module docstring. """ from piko.db import db # pylint: disable=invalid-name person_groups_t = db.Table( 'person_groups', db.Column('person_id', db.Integer, db.ForeignKey('person.uuid')), db.Column('group_id', db.Integer, db.ForeignKey('group.uuid')))
""" .. TODO:: A module docstring. """ from piko.db import db # pylint: disable=invalid-name account_roles_t = db.Table( 'account_roles', db.Column('account_id', db.Integer, db.ForeignKey('account.uuid')), db.Column('role_id', db.Integer, db.ForeignKey('role.uuid')) )
def person_id(cls): return db.Column(db.Integer, db.ForeignKey('person.uuid', ondelete="CASCADE"))