Browse Source

fix user sync by groups in azure

abhishek9686 1 week ago
parent
commit
3d6a026355
2 changed files with 53 additions and 10 deletions
  1. 2 1
      pro/auth/azure-ad.go
  2. 51 9
      pro/idp/azure/azure.go

+ 2 - 1
pro/auth/azure-ad.go

@@ -62,9 +62,10 @@ func handleAzureLogin(w http.ResponseWriter, r *http.Request) {
 
 func handleAzureCallback(w http.ResponseWriter, r *http.Request) {
 	var rState, rCode = getStateAndCode(r)
-
+	fmt.Println("======>1. HEREEE handleAzureCallback")
 	state, err := logic.GetState(rState)
 	if err != nil {
+		fmt.Println("======>6. HEREEE handleAzureCallback")
 		handleOauthNotValid(w)
 		return
 	}

+ 51 - 9
pro/idp/azure/azure.go

@@ -149,7 +149,7 @@ func (a *Client) GetGroups(filters []string) ([]idp.Group, error) {
 	}
 
 	client := &http.Client{}
-	getGroupsURL := "https://graph.microsoft.com/v1.0/groups?$select=id,displayName&$expand=members($select=id)"
+	getGroupsURL := "https://graph.microsoft.com/v1.0/groups?$select=id,displayName"
 	if len(filters) > 0 {
 		getGroupsURL += "&" + buildPrefixFilter("displayName", filters)
 	}
@@ -176,16 +176,19 @@ func (a *Client) GetGroups(filters []string) ([]idp.Group, error) {
 			return nil, err
 		}
 
+		// Fetch members for each group separately to handle pagination
 		for _, group := range groups.Value {
-			retvalMembers := make([]string, len(group.Members))
-			for j, member := range group.Members {
-				retvalMembers[j] = member.Id
+			members, err := a.getGroupMembers(accessToken, group.Id)
+			if err != nil {
+				// Continue with empty members list if error occurs
+				// This allows sync to continue for other groups
+				members = []string{}
 			}
 
 			retval = append(retval, idp.Group{
 				ID:      group.Id,
 				Name:    group.DisplayName,
-				Members: retvalMembers,
+				Members: members,
 			})
 		}
 
@@ -195,6 +198,49 @@ func (a *Client) GetGroups(filters []string) ([]idp.Group, error) {
 	return retval, nil
 }
 
+// getGroupMembers fetches all members of a group with pagination support
+func (a *Client) getGroupMembers(accessToken, groupID string) ([]string, error) {
+	client := &http.Client{}
+	getMembersURL := fmt.Sprintf("https://graph.microsoft.com/v1.0/groups/%s/members?$select=id", groupID)
+
+	var allMembers []string
+	for getMembersURL != "" {
+		req, err := http.NewRequest("GET", getMembersURL, nil)
+		if err != nil {
+			return nil, err
+		}
+
+		req.Header.Add("Authorization", "Bearer "+accessToken)
+		req.Header.Add("Accept", "application/json")
+
+		resp, err := client.Do(req)
+		if err != nil {
+			return nil, err
+		}
+
+		var membersResponse struct {
+			Value []struct {
+				Id string `json:"id"`
+			} `json:"value"`
+			NextLink string `json:"@odata.nextLink"`
+		}
+
+		err = json.NewDecoder(resp.Body).Decode(&membersResponse)
+		_ = resp.Body.Close()
+		if err != nil {
+			return nil, err
+		}
+
+		for _, member := range membersResponse.Value {
+			allMembers = append(allMembers, member.Id)
+		}
+
+		getMembersURL = membersResponse.NextLink
+	}
+
+	return allMembers, nil
+}
+
 func (a *Client) getAccessToken() (string, error) {
 	tokenURL := fmt.Sprintf("https://login.microsoftonline.com/%s/oauth2/v2.0/token", a.tenantID)
 
@@ -259,10 +305,6 @@ type getGroupsResponse struct {
 	Value        []struct {
 		Id          string `json:"id"`
 		DisplayName string `json:"displayName"`
-		Members     []struct {
-			OdataType string `json:"@odata.type"`
-			Id        string `json:"id"`
-		} `json:"members"`
 	} `json:"value"`
 	NextLink string `json:"@odata.nextLink"`
 }