class Master(BaseModel): """ Represents and defines a master password. """ salt: fields.Str() hash: fields.Str() def __init__(self, master): """ Configure master validation with the given master. Args: master (str): the master password. """ salt, hash = pbkdf2_hash(master) super().__init__(salt=salt, hash=hash) def is_valid(self, master): """ Check the given master with the stored hash. Args: master (str): the master password. Returns: bool: whether the master matches. """ return compare_digest(self.hash, pbkdf2_hash(master, self.salt)[1])
class Author(Model): """Contains information about an author. """ name: fields.Str() surname: fields.Str() affiliation: fields.Optional(fields.List(fields.Str())) def __init__(self, soup): """Creates an `Author` by parsing a `soup` of type `BeautifulSoup`. """ if not soup.persname: self.name = "" self.surname = "" else: self.name = text(soup.persname.forename) self.surname = text(soup.persname.surname) # TODO: better affiliation parsing. self.affiliation = list(map(text, soup.find_all("affiliation"))) def __str__(self): s = "" if self.name: s += self.name + " " if self.surname: s += self.surname return s.strip()
class Generatable(Secret): """ A generatable Secret. """ salt: fields.Str() algorithm: fields.Optional(Algorithm, default=Algorithm) def display(self): """ A display tuple for this tabulating this secret. Returns: (str, str, str): the label, the kind, and the salt. """ return super().display() + (self.salt,) def get(self): """ Generate the secret value for this Secret. Returns: str: the secret value. """ return generate( self.salt, self._pts.master_key, version=self.algorithm.version, length=self.algorithm.length, )
class Login(Generatable): """ An account login Secret. """ domain: fields.Domain() username: fields.Str() iteration: fields.Optional(fields.Int) @property def salt(self): """ The salt for this Generatable secret. Returns: str: the salt. """ return '|'.join((self.domain, self.username, str(self.iteration or 0)))
class Config(Model): # misc mode: fields.Str() log_level: fields.Str() logger_name: fields.Optional(fields.Str) sleep_interval: fields.Float(normalizers=[float]) keys_base_path: fields.Str() path_to_keys: fields.Optional(fields.Str) # Only used in tests # db stuff db_name: fields.Str() db_uri: fields.Optional(fields.Str) db_host: fields.Optional(fields.Str) db_password: fields.Optional(fields.Str) db_username: fields.Optional(fields.Str) # multisig stuff signatures_threshold: fields.Int(normalizers=[int]) signatures_threshold_eth: fields.Optional(fields.Int(normalizers=[int])) multisig_wallet_address: fields.Str() # Ethereum address multisig_acc_addr: fields.Str() # SN address multisig_key_name: fields.Str() secret_signers: fields.Str() # ethereum stuff eth_node: fields.Str() network: fields.Str() eth_start_block: fields.Int(normalizers=[int]) eth_confirmations: fields.Int(normalizers=[int]) # eth account stuff eth_address: fields.Optional(fields.Str) eth_private_key: fields.Optional(fields.Str) pkcs11_module: fields.Optional(fields.Str) token: fields.Optional(fields.Str) user_pin: fields.Optional(fields.Str) label: fields.Optional(fields.Str) # oracle stuff ethgastation_api_key: fields.Optional(fields.Str) # secret network stuff secretcli_home: fields.Str() secret_node: fields.Str() enclave_key: fields.Str() chain_id: fields.Str() scrt_swap_address: fields.Str() swap_code_hash: fields.Str() # scrt account stuff secret_key_file: fields.Str() secret_key_name: fields.Str() secret_key_password: fields.Optional(fields.Str) # warnings eth_funds_warning_threshold: fields.Float(normalizers=[float]) scrt_funds_warning_threshold: fields.Float(normalizers=[float])
class Package(Model): name = fields.Str(rename='packageName') version = fields.Nested(Version)
class User(Model): name = fields.Str(rename='username', serializers=[lambda s: s.strip()]) age = fields.Optional(fields.Int) addresses = fields.Optional(fields.List(Address))
class Address(Model): email = fields.Str()
class Article(_Article): """Represents an academic article or a reference contained in an article. The data is parsed from a TEI XML file (`from_file()`) or directly from a `BeautifulSoup` object. """ title: fields.Str() text: fields.Str() authors: fields.List(Author) year: fields.Optional(fields.Date()) references: fields.Optional(fields.List(_Article)) def __init__(self, soup, is_reference=False): """Create a new `Article` by parsing a `soup: BeautifulSoup` instance. The parameter `is_reference` specifies if the `soup` contains an entire article or just the content of a reference. """ self.title = text(soup.title) self.doi = text(soup.idno) self.abstract = text(soup.abstract) self.text = soup.text.strip() if soup.text else "" # FIXME self.year = None if is_reference: self.authors = list(map(Author, soup.find_all("author"))) self.references = [] else: self.authors = list(map(Author, soup.analytic.find_all("author"))) self.references = self._parse_biblio(soup) @staticmethod def from_file(tei_file): """Creates an `Article` by parsing a TEI XML file. """ with open(tei_file) as f: soup = BeautifulSoup(f, "lxml") return Article(soup) def _parse_biblio(self, soup): """Parses the bibliography from an article. """ references = [] # NOTE: we could do this without the regex. bibs = soup.find_all("biblstruct", {"xml:id": re.compile(r"b[0-9]*")}) for bib in bibs: if bib.analytic: references.append(Article(bib.analytic, is_reference=True)) # NOTE: in this case, bib.monogr contains more info # about the manuscript where the paper was published. # Not parsing for now. elif bib.monogr: references.append(Article(bib.monogr, is_reference=True)) else: print(f"Could not parse reference from {bib}") return references def __str__(self): return f"'{self.title}' - {' '.join(map(str, self.authors))}" def summary(self): """Prints a human-readable summary. """ print(f"Title: {self.title}") print("Authors: " + ", ".join(map(str, self.authors))) if self.references: print("References:") for r in self.references: r.summary() print("-------------------")
class Example(Model): b = fields.Str() a = fields.Int()
class Example(Model): a = fields.Str(serializers=[lambda x: x[::-1]])
class Example(Model): a = fields.Int() b = fields.Bool() c = fields.Str()
class TokenRefreshResponse(Model): access_token: str = fields.Str() refresh_token: str = fields.Str() expires_in: int = fields.Int()
class CodeExchangeResponse(Model): access_token: str = fields.Str() refresh_token: str = fields.Str() expires_in: int = fields.Int() scopes: List[str] = fields.List(fields.Str())
class Tag(Model): tag: fields.Str()
class JsonBookmark(Model): url: fields.Str() description: fields.Str() tags: fields.List(Tag)