@@ -24,31 +24,6 @@ func (o *userBuilder) ResourceType(ctx context.Context) *v2.ResourceType {
2424 return userResourceType
2525}
2626
27- func userResource (user gitlabSDK.User , parentResourceID * v2.ResourceId ) (* v2.Resource , error ) {
28- profile := map [string ]interface {}{
29- "id" : user .ID ,
30- "first_name" : user .Name ,
31- "username" : user .Username ,
32- "email" : user .Email ,
33- "state" : user .State ,
34- }
35-
36- userTraitOptions := []resourceSdk.UserTraitOption {
37- resourceSdk .WithEmail (user .Email , true ),
38- resourceSdk .WithStatus (v2 .UserTrait_Status_STATUS_ENABLED ),
39- resourceSdk .WithUserProfile (profile ),
40- resourceSdk .WithUserLogin (user .Email ),
41- }
42-
43- return resourceSdk .NewUserResource (
44- user .Name ,
45- userResourceType ,
46- user .ID ,
47- userTraitOptions ,
48- resourceSdk .WithParentResourceID (parentResourceID ),
49- )
50- }
51-
5227func (o * userBuilder ) setEmailsGroupMembers (ctx context.Context , users []* gitlabSDK.GroupMember ) []* gitlabSDK.GroupMember {
5328 for i , user := range users {
5429 details , _ , err := o .Users .GetUser (user .ID , gitlabSDK.GetUsersOptions {}, gitlabSDK .WithContext (ctx ))
@@ -82,35 +57,67 @@ func (o *userBuilder) setEmailsProjectMembers(ctx context.Context, users []*gitl
8257// List returns all the users from the database as resource objects.
8358// Users include a UserTrait because they are the 'shape' of a standard user.
8459func (o * userBuilder ) List (ctx context.Context , parentResourceID * v2.ResourceId , pToken * pagination.Token ) ([]* v2.Resource , string , annotations.Annotations , error ) {
85- var (
86- users []gitlabSDK.User
87- res * gitlabSDK.Response
88- pageToken string
89- err error
90- )
60+ var users []any
61+ var res * gitlabSDK.Response
62+ var groupId string
63+ var err error
64+
65+ // If the parent resource is nil, this function will exit, the users will be request based on the Groups and Projects received on the arguments.
66+ if parentResourceID == nil {
67+ return nil , "" , nil , nil
68+ }
9169
92- if pToken != nil {
93- pageToken = pToken .Token
70+ var groupMembers []* gitlabSDK.GroupMember
71+ if parentResourceID .ResourceType == groupResourceType .Id {
72+ groupId , _ , err = fromGroupResourceId (parentResourceID .Resource )
73+ if err != nil {
74+ return nil , "" , nil , fmt .Errorf ("error parsing group resource id: %w" , err )
75+ }
76+ if pToken .Token == "" {
77+ groupMembers , res , err = o .ListGroupMembers (ctx , groupId )
78+ } else {
79+ groupMembers , res , err = o .ListGroupMembersPaginate (ctx , groupId , pToken .Token )
80+ }
81+ }
82+ if err != nil {
83+ return nil , "" , nil , err
84+ }
85+
86+ groupMembers = o .setEmailsGroupMembers (ctx , groupMembers )
87+ for _ , member := range groupMembers {
88+ users = append (users , member )
89+ }
90+
91+ var projectMembers []* gitlabSDK.ProjectMember
92+ if parentResourceID .ResourceType == projectResourceType .Id {
93+ if pToken .Token == "" {
94+ projectMembers , res , err = o .ListProjectMembers (ctx , parentResourceID .Resource )
95+ } else {
96+ projectMembers , res , err = o .ListProjectMembersPaginate (ctx , parentResourceID .Resource , pToken .Token )
97+ }
9498 }
95- users , res , err = o .Client .GetAllUsers (ctx , pageToken )
9699 if err != nil {
97100 return nil , "" , nil , err
98101 }
99102
103+ projectMembers = o .setEmailsProjectMembers (ctx , projectMembers )
104+ for _ , member := range projectMembers {
105+ users = append (users , member )
106+ }
107+
100108 outResources := make ([]* v2.Resource , 0 , len (users ))
101109 for _ , user := range users {
102- resource , err := userResource (user , parentResourceID )
110+ resource , err := userResource (user )
103111 if err != nil {
104112 return nil , "" , nil , err
105113 }
106114 outResources = append (outResources , resource )
107115 }
108116
109117 var nextPage string
110- if res .NextPage != 0 {
118+ if res != nil && res .NextPage != 0 {
111119 nextPage = strconv .Itoa (res .NextPage )
112120 }
113-
114121 return outResources , nextPage , nil , nil
115122}
116123
@@ -149,12 +156,23 @@ func (o *userBuilder) CreateAccount(
149156 return nil , nil , nil , err
150157 }
151158
159+ groupID , err := o .validateUserGroup (ctx , accountInfo )
160+ if err != nil {
161+ return nil , nil , nil , err
162+ }
163+
152164 user , _ , err := o .Users .CreateUser (createUserOpts )
153165 if err != nil {
154166 return nil , nil , nil , err
155167 }
156168
157- userResource , err := userResource (* user , nil )
169+ accessLevelValue := AccessLevel ("Guest" )
170+ err = o .AddGroupMember (ctx , groupID , user .ID , accessLevelValue )
171+ if err != nil {
172+ return nil , nil , nil , err
173+ }
174+
175+ userResource , err := userResource (user )
158176 if err != nil {
159177 return nil , nil , nil , err
160178 }
@@ -236,3 +254,87 @@ func newUserBuilder(client *gitlab.Client) *userBuilder {
236254 Client : client ,
237255 }
238256}
257+
258+ func (o * userBuilder ) validateUserGroup (ctx context.Context , accountInfo * v2.AccountInfo ) (string , error ) {
259+ pMap := accountInfo .Profile .AsMap ()
260+ groupName , ok := pMap ["group_name" ].(string )
261+ if ! ok || groupName == "" {
262+ return "" , fmt .Errorf ("group_name is required" )
263+ }
264+
265+ groups , _ , err := o .Groups .ListGroups (& gitlabSDK.ListGroupsOptions {
266+ Search : & groupName ,
267+ },
268+ gitlabSDK .WithContext (ctx ),
269+ )
270+ if err != nil {
271+ return "" , err
272+ }
273+
274+ for _ , group := range groups {
275+ if group .Name == groupName {
276+ return strconv .Itoa (group .ID ), nil
277+ }
278+ }
279+
280+ return "" , fmt .Errorf ("group name %s not found" , groupName )
281+ }
282+
283+ func userResource (user any ) (* v2.Resource , error ) {
284+ var id int
285+ // NOTE: The email attribute is only visible to group owners for enterprise users of the group when an API request is sent to the group itself, or that group's subgroups or projects.
286+ // https://docs.gitlab.com/ee/api/members.html#known-issues
287+ var email string
288+ var username string
289+ var name string
290+ var state string
291+ var accessLevel int
292+
293+ switch user := user .(type ) {
294+ case * gitlabSDK.GroupMember :
295+ id = user .ID
296+ email = user .Email
297+ state = user .State
298+ name = user .Name
299+ username = user .Username
300+ accessLevel = int (user .AccessLevel )
301+ case * gitlabSDK.ProjectMember :
302+ id = user .ID
303+ email = user .Email
304+ state = user .State
305+ name = user .Name
306+ username = user .Username
307+ accessLevel = int (user .AccessLevel )
308+ case * gitlabSDK.User :
309+ id = user .ID
310+ email = user .Email
311+ state = user .State
312+ name = user .Name
313+ username = user .Username
314+ default :
315+ return nil , fmt .Errorf ("unknown user type: %T" , user )
316+ }
317+
318+ profile := map [string ]interface {}{
319+ "first_name" : name ,
320+ "username" : username ,
321+ "email" : email ,
322+ "state" : state ,
323+ "access_level" : accessLevel ,
324+ "id" : id ,
325+ }
326+
327+ userTraitOptions := []resourceSdk.UserTraitOption {
328+ resourceSdk .WithEmail (email , true ),
329+ resourceSdk .WithStatus (v2 .UserTrait_Status_STATUS_ENABLED ),
330+ resourceSdk .WithUserProfile (profile ),
331+ resourceSdk .WithUserLogin (email ),
332+ }
333+
334+ return resourceSdk .NewUserResource (
335+ name ,
336+ userResourceType ,
337+ id ,
338+ userTraitOptions ,
339+ )
340+ }
0 commit comments