diff --git a/env_dev.env b/env_dev.env index 54828aa6..ad9fcbaa 100644 --- a/env_dev.env +++ b/env_dev.env @@ -22,7 +22,7 @@ APP_JWT_SECRET_SECRET=dev_jwt_secret_token APP_TOKEN_EXPIRY=300 # CORS Configuration -APP_ALLOWED_ORIGINS=http://localhost:8080,https://playground.poweron-center.net +APP_ALLOWED_ORIGINS=http://localhost:8080,https://playground.poweron-center.net,http://localhost:5176,https://nyla.poweron-center.net # Logging configuration APP_LOGGING_LOG_LEVEL = DEBUG diff --git a/env_prod.env b/env_prod.env index 57b1da4b..47133cd6 100644 --- a/env_prod.env +++ b/env_prod.env @@ -22,7 +22,7 @@ APP_JWT_SECRET_SECRET=dev_jwt_secret_token APP_TOKEN_EXPIRY=300 # CORS Configuration -APP_ALLOWED_ORIGINS=http://localhost:8080,https://playground.poweron-center.net +APP_ALLOWED_ORIGINS=http://localhost:8080,https://playground.poweron-center.net,http://localhost:5176,https://nyla.poweron-center.net # Logging configuration APP_LOGGING_LOG_LEVEL = WARNING diff --git a/routes/routeMsft.py b/routes/routeMsft.py index ddbdc343..c5afed9b 100644 --- a/routes/routeMsft.py +++ b/routes/routeMsft.py @@ -7,9 +7,10 @@ from typing import Dict, Any, Optional, List from datetime import datetime, timedelta import secrets -from modules.auth import getCurrentActiveUser, getUserContext +from modules.auth import getCurrentActiveUser, getUserContext, createAccessToken, ACCESS_TOKEN_EXPIRE_MINUTES from modules.configuration import APP_CONFIG from modules.lucydomInterface import getLucydomInterface +from modules.gatewayInterface import getGatewayInterface # Configure logger logger = logging.getLogger(__name__) @@ -479,6 +480,70 @@ async def get_access_token(currentUser: Dict[str, Any] = Depends(getCurrentActiv detail=f"Error getting access token: {str(e)}" ) + +@router.post("/token") +async def get_backend_token(request: Request): + """Convert MSAL token to backend token""" + try: + # Get the authorization header + auth_header = request.headers.get('Authorization') + if not auth_header or not auth_header.startswith('Bearer '): + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Missing or invalid authorization header" + ) + + # Extract the MSAL token + msal_token = auth_header.split(' ')[1] + + # Verify the MSAL token and get user info + user_info = get_user_info_from_token(msal_token) + if not user_info: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="Invalid MSAL token" + ) + + # Get the user from the database using the email + gateway = getGatewayInterface() + user = gateway.getUserByUsername(user_info["email"]) + + if not user: + raise HTTPException( + status_code=status.HTTP_401_UNAUTHORIZED, + detail="User not registered in the system" + ) + + # Create backend token + access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES) + access_token = createAccessToken( + data={ + "sub": user["username"], + "mandateId": user["mandateId"] + }, + expiresDelta=access_token_expires + ) + + return { + "accessToken": access_token, + "tokenType": "bearer", + "user": { + "username": user["username"], + "email": user["email"], + "fullName": user.get("fullName", ""), + "mandateId": user["mandateId"] + } + } + + except HTTPException: + raise + except Exception as e: + logger.error(f"Error in MSAL token conversion: {str(e)}") + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail=f"Error processing MSAL token: {str(e)}" + ) +======= @router.post("/save-token") async def save_token(token_data: Dict[str, Any], currentUser: Dict[str, Any] = Depends(getCurrentActiveUser)): """Save Microsoft token data from frontend""" @@ -548,3 +613,4 @@ filesDelivered = {self.parseJson2text(matchingDocuments)} "content": "I apologize, but there was an error generating the final message. Please check the logs for more details.", "documents": [] } + diff --git a/routes/routeUsers.py b/routes/routeUsers.py index d149125e..dffa63f8 100644 --- a/routes/routeUsers.py +++ b/routes/routeUsers.py @@ -123,6 +123,63 @@ async def registerUser(userData: dict = Body(...)): logger.error(traceback.format_exc()) raise HTTPException(status_code=500, detail=f"Registration failed: {str(e)}") +@router.post("/register-with-msal", response_model=Dict[str, Any]) +async def registerUserWithMsal(userData: dict = Body(...)): + """Register a new user using Microsoft authentication""" + # Add debug logging + import logging + logger = logging.getLogger(__name__) + logger.info(f"MSAL Registration request data: {userData}") + + # Get the initial IDs for mandate and admin user + adminGateway = getGatewayInterface() + + # Get ID of the root mandate - we'll use this for new users + rootMandateId = adminGateway.getInitialId("mandates") + adminUserId = adminGateway.getInitialId("users") + + if not rootMandateId or not adminUserId: + raise HTTPException( + status_code=500, + detail="System is not properly initialized with root mandate and admin user" + ) + + # Use a gateway with admin context for user creation + gateway = getGatewayInterface(rootMandateId, adminUserId) + + if "username" not in userData: + raise HTTPException(status_code=400, detail="Username required") + + try: + # Create user data with a random password since it won't be used + import secrets + random_password = secrets.token_urlsafe(32) + + # Create user with required fields + newUser = gateway.createUser( + username=userData["username"], + password=random_password, # Random password since MSAL auth will be used + email=userData.get("email"), + fullName=userData.get("fullName"), + language=userData.get("language", "de"), + mandateId=rootMandateId, + disabled=False, + privilege="user" + ) + + return newUser + except ValueError as e: + logger.error(f"ValueError in MSAL registration: {str(e)}") + raise HTTPException(status_code=400, detail=str(e)) + except PermissionError as e: + logger.error(f"PermissionError in MSAL registration: {str(e)}") + raise HTTPException(status_code=403, detail=str(e)) + except Exception as e: + import traceback + logger.error(f"Unexpected error in MSAL registration: {str(e)}") + logger.error(traceback.format_exc()) + raise HTTPException(status_code=500, detail=f"MSAL Registration failed: {str(e)}") + @router.get("/{userId}", response_model=Dict[str, Any]) async def getUser( userId: int,