@@ -5376,32 +5376,32 @@ func FindWorkflowAppByName(ctx context.Context, appName string) ([]WorkflowApp,
53765376// Also validates that the clientID matches the org's configured SSO
53775377func FindUserBySSOIdentity (ctx context.Context , sub , clientID , orgID , email string ) (User , error ) {
53785378 var emptyUser User
5379-
5379+
53805380 // Check if Sub is empty - user hasn't connected SSO yet
53815381 if sub == "" {
53825382 return emptyUser , errors .New ("connect user account with SSO first" )
53835383 }
5384-
5384+
53855385 if clientID == "" || orgID == "" || email == "" {
53865386 return emptyUser , errors .New ("clientID, orgID, and email are all required" )
53875387 }
5388-
5388+
53895389 // Verify the clientID actually matches the org's SSO configuration
53905390 org , err := GetOrg (ctx , orgID )
53915391 if err != nil {
53925392 return emptyUser , fmt .Errorf ("failed to get org %s: %w" , orgID , err )
53935393 }
5394-
5394+
53955395 if org .SSOConfig .OpenIdClientId != clientID {
53965396 return emptyUser , fmt .Errorf ("clientID %s does not match org's configured SSO client ID %s" , clientID , org .SSOConfig .OpenIdClientId )
53975397 }
5398-
5398+
53995399 // Normalize email for comparison
54005400 normalizedEmail := strings .ToLower (strings .TrimSpace (email ))
5401-
5401+
54025402 nameKey := "Users"
54035403 var users []User
5404-
5404+
54055405 if project .DbType == "opensearch" {
54065406 // OpenSearch query to find users with matching SSO info
54075407 var buf bytes.Buffer
@@ -5445,11 +5445,11 @@ func FindUserBySSOIdentity(ctx context.Context, sub, clientID, orgID, email stri
54455445 },
54465446 },
54475447 }
5448-
5448+
54495449 if err := json .NewEncoder (& buf ).Encode (query ); err != nil {
54505450 return emptyUser , fmt .Errorf ("failed to encode opensearch query: %w" , err )
54515451 }
5452-
5452+
54535453 resp , err := project .Es .Search (ctx , & opensearchapi.SearchReq {
54545454 Indices : []string {strings .ToLower (GetESIndexPrefix (nameKey ))},
54555455 Body : & buf ,
@@ -5460,23 +5460,23 @@ func FindUserBySSOIdentity(ctx context.Context, sub, clientID, orgID, email stri
54605460 if err != nil {
54615461 return emptyUser , fmt .Errorf ("opensearch query failed: %w" , err )
54625462 }
5463-
5463+
54645464 res := resp .Inspect ().Response
54655465 defer res .Body .Close ()
54665466 if res .StatusCode != 200 && res .StatusCode != 201 {
54675467 return emptyUser , fmt .Errorf ("opensearch error response: %d" , res .StatusCode )
54685468 }
5469-
5469+
54705470 var r map [string ]interface {}
54715471 if err := json .NewDecoder (res .Body ).Decode (& r ); err != nil {
54725472 return emptyUser , fmt .Errorf ("failed to parse opensearch response: %w" , err )
54735473 }
5474-
5474+
54755475 hits , ok := r ["hits" ].(map [string ]interface {})["hits" ].([]interface {})
54765476 if ! ok {
54775477 return emptyUser , errors .New ("no matching user found" )
54785478 }
5479-
5479+
54805480 for _ , hit := range hits {
54815481 if source , ok := hit .(map [string ]interface {})["_source" ]; ok {
54825482 data , _ := json .Marshal (source )
@@ -5494,32 +5494,32 @@ func FindUserBySSOIdentity(ctx context.Context, sub, clientID, orgID, email stri
54945494 if err != nil {
54955495 return emptyUser , fmt .Errorf ("datastore query failed: %w" , err )
54965496 }
5497-
5497+
54985498 // Filter users to find exact SSO match
54995499 var matchingUsers []User
55005500 for _ , user := range users {
55015501 for _ , ssoInfo := range user .SSOInfos {
5502- if ssoInfo .Sub == sub &&
5503- ssoInfo .ClientID == clientID &&
5504- ssoInfo .OrgID == orgID {
5502+ if ssoInfo .Sub == sub &&
5503+ ssoInfo .ClientID == clientID &&
5504+ ssoInfo .OrgID == orgID {
55055505 matchingUsers = append (matchingUsers , user )
55065506 break
55075507 }
55085508 }
55095509 }
55105510 users = matchingUsers
55115511 }
5512-
5512+
55135513 if len (users ) == 0 {
55145514 return emptyUser , fmt .Errorf ("no user found with Sub=%s, ClientID=%s, OrgID=%s, Email=%s" , sub , clientID , orgID , normalizedEmail )
55155515 }
5516-
5516+
55175517 if len (users ) > 1 {
5518- log .Printf ("[CRITICAL] Multiple users found with same SSO identity: Sub=%s, ClientID=%s, OrgID=%s, Email=%s" ,
5518+ log .Printf ("[CRITICAL] Multiple users found with same SSO identity: Sub=%s, ClientID=%s, OrgID=%s, Email=%s" ,
55195519 sub , clientID , orgID , normalizedEmail )
55205520 return emptyUser , errors .New ("multiple users found with same SSO identity - data integrity issue" )
55215521 }
5522-
5522+
55235523 return users [0 ], nil
55245524}
55255525
@@ -5817,6 +5817,7 @@ func GetUser(ctx context.Context, username string) (*User, error) {
58175817}
58185818
58195819func (u * User ) GetSSOInfo (orgID string ) (SSOInfo , bool ) {
5820+ log .Printf ("[DEBUG] Getting SSOInfo for user %s and org %s" , u .Id , orgID )
58205821 for _ , sso := range u .SSOInfos {
58215822 if sso .OrgID == orgID {
58225823 return sso , true
0 commit comments