Coretex
user.py
1 # Copyright (C) 2023 Coretex LLC
2 
3 # This file is part of Coretex.ai
4 
5 # This program is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU Affero General Public License as
7 # published by the Free Software Foundation, either version 3 of the
8 # License, or (at your option) any later version.
9 
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU Affero General Public License for more details.
14 
15 # You should have received a copy of the GNU Affero General Public License
16 # along with this program. If not, see <https://www.gnu.org/licenses/>.
17 
18 from pathlib import Path
19 from typing import List, Optional, Tuple
20 from datetime import datetime, timezone
21 
22 import os
23 
24 from .base import BaseConfiguration, CONFIG_DIR
25 from ..utils import decodeDate
26 
27 
28 class UserConfiguration(BaseConfiguration):
29 
30  @classmethod
31  def getConfigPath(cls) -> Path:
32  return CONFIG_DIR / "user_config.json"
33 
34  @property
35  def username(self) -> str:
36  return self.getValue("username", str, "CTX_USERNAME")
37 
38  @username.setter
39  def username(self, value: str) -> None:
40  self._raw["username"] = value
41 
42  @property
43  def password(self) -> str:
44  return self.getValue("password", str, "CTX_PASSWORD")
45 
46  @password.setter
47  def password(self, value: str) -> None:
48  self._raw["password"] = value
49 
50  @property
51  def token(self) -> Optional[str]:
52  return self.getOptValue("token", str)
53 
54  @token.setter
55  def token(self, value: Optional[str]) -> None:
56  self._raw["token"] = value
57 
58  @property
59  def refreshToken(self) -> Optional[str]:
60  return self.getOptValue("refreshToken", str)
61 
62  @refreshToken.setter
63  def refreshToken(self, value: Optional[str]) -> None:
64  self._raw["refreshToken"] = value
65 
66  @property
67  def tokenExpirationDate(self) -> Optional[str]:
68  return self.getOptValue("tokenExpirationDate", str)
69 
70  @tokenExpirationDate.setter
71  def tokenExpirationDate(self, value: Optional[str]) -> None:
72  self._raw["tokenExpirationDate"] = value
73 
74  @property
75  def refreshTokenExpirationDate(self) -> Optional[str]:
76  return self.getOptValue("refreshTokenExpirationDate", str)
77 
78  @refreshTokenExpirationDate.setter
79  def refreshTokenExpirationDate(self, value: Optional[str]) -> None:
80  self._raw["refreshTokenExpirationDate"] = value
81 
82  @property
83  def serverUrl(self) -> str:
84  return self.getValue("serverUrl", str, "CTX_API_URL", "https://api.coretex.ai/")
85 
86  @serverUrl.setter
87  def serverUrl(self, value: str) -> None:
88  os.environ["CTX_API_URL"] = value
89  self._raw["serverUrl"] = value
90 
91  @property
92  def projectId(self) -> Optional[int]:
93  return self.getOptValue("projectId", int, "CTX_PROJECT_ID")
94 
95  @projectId.setter
96  def projectId(self, value: Optional[int]) -> None:
97  self._raw["projectId"] = value
98 
99  @property
100  def frontendUrl(self) -> str:
101  return self.getValue("frontendUrl", str, default = "app.coretex.ai")
102 
103  @frontendUrl.setter
104  def frontendUrl(self, value: Optional[str]) -> None:
105  self._raw["frontendUrl"] = value
106 
107  def _isConfigValid(self) -> Tuple[bool, List[str]]:
108  isValid = True
109  errorMessages = []
110 
111  if self._raw.get("username") is None or not isinstance(self._raw.get("username"), str):
112  isValid = False
113  errorMessages.append("Missing required field \"username\" in user configuration.")
114 
115  if self._raw.get("password") is None or not isinstance(self._raw.get("password"), str):
116  isValid = False
117  errorMessages.append("Missing required field \"password\" in user configuration.")
118 
119  return isValid, errorMessages
120 
121  def isTokenValid(self, tokenName: str) -> bool:
122  tokenValue = self._raw.get(tokenName)
123  if not isinstance(tokenValue, str) or len(tokenValue) == 0:
124  return False
125 
126  tokenExpirationDate = self._raw.get(f"{tokenName}ExpirationDate")
127  if not isinstance(tokenExpirationDate, str) or len(tokenExpirationDate) == 0:
128  return False
129 
130  try:
131  return datetime.now(timezone.utc) < decodeDate(tokenExpirationDate)
132  except ValueError:
133  return False
134 
135  def selectProject(self, id: int) -> None:
136  self.projectId = id
137  self.save()