1
0

users.py 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. import time
  2. from typing import Optional
  3. from open_webui.internal.db import Base, JSONField, get_db
  4. from open_webui.env import DATABASE_USER_ACTIVE_STATUS_UPDATE_INTERVAL
  5. from open_webui.models.chats import Chats
  6. from open_webui.models.groups import Groups
  7. from open_webui.utils.misc import throttle
  8. from pydantic import BaseModel, ConfigDict
  9. from sqlalchemy import BigInteger, Column, String, Text, Date
  10. from sqlalchemy import or_
  11. import datetime
  12. ####################
  13. # User DB Schema
  14. ####################
  15. class User(Base):
  16. __tablename__ = "user"
  17. id = Column(String, primary_key=True)
  18. name = Column(String)
  19. email = Column(String)
  20. username = Column(String(50), nullable=True)
  21. role = Column(String)
  22. profile_image_url = Column(Text)
  23. bio = Column(Text, nullable=True)
  24. gender = Column(Text, nullable=True)
  25. date_of_birth = Column(Date, nullable=True)
  26. info = Column(JSONField, nullable=True)
  27. settings = Column(JSONField, nullable=True)
  28. api_key = Column(String, nullable=True, unique=True)
  29. oauth_sub = Column(Text, unique=True)
  30. last_active_at = Column(BigInteger)
  31. updated_at = Column(BigInteger)
  32. created_at = Column(BigInteger)
  33. class UserSettings(BaseModel):
  34. ui: Optional[dict] = {}
  35. model_config = ConfigDict(extra="allow")
  36. pass
  37. class UserModel(BaseModel):
  38. id: str
  39. name: str
  40. email: str
  41. username: Optional[str] = None
  42. role: str = "pending"
  43. profile_image_url: str
  44. bio: Optional[str] = None
  45. gender: Optional[str] = None
  46. date_of_birth: Optional[datetime.date] = None
  47. info: Optional[dict] = None
  48. settings: Optional[UserSettings] = None
  49. api_key: Optional[str] = None
  50. oauth_sub: Optional[str] = None
  51. last_active_at: int # timestamp in epoch
  52. updated_at: int # timestamp in epoch
  53. created_at: int # timestamp in epoch
  54. model_config = ConfigDict(from_attributes=True)
  55. ####################
  56. # Forms
  57. ####################
  58. class UpdateProfileForm(BaseModel):
  59. profile_image_url: str
  60. name: str
  61. bio: Optional[str] = None
  62. gender: Optional[str] = None
  63. date_of_birth: Optional[datetime.date] = None
  64. class UserListResponse(BaseModel):
  65. users: list[UserModel]
  66. total: int
  67. class UserInfoResponse(BaseModel):
  68. id: str
  69. name: str
  70. email: str
  71. role: str
  72. class UserIdNameResponse(BaseModel):
  73. id: str
  74. name: str
  75. class UserInfoListResponse(BaseModel):
  76. users: list[UserInfoResponse]
  77. total: int
  78. class UserIdNameListResponse(BaseModel):
  79. users: list[UserIdNameResponse]
  80. total: int
  81. class UserResponse(BaseModel):
  82. id: str
  83. name: str
  84. email: str
  85. role: str
  86. profile_image_url: str
  87. class UserNameResponse(BaseModel):
  88. id: str
  89. name: str
  90. role: str
  91. profile_image_url: str
  92. class UserRoleUpdateForm(BaseModel):
  93. id: str
  94. role: str
  95. class UserUpdateForm(BaseModel):
  96. role: str
  97. name: str
  98. email: str
  99. profile_image_url: str
  100. password: Optional[str] = None
  101. class UsersTable:
  102. def insert_new_user(
  103. self,
  104. id: str,
  105. name: str,
  106. email: str,
  107. profile_image_url: str = "/user.png",
  108. role: str = "pending",
  109. oauth_sub: Optional[str] = None,
  110. ) -> Optional[UserModel]:
  111. with get_db() as db:
  112. user = UserModel(
  113. **{
  114. "id": id,
  115. "name": name,
  116. "email": email,
  117. "role": role,
  118. "profile_image_url": profile_image_url,
  119. "last_active_at": int(time.time()),
  120. "created_at": int(time.time()),
  121. "updated_at": int(time.time()),
  122. "oauth_sub": oauth_sub,
  123. }
  124. )
  125. result = User(**user.model_dump())
  126. db.add(result)
  127. db.commit()
  128. db.refresh(result)
  129. if result:
  130. return user
  131. else:
  132. return None
  133. def get_user_by_id(self, id: str) -> Optional[UserModel]:
  134. try:
  135. with get_db() as db:
  136. user = db.query(User).filter_by(id=id).first()
  137. return UserModel.model_validate(user)
  138. except Exception:
  139. return None
  140. def get_user_by_api_key(self, api_key: str) -> Optional[UserModel]:
  141. try:
  142. with get_db() as db:
  143. user = db.query(User).filter_by(api_key=api_key).first()
  144. return UserModel.model_validate(user)
  145. except Exception:
  146. return None
  147. def get_user_by_email(self, email: str) -> Optional[UserModel]:
  148. try:
  149. with get_db() as db:
  150. user = db.query(User).filter_by(email=email).first()
  151. return UserModel.model_validate(user)
  152. except Exception:
  153. return None
  154. def get_user_by_oauth_sub(self, sub: str) -> Optional[UserModel]:
  155. try:
  156. with get_db() as db:
  157. user = db.query(User).filter_by(oauth_sub=sub).first()
  158. return UserModel.model_validate(user)
  159. except Exception:
  160. return None
  161. def get_users(
  162. self,
  163. filter: Optional[dict] = None,
  164. skip: Optional[int] = None,
  165. limit: Optional[int] = None,
  166. ) -> dict:
  167. with get_db() as db:
  168. query = db.query(User)
  169. if filter:
  170. query_key = filter.get("query")
  171. if query_key:
  172. query = query.filter(
  173. or_(
  174. User.name.ilike(f"%{query_key}%"),
  175. User.email.ilike(f"%{query_key}%"),
  176. )
  177. )
  178. order_by = filter.get("order_by")
  179. direction = filter.get("direction")
  180. if order_by == "name":
  181. if direction == "asc":
  182. query = query.order_by(User.name.asc())
  183. else:
  184. query = query.order_by(User.name.desc())
  185. elif order_by == "email":
  186. if direction == "asc":
  187. query = query.order_by(User.email.asc())
  188. else:
  189. query = query.order_by(User.email.desc())
  190. elif order_by == "created_at":
  191. if direction == "asc":
  192. query = query.order_by(User.created_at.asc())
  193. else:
  194. query = query.order_by(User.created_at.desc())
  195. elif order_by == "last_active_at":
  196. if direction == "asc":
  197. query = query.order_by(User.last_active_at.asc())
  198. else:
  199. query = query.order_by(User.last_active_at.desc())
  200. elif order_by == "updated_at":
  201. if direction == "asc":
  202. query = query.order_by(User.updated_at.asc())
  203. else:
  204. query = query.order_by(User.updated_at.desc())
  205. elif order_by == "role":
  206. if direction == "asc":
  207. query = query.order_by(User.role.asc())
  208. else:
  209. query = query.order_by(User.role.desc())
  210. else:
  211. query = query.order_by(User.created_at.desc())
  212. if skip:
  213. query = query.offset(skip)
  214. if limit:
  215. query = query.limit(limit)
  216. users = query.all()
  217. return {
  218. "users": [UserModel.model_validate(user) for user in users],
  219. "total": db.query(User).count(),
  220. }
  221. def get_users_by_user_ids(self, user_ids: list[str]) -> list[UserModel]:
  222. with get_db() as db:
  223. users = db.query(User).filter(User.id.in_(user_ids)).all()
  224. return [UserModel.model_validate(user) for user in users]
  225. def get_num_users(self) -> Optional[int]:
  226. with get_db() as db:
  227. return db.query(User).count()
  228. def has_users(self) -> bool:
  229. with get_db() as db:
  230. return db.query(db.query(User).exists()).scalar()
  231. def get_first_user(self) -> UserModel:
  232. try:
  233. with get_db() as db:
  234. user = db.query(User).order_by(User.created_at).first()
  235. return UserModel.model_validate(user)
  236. except Exception:
  237. return None
  238. def get_user_webhook_url_by_id(self, id: str) -> Optional[str]:
  239. try:
  240. with get_db() as db:
  241. user = db.query(User).filter_by(id=id).first()
  242. if user.settings is None:
  243. return None
  244. else:
  245. return (
  246. user.settings.get("ui", {})
  247. .get("notifications", {})
  248. .get("webhook_url", None)
  249. )
  250. except Exception:
  251. return None
  252. def update_user_role_by_id(self, id: str, role: str) -> Optional[UserModel]:
  253. try:
  254. with get_db() as db:
  255. db.query(User).filter_by(id=id).update({"role": role})
  256. db.commit()
  257. user = db.query(User).filter_by(id=id).first()
  258. return UserModel.model_validate(user)
  259. except Exception:
  260. return None
  261. def update_user_profile_image_url_by_id(
  262. self, id: str, profile_image_url: str
  263. ) -> Optional[UserModel]:
  264. try:
  265. with get_db() as db:
  266. db.query(User).filter_by(id=id).update(
  267. {"profile_image_url": profile_image_url}
  268. )
  269. db.commit()
  270. user = db.query(User).filter_by(id=id).first()
  271. return UserModel.model_validate(user)
  272. except Exception:
  273. return None
  274. @throttle(DATABASE_USER_ACTIVE_STATUS_UPDATE_INTERVAL)
  275. def update_user_last_active_by_id(self, id: str) -> Optional[UserModel]:
  276. try:
  277. with get_db() as db:
  278. db.query(User).filter_by(id=id).update(
  279. {"last_active_at": int(time.time())}
  280. )
  281. db.commit()
  282. user = db.query(User).filter_by(id=id).first()
  283. return UserModel.model_validate(user)
  284. except Exception:
  285. return None
  286. def update_user_oauth_sub_by_id(
  287. self, id: str, oauth_sub: str
  288. ) -> Optional[UserModel]:
  289. try:
  290. with get_db() as db:
  291. db.query(User).filter_by(id=id).update({"oauth_sub": oauth_sub})
  292. db.commit()
  293. user = db.query(User).filter_by(id=id).first()
  294. return UserModel.model_validate(user)
  295. except Exception:
  296. return None
  297. def update_user_by_id(self, id: str, updated: dict) -> Optional[UserModel]:
  298. try:
  299. with get_db() as db:
  300. db.query(User).filter_by(id=id).update(updated)
  301. db.commit()
  302. user = db.query(User).filter_by(id=id).first()
  303. return UserModel.model_validate(user)
  304. # return UserModel(**user.dict())
  305. except Exception as e:
  306. print(e)
  307. return None
  308. def update_user_settings_by_id(self, id: str, updated: dict) -> Optional[UserModel]:
  309. try:
  310. with get_db() as db:
  311. user_settings = db.query(User).filter_by(id=id).first().settings
  312. if user_settings is None:
  313. user_settings = {}
  314. user_settings.update(updated)
  315. db.query(User).filter_by(id=id).update({"settings": user_settings})
  316. db.commit()
  317. user = db.query(User).filter_by(id=id).first()
  318. return UserModel.model_validate(user)
  319. except Exception:
  320. return None
  321. def delete_user_by_id(self, id: str) -> bool:
  322. try:
  323. # Remove User from Groups
  324. Groups.remove_user_from_all_groups(id)
  325. # Delete User Chats
  326. result = Chats.delete_chats_by_user_id(id)
  327. if result:
  328. with get_db() as db:
  329. # Delete User
  330. db.query(User).filter_by(id=id).delete()
  331. db.commit()
  332. return True
  333. else:
  334. return False
  335. except Exception:
  336. return False
  337. def update_user_api_key_by_id(self, id: str, api_key: str) -> bool:
  338. try:
  339. with get_db() as db:
  340. result = db.query(User).filter_by(id=id).update({"api_key": api_key})
  341. db.commit()
  342. return True if result == 1 else False
  343. except Exception:
  344. return False
  345. def get_user_api_key_by_id(self, id: str) -> Optional[str]:
  346. try:
  347. with get_db() as db:
  348. user = db.query(User).filter_by(id=id).first()
  349. return user.api_key
  350. except Exception:
  351. return None
  352. def get_valid_user_ids(self, user_ids: list[str]) -> list[str]:
  353. with get_db() as db:
  354. users = db.query(User).filter(User.id.in_(user_ids)).all()
  355. return [user.id for user in users]
  356. def get_super_admin_user(self) -> Optional[UserModel]:
  357. with get_db() as db:
  358. user = db.query(User).filter_by(role="admin").first()
  359. if user:
  360. return UserModel.model_validate(user)
  361. else:
  362. return None
  363. Users = UsersTable()