Skip to content
This repository has been archived by the owner on Sep 27, 2024. It is now read-only.

Commit

Permalink
Fix login endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
msathieu committed Mar 13, 2024
1 parent 20e10ca commit 8b339f1
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 30 deletions.
6 changes: 3 additions & 3 deletions backend/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
from starlette.responses import JSONResponse

from db.errors.database_errors import ActionAlreadyPerformedError, ItemNotFoundError, NoSuchRelationError
from routes.errors.authentication import InvalidRoleCredentialsError, InvalidTokenError, NoAccessToSubjectError
from routes.errors.authentication import InvalidAuthenticationError, InvalidRoleCredentialsError, NoAccessToSubjectError
from routes.group import group_router
from routes.login import login_router
from routes.project import project_router
Expand Down Expand Up @@ -87,8 +87,8 @@ def no_such_relation_error_handler(request: Request, exc: NoSuchRelationError) -
)


@app.exception_handler(InvalidTokenError)
def invalid_token_error_handler(request: Request, exc: NoSuchRelationError) -> JSONResponse:
@app.exception_handler(InvalidAuthenticationError)
def invalid_authentication_error_handler(request: Request, exc: NoSuchRelationError) -> JSONResponse:
return JSONResponse(
status_code=status.HTTP_401_UNAUTHORIZED,
content={"detail": str(exc)},
Expand Down
40 changes: 21 additions & 19 deletions backend/controllers/auth/authentication_controller.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,24 +55,26 @@ def parse_cas_xml(xml: str) -> dict | None:

namespace = "{http://www.yale.edu/tp/cas}"
root: Element | None = fromstring(xml).find(f"{namespace}authenticationSuccess")
if root is not None:
user_information: Element | None = root.find(f"{namespace}attributes")
if user_information:
givenname: Element | None = user_information.find(f"{namespace}givenname")
surname: Element | None = user_information.find(f"{namespace}surname")
email: Element | None = user_information.find(f"{namespace}mail")
role: list | None = user_information.find(f"{namespace}objectClass")
if role is not None and givenname is not None and surname is not None and email is not None:
role_str: str = ""
for r in role:
if r.text == "ugentStudent" and role_str == "":
role_str = "student"
elif r.text == "ugentEmployee":
role_str = "teacher"
if root is None:
return None
user_information: Element | None = root.find(f"{namespace}attributes")
if user_information is None:
return None
givenname: Element | None = user_information.find(f"{namespace}givenname")
surname: Element | None = user_information.find(f"{namespace}surname")
email: Element | None = user_information.find(f"{namespace}mail")
role: list | None = user_information.findall(f"{namespace}objectClass")
if role is not None and givenname is not None and surname is not None and email is not None:
role_str = ""
for r in role:
if r.text == "ugentStudent" and role_str == "":
role_str = "student"
elif r.text == "ugentEmployee":
role_str = "teacher"

return {
"email": email.text.lower(),
"name": f"{givenname.text} {surname.text}",
"role": role_str,
}
return {
"email": email.text.lower(),
"name": f"{givenname.text} {surname.text}",
"role": role_str,
}
return None
4 changes: 4 additions & 0 deletions backend/domain/models/APIUser.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ class APIUser(BaseModel):
name: str
email: EmailStr
roles: list[Role]


class LoginResponse(BaseModel):
token: str
4 changes: 2 additions & 2 deletions backend/routes/dependencies/role_dependencies.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,9 @@
from domain.models.TeacherDataclass import TeacherDataclass
from routes.errors.authentication import (
InvalidAdminCredentialsError,
InvalidAuthenticationError,
InvalidStudentCredentialsError,
InvalidTeacherCredentialsError,
InvalidTokenError,
NoAccessToSubjectError,
)

Expand All @@ -27,7 +27,7 @@
def get_authenticated_user(token: str = Depends(auth_scheme)) -> int:
uid = verify_token(token)
if uid is None:
raise InvalidTokenError
raise InvalidAuthenticationError
return uid


Expand Down
2 changes: 1 addition & 1 deletion backend/routes/errors/authentication.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,5 @@ class NoAccessToSubjectError(Exception):
ERROR_MESSAGE = "User doesn't have access to subject"


class InvalidTokenError(Exception):
class InvalidAuthenticationError(Exception):
ERROR_MESSAGE = "User is not authenticated"
12 changes: 7 additions & 5 deletions backend/routes/login.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
from fastapi import APIRouter, Depends, Response
from fastapi import APIRouter, Depends
from sqlalchemy.orm import Session

from controllers.auth.authentication_controller import authenticate_user
from controllers.auth.token_controller import create_token
from db.sessions import get_session
from domain.models.APIUser import LoginResponse
from domain.models.UserDataclass import UserDataclass
from routes.errors.authentication import InvalidAuthenticationError

# test url: https://login.ugent.be/login?service=https://localhost:8080/api/login
login_router = APIRouter()
Expand All @@ -14,7 +16,7 @@
def login(
ticket: str,
session: Session = Depends(get_session),
) -> Response:
) -> LoginResponse:
"""
This function starts a session for the user.
For authentication, it uses the given ticket and the UGent CAS server (https://login.ugent.be).
Expand All @@ -26,6 +28,6 @@ def login(
- Invalid Ticket: Response: with status_code 401 (unauthenticated) and an error message
"""
user: UserDataclass | None = authenticate_user(session, ticket)
if user:
return Response(content=create_token(user))
return Response(status_code=401, content="Invalid Ticket!")
if not user:
raise InvalidAuthenticationError
return LoginResponse(token=create_token(user))

0 comments on commit 8b339f1

Please sign in to comment.