88import secrets
99import json
1010import base64
11- from modules . config .constants import (
11+ from config .constants import (
1212 OAUTH_GOOGLE_CLIENT_ID ,
1313 OAUTH_GOOGLE_CLIENT_SECRET ,
1414 CHAINLIT_URL ,
15- GITHUB_REPO ,
16- DOCS_WEBSITE ,
17- ALL_TIME_TOKENS_ALLOCATED ,
18- TOKENS_LEFT ,
15+ EMAIL_ENCRYPTION_KEY ,
1916)
2017from fastapi .middleware .cors import CORSMiddleware
2118from fastapi .staticfiles import StaticFiles
22- from modules .chat_processor .helpers import (
23- get_user_details ,
19+ from helpers import (
2420 get_time ,
2521 reset_tokens_for_user ,
2622 check_user_cooldown ,
27- update_user_info ,
2823)
24+ from modules .chat_processor .helpers import get_user_details , update_user_info
25+ from config .config_manager import config_manager
26+ import hashlib
27+
28+ # set config
29+ config = config_manager .get_config ().dict ()
30+
31+ # set constants
32+ GITHUB_REPO = config ["misc" ]["github_repo" ]
33+ DOCS_WEBSITE = config ["misc" ]["docs_website" ]
34+ ALL_TIME_TOKENS_ALLOCATED = config ["token_config" ]["all_time_tokens_allocated" ]
35+ TOKENS_LEFT = config ["token_config" ]["tokens_left" ]
36+ COOLDOWN_TIME = config ["token_config" ]["cooldown_time" ]
37+ REGEN_TIME = config ["token_config" ]["regen_time" ]
2938
3039GOOGLE_CLIENT_ID = OAUTH_GOOGLE_CLIENT_ID
3140GOOGLE_CLIENT_SECRET = OAUTH_GOOGLE_CLIENT_SECRET
4655CHAINLIT_PATH = "/chainlit_tutor"
4756
4857# only admin is given any additional permissions for now -- no limits on tokens
49- USER_ROLES = {
50- "[email protected] " : [
"instructor" ,
"bu" ],
51- "[email protected] " : [
"admin" ,
"instructor" ,
"bu" ],
52- "[email protected] " : [
"instructor" ,
"bu" ],
53- 54- # Add more users and roles as needed
55- }
58+ with open ("public/files/students_encrypted.json" , "r" ) as file :
59+ USER_ROLES = json .load (file )
5660
5761# Create a Google OAuth flow
5862flow = Flow .from_client_config (
8084
8185
8286def get_user_role (username : str ):
83- return USER_ROLES .get (username , ["guest" ]) # Default to "guest" role
87+
88+ # Function to deterministically hash emails
89+ def deterministic_hash (email , salt ):
90+ return hashlib .pbkdf2_hmac ("sha256" , email .encode (), salt , 100000 ).hex ()
91+
92+ # encrypt email (#FIXME: this is not the best way to do this, not really encryption, more like a hash)
93+ encryption_salt = EMAIL_ENCRYPTION_KEY .encode ()
94+ encrypted_email = deterministic_hash (username , encryption_salt )
95+ role = USER_ROLES .get (encrypted_email , ["guest" ])
96+
97+ if "guest" in role :
98+ return "unauthorized"
99+
100+ return role
84101
85102
86103async def get_user_info_from_cookie (request : Request ):
@@ -146,6 +163,11 @@ async def login_page(request: Request):
146163# return response
147164
148165
166+ @app .get ("/unauthorized" , response_class = HTMLResponse )
167+ async def unauthorized (request : Request ):
168+ return templates .TemplateResponse ("unauthorized.html" , {"request" : request })
169+
170+
149171@app .get ("/login/google" )
150172async def login_google (request : Request ):
151173 # Clear any existing session cookies to avoid conflicts with guest sessions
@@ -176,6 +198,9 @@ async def auth_google(request: Request):
176198 profile_image = user_info .get ("picture" , "" )
177199 role = get_user_role (email )
178200
201+ if role == "unauthorized" :
202+ return RedirectResponse ("/unauthorized" )
203+
179204 session_token = secrets .token_hex (16 )
180205 session_store [session_token ] = {
181206 "email" : email ,
@@ -210,7 +235,7 @@ async def cooldown(request: Request):
210235 user_details = await get_user_details (user_info ["email" ])
211236 current_datetime = get_time ()
212237 cooldown , cooldown_end_time = await check_user_cooldown (
213- user_details , current_datetime
238+ user_details , current_datetime , COOLDOWN_TIME , TOKENS_LEFT , REGEN_TIME
214239 )
215240 print (f"User in cooldown: { cooldown } " )
216241 print (f"Cooldown end time: { cooldown_end_time } " )
@@ -228,7 +253,11 @@ async def cooldown(request: Request):
228253 else :
229254 user_details .metadata ["in_cooldown" ] = False
230255 await update_user_info (user_details )
231- await reset_tokens_for_user (user_details )
256+ await reset_tokens_for_user (
257+ user_details ,
258+ config ["token_config" ]["tokens_left" ],
259+ config ["token_config" ]["regen_time" ],
260+ )
232261 return RedirectResponse ("/post-signin" )
233262
234263
@@ -256,13 +285,19 @@ async def post_signin(request: Request):
256285 if "last_message_time" in user_details .metadata and "admin" not in get_user_role (
257286 user_info ["email" ]
258287 ):
259- cooldown , _ = await check_user_cooldown (user_details , current_datetime )
288+ cooldown , _ = await check_user_cooldown (
289+ user_details , current_datetime , COOLDOWN_TIME , TOKENS_LEFT , REGEN_TIME
290+ )
260291 if cooldown :
261292 user_details .metadata ["in_cooldown" ] = True
262293 return RedirectResponse ("/cooldown" )
263294 else :
264295 user_details .metadata ["in_cooldown" ] = False
265- await reset_tokens_for_user (user_details )
296+ await reset_tokens_for_user (
297+ user_details ,
298+ config ["token_config" ]["tokens_left" ],
299+ config ["token_config" ]["regen_time" ],
300+ )
266301
267302 if user_info :
268303 username = user_info ["email" ]
@@ -335,15 +370,19 @@ async def get_tokens_left(request: Request):
335370 try :
336371 user_info = await get_user_info_from_cookie (request )
337372 user_details = await get_user_details (user_info ["email" ])
338- await reset_tokens_for_user (user_details )
373+ await reset_tokens_for_user (
374+ user_details ,
375+ config ["token_config" ]["tokens_left" ],
376+ config ["token_config" ]["regen_time" ],
377+ )
339378 tokens_left = user_details .metadata ["tokens_left" ]
340379 return {"tokens_left" : tokens_left }
341380 except Exception as e :
342381 print (f"Error getting tokens left: { e } " )
343382 return {"tokens_left" : 0 }
344383
345384
346- mount_chainlit (app = app , target = "main .py" , path = CHAINLIT_PATH )
385+ mount_chainlit (app = app , target = "chainlit_app .py" , path = CHAINLIT_PATH )
347386
348387if __name__ == "__main__" :
349388 import uvicorn
0 commit comments