gitscope
https://dev.kronoz.win/r/marzneshin.git
app/db/crud.py · v0.3.0-alpha5
Source
1 12b255b Dawsh 2y ago import json
2 34a7612 Dawsh 2y ago import secrets
3 f446990 Dawsh 2y ago from datetime import datetime, timedelta
4 a47eb4c Dawsh 2y ago from enum import Enum
5 2de9d72 Dawsh 2y ago from typing import List, Optional, Tuple, Union
6 a47eb4c Dawsh 2y ago
7 512d183 Mrdn 2y ago from sqlalchemy import and_, delete, update, select
8 a47eb4c Dawsh 2y ago from sqlalchemy.orm import Session
9 a47eb4c Dawsh 2y ago
10 01cdf2e Dawsh 2y ago from app.db.models import (
11 01cdf2e Dawsh 2y ago JWT,
12 01cdf2e Dawsh 2y ago TLS,
13 01cdf2e Dawsh 2y ago Admin,
14 01cdf2e Dawsh 2y ago Node,
15 01cdf2e Dawsh 2y ago NodeUsage,
16 01cdf2e Dawsh 2y ago NodeUserUsage,
17 01cdf2e Dawsh 2y ago NotificationReminder,
18 01cdf2e Dawsh 2y ago InboundHost,
19 01cdf2e Dawsh 2y ago Service,
20 01cdf2e Dawsh 2y ago Inbound,
21 01cdf2e Dawsh 2y ago System,
22 01cdf2e Dawsh 2y ago User,
23 01cdf2e Dawsh 2y ago UserUsageResetLogs,
24 01cdf2e Dawsh 2y ago )
25 a47eb4c Dawsh 2y ago from app.models.admin import AdminCreate, AdminModify, AdminPartialModify
26 01cdf2e Dawsh 2y ago from app.models.node import NodeCreate, NodeModify, NodeStatus, NodeUsageResponse
27 a47eb4c Dawsh 2y ago from app.models.proxy import InboundHost as InboundHostModify
28 2de9d72 Dawsh 2y ago from app.models.service import Service as ServiceModify, ServiceCreate
29 01cdf2e Dawsh 2y ago from app.models.user import (
30 01cdf2e Dawsh 2y ago ReminderType,
31 01cdf2e Dawsh 2y ago UserCreate,
32 01cdf2e Dawsh 2y ago UserDataLimitResetStrategy,
33 01cdf2e Dawsh 2y ago UserModify,
34 01cdf2e Dawsh 2y ago UserStatus,
35 01cdf2e Dawsh 2y ago UserUsageResponse,
36 01cdf2e Dawsh 2y ago )
37 01cdf2e Dawsh 2y ago from app.utils.helpers import calculate_expiration_days, calculate_usage_percent
38 a47eb4c Dawsh 2y ago from config import NOTIFY_DAYS_LEFT, NOTIFY_REACHED_USAGE_PERCENT
39 a47eb4c Dawsh 2y ago
40 a47eb4c Dawsh 2y ago
41 a47eb4c Dawsh 2y ago def add_default_hosts(db: Session, inbounds: List[Inbound]):
42 01cdf2e Dawsh 2y ago hosts = [
43 01cdf2e Dawsh 2y ago InboundHost(
44 01cdf2e Dawsh 2y ago remark="🚀 Marz ({USERNAME}) [{PROTOCOL} - {TRANSPORT}]",
45 01cdf2e Dawsh 2y ago address="{SERVER_IP}",
46 01cdf2e Dawsh 2y ago inbound=i,
47 01cdf2e Dawsh 2y ago )
48 01cdf2e Dawsh 2y ago for i in inbounds
49 01cdf2e Dawsh 2y ago ]
50 a47eb4c Dawsh 2y ago db.add_all(hosts)
51 a47eb4c Dawsh 2y ago db.commit()
52 a47eb4c Dawsh 2y ago
53 a47eb4c Dawsh 2y ago
54 a47eb4c Dawsh 2y ago def assure_node_inbounds(db: Session, inbounds: List[Inbound], node_id: int):
55 01cdf2e Dawsh 2y ago current_tags = [
56 01cdf2e Dawsh 2y ago i[0]
57 01cdf2e Dawsh 2y ago for i in db.execute(
58 01cdf2e Dawsh 2y ago select(Inbound.tag).filter(Inbound.node_id == node_id)
59 01cdf2e Dawsh 2y ago ).all()
60 01cdf2e Dawsh 2y ago ]
61 512d183 Mrdn 2y ago updated_tags = set(i.tag for i in list(inbounds))
62 512d183 Mrdn 2y ago inbound_additions, tag_deletions = list(), set()
63 512d183 Mrdn 2y ago for tag in current_tags:
64 512d183 Mrdn 2y ago if tag not in updated_tags:
65 512d183 Mrdn 2y ago tag_deletions.add(tag)
66 01cdf2e Dawsh 2y ago db_inbounds = db.query(Inbound).where(
67 01cdf2e Dawsh 2y ago and_(Inbound.node_id == node_id, Inbound.tag.in_(tag_deletions))
68 01cdf2e Dawsh 2y ago )
69 512d183 Mrdn 2y ago for i in db_inbounds:
70 512d183 Mrdn 2y ago db.delete(i)
71 512d183 Mrdn 2y ago
72 512d183 Mrdn 2y ago for inb in inbounds:
73 512d183 Mrdn 2y ago if inb.tag in current_tags:
74 01cdf2e Dawsh 2y ago stmt = (
75 01cdf2e Dawsh 2y ago update(Inbound)
76 01cdf2e Dawsh 2y ago .where(and_(Inbound.node_id == node_id, Inbound.tag == inb.tag))
77 01cdf2e Dawsh 2y ago .values(protocol=json.loads(inb.config)["protocol"], config=inb.config)
78 a47eb4c Dawsh 2y ago )
79 512d183 Mrdn 2y ago db.execute(stmt)
80 512d183 Mrdn 2y ago else:
81 512d183 Mrdn 2y ago inbound_additions.append(inb)
82 01cdf2e Dawsh 2y ago new_inbounds = [
83 01cdf2e Dawsh 2y ago Inbound(
84 01cdf2e Dawsh 2y ago tag=inb.tag,
85 01cdf2e Dawsh 2y ago protocol=json.loads(inb.config)["protocol"],
86 01cdf2e Dawsh 2y ago config=inb.config,
87 01cdf2e Dawsh 2y ago node_id=node_id,
88 01cdf2e Dawsh 2y ago )
89 01cdf2e Dawsh 2y ago for inb in inbound_additions
90 01cdf2e Dawsh 2y ago ]
91 a47eb4c Dawsh 2y ago db.add_all(new_inbounds)
92 a47eb4c Dawsh 2y ago db.flush()
93 a47eb4c Dawsh 2y ago for i in new_inbounds:
94 2de9d72 Dawsh 2y ago db.refresh(i)
95 a47eb4c Dawsh 2y ago add_default_hosts(db, new_inbounds)
96 a47eb4c Dawsh 2y ago db.commit()
97 a47eb4c Dawsh 2y ago
98 a47eb4c Dawsh 2y ago
99 01cdf2e Dawsh 2y ago def get_node_users(
100 01cdf2e Dawsh 2y ago db: Session, node_id: Optional[int], statuses: Optional[List[UserStatus]] = None
101 01cdf2e Dawsh 2y ago ):
102 01cdf2e Dawsh 2y ago query = (
103 01cdf2e Dawsh 2y ago db.query(User.id, User.username, User.key, Inbound)
104 01cdf2e Dawsh 2y ago .distinct()
105 cba9caa Dawsh 2y ago .where(User.enabled is True)
106 01cdf2e Dawsh 2y ago .join(Inbound.services)
107 01cdf2e Dawsh 2y ago .join(Service.users)
108 01cdf2e Dawsh 2y ago .filter(Inbound.node_id == node_id)
109 01cdf2e Dawsh 2y ago )
110 12b255b Dawsh 2y ago if isinstance(statuses, list):
111 a47eb4c Dawsh 2y ago query = query.filter(User.status.in_(statuses))
112 a47eb4c Dawsh 2y ago return query.all()
113 a47eb4c Dawsh 2y ago
114 12b255b Dawsh 2y ago
115 a47eb4c Dawsh 2y ago def get_user_hosts(db: Session, user_id: int):
116 01cdf2e Dawsh 2y ago return (
117 01cdf2e Dawsh 2y ago db.query(InboundHost)
118 01cdf2e Dawsh 2y ago .distinct()
119 01cdf2e Dawsh 2y ago .join(User.services)
120 01cdf2e Dawsh 2y ago .join(Service.inbounds)
121 01cdf2e Dawsh 2y ago .join(Inbound.hosts)
122 01cdf2e Dawsh 2y ago .filter(User.id == user_id)
123 01cdf2e Dawsh 2y ago .all()
124 01cdf2e Dawsh 2y ago )
125 a47eb4c Dawsh 2y ago
126 12b255b Dawsh 2y ago
127 a47eb4c Dawsh 2y ago def get_inbound_hosts(db: Session, inbound_id: int) -> List[InboundHost]:
128 a47eb4c Dawsh 2y ago return db.query(InboundHost).filter(InboundHost.inbound_id == inbound_id).all()
129 a47eb4c Dawsh 2y ago
130 12b255b Dawsh 2y ago
131 a47eb4c Dawsh 2y ago def get_all_inbounds(db: Session):
132 a47eb4c Dawsh 2y ago return db.query(Inbound).all()
133 a47eb4c Dawsh 2y ago
134 a47eb4c Dawsh 2y ago
135 2de9d72 Dawsh 2y ago def get_inbound(db: Session, inbound_id: int) -> Inbound | None:
136 2de9d72 Dawsh 2y ago return db.query(Inbound).filter(Inbound.id == inbound_id).first()
137 a47eb4c Dawsh 2y ago
138 a47eb4c Dawsh 2y ago
139 2de9d72 Dawsh 2y ago def get_host(db: Session, host_id) -> InboundHost:
140 2de9d72 Dawsh 2y ago return db.query(InboundHost).filter(InboundHost.id == host_id).first()
141 a47eb4c Dawsh 2y ago
142 a47eb4c Dawsh 2y ago
143 a47eb4c Dawsh 2y ago def add_host(db: Session, inbound: Inbound, host: InboundHostModify):
144 2de9d72 Dawsh 2y ago host = InboundHost(
145 2de9d72 Dawsh 2y ago remark=host.remark,
146 2de9d72 Dawsh 2y ago address=host.address,
147 2de9d72 Dawsh 2y ago port=host.port,
148 2de9d72 Dawsh 2y ago path=host.path,
149 2de9d72 Dawsh 2y ago sni=host.sni,
150 2de9d72 Dawsh 2y ago host=host.host,
151 2de9d72 Dawsh 2y ago inbound=inbound,
152 2de9d72 Dawsh 2y ago security=host.security,
153 2de9d72 Dawsh 2y ago alpn=host.alpn,
154 01cdf2e Dawsh 2y ago fingerprint=host.fingerprint,
155 a47eb4c Dawsh 2y ago )
156 2de9d72 Dawsh 2y ago inbound.hosts.append(host)
157 a47eb4c Dawsh 2y ago db.commit()
158 2de9d72 Dawsh 2y ago db.refresh(host)
159 2de9d72 Dawsh 2y ago return host
160 2de9d72 Dawsh 2y ago
161 2de9d72 Dawsh 2y ago
162 2de9d72 Dawsh 2y ago def update_host(db: Session, db_host: InboundHost, host: InboundHostModify):
163 2de9d72 Dawsh 2y ago db_host.remark = host.remark
164 2de9d72 Dawsh 2y ago db_host.address = host.address
165 2de9d72 Dawsh 2y ago db_host.port = host.port
166 2de9d72 Dawsh 2y ago db_host.path = host.path
167 2de9d72 Dawsh 2y ago db_host.sni = host.sni
168 2de9d72 Dawsh 2y ago db_host.host = host.host
169 2de9d72 Dawsh 2y ago db_host.security = host.security
170 2de9d72 Dawsh 2y ago db_host.alpn = host.alpn
171 2de9d72 Dawsh 2y ago db_host.fingerprint = host.fingerprint
172 2de9d72 Dawsh 2y ago db.commit()
173 2de9d72 Dawsh 2y ago db.refresh(db_host)
174 2de9d72 Dawsh 2y ago return db_host
175 a47eb4c Dawsh 2y ago
176 a47eb4c Dawsh 2y ago
177 a47eb4c Dawsh 2y ago def get_user(db: Session, username: str):
178 a47eb4c Dawsh 2y ago return db.query(User).filter(User.username == username).first()
179 a47eb4c Dawsh 2y ago
180 a47eb4c Dawsh 2y ago
181 a47eb4c Dawsh 2y ago def get_user_by_id(db: Session, user_id: int):
182 a47eb4c Dawsh 2y ago return db.query(User).filter(User.id == user_id).first()
183 a47eb4c Dawsh 2y ago
184 a47eb4c Dawsh 2y ago
185 01cdf2e Dawsh 2y ago UsersSortingOptions = Enum(
186 01cdf2e Dawsh 2y ago "UsersSortingOptions",
187 01cdf2e Dawsh 2y ago {
188 01cdf2e Dawsh 2y ago "username": User.username.asc(),
189 01cdf2e Dawsh 2y ago "used_traffic": User.used_traffic.asc(),
190 01cdf2e Dawsh 2y ago "data_limit": User.data_limit.asc(),
191 01cdf2e Dawsh 2y ago "expire": User.expire.asc(),
192 01cdf2e Dawsh 2y ago "created_at": User.created_at.asc(),
193 01cdf2e Dawsh 2y ago "-username": User.username.desc(),
194 01cdf2e Dawsh 2y ago "-used_traffic": User.used_traffic.desc(),
195 01cdf2e Dawsh 2y ago "-data_limit": User.data_limit.desc(),
196 01cdf2e Dawsh 2y ago "-expire": User.expire.desc(),
197 01cdf2e Dawsh 2y ago "-created_at": User.created_at.desc(),
198 01cdf2e Dawsh 2y ago },
199 01cdf2e Dawsh 2y ago )
200 01cdf2e Dawsh 2y ago
201 01cdf2e Dawsh 2y ago
202 01cdf2e Dawsh 2y ago def get_users(
203 01cdf2e Dawsh 2y ago db: Session,
204 01cdf2e Dawsh 2y ago offset: Optional[int] = None,
205 01cdf2e Dawsh 2y ago limit: Optional[int] = None,
206 01cdf2e Dawsh 2y ago usernames: Optional[List[str]] = None,
207 01cdf2e Dawsh 2y ago status: Optional[Union[UserStatus, list]] = None,
208 01cdf2e Dawsh 2y ago sort: Optional[List[UsersSortingOptions]] = None,
209 01cdf2e Dawsh 2y ago admin: Optional[Admin] = None,
210 01cdf2e Dawsh 2y ago reset_strategy: Optional[Union[UserDataLimitResetStrategy, list]] = None,
211 01cdf2e Dawsh 2y ago return_with_count: bool = False,
212 01cdf2e Dawsh 2y ago ) -> Union[List[User], Tuple[List[User], int]]:
213 a47eb4c Dawsh 2y ago query = db.query(User)
214 a47eb4c Dawsh 2y ago
215 a47eb4c Dawsh 2y ago if usernames:
216 a47eb4c Dawsh 2y ago if len(usernames) == 1:
217 a47eb4c Dawsh 2y ago query = query.filter(User.username.ilike(f"%{usernames[0]}%"))
218 a47eb4c Dawsh 2y ago else:
219 a47eb4c Dawsh 2y ago query = query.filter(User.username.in_(usernames))
220 a47eb4c Dawsh 2y ago
221 a47eb4c Dawsh 2y ago if status:
222 a47eb4c Dawsh 2y ago if isinstance(status, list):
223 a47eb4c Dawsh 2y ago query = query.filter(User.status.in_(status))
224 a47eb4c Dawsh 2y ago else:
225 a47eb4c Dawsh 2y ago query = query.filter(User.status == status)
226 a47eb4c Dawsh 2y ago
227 a47eb4c Dawsh 2y ago if reset_strategy:
228 a47eb4c Dawsh 2y ago if isinstance(reset_strategy, list):
229 a47eb4c Dawsh 2y ago query = query.filter(User.data_limit_reset_strategy.in_(reset_strategy))
230 a47eb4c Dawsh 2y ago else:
231 a47eb4c Dawsh 2y ago query = query.filter(User.data_limit_reset_strategy == reset_strategy)
232 a47eb4c Dawsh 2y ago
233 a47eb4c Dawsh 2y ago if admin:
234 a47eb4c Dawsh 2y ago query = query.filter(User.admin == admin)
235 a47eb4c Dawsh 2y ago
236 a47eb4c Dawsh 2y ago # count it before applying limit and offset
237 a47eb4c Dawsh 2y ago if return_with_count:
238 a47eb4c Dawsh 2y ago count = query.count()
239 a47eb4c Dawsh 2y ago
240 a47eb4c Dawsh 2y ago if sort:
241 a47eb4c Dawsh 2y ago query = query.order_by(*(opt.value for opt in sort))
242 a47eb4c Dawsh 2y ago
243 a47eb4c Dawsh 2y ago if offset:
244 a47eb4c Dawsh 2y ago query = query.offset(offset)
245 a47eb4c Dawsh 2y ago if limit:
246 a47eb4c Dawsh 2y ago query = query.limit(limit)
247 a47eb4c Dawsh 2y ago
248 a47eb4c Dawsh 2y ago if return_with_count:
249 a47eb4c Dawsh 2y ago return query.all(), count
250 a47eb4c Dawsh 2y ago
251 a47eb4c Dawsh 2y ago return query.all()
252 a47eb4c Dawsh 2y ago
253 a47eb4c Dawsh 2y ago
254 01cdf2e Dawsh 2y ago def get_user_usages(
255 01cdf2e Dawsh 2y ago db: Session,
256 01cdf2e Dawsh 2y ago dbuser: User,
257 01cdf2e Dawsh 2y ago start: datetime,
258 01cdf2e Dawsh 2y ago end: datetime,
259 01cdf2e Dawsh 2y ago ) -> List[UserUsageResponse]:
260 eb74041 Dawsh 2y ago usages = dict()
261 a47eb4c Dawsh 2y ago
262 a47eb4c Dawsh 2y ago for node in db.query(Node).all():
263 a47eb4c Dawsh 2y ago usages[node.id] = UserUsageResponse(
264 01cdf2e Dawsh 2y ago node_id=node.id, node_name=node.name, used_traffic=0
265 a47eb4c Dawsh 2y ago )
266 a47eb4c Dawsh 2y ago
267 01cdf2e Dawsh 2y ago cond = and_(
268 01cdf2e Dawsh 2y ago NodeUserUsage.user_id == dbuser.id,
269 01cdf2e Dawsh 2y ago NodeUserUsage.created_at >= start,
270 01cdf2e Dawsh 2y ago NodeUserUsage.created_at <= end,
271 01cdf2e Dawsh 2y ago )
272 a47eb4c Dawsh 2y ago
273 a47eb4c Dawsh 2y ago for v in db.query(NodeUserUsage).filter(cond):
274 a47eb4c Dawsh 2y ago try:
275 a47eb4c Dawsh 2y ago usages[v.node_id or 0].used_traffic += v.used_traffic
276 a47eb4c Dawsh 2y ago except KeyError:
277 a47eb4c Dawsh 2y ago pass
278 a47eb4c Dawsh 2y ago
279 a47eb4c Dawsh 2y ago return list(usages.values())
280 a47eb4c Dawsh 2y ago
281 a47eb4c Dawsh 2y ago
282 a47eb4c Dawsh 2y ago def get_users_count(db: Session, status: UserStatus = None, admin: Admin = None):
283 a47eb4c Dawsh 2y ago query = db.query(User.id)
284 a47eb4c Dawsh 2y ago if admin:
285 a47eb4c Dawsh 2y ago query = query.filter(User.admin == admin)
286 a47eb4c Dawsh 2y ago if status:
287 a47eb4c Dawsh 2y ago query = query.filter(User.status == status)
288 a47eb4c Dawsh 2y ago return query.count()
289 a47eb4c Dawsh 2y ago
290 a47eb4c Dawsh 2y ago
291 a47eb4c Dawsh 2y ago def create_user(db: Session, user: UserCreate, admin: Admin = None):
292 a47eb4c Dawsh 2y ago dbuser = User(
293 a47eb4c Dawsh 2y ago username=user.username,
294 a47eb4c Dawsh 2y ago # proxies=proxies,
295 a47eb4c Dawsh 2y ago key=user.key,
296 01cdf2e Dawsh 2y ago services=db.query(Service)
297 01cdf2e Dawsh 2y ago .filter(Service.id.in_(user.services))
298 01cdf2e Dawsh 2y ago .all(), # user.services,
299 a47eb4c Dawsh 2y ago status=user.status,
300 a47eb4c Dawsh 2y ago data_limit=(user.data_limit or None),
301 a47eb4c Dawsh 2y ago expire=(user.expire or None),
302 a47eb4c Dawsh 2y ago admin=admin,
303 a47eb4c Dawsh 2y ago data_limit_reset_strategy=user.data_limit_reset_strategy,
304 a47eb4c Dawsh 2y ago note=user.note,
305 a47eb4c Dawsh 2y ago on_hold_expire_duration=(user.on_hold_expire_duration or None),
306 a47eb4c Dawsh 2y ago on_hold_timeout=(user.on_hold_timeout or None),
307 a47eb4c Dawsh 2y ago )
308 a47eb4c Dawsh 2y ago db.add(dbuser)
309 a47eb4c Dawsh 2y ago db.commit()
310 a47eb4c Dawsh 2y ago db.refresh(dbuser)
311 a47eb4c Dawsh 2y ago return dbuser
312 a47eb4c Dawsh 2y ago
313 a47eb4c Dawsh 2y ago
314 a47eb4c Dawsh 2y ago def remove_user(db: Session, dbuser: User):
315 a47eb4c Dawsh 2y ago db.delete(dbuser)
316 a47eb4c Dawsh 2y ago # db.query(User).filter_by(id=user_id).delete()
317 a47eb4c Dawsh 2y ago db.commit()
318 a47eb4c Dawsh 2y ago
319 a47eb4c Dawsh 2y ago
320 a47eb4c Dawsh 2y ago def update_user(db: Session, dbuser: User, modify: UserModify):
321 a47eb4c Dawsh 2y ago if modify.status is not None:
322 a47eb4c Dawsh 2y ago dbuser.status = modify.status
323 a47eb4c Dawsh 2y ago
324 a47eb4c Dawsh 2y ago if modify.data_limit is not None:
325 01cdf2e Dawsh 2y ago dbuser.data_limit = modify.data_limit or None
326 a47eb4c Dawsh 2y ago if dbuser.status not in (UserStatus.expired, UserStatus.disabled):
327 a47eb4c Dawsh 2y ago if not dbuser.data_limit or dbuser.used_traffic < dbuser.data_limit:
328 a47eb4c Dawsh 2y ago if dbuser.status != UserStatus.on_hold:
329 a47eb4c Dawsh 2y ago dbuser.status = UserStatus.active
330 a47eb4c Dawsh 2y ago
331 01cdf2e Dawsh 2y ago if not dbuser.data_limit or (
332 01cdf2e Dawsh 2y ago calculate_usage_percent(dbuser.used_traffic, dbuser.data_limit)
333 01cdf2e Dawsh 2y ago < NOTIFY_REACHED_USAGE_PERCENT
334 01cdf2e Dawsh 2y ago ):
335 01cdf2e Dawsh 2y ago delete_notification_reminder_by_type(
336 01cdf2e Dawsh 2y ago db, dbuser.id, ReminderType.data_usage
337 01cdf2e Dawsh 2y ago )
338 a47eb4c Dawsh 2y ago else:
339 a47eb4c Dawsh 2y ago dbuser.status = UserStatus.limited
340 a47eb4c Dawsh 2y ago
341 a47eb4c Dawsh 2y ago if modify.expire is not None:
342 01cdf2e Dawsh 2y ago dbuser.expire = modify.expire or None
343 a47eb4c Dawsh 2y ago if dbuser.status in (UserStatus.active, UserStatus.expired):
344 3b7feef Mrdn 2y ago if not dbuser.expire or dbuser.expire > datetime.utcnow():
345 a47eb4c Dawsh 2y ago dbuser.status = UserStatus.active
346 01cdf2e Dawsh 2y ago if not dbuser.expire or (
347 01cdf2e Dawsh 2y ago calculate_expiration_days(dbuser.expire) > NOTIFY_DAYS_LEFT
348 01cdf2e Dawsh 2y ago ):
349 01cdf2e Dawsh 2y ago delete_notification_reminder_by_type(
350 01cdf2e Dawsh 2y ago db, dbuser.id, ReminderType.expiration_date
351 01cdf2e Dawsh 2y ago )
352 a47eb4c Dawsh 2y ago else:
353 a47eb4c Dawsh 2y ago dbuser.status = UserStatus.expired
354 a47eb4c Dawsh 2y ago
355 a47eb4c Dawsh 2y ago if modify.note is not None:
356 a47eb4c Dawsh 2y ago dbuser.note = modify.note or None
357 a47eb4c Dawsh 2y ago
358 a47eb4c Dawsh 2y ago if modify.data_limit_reset_strategy is not None:
359 a47eb4c Dawsh 2y ago dbuser.data_limit_reset_strategy = modify.data_limit_reset_strategy.value
360 a47eb4c Dawsh 2y ago
361 a47eb4c Dawsh 2y ago if modify.on_hold_timeout is not None:
362 a47eb4c Dawsh 2y ago dbuser.on_hold_timeout = modify.on_hold_timeout
363 a47eb4c Dawsh 2y ago
364 a47eb4c Dawsh 2y ago if modify.on_hold_expire_duration is not None:
365 a47eb4c Dawsh 2y ago dbuser.on_hold_expire_duration = modify.on_hold_expire_duration
366 2de9d72 Dawsh 2y ago
367 a47eb4c Dawsh 2y ago if modify.services is not None:
368 01cdf2e Dawsh 2y ago dbuser.services = (
369 01cdf2e Dawsh 2y ago db.query(Service).filter(Service.id.in_(modify.services)).all()
370 01cdf2e Dawsh 2y ago )
371 a47eb4c Dawsh 2y ago dbuser.edit_at = datetime.utcnow()
372 a47eb4c Dawsh 2y ago
373 a47eb4c Dawsh 2y ago db.commit()
374 a47eb4c Dawsh 2y ago db.refresh(dbuser)
375 a47eb4c Dawsh 2y ago return dbuser
376 a47eb4c Dawsh 2y ago
377 a47eb4c Dawsh 2y ago
378 a47eb4c Dawsh 2y ago def reset_user_data_usage(db: Session, dbuser: User):
379 a47eb4c Dawsh 2y ago usage_log = UserUsageResetLogs(
380 a47eb4c Dawsh 2y ago user=dbuser,
381 a47eb4c Dawsh 2y ago used_traffic_at_reset=dbuser.used_traffic,
382 a47eb4c Dawsh 2y ago )
383 a47eb4c Dawsh 2y ago db.add(usage_log)
384 a47eb4c Dawsh 2y ago
385 a47eb4c Dawsh 2y ago dbuser.used_traffic = 0
386 a47eb4c Dawsh 2y ago dbuser.node_usages.clear()
387 6da1b8a Dawsh 2y ago if dbuser.status == UserStatus.limited:
388 a47eb4c Dawsh 2y ago dbuser.status = UserStatus.active.value
389 a47eb4c Dawsh 2y ago db.add(dbuser)
390 a47eb4c Dawsh 2y ago
391 a47eb4c Dawsh 2y ago db.commit()
392 a47eb4c Dawsh 2y ago db.refresh(dbuser)
393 a47eb4c Dawsh 2y ago return dbuser
394 a47eb4c Dawsh 2y ago
395 a47eb4c Dawsh 2y ago
396 a47eb4c Dawsh 2y ago def revoke_user_sub(db: Session, dbuser: User):
397 34a7612 Dawsh 2y ago dbuser.key = secrets.token_hex(16)
398 a47eb4c Dawsh 2y ago db.commit()
399 a47eb4c Dawsh 2y ago db.refresh(dbuser)
400 a47eb4c Dawsh 2y ago return dbuser
401 a47eb4c Dawsh 2y ago
402 a47eb4c Dawsh 2y ago
403 a47eb4c Dawsh 2y ago def update_user_sub(db: Session, dbuser: User, user_agent: str):
404 a47eb4c Dawsh 2y ago dbuser.sub_updated_at = datetime.utcnow()
405 a47eb4c Dawsh 2y ago dbuser.sub_last_user_agent = user_agent
406 a47eb4c Dawsh 2y ago
407 a47eb4c Dawsh 2y ago db.commit()
408 a47eb4c Dawsh 2y ago db.refresh(dbuser)
409 a47eb4c Dawsh 2y ago return dbuser
410 a47eb4c Dawsh 2y ago
411 a47eb4c Dawsh 2y ago
412 a47eb4c Dawsh 2y ago def reset_all_users_data_usage(db: Session, admin: Optional[Admin] = None):
413 a47eb4c Dawsh 2y ago query = db.query(User)
414 a47eb4c Dawsh 2y ago
415 a47eb4c Dawsh 2y ago if admin:
416 a47eb4c Dawsh 2y ago query = query.filter(User.admin == admin)
417 a47eb4c Dawsh 2y ago
418 a47eb4c Dawsh 2y ago for dbuser in query.all():
419 a47eb4c Dawsh 2y ago dbuser.used_traffic = 0
420 01cdf2e Dawsh 2y ago if dbuser.status not in [
421 01cdf2e Dawsh 2y ago UserStatus.on_hold,
422 01cdf2e Dawsh 2y ago UserStatus.expired,
423 01cdf2e Dawsh 2y ago UserStatus.disabled,
424 01cdf2e Dawsh 2y ago ]:
425 a47eb4c Dawsh 2y ago dbuser.status = UserStatus.active
426 a47eb4c Dawsh 2y ago dbuser.usage_logs.clear()
427 a47eb4c Dawsh 2y ago dbuser.node_usages.clear()
428 a47eb4c Dawsh 2y ago db.add(dbuser)
429 a47eb4c Dawsh 2y ago
430 a47eb4c Dawsh 2y ago db.commit()
431 a47eb4c Dawsh 2y ago
432 a47eb4c Dawsh 2y ago
433 a47eb4c Dawsh 2y ago def update_user_status(db: Session, dbuser: User, status: UserStatus):
434 a47eb4c Dawsh 2y ago dbuser.status = status
435 a47eb4c Dawsh 2y ago db.commit()
436 a47eb4c Dawsh 2y ago db.refresh(dbuser)
437 a47eb4c Dawsh 2y ago return dbuser
438 a47eb4c Dawsh 2y ago
439 a47eb4c Dawsh 2y ago
440 a47eb4c Dawsh 2y ago def set_owner(db: Session, dbuser: User, admin: Admin):
441 a47eb4c Dawsh 2y ago dbuser.admin = admin
442 a47eb4c Dawsh 2y ago db.commit()
443 a47eb4c Dawsh 2y ago db.refresh(dbuser)
444 a47eb4c Dawsh 2y ago return dbuser
445 a47eb4c Dawsh 2y ago
446 a47eb4c Dawsh 2y ago
447 a47eb4c Dawsh 2y ago def start_user_expire(db: Session, dbuser: User):
448 f446990 Dawsh 2y ago expire = datetime.utcnow() + timedelta(seconds=dbuser.on_hold_expire_duration)
449 a47eb4c Dawsh 2y ago dbuser.expire = expire
450 a47eb4c Dawsh 2y ago db.commit()
451 a47eb4c Dawsh 2y ago db.refresh(dbuser)
452 a47eb4c Dawsh 2y ago return dbuser
453 a47eb4c Dawsh 2y ago
454 a47eb4c Dawsh 2y ago
455 a47eb4c Dawsh 2y ago def get_system_usage(db: Session):
456 a47eb4c Dawsh 2y ago return db.query(System).first()
457 a47eb4c Dawsh 2y ago
458 a47eb4c Dawsh 2y ago
459 a47eb4c Dawsh 2y ago def get_jwt_secret_key(db: Session):
460 a47eb4c Dawsh 2y ago return db.query(JWT).first().secret_key
461 a47eb4c Dawsh 2y ago
462 a47eb4c Dawsh 2y ago
463 a47eb4c Dawsh 2y ago def get_tls_certificate(db: Session):
464 a47eb4c Dawsh 2y ago return db.query(TLS).first()
465 a47eb4c Dawsh 2y ago
466 a47eb4c Dawsh 2y ago
467 a47eb4c Dawsh 2y ago def get_admin(db: Session, username: str):
468 a47eb4c Dawsh 2y ago return db.query(Admin).filter(Admin.username == username).first()
469 a47eb4c Dawsh 2y ago
470 a47eb4c Dawsh 2y ago
471 a47eb4c Dawsh 2y ago def create_admin(db: Session, admin: AdminCreate):
472 a47eb4c Dawsh 2y ago dbadmin = Admin(
473 a47eb4c Dawsh 2y ago username=admin.username,
474 a47eb4c Dawsh 2y ago hashed_password=admin.hashed_password,
475 01cdf2e Dawsh 2y ago is_sudo=admin.is_sudo,
476 a47eb4c Dawsh 2y ago )
477 a47eb4c Dawsh 2y ago db.add(dbadmin)
478 a47eb4c Dawsh 2y ago db.commit()
479 a47eb4c Dawsh 2y ago db.refresh(dbadmin)
480 a47eb4c Dawsh 2y ago return dbadmin
481 a47eb4c Dawsh 2y ago
482 a47eb4c Dawsh 2y ago
483 a47eb4c Dawsh 2y ago def update_admin(db: Session, dbadmin: Admin, modified_admin: AdminModify):
484 a47eb4c Dawsh 2y ago dbadmin.is_sudo = modified_admin.is_sudo
485 a47eb4c Dawsh 2y ago if dbadmin.hashed_password != modified_admin.hashed_password:
486 a47eb4c Dawsh 2y ago dbadmin.hashed_password = modified_admin.hashed_password
487 a47eb4c Dawsh 2y ago dbadmin.password_reset_at = datetime.utcnow()
488 a47eb4c Dawsh 2y ago db.commit()
489 a47eb4c Dawsh 2y ago db.refresh(dbadmin)
490 2de9d72 Dawsh 2y ago return dbadmin
491 a47eb4c Dawsh 2y ago
492 a47eb4c Dawsh 2y ago
493 01cdf2e Dawsh 2y ago def partial_update_admin(
494 01cdf2e Dawsh 2y ago db: Session, dbadmin: Admin, modified_admin: AdminPartialModify
495 01cdf2e Dawsh 2y ago ):
496 a47eb4c Dawsh 2y ago if modified_admin.is_sudo is not None:
497 a47eb4c Dawsh 2y ago dbadmin.is_sudo = modified_admin.is_sudo
498 01cdf2e Dawsh 2y ago if (
499 01cdf2e Dawsh 2y ago modified_admin.password is not None
500 01cdf2e Dawsh 2y ago and dbadmin.hashed_password != modified_admin.hashed_password
501 01cdf2e Dawsh 2y ago ):
502 a47eb4c Dawsh 2y ago dbadmin.hashed_password = modified_admin.hashed_password
503 a47eb4c Dawsh 2y ago dbadmin.password_reset_at = datetime.utcnow()
504 a47eb4c Dawsh 2y ago
505 a47eb4c Dawsh 2y ago db.commit()
506 a47eb4c Dawsh 2y ago db.refresh(dbadmin)
507 a47eb4c Dawsh 2y ago return dbadmin
508 a47eb4c Dawsh 2y ago
509 a47eb4c Dawsh 2y ago
510 a47eb4c Dawsh 2y ago def remove_admin(db: Session, dbadmin: Admin):
511 a47eb4c Dawsh 2y ago db.delete(dbadmin)
512 a47eb4c Dawsh 2y ago db.commit()
513 a47eb4c Dawsh 2y ago return dbadmin
514 a47eb4c Dawsh 2y ago
515 a47eb4c Dawsh 2y ago
516 01cdf2e Dawsh 2y ago def get_admins(
517 01cdf2e Dawsh 2y ago db: Session,
518 01cdf2e Dawsh 2y ago offset: Optional[int] = None,
519 01cdf2e Dawsh 2y ago limit: Optional[int] = None,
520 01cdf2e Dawsh 2y ago username: Optional[str] = None,
521 01cdf2e Dawsh 2y ago ):
522 a47eb4c Dawsh 2y ago query = db.query(Admin)
523 a47eb4c Dawsh 2y ago if username:
524 01cdf2e Dawsh 2y ago query = query.filter(Admin.username.ilike(f"%{username}%"))
525 a47eb4c Dawsh 2y ago if offset:
526 a47eb4c Dawsh 2y ago query = query.offset(offset)
527 a47eb4c Dawsh 2y ago if limit:
528 a47eb4c Dawsh 2y ago query = query.limit(limit)
529 a47eb4c Dawsh 2y ago return query.all()
530 a47eb4c Dawsh 2y ago
531 a47eb4c Dawsh 2y ago
532 ee1351a Dawsh 2y ago def create_service(db: Session, service: ServiceCreate) -> Service:
533 a47eb4c Dawsh 2y ago dbservice = Service(
534 a47eb4c Dawsh 2y ago name=service.name,
535 a47eb4c Dawsh 2y ago inbounds=db.query(Inbound).filter(Inbound.id.in_(service.inbounds)).all(),
536 01cdf2e Dawsh 2y ago users=db.query(User).filter(User.id.in_(service.users)).all(),
537 2de9d72 Dawsh 2y ago )
538 a47eb4c Dawsh 2y ago db.add(dbservice)
539 a47eb4c Dawsh 2y ago db.commit()
540 a47eb4c Dawsh 2y ago db.refresh(dbservice)
541 a47eb4c Dawsh 2y ago return dbservice
542 a47eb4c Dawsh 2y ago
543 a47eb4c Dawsh 2y ago
544 ee1351a Dawsh 2y ago def get_service(db: Session, service_id: id) -> Service:
545 ee1351a Dawsh 2y ago return db.query(Service).filter(Service.id == service_id).first()
546 a47eb4c Dawsh 2y ago
547 12b255b Dawsh 2y ago
548 a47eb4c Dawsh 2y ago def get_services(db: Session) -> List[Service]:
549 a47eb4c Dawsh 2y ago return db.query(Service).all()
550 a47eb4c Dawsh 2y ago
551 12b255b Dawsh 2y ago
552 ee1351a Dawsh 2y ago def update_service(db: Session, db_service: Service, modification: ServiceModify):
553 ee1351a Dawsh 2y ago if modification.name is not None:
554 ee1351a Dawsh 2y ago db_service.name = modification.name
555 ee1351a Dawsh 2y ago
556 ee1351a Dawsh 2y ago if modification.inbounds is not None:
557 01cdf2e Dawsh 2y ago db_service.inbounds = (
558 01cdf2e Dawsh 2y ago db.query(Inbound).filter(Inbound.id.in_(modification.inbounds)).all()
559 01cdf2e Dawsh 2y ago )
560 ee1351a Dawsh 2y ago
561 ee1351a Dawsh 2y ago db.commit()
562 ee1351a Dawsh 2y ago db.refresh(db_service)
563 ee1351a Dawsh 2y ago return db_service
564 ee1351a Dawsh 2y ago
565 ee1351a Dawsh 2y ago
566 ee1351a Dawsh 2y ago def remove_service(db: Session, db_service: Service):
567 ee1351a Dawsh 2y ago db.delete(db_service)
568 ee1351a Dawsh 2y ago db.commit()
569 ee1351a Dawsh 2y ago return db_service
570 ee1351a Dawsh 2y ago
571 ee1351a Dawsh 2y ago
572 a47eb4c Dawsh 2y ago def get_node(db: Session, name: str):
573 a47eb4c Dawsh 2y ago return db.query(Node).filter(Node.name == name).first()
574 a47eb4c Dawsh 2y ago
575 a47eb4c Dawsh 2y ago
576 a47eb4c Dawsh 2y ago def get_node_by_id(db: Session, node_id: int):
577 a47eb4c Dawsh 2y ago return db.query(Node).filter(Node.id == node_id).first()
578 a47eb4c Dawsh 2y ago
579 a47eb4c Dawsh 2y ago
580 01cdf2e Dawsh 2y ago def get_nodes(
581 01cdf2e Dawsh 2y ago db: Session, status: Optional[Union[NodeStatus, list]] = None, enabled: bool = None
582 01cdf2e Dawsh 2y ago ):
583 a47eb4c Dawsh 2y ago query = db.query(Node)
584 a47eb4c Dawsh 2y ago
585 a47eb4c Dawsh 2y ago if status:
586 a47eb4c Dawsh 2y ago if isinstance(status, list):
587 a47eb4c Dawsh 2y ago query = query.filter(Node.status.in_(status))
588 a47eb4c Dawsh 2y ago else:
589 a47eb4c Dawsh 2y ago query = query.filter(Node.status == status)
590 a47eb4c Dawsh 2y ago
591 a47eb4c Dawsh 2y ago if enabled:
592 a47eb4c Dawsh 2y ago query = query.filter(Node.status != NodeStatus.disabled)
593 a47eb4c Dawsh 2y ago
594 a47eb4c Dawsh 2y ago return query.all()
595 a47eb4c Dawsh 2y ago
596 a47eb4c Dawsh 2y ago
597 01cdf2e Dawsh 2y ago def get_nodes_usage(
598 01cdf2e Dawsh 2y ago db: Session, start: datetime, end: datetime
599 01cdf2e Dawsh 2y ago ) -> List[NodeUsageResponse]:
600 12b255b Dawsh 2y ago usages = dict()
601 a47eb4c Dawsh 2y ago
602 a47eb4c Dawsh 2y ago usages[0] = NodeUsageResponse( # Main Core
603 01cdf2e Dawsh 2y ago node_id=None, node_name="Master", uplink=0, downlink=0
604 a47eb4c Dawsh 2y ago )
605 a47eb4c Dawsh 2y ago for node in db.query(Node).all():
606 a47eb4c Dawsh 2y ago usages[node.id] = NodeUsageResponse(
607 01cdf2e Dawsh 2y ago node_id=node.id, node_name=node.name, uplink=0, downlink=0
608 a47eb4c Dawsh 2y ago )
609 a47eb4c Dawsh 2y ago
610 a47eb4c Dawsh 2y ago cond = and_(NodeUsage.created_at >= start, NodeUsage.created_at <= end)
611 a47eb4c Dawsh 2y ago
612 a47eb4c Dawsh 2y ago for v in db.query(NodeUsage).filter(cond):
613 a47eb4c Dawsh 2y ago try:
614 a47eb4c Dawsh 2y ago usages[v.node_id or 0].uplink += v.uplink
615 a47eb4c Dawsh 2y ago usages[v.node_id or 0].downlink += v.downlink
616 a47eb4c Dawsh 2y ago except KeyError:
617 a47eb4c Dawsh 2y ago pass
618 a47eb4c Dawsh 2y ago
619 a47eb4c Dawsh 2y ago return list(usages.values())
620 a47eb4c Dawsh 2y ago
621 a47eb4c Dawsh 2y ago
622 a47eb4c Dawsh 2y ago def create_node(db: Session, node: NodeCreate):
623 01cdf2e Dawsh 2y ago dbnode = Node(
624 01cdf2e Dawsh 2y ago name=node.name,
625 01cdf2e Dawsh 2y ago address=node.address,
626 01cdf2e Dawsh 2y ago port=node.port,
627 01cdf2e Dawsh 2y ago connection_backend=node.connection_backend,
628 01cdf2e Dawsh 2y ago )
629 a47eb4c Dawsh 2y ago
630 a47eb4c Dawsh 2y ago db.add(dbnode)
631 a47eb4c Dawsh 2y ago db.commit()
632 a47eb4c Dawsh 2y ago db.refresh(dbnode)
633 a47eb4c Dawsh 2y ago return dbnode
634 a47eb4c Dawsh 2y ago
635 a47eb4c Dawsh 2y ago
636 a47eb4c Dawsh 2y ago def remove_node(db: Session, dbnode: Node):
637 a47eb4c Dawsh 2y ago db.delete(dbnode)
638 a47eb4c Dawsh 2y ago db.commit()
639 a47eb4c Dawsh 2y ago return dbnode
640 a47eb4c Dawsh 2y ago
641 a47eb4c Dawsh 2y ago
642 a47eb4c Dawsh 2y ago def update_node(db: Session, dbnode: Node, modify: NodeModify):
643 a47eb4c Dawsh 2y ago if modify.name is not None:
644 a47eb4c Dawsh 2y ago dbnode.name = modify.name
645 a47eb4c Dawsh 2y ago
646 a47eb4c Dawsh 2y ago if modify.address is not None:
647 a47eb4c Dawsh 2y ago dbnode.address = modify.address
648 a47eb4c Dawsh 2y ago
649 a47eb4c Dawsh 2y ago if modify.port is not None:
650 a47eb4c Dawsh 2y ago dbnode.port = modify.port
651 a47eb4c Dawsh 2y ago
652 a47eb4c Dawsh 2y ago if modify.status is NodeStatus.disabled:
653 a47eb4c Dawsh 2y ago dbnode.status = modify.status
654 a47eb4c Dawsh 2y ago dbnode.xray_version = None
655 a47eb4c Dawsh 2y ago dbnode.message = None
656 a47eb4c Dawsh 2y ago else:
657 12b255b Dawsh 2y ago dbnode.status = NodeStatus.unhealthy
658 a47eb4c Dawsh 2y ago
659 a47eb4c Dawsh 2y ago if modify.usage_coefficient:
660 a47eb4c Dawsh 2y ago dbnode.usage_coefficient = modify.usage_coefficient
661 a47eb4c Dawsh 2y ago
662 a47eb4c Dawsh 2y ago db.commit()
663 a47eb4c Dawsh 2y ago db.refresh(dbnode)
664 a47eb4c Dawsh 2y ago return dbnode
665 a47eb4c Dawsh 2y ago
666 a47eb4c Dawsh 2y ago
667 01cdf2e Dawsh 2y ago def update_node_status(
668 01cdf2e Dawsh 2y ago db: Session,
669 01cdf2e Dawsh 2y ago node_id: int,
670 01cdf2e Dawsh 2y ago status: NodeStatus,
671 01cdf2e Dawsh 2y ago message: str = None,
672 01cdf2e Dawsh 2y ago version: str = None,
673 01cdf2e Dawsh 2y ago ):
674 f6a32ea Dawsh 2y ago db_node = db.query(Node).where(Node.id == node_id).first()
675 f6a32ea Dawsh 2y ago db_node.status = status
676 f6a32ea Dawsh 2y ago if message:
677 f6a32ea Dawsh 2y ago db_node.message = message
678 f6a32ea Dawsh 2y ago db_node.last_status_change = datetime.utcnow()
679 a47eb4c Dawsh 2y ago db.commit()
680 a47eb4c Dawsh 2y ago
681 a47eb4c Dawsh 2y ago
682 a47eb4c Dawsh 2y ago def create_notification_reminder(
683 01cdf2e Dawsh 2y ago db: Session, reminder_type: ReminderType, expires_at: datetime, user_id: int
684 01cdf2e Dawsh 2y ago ) -> NotificationReminder:
685 01cdf2e Dawsh 2y ago reminder = NotificationReminder(
686 01cdf2e Dawsh 2y ago type=reminder_type, expires_at=expires_at, user_id=user_id
687 01cdf2e Dawsh 2y ago )
688 a47eb4c Dawsh 2y ago db.add(reminder)
689 a47eb4c Dawsh 2y ago db.commit()
690 a47eb4c Dawsh 2y ago db.refresh(reminder)
691 a47eb4c Dawsh 2y ago return reminder
692 a47eb4c Dawsh 2y ago
693 a47eb4c Dawsh 2y ago
694 a47eb4c Dawsh 2y ago def get_notification_reminder(
695 01cdf2e Dawsh 2y ago db: Session,
696 01cdf2e Dawsh 2y ago user_id: int,
697 01cdf2e Dawsh 2y ago reminder_type: ReminderType,
698 12b255b Dawsh 2y ago ) -> Optional[NotificationReminder]:
699 01cdf2e Dawsh 2y ago reminder = (
700 01cdf2e Dawsh 2y ago db.query(NotificationReminder)
701 01cdf2e Dawsh 2y ago .filter(NotificationReminder.user_id == user_id)
702 01cdf2e Dawsh 2y ago .filter(NotificationReminder.type == reminder_type)
703 01cdf2e Dawsh 2y ago .first()
704 01cdf2e Dawsh 2y ago )
705 a47eb4c Dawsh 2y ago if reminder is None:
706 a47eb4c Dawsh 2y ago return
707 a47eb4c Dawsh 2y ago if reminder.expires_at and reminder.expires_at < datetime.utcnow():
708 a47eb4c Dawsh 2y ago db.delete(reminder)
709 a47eb4c Dawsh 2y ago db.commit()
710 a47eb4c Dawsh 2y ago return
711 a47eb4c Dawsh 2y ago return reminder
712 a47eb4c Dawsh 2y ago
713 a47eb4c Dawsh 2y ago
714 01cdf2e Dawsh 2y ago def delete_notification_reminder_by_type(
715 01cdf2e Dawsh 2y ago db: Session, user_id: int, reminder_type: ReminderType
716 01cdf2e Dawsh 2y ago ) -> None:
717 a47eb4c Dawsh 2y ago """Deletes notification reminder filtered by user_id and type if exists"""
718 a47eb4c Dawsh 2y ago stmt = delete(NotificationReminder).where(
719 a47eb4c Dawsh 2y ago NotificationReminder.user_id == user_id,
720 a47eb4c Dawsh 2y ago NotificationReminder.type == reminder_type,
721 a47eb4c Dawsh 2y ago )
722 a47eb4c Dawsh 2y ago db.execute(stmt)
723 a47eb4c Dawsh 2y ago db.commit()
724 a47eb4c Dawsh 2y ago return
725 a47eb4c Dawsh 2y ago
726 a47eb4c Dawsh 2y ago
727 a47eb4c Dawsh 2y ago def delete_notification_reminder(db: Session, dbreminder: NotificationReminder) -> None:
728 a47eb4c Dawsh 2y ago db.delete(dbreminder)
729 a47eb4c Dawsh 2y ago db.commit()
730 a47eb4c Dawsh 2y ago return