1//
2// Copyright 2021, Eric Stevens
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//     http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17package gitlab
18
19import (
20	"fmt"
21	"net/http"
22	"time"
23)
24
25// GroupHook represents a GitLab group hook.
26//
27// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#list-group-hooks
28type GroupHook struct {
29	ID                       int        `json:"id"`
30	URL                      string     `json:"url"`
31	GroupID                  int        `json:"group_id"`
32	PushEvents               bool       `json:"push_events"`
33	IssuesEvents             bool       `json:"issues_events"`
34	ConfidentialIssuesEvents bool       `json:"confidential_issues_events"`
35	ConfidentialNoteEvents   bool       `json:"confidential_note_events"`
36	MergeRequestsEvents      bool       `json:"merge_requests_events"`
37	TagPushEvents            bool       `json:"tag_push_events"`
38	NoteEvents               bool       `json:"note_events"`
39	JobEvents                bool       `json:"job_events"`
40	PipelineEvents           bool       `json:"pipeline_events"`
41	WikiPageEvents           bool       `json:"wiki_page_events"`
42	DeploymentEvents         bool       `json:"deployment_events"`
43	ReleasesEvents           bool       `json:"releases_events"`
44	EnableSSLVerification    bool       `json:"enable_ssl_verification"`
45	CreatedAt                *time.Time `json:"created_at"`
46}
47
48// ListGroupHooks gets a list of group hooks.
49//
50// GitLab API docs: https://docs.gitlab.com/ce/api/groups.html#list-group-hooks
51func (s *GroupsService) ListGroupHooks(gid interface{}) ([]*GroupHook, *Response, error) {
52	group, err := parseID(gid)
53	if err != nil {
54		return nil, nil, err
55	}
56	u := fmt.Sprintf("groups/%s/hooks", pathEscape(group))
57
58	req, err := s.client.NewRequest(http.MethodGet, u, nil, nil)
59	if err != nil {
60		return nil, nil, err
61	}
62	var gh []*GroupHook
63	resp, err := s.client.Do(req, &gh)
64	if err != nil {
65		return nil, resp, err
66	}
67
68	return gh, resp, err
69}
70
71// GetGroupHook gets a specific hook for a group.
72//
73// GitLab API docs:
74// https://docs.gitlab.com/ce/api/groups.html#get-group-hook
75func (s *GroupsService) GetGroupHook(pid interface{}, hook int, options ...RequestOptionFunc) (*GroupHook, *Response, error) {
76	group, err := parseID(pid)
77	if err != nil {
78		return nil, nil, err
79	}
80	u := fmt.Sprintf("groups/%s/hooks/%d", pathEscape(group), hook)
81
82	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
83	if err != nil {
84		return nil, nil, err
85	}
86
87	gh := new(GroupHook)
88	resp, err := s.client.Do(req, gh)
89	if err != nil {
90		return nil, resp, err
91	}
92
93	return gh, resp, err
94}
95
96// AddGroupHookOptions represents the available AddGroupHook() options.
97//
98// GitLab API docs: https://docs.gitlab.com/ee/api/groups.html#add-group-hook
99type AddGroupHookOptions struct {
100	URL                      *string `url:"url,omitempty" json:"url,omitempty"`
101	PushEvents               *bool   `url:"push_events,omitempty"  json:"push_events,omitempty"`
102	IssuesEvents             *bool   `url:"issues_events,omitempty"  json:"issues_events,omitempty"`
103	ConfidentialIssuesEvents *bool   `url:"confidential_issues_events,omitempty"  json:"confidential_issues_events,omitempty"`
104	ConfidentialNoteEvents   *bool   `url:"confidential_note_events,omitempty"  json:"confidential_note_events,omitempty"`
105	MergeRequestsEvents      *bool   `url:"merge_requests_events,omitempty"  json:"merge_requests_events,omitempty"`
106	TagPushEvents            *bool   `url:"tag_push_events,omitempty"  json:"tag_push_events,omitempty"`
107	NoteEvents               *bool   `url:"note_events,omitempty"  json:"note_events,omitempty"`
108	JobEvents                *bool   `url:"job_events,omitempty"  json:"job_events,omitempty"`
109	PipelineEvents           *bool   `url:"pipeline_events,omitempty"  json:"pipeline_events,omitempty"`
110	WikiPageEvents           *bool   `url:"wiki_page_events,omitempty"  json:"wiki_page_events,omitempty"`
111	DeploymentEvents         *bool   `url:"deployment_events,omitempty" json:"deployment_events,omitempty"`
112	ReleasesEvents           *bool   `url:"releases_events,omitempty" json:"releases_events,omitempty"`
113	EnableSSLVerification    *bool   `url:"enable_ssl_verification,omitempty"  json:"enable_ssl_verification,omitempty"`
114	Token                    *string `url:"token,omitempty" json:"token,omitempty"`
115}
116
117// AddGroupHook create a new group scoped webhook.
118//
119// GitLab API docs: https://docs.gitlab.com/ee/api/groups.html#add-group-hook
120func (s *GroupsService) AddGroupHook(gid interface{}, opt *AddGroupHookOptions, options ...RequestOptionFunc) (*GroupHook, *Response, error) {
121	group, err := parseID(gid)
122	if err != nil {
123		return nil, nil, err
124	}
125	u := fmt.Sprintf("groups/%s/hooks", pathEscape(group))
126
127	req, err := s.client.NewRequest(http.MethodPost, u, opt, options)
128	if err != nil {
129		return nil, nil, err
130	}
131
132	gh := new(GroupHook)
133	resp, err := s.client.Do(req, gh)
134	if err != nil {
135		return nil, resp, err
136	}
137
138	return gh, resp, err
139}
140
141// EditGroupHookOptions represents the available EditGroupHook() options.
142//
143// GitLab API docs:
144// https://docs.gitlab.com/ce/api/groups.html#edit-group-hook
145type EditGroupHookOptions struct {
146	URL                      *string `url:"url,omitempty" json:"url,omitempty"`
147	PushEvents               *bool   `url:"push_events,omitempty" json:"push_events,omitempty"`
148	IssuesEvents             *bool   `url:"issues_events,omitempty" json:"issues_events,omitempty"`
149	ConfidentialIssuesEvents *bool   `url:"confidential_issues_events,omitempty" json:"confidential_issues_events,omitempty"`
150	ConfidentialNoteEvents   *bool   `url:"confidential_note_events,omitempty" json:"confidential_note_events,omitempty"`
151	MergeRequestsEvents      *bool   `url:"merge_requests_events,omitempty" json:"merge_requests_events,omitempty"`
152	TagPushEvents            *bool   `url:"tag_push_events,omitempty" json:"tag_push_events,omitempty"`
153	NoteEvents               *bool   `url:"note_events,omitempty" json:"note_events,omitempty"`
154	JobEvents                *bool   `url:"job_events,omitempty" json:"job_events,omitempty"`
155	PipelineEvents           *bool   `url:"pipeline_events,omitempty" json:"pipeline_events,omitempty"`
156	WikiPageEvents           *bool   `url:"wiki_page_events,omitempty" json:"wiki_page_events,omitempty"`
157	DeploymentEvents         *bool   `url:"deployment_events,omitempty" json:"deployment_events,omitempty"`
158	ReleasesEvents           *bool   `url:"releases_events,omitempty" json:"releases_events,omitempty"`
159	EnableSSLVerification    *bool   `url:"enable_ssl_verification,omitempty" json:"enable_ssl_verification,omitempty"`
160	Token                    *string `url:"token,omitempty" json:"token,omitempty"`
161}
162
163// EditGroupHook edits a hook for a specified group.
164//
165// Gitlab API docs:
166// https://docs.gitlab.com/ce/api/groups.html#edit-group-hook
167func (s *GroupsService) EditGroupHook(pid interface{}, hook int, opt *EditGroupHookOptions, options ...RequestOptionFunc) (*GroupHook, *Response, error) {
168	group, err := parseID(pid)
169	if err != nil {
170		return nil, nil, err
171	}
172	u := fmt.Sprintf("groups/%s/hooks/%d", pathEscape(group), hook)
173
174	req, err := s.client.NewRequest(http.MethodPut, u, opt, options)
175	if err != nil {
176		return nil, nil, err
177	}
178
179	gh := new(GroupHook)
180	resp, err := s.client.Do(req, gh)
181	if err != nil {
182		return nil, resp, err
183	}
184
185	return gh, resp, err
186}
187
188// DeleteGroupHook removes a hook from a group. This is an idempotent
189// method and can be called multiple times.
190//
191// GitLab API docs:
192// https://docs.gitlab.com/ce/api/groups.html#delete-group-hook
193func (s *GroupsService) DeleteGroupHook(pid interface{}, hook int, options ...RequestOptionFunc) (*Response, error) {
194	group, err := parseID(pid)
195	if err != nil {
196		return nil, err
197	}
198	u := fmt.Sprintf("groups/%s/hooks/%d", pathEscape(group), hook)
199
200	req, err := s.client.NewRequest(http.MethodDelete, u, nil, options)
201	if err != nil {
202		return nil, err
203	}
204
205	return s.client.Do(req, nil)
206}
207