Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""LICENSE
2Copyright 2020 Hermann Krumrey <hermann@krumreyh.com>
4This file is part of stockstert.
6stockstert is free software: you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation, either version 3 of the License, or
9(at your option) any later version.
11stockstert is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
16You should have received a copy of the GNU General Public License
17along with stockstert. If not, see <http://www.gnu.org/licenses/>.
18LICENSE"""
21import time
22from typing import Dict, Any
23from stockstert.flask import db
24from stockstert.db.ModelMixin import ModelMixin
25from puffotter.crypto import verify_password
28class ApiKey(ModelMixin, db.Model):
29 """
30 Model that describes the 'api_keys' SQL table
31 An ApiKey is used for API access using HTTP basic auth
32 """
34 def __init__(self, *args, **kwargs):
35 """
36 Initializes the Model
37 :param args: The constructor arguments
38 :param kwargs: The constructor keyword arguments
39 """
40 super().__init__(*args, **kwargs)
42 MAX_AGE = 2592000 # 30 days
43 """
44 The maximum age of an API key in seconds
45 """
47 __tablename__ = "api_keys"
48 """
49 The name of the table
50 """
52 user_id = db.Column(
53 db.Integer, db.ForeignKey(
54 "users.id", onupdate="CASCADE", ondelete="CASCADE"
55 ),
56 nullable=False
57 )
58 """
59 The ID of the user associated with this API key
60 """
62 user = db.relationship(
63 "User", backref=db.backref("api_keys", lazy=True, cascade="all,delete")
64 )
65 """
66 The user associated with this API key
67 """
69 key_hash = db.Column(db.String(255), nullable=False)
70 """
71 The hash of the API key
72 """
74 creation_time = db.Column(db.Integer, nullable=False, default=time.time)
75 """
76 The time at which this API key was created as a UNIX timestamp
77 """
79 def has_expired(self) -> bool:
80 """
81 Checks if the API key has expired.
82 API Keys expire after 30 days
83 :return: True if the key has expired, False otherwise
84 """
85 return time.time() - self.creation_time > self.MAX_AGE
87 def verify_key(self, key: str) -> bool:
88 """
89 Checks if a given key is valid
90 :param key: The key to check
91 :return: True if the key is valid, False otherwise
92 """
93 try:
94 _id, api_key = key.split(":", 1)
95 if int(_id) != self.id:
96 return False
97 else:
98 return verify_password(api_key, self.key_hash)
99 except ValueError:
100 return False
102 def __json__(self, include_children: bool = False) -> Dict[str, Any]:
103 """
104 Generates a dictionary containing the information of this model
105 :param include_children: Specifies if children data models will be
106 included or if they're limited to IDs
107 :return: A dictionary representing the model's values
108 """
109 data = {
110 "id": self.id,
111 "user_id": self.user_id,
112 "creation_time": self.creation_time
113 }
114 if include_children:
115 data["user"] = self.user.__json__(include_children)
116 return data