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