1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package gitlab
18
19 import (
20 "bytes"
21 "encoding/json"
22 "fmt"
23 "io"
24 "net/http"
25 "time"
26
27 retryablehttp "github.com/hashicorp/go-retryablehttp"
28 )
29
30
31
32
33
34 type GroupsService struct {
35 client *Client
36 }
37
38
39
40
41 type Group struct {
42 ID int `json:"id"`
43 Name string `json:"name"`
44 Path string `json:"path"`
45 Description string `json:"description"`
46 MembershipLock bool `json:"membership_lock"`
47 Visibility VisibilityValue `json:"visibility"`
48 LFSEnabled bool `json:"lfs_enabled"`
49 DefaultBranchProtection int `json:"default_branch_protection"`
50 AvatarURL string `json:"avatar_url"`
51 WebURL string `json:"web_url"`
52 RequestAccessEnabled bool `json:"request_access_enabled"`
53 RepositoryStorage string `json:"repository_storage"`
54 FullName string `json:"full_name"`
55 FullPath string `json:"full_path"`
56 FileTemplateProjectID int `json:"file_template_project_id"`
57 ParentID int `json:"parent_id"`
58 Projects []*Project `json:"projects"`
59 Statistics *Statistics `json:"statistics"`
60 CustomAttributes []*CustomAttribute `json:"custom_attributes"`
61 ShareWithGroupLock bool `json:"share_with_group_lock"`
62 RequireTwoFactorAuth bool `json:"require_two_factor_authentication"`
63 TwoFactorGracePeriod int `json:"two_factor_grace_period"`
64 ProjectCreationLevel ProjectCreationLevelValue `json:"project_creation_level"`
65 AutoDevopsEnabled bool `json:"auto_devops_enabled"`
66 SubGroupCreationLevel SubGroupCreationLevelValue `json:"subgroup_creation_level"`
67 EmailsEnabled bool `json:"emails_enabled"`
68 MentionsDisabled bool `json:"mentions_disabled"`
69 RunnersToken string `json:"runners_token"`
70 SharedProjects []*Project `json:"shared_projects"`
71 SharedRunnersSetting SharedRunnersSettingValue `json:"shared_runners_setting"`
72 SharedWithGroups []struct {
73 GroupID int `json:"group_id"`
74 GroupName string `json:"group_name"`
75 GroupFullPath string `json:"group_full_path"`
76 GroupAccessLevel int `json:"group_access_level"`
77 ExpiresAt *ISOTime `json:"expires_at"`
78 } `json:"shared_with_groups"`
79 LDAPCN string `json:"ldap_cn"`
80 LDAPAccess AccessLevelValue `json:"ldap_access"`
81 LDAPGroupLinks []*LDAPGroupLink `json:"ldap_group_links"`
82 SAMLGroupLinks []*SAMLGroupLink `json:"saml_group_links"`
83 SharedRunnersMinutesLimit int `json:"shared_runners_minutes_limit"`
84 ExtraSharedRunnersMinutesLimit int `json:"extra_shared_runners_minutes_limit"`
85 PreventForkingOutsideGroup bool `json:"prevent_forking_outside_group"`
86 MarkedForDeletionOn *ISOTime `json:"marked_for_deletion_on"`
87 CreatedAt *time.Time `json:"created_at"`
88 IPRestrictionRanges string `json:"ip_restriction_ranges"`
89 WikiAccessLevel AccessControlValue `json:"wiki_access_level"`
90
91
92 EmailsDisabled bool `json:"emails_disabled"`
93 }
94
95
96
97
98 type GroupAvatar struct {
99 Filename string
100 Image io.Reader
101 }
102
103
104 func (a *GroupAvatar) MarshalJSON() ([]byte, error) {
105 if a.Filename == "" && a.Image == nil {
106 return []byte(`""`), nil
107 }
108 type alias GroupAvatar
109 return json.Marshal((*alias)(a))
110 }
111
112
113
114
115 type LDAPGroupLink struct {
116 CN string `json:"cn"`
117 Filter string `json:"filter"`
118 GroupAccess AccessLevelValue `json:"group_access"`
119 Provider string `json:"provider"`
120 }
121
122
123
124
125 type SAMLGroupLink struct {
126 Name string `json:"name"`
127 AccessLevel AccessLevelValue `json:"access_level"`
128 }
129
130
131
132
133 type ListGroupsOptions struct {
134 ListOptions
135 SkipGroups *[]int `url:"skip_groups,omitempty" del:"," json:"skip_groups,omitempty"`
136 AllAvailable *bool `url:"all_available,omitempty" json:"all_available,omitempty"`
137 Search *string `url:"search,omitempty" json:"search,omitempty"`
138 OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"`
139 Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
140 Statistics *bool `url:"statistics,omitempty" json:"statistics,omitempty"`
141 WithCustomAttributes *bool `url:"with_custom_attributes,omitempty" json:"with_custom_attributes,omitempty"`
142 Owned *bool `url:"owned,omitempty" json:"owned,omitempty"`
143 MinAccessLevel *AccessLevelValue `url:"min_access_level,omitempty" json:"min_access_level,omitempty"`
144 TopLevelOnly *bool `url:"top_level_only,omitempty" json:"top_level_only,omitempty"`
145 RepositoryStorage *string `url:"repository_storage,omitempty" json:"repository_storage,omitempty"`
146 }
147
148
149
150
151
152 func (s *GroupsService) ListGroups(opt *ListGroupsOptions, options ...RequestOptionFunc) ([]*Group, *Response, error) {
153 req, err := s.client.NewRequest(http.MethodGet, "groups", opt, options)
154 if err != nil {
155 return nil, nil, err
156 }
157
158 var gs []*Group
159 resp, err := s.client.Do(req, &gs)
160 if err != nil {
161 return nil, resp, err
162 }
163
164 return gs, resp, nil
165 }
166
167
168
169
170
171 type ListSubGroupsOptions ListGroupsOptions
172
173
174
175
176
177 func (s *GroupsService) ListSubGroups(gid interface{}, opt *ListSubGroupsOptions, options ...RequestOptionFunc) ([]*Group, *Response, error) {
178 group, err := parseID(gid)
179 if err != nil {
180 return nil, nil, err
181 }
182 u := fmt.Sprintf("groups/%s/subgroups", PathEscape(group))
183
184 req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
185 if err != nil {
186 return nil, nil, err
187 }
188
189 var gs []*Group
190 resp, err := s.client.Do(req, &gs)
191 if err != nil {
192 return nil, resp, err
193 }
194
195 return gs, resp, nil
196 }
197
198
199
200
201
202
203 type ListDescendantGroupsOptions ListGroupsOptions
204
205
206
207
208
209 func (s *GroupsService) ListDescendantGroups(gid interface{}, opt *ListDescendantGroupsOptions, options ...RequestOptionFunc) ([]*Group, *Response, error) {
210 group, err := parseID(gid)
211 if err != nil {
212 return nil, nil, err
213 }
214 u := fmt.Sprintf("groups/%s/descendant_groups", PathEscape(group))
215
216 req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
217 if err != nil {
218 return nil, nil, err
219 }
220
221 var gs []*Group
222 resp, err := s.client.Do(req, &gs)
223 if err != nil {
224 return nil, resp, err
225 }
226
227 return gs, resp, nil
228 }
229
230
231
232
233
234 type ListGroupProjectsOptions struct {
235 ListOptions
236 Archived *bool `url:"archived,omitempty" json:"archived,omitempty"`
237 IncludeSubGroups *bool `url:"include_subgroups,omitempty" json:"include_subgroups,omitempty"`
238 MinAccessLevel *AccessLevelValue `url:"min_access_level,omitempty" json:"min_access_level,omitempty"`
239 OrderBy *string `url:"order_by,omitempty" json:"order_by,omitempty"`
240 Owned *bool `url:"owned,omitempty" json:"owned,omitempty"`
241 Search *string `url:"search,omitempty" json:"search,omitempty"`
242 Simple *bool `url:"simple,omitempty" json:"simple,omitempty"`
243 Sort *string `url:"sort,omitempty" json:"sort,omitempty"`
244 Starred *bool `url:"starred,omitempty" json:"starred,omitempty"`
245 Topic *string `url:"topic,omitempty" json:"topic,omitempty"`
246 Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"`
247 WithCustomAttributes *bool `url:"with_custom_attributes,omitempty" json:"with_custom_attributes,omitempty"`
248 WithIssuesEnabled *bool `url:"with_issues_enabled,omitempty" json:"with_issues_enabled,omitempty"`
249 WithMergeRequestsEnabled *bool `url:"with_merge_requests_enabled,omitempty" json:"with_merge_requests_enabled,omitempty"`
250 WithSecurityReports *bool `url:"with_security_reports,omitempty" json:"with_security_reports,omitempty"`
251 WithShared *bool `url:"with_shared,omitempty" json:"with_shared,omitempty"`
252 }
253
254
255
256
257
258 func (s *GroupsService) ListGroupProjects(gid interface{}, opt *ListGroupProjectsOptions, options ...RequestOptionFunc) ([]*Project, *Response, error) {
259 group, err := parseID(gid)
260 if err != nil {
261 return nil, nil, err
262 }
263 u := fmt.Sprintf("groups/%s/projects", PathEscape(group))
264
265 req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
266 if err != nil {
267 return nil, nil, err
268 }
269
270 var ps []*Project
271 resp, err := s.client.Do(req, &ps)
272 if err != nil {
273 return nil, resp, err
274 }
275
276 return ps, resp, nil
277 }
278
279
280
281
282 type GetGroupOptions struct {
283 ListOptions
284 WithCustomAttributes *bool `url:"with_custom_attributes,omitempty" json:"with_custom_attributes,omitempty"`
285 WithProjects *bool `url:"with_projects,omitempty" json:"with_projects,omitempty"`
286 }
287
288
289
290
291 func (s *GroupsService) GetGroup(gid interface{}, opt *GetGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) {
292 group, err := parseID(gid)
293 if err != nil {
294 return nil, nil, err
295 }
296 u := fmt.Sprintf("groups/%s", PathEscape(group))
297
298 req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
299 if err != nil {
300 return nil, nil, err
301 }
302
303 g := new(Group)
304 resp, err := s.client.Do(req, g)
305 if err != nil {
306 return nil, resp, err
307 }
308
309 return g, resp, nil
310 }
311
312
313
314
315
316 func (s *GroupsService) DownloadAvatar(gid interface{}, options ...RequestOptionFunc) (*bytes.Reader, *Response, error) {
317 group, err := parseID(gid)
318 if err != nil {
319 return nil, nil, err
320 }
321 u := fmt.Sprintf("groups/%s/avatar", PathEscape(group))
322
323 req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
324 if err != nil {
325 return nil, nil, err
326 }
327
328 avatar := new(bytes.Buffer)
329 resp, err := s.client.Do(req, avatar)
330 if err != nil {
331 return nil, resp, err
332 }
333
334 return bytes.NewReader(avatar.Bytes()), resp, err
335 }
336
337
338
339
340 type CreateGroupOptions struct {
341 Name *string `url:"name,omitempty" json:"name,omitempty"`
342 Path *string `url:"path,omitempty" json:"path,omitempty"`
343 Avatar *GroupAvatar `url:"-" json:"-"`
344 Description *string `url:"description,omitempty" json:"description,omitempty"`
345 MembershipLock *bool `url:"membership_lock,omitempty" json:"membership_lock,omitempty"`
346 Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"`
347 ShareWithGroupLock *bool `url:"share_with_group_lock,omitempty" json:"share_with_group_lock,omitempty"`
348 RequireTwoFactorAuth *bool `url:"require_two_factor_authentication,omitempty" json:"require_two_factor_authentication,omitempty"`
349 TwoFactorGracePeriod *int `url:"two_factor_grace_period,omitempty" json:"two_factor_grace_period,omitempty"`
350 ProjectCreationLevel *ProjectCreationLevelValue `url:"project_creation_level,omitempty" json:"project_creation_level,omitempty"`
351 AutoDevopsEnabled *bool `url:"auto_devops_enabled,omitempty" json:"auto_devops_enabled,omitempty"`
352 SubGroupCreationLevel *SubGroupCreationLevelValue `url:"subgroup_creation_level,omitempty" json:"subgroup_creation_level,omitempty"`
353 EmailsEnabled *bool `url:"emails_enabled,omitempty" json:"emails_enabled,omitempty"`
354 MentionsDisabled *bool `url:"mentions_disabled,omitempty" json:"mentions_disabled,omitempty"`
355 LFSEnabled *bool `url:"lfs_enabled,omitempty" json:"lfs_enabled,omitempty"`
356 DefaultBranchProtection *int `url:"default_branch_protection,omitempty" json:"default_branch_protection"`
357 RequestAccessEnabled *bool `url:"request_access_enabled,omitempty" json:"request_access_enabled,omitempty"`
358 ParentID *int `url:"parent_id,omitempty" json:"parent_id,omitempty"`
359 SharedRunnersMinutesLimit *int `url:"shared_runners_minutes_limit,omitempty" json:"shared_runners_minutes_limit,omitempty"`
360 ExtraSharedRunnersMinutesLimit *int `url:"extra_shared_runners_minutes_limit,omitempty" json:"extra_shared_runners_minutes_limit,omitempty"`
361 IPRestrictionRanges *string `url:"ip_restriction_ranges,omitempty" json:"ip_restriction_ranges,omitempty"`
362 WikiAccessLevel *AccessControlValue `url:"wiki_access_level,omitempty" json:"wiki_access_level,omitempty"`
363
364
365 EmailsDisabled *bool `url:"emails_disabled,omitempty" json:"emails_disabled,omitempty"`
366 }
367
368
369
370
371
372 func (s *GroupsService) CreateGroup(opt *CreateGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) {
373 var err error
374 var req *retryablehttp.Request
375
376 if opt.Avatar == nil {
377 req, err = s.client.NewRequest(http.MethodPost, "groups", opt, options)
378 } else {
379 req, err = s.client.UploadRequest(
380 http.MethodPost,
381 "groups",
382 opt.Avatar.Image,
383 opt.Avatar.Filename,
384 UploadAvatar,
385 opt,
386 options,
387 )
388 }
389 if err != nil {
390 return nil, nil, err
391 }
392
393 g := new(Group)
394 resp, err := s.client.Do(req, g)
395 if err != nil {
396 return nil, resp, err
397 }
398
399 return g, resp, nil
400 }
401
402
403
404
405
406
407 func (s *GroupsService) TransferGroup(gid interface{}, pid interface{}, options ...RequestOptionFunc) (*Group, *Response, error) {
408 group, err := parseID(gid)
409 if err != nil {
410 return nil, nil, err
411 }
412 project, err := parseID(pid)
413 if err != nil {
414 return nil, nil, err
415 }
416 u := fmt.Sprintf("groups/%s/projects/%s", PathEscape(group), PathEscape(project))
417
418 req, err := s.client.NewRequest(http.MethodPost, u, nil, options)
419 if err != nil {
420 return nil, nil, err
421 }
422
423 g := new(Group)
424 resp, err := s.client.Do(req, g)
425 if err != nil {
426 return nil, resp, err
427 }
428
429 return g, resp, nil
430 }
431
432
433
434
435
436 type TransferSubGroupOptions struct {
437 GroupID *int `url:"group_id,omitempty" json:"group_id,omitempty"`
438 }
439
440
441
442
443
444
445 func (s *GroupsService) TransferSubGroup(gid interface{}, opt *TransferSubGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) {
446 group, err := parseID(gid)
447 if err != nil {
448 return nil, nil, err
449 }
450 u := fmt.Sprintf("groups/%s/transfer", PathEscape(group))
451
452 req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
453 if err != nil {
454 return nil, nil, err
455 }
456
457 g := new(Group)
458 resp, err := s.client.Do(req, g)
459 if err != nil {
460 return nil, resp, err
461 }
462
463 return g, resp, nil
464 }
465
466
467
468
469 type UpdateGroupOptions struct {
470 Name *string `url:"name,omitempty" json:"name,omitempty"`
471 Path *string `url:"path,omitempty" json:"path,omitempty"`
472 Avatar *GroupAvatar `url:"-" json:"avatar,omitempty"`
473 Description *string `url:"description,omitempty" json:"description,omitempty"`
474 MembershipLock *bool `url:"membership_lock,omitempty" json:"membership_lock,omitempty"`
475 Visibility *VisibilityValue `url:"visibility,omitempty" json:"visibility,omitempty"`
476 ShareWithGroupLock *bool `url:"share_with_group_lock,omitempty" json:"share_with_group_lock,omitempty"`
477 RequireTwoFactorAuth *bool `url:"require_two_factor_authentication,omitempty" json:"require_two_factor_authentication,omitempty"`
478 TwoFactorGracePeriod *int `url:"two_factor_grace_period,omitempty" json:"two_factor_grace_period,omitempty"`
479 ProjectCreationLevel *ProjectCreationLevelValue `url:"project_creation_level,omitempty" json:"project_creation_level,omitempty"`
480 AutoDevopsEnabled *bool `url:"auto_devops_enabled,omitempty" json:"auto_devops_enabled,omitempty"`
481 SubGroupCreationLevel *SubGroupCreationLevelValue `url:"subgroup_creation_level,omitempty" json:"subgroup_creation_level,omitempty"`
482 EmailsEnabled *bool `url:"emails_enabled,omitempty" json:"emails_enabled,omitempty"`
483 MentionsDisabled *bool `url:"mentions_disabled,omitempty" json:"mentions_disabled,omitempty"`
484 LFSEnabled *bool `url:"lfs_enabled,omitempty" json:"lfs_enabled,omitempty"`
485 RequestAccessEnabled *bool `url:"request_access_enabled,omitempty" json:"request_access_enabled,omitempty"`
486 DefaultBranchProtection *int `url:"default_branch_protection,omitempty" json:"default_branch_protection,omitempty"`
487 FileTemplateProjectID *int `url:"file_template_project_id,omitempty" json:"file_template_project_id,omitempty"`
488 SharedRunnersMinutesLimit *int `url:"shared_runners_minutes_limit,omitempty" json:"shared_runners_minutes_limit,omitempty"`
489 ExtraSharedRunnersMinutesLimit *int `url:"extra_shared_runners_minutes_limit,omitempty" json:"extra_shared_runners_minutes_limit,omitempty"`
490 PreventForkingOutsideGroup *bool `url:"prevent_forking_outside_group,omitempty" json:"prevent_forking_outside_group,omitempty"`
491 SharedRunnersSetting *SharedRunnersSettingValue `url:"shared_runners_setting,omitempty" json:"shared_runners_setting,omitempty"`
492 PreventSharingGroupsOutsideHierarchy *bool `url:"prevent_sharing_groups_outside_hierarchy,omitempty" json:"prevent_sharing_groups_outside_hierarchy,omitempty"`
493 IPRestrictionRanges *string `url:"ip_restriction_ranges,omitempty" json:"ip_restriction_ranges,omitempty"`
494 WikiAccessLevel *AccessControlValue `url:"wiki_access_level,omitempty" json:"wiki_access_level,omitempty"`
495
496
497 EmailsDisabled *bool `url:"emails_disabled,omitempty" json:"emails_disabled,omitempty"`
498 }
499
500
501
502
503
504 func (s *GroupsService) UpdateGroup(gid interface{}, opt *UpdateGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) {
505 group, err := parseID(gid)
506 if err != nil {
507 return nil, nil, err
508 }
509 u := fmt.Sprintf("groups/%s", PathEscape(group))
510
511 var req *retryablehttp.Request
512
513 if opt.Avatar == nil || (opt.Avatar.Filename == "" && opt.Avatar.Image == nil) {
514 req, err = s.client.NewRequest(http.MethodPut, u, opt, options)
515 } else {
516 req, err = s.client.UploadRequest(
517 http.MethodPut,
518 u,
519 opt.Avatar.Image,
520 opt.Avatar.Filename,
521 UploadAvatar,
522 opt,
523 options,
524 )
525 }
526 if err != nil {
527 return nil, nil, err
528 }
529
530 g := new(Group)
531 resp, err := s.client.Do(req, g)
532 if err != nil {
533 return nil, resp, err
534 }
535
536 return g, resp, nil
537 }
538
539
540
541
542
543 func (s *GroupsService) UploadAvatar(gid interface{}, avatar io.Reader, filename string, options ...RequestOptionFunc) (*Group, *Response, error) {
544 group, err := parseID(gid)
545 if err != nil {
546 return nil, nil, err
547 }
548 u := fmt.Sprintf("groups/%s", PathEscape(group))
549
550 req, err := s.client.UploadRequest(
551 http.MethodPut,
552 u,
553 avatar,
554 filename,
555 UploadAvatar,
556 nil,
557 options,
558 )
559 if err != nil {
560 return nil, nil, err
561 }
562
563 g := new(Group)
564 resp, err := s.client.Do(req, g)
565 if err != nil {
566 return nil, resp, err
567 }
568
569 return g, resp, nil
570 }
571
572
573
574
575 type DeleteGroupOptions struct {
576 PermanentlyRemove *bool `url:"permanently_remove,omitempty" json:"permanently_remove,omitempty"`
577 FullPath *string `url:"full_path,omitempty" json:"full_path,omitempty"`
578 }
579
580
581
582
583 func (s *GroupsService) DeleteGroup(gid interface{}, opt *DeleteGroupOptions, options ...RequestOptionFunc) (*Response, error) {
584 group, err := parseID(gid)
585 if err != nil {
586 return nil, err
587 }
588 u := fmt.Sprintf("groups/%s", PathEscape(group))
589
590 req, err := s.client.NewRequest(http.MethodDelete, u, opt, options)
591 if err != nil {
592 return nil, err
593 }
594
595 return s.client.Do(req, nil)
596 }
597
598
599
600
601
602 func (s *GroupsService) RestoreGroup(gid interface{}, options ...RequestOptionFunc) (*Group, *Response, error) {
603 group, err := parseID(gid)
604 if err != nil {
605 return nil, nil, err
606 }
607 u := fmt.Sprintf("groups/%s/restore", PathEscape(group))
608
609 req, err := s.client.NewRequest(http.MethodPost, u, nil, options)
610 if err != nil {
611 return nil, nil, err
612 }
613
614 g := new(Group)
615 resp, err := s.client.Do(req, g)
616 if err != nil {
617 return nil, resp, err
618 }
619
620 return g, resp, nil
621 }
622
623
624
625
626 func (s *GroupsService) SearchGroup(query string, options ...RequestOptionFunc) ([]*Group, *Response, error) {
627 var q struct {
628 Search string `url:"search,omitempty" json:"search,omitempty"`
629 }
630 q.Search = query
631
632 req, err := s.client.NewRequest(http.MethodGet, "groups", &q, options)
633 if err != nil {
634 return nil, nil, err
635 }
636
637 var gs []*Group
638 resp, err := s.client.Do(req, &gs)
639 if err != nil {
640 return nil, resp, err
641 }
642
643 return gs, resp, nil
644 }
645
646
647
648
649
650
651 type ListProvisionedUsersOptions struct {
652 ListOptions
653 Username *string `url:"username,omitempty" json:"username,omitempty"`
654 Search *string `url:"search,omitempty" json:"search,omitempty"`
655 Active *bool `url:"active,omitempty" json:"active,omitempty"`
656 Blocked *bool `url:"blocked,omitempty" json:"blocked,omitempty"`
657 CreatedAfter *time.Time `url:"created_after,omitempty" json:"created_after,omitempty"`
658 CreatedBefore *time.Time `url:"created_before,omitempty" json:"created_before,omitempty"`
659 }
660
661
662
663
664
665 func (s *GroupsService) ListProvisionedUsers(gid interface{}, opt *ListProvisionedUsersOptions, options ...RequestOptionFunc) ([]*User, *Response, error) {
666 group, err := parseID(gid)
667 if err != nil {
668 return nil, nil, err
669 }
670 u := fmt.Sprintf("groups/%s/provisioned_users", PathEscape(group))
671
672 req, err := s.client.NewRequest(http.MethodGet, u, opt, options)
673 if err != nil {
674 return nil, nil, err
675 }
676
677 var us []*User
678 resp, err := s.client.Do(req, &us)
679 if err != nil {
680 return nil, resp, err
681 }
682
683 return us, resp, nil
684 }
685
686
687
688
689
690
691 func (s *GroupsService) ListGroupLDAPLinks(gid interface{}, options ...RequestOptionFunc) ([]*LDAPGroupLink, *Response, error) {
692 group, err := parseID(gid)
693 if err != nil {
694 return nil, nil, err
695 }
696 u := fmt.Sprintf("groups/%s/ldap_group_links", PathEscape(group))
697
698 req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
699 if err != nil {
700 return nil, nil, err
701 }
702
703 var gls []*LDAPGroupLink
704 resp, err := s.client.Do(req, &gls)
705 if err != nil {
706 return nil, resp, err
707 }
708
709 return gls, resp, nil
710 }
711
712
713
714
715
716 type AddGroupLDAPLinkOptions struct {
717 CN *string `url:"cn,omitempty" json:"cn,omitempty"`
718 Filter *string `url:"filter,omitempty" json:"filter,omitempty"`
719 GroupAccess *AccessLevelValue `url:"group_access,omitempty" json:"group_access,omitempty"`
720 Provider *string `url:"provider,omitempty" json:"provider,omitempty"`
721 }
722
723
724
725
726
727 type DeleteGroupLDAPLinkWithCNOrFilterOptions struct {
728 CN *string `url:"cn,omitempty" json:"cn,omitempty"`
729 Filter *string `url:"filter,omitempty" json:"filter,omitempty"`
730 Provider *string `url:"provider,omitempty" json:"provider,omitempty"`
731 }
732
733
734
735
736
737
738 func (s *GroupsService) AddGroupLDAPLink(gid interface{}, opt *AddGroupLDAPLinkOptions, options ...RequestOptionFunc) (*LDAPGroupLink, *Response, error) {
739 group, err := parseID(gid)
740 if err != nil {
741 return nil, nil, err
742 }
743 u := fmt.Sprintf("groups/%s/ldap_group_links", PathEscape(group))
744
745 req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
746 if err != nil {
747 return nil, nil, err
748 }
749
750 gl := new(LDAPGroupLink)
751 resp, err := s.client.Do(req, gl)
752 if err != nil {
753 return nil, resp, err
754 }
755
756 return gl, resp, nil
757 }
758
759
760
761
762
763
764 func (s *GroupsService) DeleteGroupLDAPLink(gid interface{}, cn string, options ...RequestOptionFunc) (*Response, error) {
765 group, err := parseID(gid)
766 if err != nil {
767 return nil, err
768 }
769 u := fmt.Sprintf("groups/%s/ldap_group_links/%s", PathEscape(group), PathEscape(cn))
770
771 req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
772 if err != nil {
773 return nil, err
774 }
775
776 return s.client.Do(req, nil)
777 }
778
779
780
781
782
783
784 func (s *GroupsService) DeleteGroupLDAPLinkWithCNOrFilter(gid interface{}, opts *DeleteGroupLDAPLinkWithCNOrFilterOptions, options ...RequestOptionFunc) (*Response, error) {
785 group, err := parseID(gid)
786 if err != nil {
787 return nil, err
788 }
789 u := fmt.Sprintf("groups/%s/ldap_group_links", PathEscape(group))
790
791 req, err := s.client.NewRequest(http.MethodDelete, u, opts, options)
792 if err != nil {
793 return nil, err
794 }
795
796 return s.client.Do(req, nil)
797 }
798
799
800
801
802
803
804 func (s *GroupsService) DeleteGroupLDAPLinkForProvider(gid interface{}, provider, cn string, options ...RequestOptionFunc) (*Response, error) {
805 group, err := parseID(gid)
806 if err != nil {
807 return nil, err
808 }
809 u := fmt.Sprintf(
810 "groups/%s/ldap_group_links/%s/%s",
811 PathEscape(group),
812 PathEscape(provider),
813 PathEscape(cn),
814 )
815
816 req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
817 if err != nil {
818 return nil, err
819 }
820
821 return s.client.Do(req, nil)
822 }
823
824
825
826
827
828
829 func (s *GroupsService) ListGroupSAMLLinks(gid interface{}, options ...RequestOptionFunc) ([]*SAMLGroupLink, *Response, error) {
830 group, err := parseID(gid)
831 if err != nil {
832 return nil, nil, err
833 }
834 u := fmt.Sprintf("groups/%s/saml_group_links", PathEscape(group))
835
836 req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
837 if err != nil {
838 return nil, nil, err
839 }
840
841 var gl []*SAMLGroupLink
842 resp, err := s.client.Do(req, &gl)
843 if err != nil {
844 return nil, resp, err
845 }
846
847 return gl, resp, nil
848 }
849
850
851
852
853
854
855 func (s *GroupsService) GetGroupSAMLLink(gid interface{}, samlGroupName string, options ...RequestOptionFunc) (*SAMLGroupLink, *Response, error) {
856 group, err := parseID(gid)
857 if err != nil {
858 return nil, nil, err
859 }
860 u := fmt.Sprintf("groups/%s/saml_group_links/%s", PathEscape(group), PathEscape(samlGroupName))
861
862 req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
863 if err != nil {
864 return nil, nil, err
865 }
866
867 gl := new(SAMLGroupLink)
868 resp, err := s.client.Do(req, &gl)
869 if err != nil {
870 return nil, resp, err
871 }
872
873 return gl, resp, nil
874 }
875
876
877
878
879
880 type AddGroupSAMLLinkOptions struct {
881 SAMLGroupName *string `url:"saml_group_name,omitempty" json:"saml_group_name,omitempty"`
882 AccessLevel *AccessLevelValue `url:"access_level,omitempty" json:"access_level,omitempty"`
883 }
884
885
886
887
888
889
890 func (s *GroupsService) AddGroupSAMLLink(gid interface{}, opt *AddGroupSAMLLinkOptions, options ...RequestOptionFunc) (*SAMLGroupLink, *Response, error) {
891 group, err := parseID(gid)
892 if err != nil {
893 return nil, nil, err
894 }
895 u := fmt.Sprintf("groups/%s/saml_group_links", PathEscape(group))
896
897 req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
898 if err != nil {
899 return nil, nil, err
900 }
901
902 gl := new(SAMLGroupLink)
903 resp, err := s.client.Do(req, &gl)
904 if err != nil {
905 return nil, resp, err
906 }
907
908 return gl, resp, nil
909 }
910
911
912
913
914
915
916 func (s *GroupsService) DeleteGroupSAMLLink(gid interface{}, samlGroupName string, options ...RequestOptionFunc) (*Response, error) {
917 group, err := parseID(gid)
918 if err != nil {
919 return nil, err
920 }
921 u := fmt.Sprintf("groups/%s/saml_group_links/%s", PathEscape(group), PathEscape(samlGroupName))
922
923 req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
924 if err != nil {
925 return nil, err
926 }
927
928 return s.client.Do(req, nil)
929 }
930
931
932
933
934
935 type ShareGroupWithGroupOptions struct {
936 GroupID *int `url:"group_id,omitempty" json:"group_id,omitempty"`
937 GroupAccess *AccessLevelValue `url:"group_access,omitempty" json:"group_access,omitempty"`
938 ExpiresAt *ISOTime `url:"expires_at,omitempty" json:"expires_at,omitempty"`
939 }
940
941
942
943
944
945 func (s *GroupsService) ShareGroupWithGroup(gid interface{}, opt *ShareGroupWithGroupOptions, options ...RequestOptionFunc) (*Group, *Response, error) {
946 group, err := parseID(gid)
947 if err != nil {
948 return nil, nil, err
949 }
950 u := fmt.Sprintf("groups/%s/share", PathEscape(group))
951
952 req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
953 if err != nil {
954 return nil, nil, err
955 }
956
957 g := new(Group)
958 resp, err := s.client.Do(req, g)
959 if err != nil {
960 return nil, resp, err
961 }
962
963 return g, resp, nil
964 }
965
966
967
968
969
970 func (s *GroupsService) UnshareGroupFromGroup(gid interface{}, groupID int, options ...RequestOptionFunc) (*Response, error) {
971 group, err := parseID(gid)
972 if err != nil {
973 return nil, err
974 }
975 u := fmt.Sprintf("groups/%s/share/%d", PathEscape(group), groupID)
976
977 req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
978 if err != nil {
979 return nil, err
980 }
981
982 return s.client.Do(req, nil)
983 }
984
985
986
987
988
989 type GroupPushRules struct {
990 ID int `json:"id"`
991 CreatedAt *time.Time `json:"created_at"`
992 CommitMessageRegex string `json:"commit_message_regex"`
993 CommitMessageNegativeRegex string `json:"commit_message_negative_regex"`
994 BranchNameRegex string `json:"branch_name_regex"`
995 DenyDeleteTag bool `json:"deny_delete_tag"`
996 MemberCheck bool `json:"member_check"`
997 PreventSecrets bool `json:"prevent_secrets"`
998 AuthorEmailRegex string `json:"author_email_regex"`
999 FileNameRegex string `json:"file_name_regex"`
1000 MaxFileSize int `json:"max_file_size"`
1001 CommitCommitterCheck bool `json:"commit_committer_check"`
1002 RejectUnsignedCommits bool `json:"reject_unsigned_commits"`
1003 }
1004
1005
1006
1007
1008
1009 func (s *GroupsService) GetGroupPushRules(gid interface{}, options ...RequestOptionFunc) (*GroupPushRules, *Response, error) {
1010 group, err := parseID(gid)
1011 if err != nil {
1012 return nil, nil, err
1013 }
1014 u := fmt.Sprintf("groups/%s/push_rule", PathEscape(group))
1015
1016 req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
1017 if err != nil {
1018 return nil, nil, err
1019 }
1020
1021 gpr := new(GroupPushRules)
1022 resp, err := s.client.Do(req, gpr)
1023 if err != nil {
1024 return nil, resp, err
1025 }
1026
1027 return gpr, resp, nil
1028 }
1029
1030
1031
1032
1033
1034
1035 type AddGroupPushRuleOptions struct {
1036 AuthorEmailRegex *string `url:"author_email_regex,omitempty" json:"author_email_regex,omitempty"`
1037 BranchNameRegex *string `url:"branch_name_regex,omitempty" json:"branch_name_regex,omitempty"`
1038 CommitCommitterCheck *bool `url:"commit_committer_check,omitempty" json:"commit_committer_check,omitempty"`
1039 CommitMessageNegativeRegex *string `url:"commit_message_negative_regex,omitempty" json:"commit_message_negative_regex,omitempty"`
1040 CommitMessageRegex *string `url:"commit_message_regex,omitempty" json:"commit_message_regex,omitempty"`
1041 DenyDeleteTag *bool `url:"deny_delete_tag,omitempty" json:"deny_delete_tag,omitempty"`
1042 FileNameRegex *string `url:"file_name_regex,omitempty" json:"file_name_regex,omitempty"`
1043 MaxFileSize *int `url:"max_file_size,omitempty" json:"max_file_size,omitempty"`
1044 MemberCheck *bool `url:"member_check,omitempty" json:"member_check,omitempty"`
1045 PreventSecrets *bool `url:"prevent_secrets,omitempty" json:"prevent_secrets,omitempty"`
1046 RejectUnsignedCommits *bool `url:"reject_unsigned_commits,omitempty" json:"reject_unsigned_commits,omitempty"`
1047 }
1048
1049
1050
1051
1052
1053 func (s *GroupsService) AddGroupPushRule(gid interface{}, opt *AddGroupPushRuleOptions, options ...RequestOptionFunc) (*GroupPushRules, *Response, error) {
1054 group, err := parseID(gid)
1055 if err != nil {
1056 return nil, nil, err
1057 }
1058 u := fmt.Sprintf("groups/%s/push_rule", PathEscape(group))
1059
1060 req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
1061 if err != nil {
1062 return nil, nil, err
1063 }
1064
1065 gpr := new(GroupPushRules)
1066 resp, err := s.client.Do(req, gpr)
1067 if err != nil {
1068 return nil, resp, err
1069 }
1070
1071 return gpr, resp, nil
1072 }
1073
1074
1075
1076
1077
1078
1079 type EditGroupPushRuleOptions struct {
1080 AuthorEmailRegex *string `url:"author_email_regex,omitempty" json:"author_email_regex,omitempty"`
1081 BranchNameRegex *string `url:"branch_name_regex,omitempty" json:"branch_name_regex,omitempty"`
1082 CommitCommitterCheck *bool `url:"commit_committer_check,omitempty" json:"commit_committer_check,omitempty"`
1083 CommitMessageNegativeRegex *string `url:"commit_message_negative_regex,omitempty" json:"commit_message_negative_regex,omitempty"`
1084 CommitMessageRegex *string `url:"commit_message_regex,omitempty" json:"commit_message_regex,omitempty"`
1085 DenyDeleteTag *bool `url:"deny_delete_tag,omitempty" json:"deny_delete_tag,omitempty"`
1086 FileNameRegex *string `url:"file_name_regex,omitempty" json:"file_name_regex,omitempty"`
1087 MaxFileSize *int `url:"max_file_size,omitempty" json:"max_file_size,omitempty"`
1088 MemberCheck *bool `url:"member_check,omitempty" json:"member_check,omitempty"`
1089 PreventSecrets *bool `url:"prevent_secrets,omitempty" json:"prevent_secrets,omitempty"`
1090 RejectUnsignedCommits *bool `url:"reject_unsigned_commits,omitempty" json:"reject_unsigned_commits,omitempty"`
1091 }
1092
1093
1094
1095
1096
1097 func (s *GroupsService) EditGroupPushRule(gid interface{}, opt *EditGroupPushRuleOptions, options ...RequestOptionFunc) (*GroupPushRules, *Response, error) {
1098 group, err := parseID(gid)
1099 if err != nil {
1100 return nil, nil, err
1101 }
1102 u := fmt.Sprintf("groups/%s/push_rule", PathEscape(group))
1103
1104 req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
1105 if err != nil {
1106 return nil, nil, err
1107 }
1108
1109 gpr := new(GroupPushRules)
1110 resp, err := s.client.Do(req, gpr)
1111 if err != nil {
1112 return nil, resp, err
1113 }
1114
1115 return gpr, resp, nil
1116 }
1117
1118
1119
1120
1121
1122 func (s *GroupsService) DeleteGroupPushRule(gid interface{}, options ...RequestOptionFunc) (*Response, error) {
1123 group, err := parseID(gid)
1124 if err != nil {
1125 return nil, err
1126 }
1127 u := fmt.Sprintf("groups/%s/push_rule", PathEscape(group))
1128
1129 req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
1130 if err != nil {
1131 return nil, err
1132 }
1133
1134 return s.client.Do(req, nil)
1135 }
1136
View as plain text