- Enhanced the SignIDToken method to include the original Yao user ID in the token claims, improving user identification. - Updated the MakeOIDCUserInfo function to extract and set the Yao user ID from the user map, ensuring consistency in user information. - Modified the OIDCUserInfo structure to include a field for Yao user ID, facilitating better integration with Yao-specific features. - Adjusted the team invitation response to include the inviter's user ID, enhancing the invitation context.
152 lines
4.2 KiB
Go
152 lines
4.2 KiB
Go
package user
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/yaoapp/kun/log"
|
|
"github.com/yaoapp/yao/openapi/oauth"
|
|
oauthtypes "github.com/yaoapp/yao/openapi/oauth/types"
|
|
"github.com/yaoapp/yao/openapi/response"
|
|
)
|
|
|
|
// User Profile Management Handlers
|
|
|
|
// GinProfileGet handles GET /profile - Get current user profile
|
|
func GinProfileGet(c *gin.Context) {
|
|
// Get authorized user info
|
|
authInfo := oauth.GetAuthorizedInfo(c)
|
|
if authInfo == nil || authInfo.UserID == "" {
|
|
errorResp := &response.ErrorResponse{
|
|
Code: response.ErrInvalidClient.Code,
|
|
ErrorDescription: "User not authenticated",
|
|
}
|
|
response.RespondWithError(c, response.StatusUnauthorized, errorResp)
|
|
return
|
|
}
|
|
|
|
// Get user provider
|
|
userProvider, err := oauth.OAuth.GetUserProvider()
|
|
if err != nil {
|
|
log.Error("Failed to get user provider: %v", err)
|
|
errorResp := &response.ErrorResponse{
|
|
Code: response.ErrServerError.Code,
|
|
ErrorDescription: "Failed to get user provider",
|
|
}
|
|
response.RespondWithError(c, response.StatusInternalServerError, errorResp)
|
|
return
|
|
}
|
|
|
|
// Get user data with scopes
|
|
ctx := c.Request.Context()
|
|
if ctx == nil {
|
|
ctx = context.Background()
|
|
}
|
|
|
|
user, err := userProvider.GetUserWithScopes(ctx, authInfo.UserID)
|
|
if err != nil {
|
|
log.Error("Failed to get user profile: %v", err)
|
|
errorResp := &response.ErrorResponse{
|
|
Code: response.ErrServerError.Code,
|
|
ErrorDescription: "Failed to retrieve user profile",
|
|
}
|
|
response.RespondWithError(c, response.StatusInternalServerError, errorResp)
|
|
return
|
|
}
|
|
|
|
// Get Yao client config
|
|
yaoClientConfig := GetYaoClientConfig()
|
|
|
|
// Get or create subject
|
|
subject, err := oauth.OAuth.Subject(yaoClientConfig.ClientID, authInfo.UserID)
|
|
if err != nil {
|
|
log.Warn("Failed to get user subject: %s", err.Error())
|
|
subject = authInfo.UserID // Fallback to user ID
|
|
}
|
|
|
|
// Prepare OIDC user info (same format as login response)
|
|
oidcUserInfo := oauthtypes.MakeOIDCUserInfo(user)
|
|
oidcUserInfo.Sub = subject
|
|
oidcUserInfo.YaoUserID = authInfo.UserID
|
|
|
|
// Add team context if available from token
|
|
if authInfo.TeamID != "" {
|
|
// Get team details
|
|
team, err := userProvider.GetTeamByMember(ctx, authInfo.TeamID, authInfo.UserID)
|
|
if err == nil && team != nil {
|
|
// Add team info to OIDC user info
|
|
oidcUserInfo.YaoTeamID = authInfo.TeamID
|
|
|
|
teamInfo := &oauthtypes.OIDCTeamInfo{}
|
|
if teamIDVal := toString(team["team_id"]); teamIDVal != "" {
|
|
teamInfo.TeamID = teamIDVal
|
|
}
|
|
if logo := toString(team["logo"]); logo != "" {
|
|
teamInfo.Logo = logo
|
|
}
|
|
if name := toString(team["name"]); name != "" {
|
|
teamInfo.Name = name
|
|
}
|
|
if description := toString(team["description"]); description != "" {
|
|
teamInfo.Description = description
|
|
}
|
|
if ownerID := toString(team["owner_id"]); ownerID != "" {
|
|
teamInfo.OwnerID = ownerID
|
|
|
|
// Check if user is owner
|
|
if ownerID == authInfo.UserID {
|
|
isOwner := true
|
|
oidcUserInfo.YaoIsOwner = &isOwner
|
|
}
|
|
}
|
|
oidcUserInfo.YaoTeam = teamInfo
|
|
|
|
// Add tenant_id if available from the team
|
|
if tenantID := toString(team["tenant_id"]); tenantID != "" {
|
|
oidcUserInfo.YaoTenantID = tenantID
|
|
}
|
|
}
|
|
}
|
|
|
|
// Add type information
|
|
var typeID string
|
|
if authInfo.TeamID != "" {
|
|
// Team context - try to get team's type first
|
|
team, err := userProvider.GetTeamByMember(ctx, authInfo.TeamID, authInfo.UserID)
|
|
if err == nil && team != nil {
|
|
typeID = toString(team["type_id"])
|
|
}
|
|
}
|
|
|
|
// Fallback to user's type if no team type
|
|
if typeID == "" {
|
|
typeID = toString(user["type_id"])
|
|
}
|
|
|
|
if typeID != "" {
|
|
oidcUserInfo.YaoTypeID = typeID
|
|
|
|
// Get type details
|
|
typeInfo, err := userProvider.GetType(ctx, typeID)
|
|
if err == nil && typeInfo != nil {
|
|
typeDetails := &oauthtypes.OIDCTypeInfo{}
|
|
if typeIDVal := toString(typeInfo["type_id"]); typeIDVal != "" {
|
|
typeDetails.TypeID = typeIDVal
|
|
}
|
|
if name := toString(typeInfo["name"]); name != "" {
|
|
typeDetails.Name = name
|
|
}
|
|
if locale := toString(typeInfo["locale"]); locale != "" {
|
|
typeDetails.Locale = locale
|
|
}
|
|
oidcUserInfo.YaoType = typeDetails
|
|
}
|
|
}
|
|
|
|
// Convert to map for response
|
|
profileData := oidcUserInfo.Map()
|
|
|
|
// Return user profile
|
|
response.RespondWithSuccess(c, http.StatusOK, profileData)
|
|
}
|