users.py 7.76 KB
Newer Older
1
from pydantic import BaseModel, ConfigDict, parse_obj_as
2
3
from typing import List, Union, Optional
import time
4
5
6
7

from sqlalchemy import String, Column, BigInteger, Text
from sqlalchemy.orm import Session

Timothy J. Baek's avatar
Timothy J. Baek committed
8
9
from utils.misc import get_gravatar_url

10
from apps.webui.internal.db import Base, JSONField, get_session
11
from apps.webui.models.chats import Chats
12

13
14
15
16
17
####################
# User DB Schema
####################


18
19
class User(Base):
    __tablename__ = "user"
Timothy J. Baek's avatar
Timothy J. Baek committed
20

21
22
23
24
25
    id = Column(String, primary_key=True)
    name = Column(String)
    email = Column(String)
    role = Column(String)
    profile_image_url = Column(String)
Timothy J. Baek's avatar
Timothy J. Baek committed
26

27
28
29
    last_active_at = Column(BigInteger)
    updated_at = Column(BigInteger)
    created_at = Column(BigInteger)
Timothy J. Baek's avatar
Timothy J. Baek committed
30

31
32
33
    api_key = Column(String, nullable=True, unique=True)
    settings = Column(JSONField, nullable=True)
    info = Column(JSONField, nullable=True)
34

35
    oauth_sub = Column(Text, unique=True)
Timothy J. Baek's avatar
Timothy J. Baek committed
36
37


38
39
40
41
42
43
class UserSettings(BaseModel):
    ui: Optional[dict] = {}
    model_config = ConfigDict(extra="allow")
    pass


44
45
46
47
class UserModel(BaseModel):
    id: str
    name: str
    email: str
Timothy J. Baek's avatar
Timothy J. Baek committed
48
    role: str = "pending"
49
    profile_image_url: str
Timothy J. Baek's avatar
Timothy J. Baek committed
50
51
52
53
54

    last_active_at: int  # timestamp in epoch
    updated_at: int  # timestamp in epoch
    created_at: int  # timestamp in epoch

55
    api_key: Optional[str] = None
56
    settings: Optional[UserSettings] = None
Timothy J. Baek's avatar
Timothy J. Baek committed
57
    info: Optional[dict] = None
58

59
60
    oauth_sub: Optional[str] = None

61
62
    model_config = ConfigDict(from_attributes=True)

63
64
65
66
67
68

####################
# Forms
####################


Timothy J. Baek's avatar
Timothy J. Baek committed
69
70
71
72
73
class UserRoleUpdateForm(BaseModel):
    id: str
    role: str


Timothy J. Baek's avatar
Timothy J. Baek committed
74
75
76
77
78
79
class UserUpdateForm(BaseModel):
    name: str
    email: str
    profile_image_url: str
    password: Optional[str] = None

80

Timothy J. Baek's avatar
Timothy J. Baek committed
81
class UsersTable:
82

Timothy J. Baek's avatar
Timothy J. Baek committed
83
    def insert_new_user(
Danny Liu's avatar
Danny Liu committed
84
85
86
87
        self,
        id: str,
        name: str,
        email: str,
Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
88
        profile_image_url: str = "/user.png",
Danny Liu's avatar
Danny Liu committed
89
        role: str = "pending",
90
        oauth_sub: Optional[str] = None,
Timothy J. Baek's avatar
Timothy J. Baek committed
91
    ) -> Optional[UserModel]:
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
        with get_session() as db:
            user = UserModel(
                **{
                    "id": id,
                    "name": name,
                    "email": email,
                    "role": role,
                    "profile_image_url": profile_image_url,
                    "last_active_at": int(time.time()),
                    "created_at": int(time.time()),
                    "updated_at": int(time.time()),
                    "oauth_sub": oauth_sub,
                }
            )
            result = User(**user.model_dump())
            db.add(result)
            db.commit()
            db.refresh(result)
            if result:
                return user
            else:
                return None

    def get_user_by_id(self, id: str) -> Optional[UserModel]:
        with get_session() as db:
            try:
                user = db.query(User).filter_by(id=id).first()
                return UserModel.model_validate(user)
            except Exception as e:
                return None

    def get_user_by_api_key(self, api_key: str) -> Optional[UserModel]:
        with get_session() as db:
            try:
                user = db.query(User).filter_by(api_key=api_key).first()
                return UserModel.model_validate(user)
            except:
                return None

    def get_user_by_email(self, email: str) -> Optional[UserModel]:
        with get_session() as db:
            try:
                user = db.query(User).filter_by(email=email).first()
                return UserModel.model_validate(user)
            except:
                return None
138

139
    def get_user_by_oauth_sub(self, sub: str) -> Optional[UserModel]:
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
        with get_session() as db:
            try:
                user = db.query(User).filter_by(oauth_sub=sub).first()
                return UserModel.model_validate(user)
            except:
                return None

    def get_users(self, skip: int = 0, limit: int = 50) -> List[UserModel]:
        with get_session() as db:
            users = (
                db.query(User)
                # .offset(skip).limit(limit)
                .all()
            )
            return [UserModel.model_validate(user) for user in users]

    def get_num_users(self) -> Optional[int]:
        with get_session() as db:
            return db.query(User).count()

    def get_first_user(self) -> UserModel:
        with get_session() as db:
            try:
                user = db.query(User).order_by(User.created_at).first()
                return UserModel.model_validate(user)
            except:
                return None
167

168
    def update_user_role_by_id(
169
        self, id: str, role: str
170
    ) -> Optional[UserModel]:
171
172
173
174
        with get_session() as db:
            try:
                db.query(User).filter_by(id=id).update({"role": role})
                db.commit()
Timothy J. Baek's avatar
Timothy J. Baek committed
175

176
177
178
179
                user = db.query(User).filter_by(id=id).first()
                return UserModel.model_validate(user)
            except:
                return None
Timothy J. Baek's avatar
Timothy J. Baek committed
180

181
    def update_user_profile_image_url_by_id(
182
        self, id: str, profile_image_url: str
183
    ) -> Optional[UserModel]:
184
185
186
187
188
189
        with get_session() as db:
            try:
                db.query(User).filter_by(id=id).update(
                    {"profile_image_url": profile_image_url}
                )
                db.commit()
190

191
192
193
194
                user = db.query(User).filter_by(id=id).first()
                return UserModel.model_validate(user)
            except:
                return None
195

196
    def update_user_last_active_by_id(
197
        self, id: str
198
    ) -> Optional[UserModel]:
199
200
201
        with get_session() as db:
            try:
                db.query(User).filter_by(id=id).update({"last_active_at": int(time.time())})
Timothy J. Baek's avatar
Timothy J. Baek committed
202

203
204
205
206
                user = db.query(User).filter_by(id=id).first()
                return UserModel.model_validate(user)
            except:
                return None
Timothy J. Baek's avatar
Timothy J. Baek committed
207

208
    def update_user_oauth_sub_by_id(
209
        self, id: str, oauth_sub: str
210
    ) -> Optional[UserModel]:
211
212
213
        with get_session() as db:
            try:
                db.query(User).filter_by(id=id).update({"oauth_sub": oauth_sub})
214

215
216
217
218
                user = db.query(User).filter_by(id=id).first()
                return UserModel.model_validate(user)
            except:
                return None
219

220
    def update_user_by_id(
221
        self, id: str, updated: dict
222
    ) -> Optional[UserModel]:
223
224
225
226
        with get_session() as db:
            try:
                db.query(User).filter_by(id=id).update(updated)
                db.commit()
Timothy J. Baek's avatar
Timothy J. Baek committed
227

228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
                user = db.query(User).filter_by(id=id).first()
                return UserModel.model_validate(user)
                # return UserModel(**user.dict())
            except Exception as e:
                return None

    def delete_user_by_id(self, id: str) -> bool:
        with get_session() as db:
            try:
                # Delete User Chats
                result = Chats.delete_chats_by_user_id(id)

                if result:
                    # Delete User
                    db.query(User).filter_by(id=id).delete()
                    db.commit()

                    return True
                else:
                    return False
            except:
                return False
250

251
252
253
254
    def update_user_api_key_by_id(self, id: str, api_key: str) -> str:
        with get_session() as db:
            try:
                result = db.query(User).filter_by(id=id).update({"api_key": api_key})
255
                db.commit()
256
257
                return True if result == 1 else False
            except:
258
                return False
259

260
261
262
263
264
265
266
    def get_user_api_key_by_id(self, id: str) -> Optional[str]:
        with get_session() as db:
            try:
                user = db.query(User).filter_by(id=id).first()
                return user.api_key
            except Exception as e:
                return None
Timothy J. Baek's avatar
refac  
Timothy J. Baek committed
267

268

269
Users = UsersTable()