class UserModel(ModelBase): user_id = CharField(primary_key=True) passwd_hashed = BlobField() salt = BlobField() @classmethod def create_model( cls, user_id: str, passwd_hashed: bytes, salt: bytes, ) -> UserModel: return cls.create( user_id=user_id, passwd_hashed=passwd_hashed, salt=salt, ) def update_model( self, passwd_hashed: bytes, salt: bytes, ) -> None: self.passwd_hashed = passwd_hashed self.salt = salt self.save()
class Regticket(Model): upload_code = BlobField(unique=True, null=True) regticket = BlobField() artist_pk = BlobField() image_hash = BlobField() artists_signature_ticket = BlobField() created = DateTimeField() image_data = BlobField(null=True) localfee = DecimalField(null=True) is_valid_mn0 = BooleanField(null=True) mn1_pk = BlobField(null=True) mn1_serialized_signature = BlobField(null=True) is_valid_mn1 = BooleanField(null=True) mn2_pk = BlobField(null=True) mn2_serialized_signature = BlobField(null=True) is_valid_mn2 = BooleanField(null=True) status = IntegerField(choices=REGTICKET_STATUS_CHOICES, default=REGTICKET_STATUS_CREATED) error = CharField(null=True) confirmed = BooleanField( default=False ) # track if confirmation ticket for a given regticket exists class Meta: database = MASTERNODE_DB table_name = 'regticket'
class GuildConfigChange(BaseModel): user_id = BigIntegerField(null=True) guild_id = BigIntegerField() before_raw = BlobField(null=True) after_raw = BlobField() created_at = DateTimeField(default=datetime.utcnow) class Meta: db_table = 'guild_config_changes' indexes = ( (('user_id', 'guild_id'), False), ) # TODO: dispatch guild change events def rollback_to(self): Guild.update( config_raw=self.after_raw, config=yaml.load(self.after_raw) ).where(Guild.guild_id == self.guild_id).execute() def revert(self): Guild.update( config_raw=self.before_raw, config=yaml.load(self.before_raw) ).where(Guild.guild_id == self.guild_id).execute()
class PrivateKey(BaseModel): d = BlobField() p = BlobField() q = BlobField() class Meta(BaseModel._meta.__class__): table_name = 'private_keys'
class Block(BaseModel): height = IntegerField(index=True) hash = CharField(max_length=64, unique=True, index=True) timestamp = DateTimeField(index=True) merkle_root = CharField(max_length=64, unique=True) tx = BinaryJSONField() difficulty = FloatField() size = IntegerField() version = BlobField() bits = BlobField() nonce = BigIntegerField() coinbase = BlobField() tx_count = IntegerField() orphaned = BooleanField(default=False, index=True) def to_json(self): pool = None cb = bytes(self.coinbase) for key, value in POOLS.items(): if cb.find(key.encode()) != -1: pool = value return { 'height': self.height, 'hash': self.hash, 'timestamp': int(self.timestamp.timestamp()), 'merkle_root': self.merkle_root, 'tx': self.tx, 'difficulty': self.difficulty, 'size': self.size, 'version_hex': bytes(self.version).hex(), 'version': struct.unpack('i', bytes(self.version))[0], 'bits': bytes(self.bits).hex(), 'nonce': self.nonce, 'pool': pool }
class GuildConfigChange(ModelBase): user_id = BigIntegerField(null=True) guild_id = BigIntegerField() before_raw = BlobField(null=True) after_raw = BlobField() created_at = DateTimeField(default=datetime.utcnow) class Meta: table_name = 'guild_config_changes' indexes = ((('user_id', 'guild_id'), False), ) def rollback_to(self): Guild.update(config_raw=self.after_raw, config=yaml.safe_load(self.after_raw)).where( Guild.guild_id == self.guild_id).execute() Guild.emit_update() def revert(self): Guild.update(config_raw=self.before_raw, config=yaml.safe_load(self.before_raw)).where( Guild.guild_id == self.guild_id).execute() Guild.emit_update()
class LS_DBA(Model): user_id = ForeignKeyField(User, field=User.id, backref='ls_dba') eb_dba_tpl = BlobField() ls = BlobField() threshold = FloatField() class Meta: database = db
class Mention(LongIdPostModel): who = BlobField(index=True) # 被@的用户 related_id = BlobField(index=True) # @相关对象 related_type = IntegerField(index=True) # @相关对象的类型 data = BinaryJSONField(dumps=json_ex_dumps, null=True) # 附加数据 class Meta: db_table = 'mention'
class UserToken(BaseModel): id = BlobField(primary_key=True) user_id = BlobField(index=True) time = BigIntegerField(index=True) expire = BigIntegerField(null=True) first_meet_time = BigIntegerField(null=True) ip_first_meet = INETField(default=None, null=True) # 注册IP ua_first_meet = TextField(null=True) last_access_time = BigIntegerField(null=True) ip_latest = INETField(default=None, null=True) ua_latest = TextField(null=True) class Meta: db_table = 'user_token' @classmethod def new(cls, user_id): create_time = int(time.time()) expire_time = create_time + 30 * 24 * 60 * 60 token = os.urandom(16) return UserToken.create(id=token, time=create_time, user_id=user_id, expire=expire_time) @classmethod def get_by_token(cls, token) -> Optional['UserToken']: if isinstance(token, str): try: token = to_bin(token) except binascii.Error: return t = cls.get_by_pk(token) if t and time.time() < t.expire: return t def get_token(self): return get_bytes_from_blob(self.id) async def init(self, view: AbstractSQLView): """ 从请求初始化信息 :param view: :return: """ # req = view._request self.first_meet_time = int(time.time()) self.ip_first_meet = await view.get_ip() self.ua_first_meet = view.headers.get('User-Agent', None) self.save() async def access_save(self, view: AbstractSQLView): self.last_access_time = int(time.time()) self.ip_latest = await view.get_ip() self.ua_latest = view.headers.get('User-Agent', None) self.save()
class User(BaseModel): username = CharField(unique=True) salt = BlobField() password = BlobField() email = CharField(unique=True) added_date = DateTimeField() theme = IntegerField() followers = IntegerField() level = IntegerField()
class Coin(ModelBase): Id = AutoField() TxId = BlobField() Index = IntegerField() AssetId = BlobField() Value = IntegerField() ScriptHash = BlobField() State = IntegerField() Address = ForeignKeyField(Address)
class DataTable(BaseModel): secret_ref = ForeignKeyField(SecretTable, backref="data") kdf_salt = BlobField() ciphertext = BlobField() iv = BlobField() auth_tag = BlobField() pass_phrase = BlobField() def generate_enc_msg(self): return (self.kdf_salt, self.ciphertext, self.iv, self.auth_tag)
class UserData(Blog): id = PrimaryKeyField() full_name = TextField(null=True, default=None) footer_text = TextField(null=True, default=None) blog_subtitle = TextField(null=True, default=None) tags = TextField(null=True, default=None) blog_title = TextField(null=True, default=None) password = BlobField(null=True, default=None) username = TextField(null=True, default=None) forgot_password = BlobField(null=True, default=None) email = TextField(null=True, default=None)
class Mention(LongIdPostModel): who = BlobField(index=True) # 被@的用户 loc_post_type = IntegerField() # 地点,类型 loc_post_id = BlobField() # 地点 loc_post_title = TextField(null=True) # 地点标题 related_type = IntegerField(index=True) # @相关对象的类型 related_id = BlobField(index=True) # @相关对象 data = BinaryJSONField(dumps=json_ex_dumps, null=True) # 附加数据,一般不需要了 class Meta: db_table = 'mention'
class UserToken(BaseModel): id = BlobField(primary_key=True) user_id = BlobField(index=True) time = BigIntegerField(index=True) expire = BigIntegerField(null=True) first_meet_time = BigIntegerField(null=True) ip_first_meet = INETField(default=None, null=True) # 注册IP ua_first_meet = TextField(null=True) last_access_time = BigIntegerField(null=True) ip_latest = INETField(default=None, null=True) ua_latest = TextField(null=True) @classmethod def new(cls, user_id): create_time = int(time.time()) expire_time = create_time + 30 * 24 * 60 * 60 token = os.urandom(16) return UserToken.create(id=token, time=create_time, user_id=user_id, expire=expire_time) @classmethod def get_by_token(cls, token) -> 'UserToken': t = cls.get_by_pk(token) if t and time.time() > t.expire: return t async def init(self, view: AbstractSQLView): """ 从请求初始化信息 :param view: :return: """ # req = view._request self.first_meet_time = int(time.time()) self.ip_first_meet = await view.get_ip() self.ua_first_meet = view.headers.get('User-Agent', None) self.save() async def access_save(self, view: AbstractSQLView): self.last_access_time = int(time.time()) self.ip_latest = await view.get_ip() self.ua_latest = view.headers.get('User-Agent', None) self.save()
class Address(ModelBase): Id = AutoField() ScriptHash = BlobField(unique=True) IsWatchOnly = BooleanField(default=False) def ToString(self): return Crypto.ToAddress(UInt160(data=self.ScriptHash))
class UnverifiedSignature(Model): """ Signature that is supposed to verify a post but not yet checked. The worst case scenario here is that the signature is corrupted or just made by someone else, and so we are destined to store this unverified signature forever without ability to confirm it. But that's not the only case. Maybe we just use an outdated profile database and therefore don't know yet that the user identified by `user_string` added a new public key. After we will eventually update his profile, we will revalidate all signatures that have his username and, probably, will be able to apply some of previously rejected events. If it happens, we will delete the ``UnverifiedSignature`` and save the same data as a normal :class:`Signature`. It's important that there is a small possibility that user who currently has given username has nothing to do with the user who signed the message long time ago. (This depends on a server's policy about how nicknames are managed and how users are being deleted.) That's why even if we have a user with matching the user name in our database, we must not reference them from any messages until we will find the missing public key. Only a public key can be a proof that certain user said certain things, not a username without a key. Just like :class:`Signature`, this class can contain `NULL` in :data:`post` because the :data:`event` that contained an unverified signature could easily end up being rejected and not produce a :class:`Post`. """ class Meta: table_name = 'signature_unverified' id: int = PrimaryKeyField() created: datetime = DateTimeField(default=fn.now) modified: datetime = DateTimeField(default=fn.now) event: Event = ForeignKeyField(Event) user: str = TextField() post: Union[ForeignKeyField, Post] = ForeignKeyField(Post, null=True) data: bytes = BlobField()
class Profile(BaseModel): id = AutoField(primary_key=True) name = TextField(unique=True) options = BlobField() @classmethod def from_json(cls, data: bytes) -> 'Profile': return Profile(**json.loads(data)) @property def options_dict(self) -> dict: return json.loads(self.options) def to_dict(self) -> dict: return { 'id': self.id, 'name': self.name, 'options': self.options_dict, } def to_json(self) -> bytes: return json.dumps(self.to_dict())
class MultiMean(Model): user_id = ForeignKeyField(User, field=User.id, backref='multimean') signatures = BlobField() threshold = FloatField() class Meta: database = db
class Test(IndexedBlobModel, BaseModel): # Inherited classes order matters! """Test model""" blob = BlobField() cs = ForeignKeyField(ChallengeSet, related_name='tests') job = ForeignKeyField(Job, related_name='tests') drilled = BooleanField(null=False, default=False) colorguard_traced = BooleanField(null=False, default=False) poll_created = BooleanField(null=False, default=False) sha256 = FixedCharField(max_length=64) @classmethod def unsynced_testcases(cls, prev_sync_time): """Return test cases not synced""" return cls.select().where(cls.created_at > prev_sync_time) def to_cqe_pov_xml(self): """ Method to convert job into to cqe xml format :return Xml Containing test data in CQE POV format """ pov_header = """<?xml version="1.0" standalone="no" ?> <!DOCTYPE pov SYSTEM "/usr/share/cgc-docs/replay.dtd"> """ pov = CQE_POV(str(self.cs.id), []) # pylint:disable=no-member pov.actions.append(Write([Data(self.blob)])) return pov_header + str(pov)
class TableMovies(BaseModel): rowid = RowIDField() alternativeTitles = TextField(null=True) audio_codec = TextField(null=True) audio_language = TextField(null=True) failedAttempts = TextField(null=True) fanart = TextField(null=True) ffprobe_cache = BlobField(null=True) file_size = IntegerField(default=0, null=True) format = TextField(null=True) imdbId = TextField(null=True) missing_subtitles = TextField(null=True) monitored = TextField(null=True) movie_file_id = IntegerField(null=True) overview = TextField(null=True) path = TextField(unique=True) poster = TextField(null=True) profileId = IntegerField(null=True) radarrId = IntegerField(unique=True) resolution = TextField(null=True) sceneName = TextField(null=True) sortTitle = TextField(null=True) subtitles = TextField(null=True) tags = TextField(null=True) title = TextField() tmdbId = TextField(unique=True) video_codec = TextField(null=True) year = TextField(null=True) class Meta: table_name = 'table_movies'
class TableEpisodes(BaseModel): rowid = RowIDField() audio_codec = TextField(null=True) audio_language = TextField(null=True) episode = IntegerField() episode_file_id = IntegerField(null=True) failedAttempts = TextField(null=True) ffprobe_cache = BlobField(null=True) file_size = IntegerField(default=0, null=True) format = TextField(null=True) missing_subtitles = TextField(null=True) monitored = TextField(null=True) path = TextField() resolution = TextField(null=True) scene_name = TextField(null=True) season = IntegerField() sonarrEpisodeId = IntegerField(unique=True) sonarrSeriesId = IntegerField() subtitles = TextField(null=True) title = TextField() video_codec = TextField(null=True) class Meta: table_name = 'table_episodes' primary_key = False
class Statement(BaseModel): code = ForeignKeyField(Code, backref='statements') case = ForeignKeyField(Case, backref='statements') submitted = DateTimeField(default=datetime.now, index=True) text = TextField() spacy_doc = BlobField() supervised = BooleanField()
class RawRoundTraffic(BaseModel): """ Result corresponding to the network dude """ round = ForeignKeyField(Round, related_name='raw_round_traffics') processed = BooleanField(null=False, default=False) pickled_data = BlobField()
class Setting(Model): key = CharField(primary_key=True) value = BlobField() class Meta: legacy_table_names = False database = INJECTOR.get(SqliteDatabase)
class Crash(IndexedBlobModel, BaseModel): # Inherited classes order matters! blob = BlobField(null=True) cs = ForeignKeyField(ChallengeSet, related_name='crashes') exploited = BooleanField(default=False) explored = BooleanField(default=False) job = ForeignKeyField(Job, related_name='crashes') triaged = BooleanField(null=False, default=False) kind = EnumField(choices=['unclassified', 'unknown', 'ip_overwrite', 'partial_ip_overwrite', 'uncontrolled_ip_overwrite', 'bp_overwrite', 'partial_bp_overwrite', 'write_what_where', 'write_x_where', 'uncontrolled_write', 'arbitrary_read', 'null_dereference', 'arbitrary_transmit', 'arbitrary_receive'], enum_name='enum_crash_kind', default='unclassified', null=True) crash_pc = BigIntegerField(null=True) # pc at the time of the crash bb_count = BigIntegerField(null=True) # basic block count sha256 = FixedCharField(max_length=64) class Meta: # pylint: disable=no-init,too-few-public-methods,old-style-class db_table = 'crashes'
class Upload(LongIdPostModel): id = BlobField(primary_key=True) key = TextField(index=True) size = BigIntegerField() ext = TextField(null=True) type_name = TextField(null=True, default=None) image_info = BinaryJSONField(null=True, default=None) class Meta: db_table = 'upload' @classmethod def new(cls, user_id, key, size, ext=None, type_name=None, image_info=None): # 之所以有key的情况下还有独立id,是因为上传是一个一对多的过程,多个用户可能上传同一张图片,那么key就相同 return cls.create(id=config.LONG_ID_GENERATOR().digest(), time=int(time.time()), user_id=user_id, key=key, size=int(size), ext=ext, type_name=type_name, image_info=image_info) @classmethod def get_post_type(cls): return POST_TYPES.UPLOAD
class Chunk(Model): chunk_id = CharField(unique=True) image_hash = BlobField() indexed = BooleanField( default=False ) # to track fresh added chunks, and calculate XOR distances for them. confirmed = BooleanField( default=False ) # indicates if chunk ID is contained in one of confirmed registration tickets stored = BooleanField(default=False) attempts_to_load = IntegerField(default=0) class Meta: database = MASTERNODE_DB table_name = 'chunk' @classmethod def create_from_hash(cls, chunkhash, artwork_hash, stored=False): chunkhash_int = bytes_to_chunkid(chunkhash) return Chunk.create(chunk_id=str(chunkhash_int), image_hash=artwork_hash, stored=stored) @classmethod def get_by_hash(cls, chunkhash): chunkhash_int = bytes_to_chunkid(chunkhash) return Chunk.get(chunk_id=str(chunkhash_int))
class Contract(ModelBase): Id = AutoField() RawData = CharField() ScriptHash = BlobField() PublicKeyHash = CharField() Account = ForeignKeyField(Account, null=True) Address = ForeignKeyField(Address)
class User(DBModel): name = TextField(unique=True) password_hash = BlobField() def verify(self, password: str) -> bool: """Verify the login attempt from this user Arguments: password {str} -- The password of the login attempt Returns: bool -- Whether the login was accepted """ return pwhash.verify(self.password_hash, password.encode()) def change_password(self, old_password: str, new_password: str) -> bool: """Change the user's password Arguments: old_password {str} -- The old password of the user new_password {str} -- The new password of the user Returns: bool -- Whether the password change was succesful """ if self.verify(old_password): self.password_hash = pwhash.str(new_password.encode()) with self._meta.database.atomic(): self.save() return True return False