@@ -283,7 +283,8 @@ def signout():
283283 # send response
284284 return response
285285
286- def token (): # get code from body
286+ def google_sign_in ():
287+ # get code from body
287288 code = request .get_json ()['code' ]
288289 client_id = current_app .config ['COGNITO_CLIENT_ID' ]
289290 client_secret = current_app .config ['COGNITO_CLIENT_SECRET' ]
@@ -320,43 +321,143 @@ def token(): # get code from body
320321
321322 # create user object from user data
322323 user_attrs = get_user_attr (user_data )
323-
324- # check if user exists in database
325- user = None
326324
325+ # check if user exists in database
327326 with DataAccessLayer .session () as db_session :
328327 user_repo = UserRepository (db_session )
329328 signed_in_user = user_repo .get_user (user_attrs ['email' ])
330329 if (bool (signed_in_user ) == True ):
331330 user = user_schema .dump (signed_in_user )
331+ else :
332+ #if user does not exist in database, they haven't gone through sign up process, delete user from Cognito and return error
333+ try :
334+ decoded = jwt .decode (id_token , algorithms = ["RS256" ], options = {"verify_signature" : False })
335+
336+ current_app .logger .info ('Deleting user from Cognito' )
337+ response = current_app .boto_client .admin_delete_user (
338+ UserPoolId = current_app .config ['COGNITO_USER_POOL_ID' ],
339+ Username = decoded ["cognito:username" ]
340+ )
341+ current_app .logger .info ('User deleted from Cognito' )
342+ raise AuthError ({
343+ 'code' : 'No user found' ,
344+ 'message' : 'No user found'
345+ }, 400 )
346+ except botocore .exceptions .ClientError as e :
347+ current_app .logger .error ('Failed to delete user from Cognito' )
348+ code = e .response ['Error' ]['Code' ]
349+ message = e .response ['Error' ]['Message' ]
350+ raise AuthError ({
351+ 'code' : code ,
352+ 'message' : message
353+ }, 400 )
354+
355+ # set refresh token cookie
356+ session ['refresh_token' ] = refresh_token
357+ session ['username' ] = user_attrs ['email' ]
358+ session ['id_token' ] = id_token
359+
360+
361+ # return user data json
362+ return {
363+ 'token' : access_token ,
364+ 'user' : user
365+ }
366+
367+ def google_sign_up ():
368+ # get code from body
369+ code = request .get_json ()['code' ]
370+ client_id = current_app .config ['COGNITO_CLIENT_ID' ]
371+ client_secret = current_app .config ['COGNITO_CLIENT_SECRET' ]
372+ callback_uri = request .args ['callback_uri' ]
373+
374+ token_url = f"{ cognito_client_url } /oauth2/token"
375+ auth = requests .auth .HTTPBasicAuth (client_id , client_secret )
376+ redirect_uri = f"{ current_app .root_url } { callback_uri } "
377+
378+ params = {
379+ 'grant_type' : 'authorization_code' ,
380+ 'client_id' : client_id ,
381+ 'code' : code ,
382+ 'redirect_uri' : redirect_uri
383+ }
384+
385+ # get tokens from oauth2/token endpoint
386+ response = requests .post (token_url , auth = auth , data = params )
387+
388+ refresh_token = response .json ().get ('refresh_token' )
389+ access_token = response .json ().get ('access_token' )
390+ id_token = response .json ().get ('id_token' )
332391
392+ # retrieve user data
393+ try :
394+ user_data = current_app .boto_client .get_user (AccessToken = access_token )
395+ except botocore .exceptions .ClientError as e :
396+ code = e .response ['Error' ]['Code' ]
397+ message = e .response ['Error' ]['Message' ]
398+ raise AuthError ({
399+ "code" : code ,
400+ "message" : message
401+ }, 401 )
333402
334- # If not, add user to database and get user object
335- if (user is None ):
336- user_role = callback_uri .split ('/' )[2 ].capitalize ()
337- role = UserRole .COORDINATOR if user_role == 'Coordinator' else UserRole .HOST
403+ # create user object from user data
404+ user_attrs = get_user_attr (user_data )
405+ user_role = callback_uri .split ('/' )[2 ].capitalize ()
338406
407+ role = None
408+ if user_role == 'Coordinator' :
409+ role = UserRole .COORDINATOR
410+
411+ if user_role == 'Host' :
412+ role = UserRole .HOST
413+
414+ # if role is None, delete user from Cognito and return error
415+ if role is None :
339416 try :
340- with DataAccessLayer .session () as db_session :
341- user_repo = UserRepository (db_session )
342- user_repo .add_user (
343- email = user_attrs ['email' ],
344- role = role ,
345- firstName = user_attrs ['first_name' ],
346- middleName = user_attrs .get ('middle_name' , '' ),
347- lastName = user_attrs .get ('last_name' , '' )
348- )
349- except Exception as error :
350- raise AuthError ({"message" : str (error )}, 400 )
351-
417+ current_app .logger .info ('Deleting user from Cognito' )
418+ decoded = jwt .decode (id_token , algorithms = ["RS256" ], options = {"verify_signature" : False })
419+
420+ response = current_app .boto_client .admin_delete_user (
421+ UserPoolId = current_app .config ['COGNITO_USER_POOL_ID' ],
422+ Username = decoded ["cognito:username" ]
423+ )
424+ current_app .logger .info ('User deleted from Cognito' )
425+ raise AuthError ({
426+ 'code' : 'invalid_role' ,
427+ 'message' : 'Invalid role. no role found provided'
428+ }, 400 )
429+ except botocore .exceptions .ClientError as e :
430+ current_app .logger .error ('Failed to delete user from Cognito' )
431+ code = e .response ['Error' ]['Code' ]
432+ message = e .response ['Error' ]['Message' ]
433+ raise AuthError ({
434+ 'code' : code ,
435+ 'message' : message
436+ }, 400 )
437+
438+
439+
440+ try :
352441 with DataAccessLayer .session () as db_session :
353442 user_repo = UserRepository (db_session )
354- signed_in_user = user_repo .get_user (user_attrs ['email' ])
355- if (bool (signed_in_user ) == True ):
356- user = user_schema .dump (signed_in_user )
357- else :
358- raise AuthError ({"message" : "User not found in database" }, 400 )
359-
443+ user_repo .add_user (
444+ email = user_attrs ['email' ],
445+ role = role ,
446+ firstName = user_attrs ['first_name' ],
447+ middleName = user_attrs .get ('middle_name' , '' ),
448+ lastName = user_attrs .get ('last_name' , '' )
449+ )
450+ except Exception as error :
451+ raise AuthError ({"message" : str (error )}, 400 )
452+
453+ with DataAccessLayer .session () as db_session :
454+ user_repo = UserRepository (db_session )
455+ signed_in_user = user_repo .get_user (user_attrs ['email' ])
456+ if (bool (signed_in_user ) == True ):
457+ user = user_schema .dump (signed_in_user )
458+ else :
459+ raise AuthError ({"message" : "User not found in database" }, 400 )
460+
360461 # set refresh token cookie
361462 session ['refresh_token' ] = refresh_token
362463 session ['username' ] = user_attrs ['email' ]
@@ -369,7 +470,6 @@ def token(): # get code from body
369470 'user' : user
370471 }
371472
372-
373473def current_session ():
374474 user_data = None
375475 with DataAccessLayer .session () as db_session :
0 commit comments