Merge pull request #6 from valueonag/dev-ida
registration and token aquisition with msal
This commit is contained in:
commit
c489842268
5 changed files with 127 additions and 4 deletions
2
app.py
2
app.py
|
|
@ -86,7 +86,7 @@ async def lifespan(app: FastAPI):
|
|||
|
||||
# Parse CORS origins from environment variable
|
||||
def get_allowed_origins():
|
||||
origins_str = APP_CONFIG.get("APP_ALLOWED_ORIGINS", "http://localhost:8080")
|
||||
origins_str = APP_CONFIG.get("APP_ALLOWED_ORIGINS", "http://localhost:5176")
|
||||
# Split by comma and strip whitespace
|
||||
origins = [origin.strip() for origin in origins_str.split(",")]
|
||||
logger.info(f"CORS allowed origins: {origins}")
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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": []
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue