@@ -4,10 +4,11 @@ import (
4
4
"encoding/json"
5
5
"errors"
6
6
"fmt"
7
- "github.com/gravitl/netmaker/logic"
8
- "github.com/gravitl/netmaker/pro/idp"
9
7
"net/http"
10
8
"net/url"
9
+
10
+ "github.com/gravitl/netmaker/logic"
11
+ "github.com/gravitl/netmaker/pro/idp"
11
12
)
12
13
13
14
type Client struct {
@@ -26,89 +27,103 @@ func NewAzureEntraIDClient() *Client {
26
27
}
27
28
}
28
29
29
- func (a * Client ) GetUsers () ([]idp.User , error ) {
30
+ func (a * Client ) GetUsers (filters [] string ) ([]idp.User , error ) {
30
31
accessToken , err := a .getAccessToken ()
31
32
if err != nil {
32
33
return nil , err
33
34
}
34
35
35
36
client := & http.Client {}
36
- req , err := http . NewRequest ( "GET" , " https://graph.microsoft.com/v1.0/users?$select=id,userPrincipalName,displayName,accountEnabled", nil )
37
- if err != nil {
38
- return nil , err
37
+ getUsersURL := " https://graph.microsoft.com/v1.0/users?$select=id,userPrincipalName,displayName,accountEnabled"
38
+ if len ( filters ) > 0 {
39
+ getUsersURL += "&" + buildPrefixFilter ( "userPrincipalName" , filters )
39
40
}
40
41
41
- req .Header .Add ("Authorization" , "Bearer " + accessToken )
42
- req .Header .Add ("Accept" , "application/json" )
42
+ var retval []idp.User
43
+ for getUsersURL != "" {
44
+ req , err := http .NewRequest ("GET" , getUsersURL , nil )
45
+ if err != nil {
46
+ return nil , err
47
+ }
43
48
44
- resp , err := client .Do (req )
45
- if err != nil {
46
- return nil , err
47
- }
48
- defer func () {
49
- _ = resp .Body .Close ()
50
- }()
49
+ req .Header .Add ("Authorization" , "Bearer " + accessToken )
50
+ req .Header .Add ("Accept" , "application/json" )
51
51
52
- var users getUsersResponse
53
- err = json .NewDecoder (resp .Body ).Decode (& users )
54
- if err != nil {
55
- return nil , err
56
- }
52
+ resp , err := client .Do (req )
53
+ if err != nil {
54
+ return nil , err
55
+ }
57
56
58
- retval := make ([]idp.User , len (users .Value ))
59
- for i , user := range users .Value {
60
- retval [i ] = idp.User {
61
- ID : user .Id ,
62
- Username : user .UserPrincipalName ,
63
- DisplayName : user .DisplayName ,
64
- AccountDisabled : ! user .AccountEnabled ,
57
+ var users getUsersResponse
58
+ err = json .NewDecoder (resp .Body ).Decode (& users )
59
+ _ = resp .Body .Close ()
60
+ if err != nil {
61
+ return nil , err
65
62
}
63
+
64
+ for _ , user := range users .Value {
65
+ retval = append (retval , idp.User {
66
+ ID : user .Id ,
67
+ Username : user .UserPrincipalName ,
68
+ DisplayName : user .DisplayName ,
69
+ AccountDisabled : ! user .AccountEnabled ,
70
+ })
71
+ }
72
+
73
+ getUsersURL = users .NextLink
66
74
}
67
75
68
76
return retval , nil
69
77
}
70
78
71
- func (a * Client ) GetGroups () ([]idp.Group , error ) {
79
+ func (a * Client ) GetGroups (filters [] string ) ([]idp.Group , error ) {
72
80
accessToken , err := a .getAccessToken ()
73
81
if err != nil {
74
82
return nil , err
75
83
}
76
84
77
85
client := & http.Client {}
78
- req , err := http . NewRequest ( "GET" , " https://graph.microsoft.com/v1.0/groups?$select=id,displayName&$expand=members($select=id)", nil )
79
- if err != nil {
80
- return nil , err
86
+ getGroupsURL := " https://graph.microsoft.com/v1.0/groups?$select=id,displayName&$expand=members($select=id)"
87
+ if len ( filters ) > 0 {
88
+ getGroupsURL += "&" + buildPrefixFilter ( "displayName" , filters )
81
89
}
82
90
83
- req .Header .Add ("Authorization" , "Bearer " + accessToken )
84
- req .Header .Add ("Accept" , "application/json" )
91
+ var retval []idp.Group
92
+ for getGroupsURL != "" {
93
+ req , err := http .NewRequest ("GET" , getGroupsURL , nil )
94
+ if err != nil {
95
+ return nil , err
96
+ }
85
97
86
- resp , err := client .Do (req )
87
- if err != nil {
88
- return nil , err
89
- }
90
- defer func () {
91
- _ = resp .Body .Close ()
92
- }()
98
+ req .Header .Add ("Authorization" , "Bearer " + accessToken )
99
+ req .Header .Add ("Accept" , "application/json" )
93
100
94
- var groups getGroupsResponse
95
- err = json .NewDecoder (resp .Body ).Decode (& groups )
96
- if err != nil {
97
- return nil , err
98
- }
101
+ resp , err := client .Do (req )
102
+ if err != nil {
103
+ return nil , err
104
+ }
99
105
100
- retval := make ([]idp. Group , len ( groups . Value ))
101
- for i , group := range groups . Value {
102
- retvalMembers := make ([] string , len ( group . Members ) )
103
- for j , member := range group . Members {
104
- retvalMembers [ j ] = member . Id
106
+ var groups getGroupsResponse
107
+ err = json . NewDecoder ( resp . Body ). Decode ( & groups )
108
+ _ = resp . Body . Close ( )
109
+ if err != nil {
110
+ return nil , err
105
111
}
106
112
107
- retval [i ] = idp.Group {
108
- ID : group .Id ,
109
- Name : group .DisplayName ,
110
- Members : retvalMembers ,
113
+ for _ , group := range groups .Value {
114
+ retvalMembers := make ([]string , len (group .Members ))
115
+ for j , member := range group .Members {
116
+ retvalMembers [j ] = member .Id
117
+ }
118
+
119
+ retval = append (retval , idp.Group {
120
+ ID : group .Id ,
121
+ Name : group .DisplayName ,
122
+ Members : retvalMembers ,
123
+ })
111
124
}
125
+
126
+ getGroupsURL = groups .NextLink
112
127
}
113
128
114
129
return retval , nil
@@ -144,6 +159,18 @@ func (a *Client) getAccessToken() (string, error) {
144
159
return "" , errors .New ("failed to get access token" )
145
160
}
146
161
162
+ func buildPrefixFilter (field string , prefixes []string ) string {
163
+ if len (prefixes ) == 0 {
164
+ return ""
165
+ }
166
+
167
+ if len (prefixes ) == 1 {
168
+ return fmt .Sprintf ("$filter=startswith(%s,'%s')" , field , prefixes [0 ])
169
+ }
170
+
171
+ return buildPrefixFilter (field , prefixes [1 :]) + fmt .Sprintf ("%%20or%%20startswith(%s,'%s')" , field , prefixes [0 ])
172
+ }
173
+
147
174
type getUsersResponse struct {
148
175
OdataContext string `json:"@odata.context"`
149
176
Value []struct {
@@ -152,6 +179,7 @@ type getUsersResponse struct {
152
179
DisplayName string `json:"displayName"`
153
180
AccountEnabled bool `json:"accountEnabled"`
154
181
} `json:"value"`
182
+ NextLink string `json:"@odata.nextLink"`
155
183
}
156
184
157
185
type getGroupsResponse struct {
@@ -164,4 +192,5 @@ type getGroupsResponse struct {
164
192
Id string `json:"id"`
165
193
} `json:"members"`
166
194
} `json:"value"`
195
+ NextLink string `json:"@odata.nextLink"`
167
196
}
0 commit comments