MGLDZM commited on
Commit
6f6eeb8
1 Parent(s): 9e2a147

test: oauth

Browse files
Files changed (4) hide show
  1. main.py +29 -78
  2. modules/oauth.py +30 -0
  3. modules/security.py +58 -0
  4. static/iniciar_sesion.html +3 -3
main.py CHANGED
@@ -1,100 +1,33 @@
1
  from fastapi import FastAPI, Request, staticfiles, Depends, HTTPException, status
2
- from fastapi.responses import HTMLResponse, StreamingResponse, JSONResponse
3
 
4
  from fastapi.security import HTTPBasic, HTTPBasicCredentials
5
  import os, json
6
- from datetime import datetime, timedelta
7
  import time
8
- import jwt
9
  from openai import OpenAI
10
  from hashlib import sha256
11
  from error_map import error_table
12
  from logger import log_write, logger
13
- from oauthlib.oauth2 import WebApplicationClient
14
 
15
  from pymongo.mongo_client import MongoClient
16
  from pymongo.server_api import ServerApi
17
 
18
-
19
-
20
- GOOGLE_CLIENT_ID = os.environ.get("GOOGLE_CSE_ID", None)
21
- GOOGLE_CLIENT_SECRET = os.environ.get("GOOGLE_API_KEY", None)
22
- GOOGLE_DISCOVERY_URL = (
23
- "https://accounts.google.com/.well-known/openid-configuration"
24
- )
25
-
26
  MONGO_URL = os.environ.get("MONGO_URL", None)
27
  MONGO_PWD = os.environ.get("MONGO_PWD", None)
28
  MONGO_USR = os.environ.get("MONGO_USR", None)
29
 
30
-
31
-
32
  import chat_functions
33
 
34
-
35
-
36
-
37
  app = FastAPI()
38
- security = HTTPBasic()
39
  model = "gpt-3.5-turbo-16k"
40
  app.mount("/static", staticfiles.StaticFiles(directory="static"), name="static")
41
  users = json.loads(str(os.getenv("USER_KEYS")).replace("\n", ""))
42
 
43
-
44
- for key in users:
45
- if key == "master": continue
46
- password = key+users[key]+users["master"]
47
- users[key] = sha256(password.encode('UTF-8')).hexdigest()
48
-
49
-
50
  fecha_unix = str(int(time.time()))
51
-
52
- JWT_SECRET = users["master"]
53
- JWT_ALGORITHM = "HS256"
54
- JWT_EXPIRATION_TIME_MINUTES = 30
55
-
56
-
57
  log_write("master", "iniciado", "-")
58
 
59
- ### Login stuff
60
-
61
- def authenticate_user(credentials: HTTPBasicCredentials) -> bool:
62
- username = credentials.username
63
- password = credentials.password
64
- password = username+password+users["master"]
65
- password = sha256(password.encode('UTF-8')).hexdigest()
66
-
67
- if credentials.username not in users or password != users[credentials.username]:
68
- log_write(credentials.username, "Autenticacion usuario fallida", "")
69
- raise HTTPException(
70
- status_code=status.HTTP_401_UNAUTHORIZED,
71
- detail="Incorrect username or password",
72
- headers={"WWW-Authenticate": "Basic"},
73
- )
74
-
75
- log_write(credentials.username, "Usuario autenticado", "")
76
- return True
77
-
78
-
79
- def create_jwt_token(data):
80
- to_encode = {"data": data}
81
- expire = datetime.utcnow() + timedelta(minutes=JWT_EXPIRATION_TIME_MINUTES)
82
- to_encode.update({"exp": expire})
83
- encoded_jwt = jwt.encode(to_encode, JWT_SECRET, algorithm=JWT_ALGORITHM)
84
- return encoded_jwt
85
-
86
- async def validate_token(request: Request):
87
- data = {}
88
- try:
89
- data = await request.json()
90
- token = data.pop("token")
91
- payload = jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALGORITHM])
92
- data["token_data"] = payload["data"]
93
- except Exception as e:
94
- logger.error(repr(e) + " - " + str(data))
95
- raise HTTPException(status_code=404, detail="Token inv谩lido")
96
- return data
97
-
98
 
99
 
100
  def ejecutar_llm(data):
@@ -136,14 +69,14 @@ def manejar_funciones(chunk, response_async, data):
136
  return json.dumps(f_cb), ejecutar_llm(data)
137
 
138
  @app.get("/", response_class=HTMLResponse)
139
- async def root(request: Request, credentials: HTTPBasicCredentials = Depends(security)):
140
- if authenticate_user(credentials):
141
- token = create_jwt_token({"user":credentials.username})
142
  with open(os.path.join("static", "main.html")) as f:
143
  return HTMLResponse(f.read().replace("{% token %}", token).replace("{% version %}", fecha_unix))
144
 
145
  @app.post("/chat")
146
- async def s_chat(data = Depends(validate_token)):
147
  messages = data.get("messages", "")
148
 
149
  if not messages:
@@ -173,7 +106,7 @@ async def s_chat(data = Depends(validate_token)):
173
 
174
 
175
  @app.post("/a_chat")
176
- async def a_chat(data = Depends(validate_token)):
177
  messages = data.get("messages", "")
178
 
179
 
@@ -213,13 +146,13 @@ async def a_chat(data = Depends(validate_token)):
213
 
214
  mensaje = {"role": "assistant", "content":content}
215
  yield json.dumps({"comando": "mensaje", "mensaje": mensaje})
216
- yield json.dumps({"comando": "token", "token":create_jwt_token(data["token_data"])})
217
  return StreamingResponse(__streamer(response_async, data), media_type="application/json")
218
 
219
 
220
  @app.get("/read_log", response_class=HTMLResponse)
221
- async def read_log(request: Request, credentials: HTTPBasicCredentials = Depends(security)):
222
- if sha256(credentials.username.encode()).hexdigest()=="bc1c32d709aef061bbde4fc848421cdb933e8a9f391c3a089f2861ac0772c168" and authenticate_user(credentials):
223
  log_write(credentials.username, "Log Accesado", "")
224
  with open("logs/eventos.log", "r") as f:
225
  return HTMLResponse(f.read())
@@ -236,4 +169,22 @@ async def test(request: Request):
236
  except Exception as e:
237
  log_write("", "test", str(e))
238
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
 
 
1
  from fastapi import FastAPI, Request, staticfiles, Depends, HTTPException, status
2
+ from fastapi.responses import HTMLResponse, StreamingResponse
3
 
4
  from fastapi.security import HTTPBasic, HTTPBasicCredentials
5
  import os, json
 
6
  import time
 
7
  from openai import OpenAI
8
  from hashlib import sha256
9
  from error_map import error_table
10
  from logger import log_write, logger
11
+ from modules import oauth, security
12
 
13
  from pymongo.mongo_client import MongoClient
14
  from pymongo.server_api import ServerApi
15
 
 
 
 
 
 
 
 
 
16
  MONGO_URL = os.environ.get("MONGO_URL", None)
17
  MONGO_PWD = os.environ.get("MONGO_PWD", None)
18
  MONGO_USR = os.environ.get("MONGO_USR", None)
19
 
 
 
20
  import chat_functions
21
 
 
 
 
22
  app = FastAPI()
23
+ httpsecurity = HTTPBasic()
24
  model = "gpt-3.5-turbo-16k"
25
  app.mount("/static", staticfiles.StaticFiles(directory="static"), name="static")
26
  users = json.loads(str(os.getenv("USER_KEYS")).replace("\n", ""))
27
 
 
 
 
 
 
 
 
28
  fecha_unix = str(int(time.time()))
 
 
 
 
 
 
29
  log_write("master", "iniciado", "-")
30
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
 
33
  def ejecutar_llm(data):
 
69
  return json.dumps(f_cb), ejecutar_llm(data)
70
 
71
  @app.get("/", response_class=HTMLResponse)
72
+ async def root(request: Request, credentials: HTTPBasicCredentials = Depends(httpsecurity)):
73
+ if security.authenticate_user(credentials):
74
+ token = security.create_jwt_token({"user":credentials.username})
75
  with open(os.path.join("static", "main.html")) as f:
76
  return HTMLResponse(f.read().replace("{% token %}", token).replace("{% version %}", fecha_unix))
77
 
78
  @app.post("/chat")
79
+ async def s_chat(data = Depends(security.validate_token)):
80
  messages = data.get("messages", "")
81
 
82
  if not messages:
 
106
 
107
 
108
  @app.post("/a_chat")
109
+ async def a_chat(data = Depends(security.validate_token)):
110
  messages = data.get("messages", "")
111
 
112
 
 
146
 
147
  mensaje = {"role": "assistant", "content":content}
148
  yield json.dumps({"comando": "mensaje", "mensaje": mensaje})
149
+ yield json.dumps({"comando": "token", "token": security.create_jwt_token(data["token_data"])})
150
  return StreamingResponse(__streamer(response_async, data), media_type="application/json")
151
 
152
 
153
  @app.get("/read_log", response_class=HTMLResponse)
154
+ async def read_log(request: Request, credentials: HTTPBasicCredentials = Depends(httpsecurity)):
155
+ if sha256(credentials.username.encode()).hexdigest()=="bc1c32d709aef061bbde4fc848421cdb933e8a9f391c3a089f2861ac0772c168" and security.authenticate_user(credentials):
156
  log_write(credentials.username, "Log Accesado", "")
157
  with open("logs/eventos.log", "r") as f:
158
  return HTMLResponse(f.read())
 
169
  except Exception as e:
170
  log_write("", "test", str(e))
171
 
172
+ @app.get("/privacy", response_class=HTMLResponse)
173
+ async def sesion_i(request: Request):
174
+ with open(os.path.join("static", "PrivacyPolicy.html")) as f:
175
+ return HTMLResponse(f.read())
176
+
177
+ @app.get("/login", response_class=HTMLResponse)
178
+ async def login(request: Request):
179
+ with open(os.path.join("static", "iniciar_sesion.html")) as f:
180
+ return HTMLResponse(f.read())
181
+
182
+ @app.get("/oauth", response_class=HTMLResponse)
183
+ async def validate_oauth(request: Request):
184
+ params = dict(request.query_params)
185
+ google_userinfo = oauth.validate_redirect(params)
186
+ return json.dumps(google_userinfo, indent=2)
187
+
188
+
189
+
190
 
modules/oauth.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests, os
2
+
3
+
4
+ GOOGLE_CLIENT_ID = os.environ.get("GOOGLE_CLIENT_ID", None)
5
+ GOOGLE_CLIENT_SECRET = os.environ.get("GOOGLE_CLIENT_SECRET", None)
6
+ OAUTH_REDIRECT = os.environ.get("OAUTH_REDIRECT", None)
7
+
8
+ def validate_redirect(params):
9
+ data = {
10
+ 'code': params["code"],
11
+ 'redirect_uri': OAUTH_REDIRECT,
12
+ 'client_id': GOOGLE_CLIENT_ID,
13
+ 'client_secret': GOOGLE_CLIENT_SECRET,
14
+ 'scope': params["scope"],
15
+ 'grant_type': 'authorization_code'
16
+ }
17
+
18
+ google_auth_rq = requests.post("https://oauth2.googleapis.com/token", data=data)
19
+ google_auth = google_auth_rq.json()
20
+
21
+ try:
22
+ headers = {
23
+ 'Authorization': google_auth["token_type"]+" "+google_auth["access_token"]
24
+ }
25
+ except Exception as e:
26
+ print(e)
27
+ print(google_auth_rq.content)
28
+ return str(e)+" "+google_auth_rq.content
29
+ google_userinfo_rq = requests.get("https://www.googleapis.com/oauth2/v2/userinfo", headers=headers)
30
+ return google_userinfo_rq.json()
modules/security.py ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json, os, jwt
2
+ from hashlib import sha256
3
+ from fastapi import HTTPException, status, Request
4
+ from fastapi.security import HTTPBasicCredentials
5
+ from logger import log_write, logger
6
+ from datetime import datetime, timedelta
7
+
8
+
9
+
10
+
11
+ users = json.loads(str(os.getenv("USER_KEYS")).replace("\n", ""))
12
+ for key in users:
13
+ if key == "master": continue
14
+ password = key+users[key]+users["master"]
15
+ users[key] = sha256(password.encode('UTF-8')).hexdigest()
16
+
17
+ JWT_SECRET = users["master"]
18
+ JWT_ALGORITHM = "HS256"
19
+ JWT_EXPIRATION_TIME_MINUTES = 30
20
+
21
+ def authenticate_user(credentials: HTTPBasicCredentials) -> bool:
22
+ username = credentials.username
23
+ password = credentials.password
24
+ password = username+password+users["master"]
25
+ password = sha256(password.encode('UTF-8')).hexdigest()
26
+
27
+ if credentials.username not in users or password != users[credentials.username]:
28
+ log_write(credentials.username, "Autenticacion usuario fallida", "")
29
+ raise HTTPException(
30
+ status_code=status.HTTP_401_UNAUTHORIZED,
31
+ detail="Incorrect username or password",
32
+ headers={"WWW-Authenticate": "Basic"},
33
+ )
34
+
35
+ log_write(credentials.username, "Usuario autenticado", "")
36
+ return True
37
+
38
+ def create_jwt_token(data):
39
+ to_encode = {"data": data}
40
+ expire = datetime.utcnow() + timedelta(minutes=JWT_EXPIRATION_TIME_MINUTES)
41
+ to_encode.update({"exp": expire})
42
+ encoded_jwt = jwt.encode(to_encode, JWT_SECRET, algorithm=JWT_ALGORITHM)
43
+ return encoded_jwt
44
+
45
+
46
+
47
+ async def validate_token(request: Request):
48
+ data = {}
49
+ try:
50
+ data = await request.json()
51
+ token = data.pop("token")
52
+ payload = jwt.decode(token, JWT_SECRET, algorithms=[JWT_ALGORITHM])
53
+ data["token_data"] = payload["data"]
54
+ except Exception as e:
55
+ logger.error(repr(e) + " - " + str(data))
56
+ raise HTTPException(status_code=404, detail="Token inv谩lido")
57
+ return data
58
+
static/iniciar_sesion.html CHANGED
@@ -1,5 +1,5 @@
1
  <!DOCTYPE html>
2
- <html>
3
  <head>
4
  <title>Login con Google</title>
5
  </head>
@@ -8,8 +8,8 @@
8
 
9
  <script>
10
  function iniciarSesion() {
11
- var redirectUri = 'http://127.0.0.1:8000/sesioni'; // Reemplaza con la URL a la que se redirigir谩 despu茅s del inicio de sesi贸n
12
- var clientId = 'e743f8a36120049fb'; // Reemplaza con tu ID de cliente de Google
13
 
14
  var url = 'https://accounts.google.com/o/oauth2/auth' +
15
  '?response_type=code' +
 
1
  <!DOCTYPE html>
2
+ <html lang="ES">
3
  <head>
4
  <title>Login con Google</title>
5
  </head>
 
8
 
9
  <script>
10
  function iniciarSesion() {
11
+ var redirectUri = 'http://127.0.0.1:8000/oauth'; // Reemplaza con la URL a la que se redirigir谩 despu茅s del inicio de sesi贸n
12
+ var clientId = '1051565752404-h4un77s3k4el280e589hn98s8ea4bg69.apps.googleusercontent.com'; // Reemplaza con tu ID de cliente de Google
13
 
14
  var url = 'https://accounts.google.com/o/oauth2/auth' +
15
  '?response_type=code' +