@@ -2,8 +2,340 @@ package mailgun
22
33import (
44 "context"
5+ "fmt"
6+ "strconv"
7+
8+ "github.com/mailgun/mailgun-go/v5/mtypes"
59)
610
11+ type ListAllDomainsKeysOptions struct {
12+ Limit int
13+ }
14+
15+ type CreateDomainKeyOptions struct {
16+ Bits int
17+ PEM string
18+ }
19+
20+ type AllDomainsKeysIterator struct {
21+ mtypes.ListAllDomainsKeysResponse
22+
23+ limit int
24+ mg Mailgun
25+ url string
26+ err error
27+ }
28+
29+ type DomainKeysIterator struct {
30+ mtypes.ListDomainKeysResponse
31+
32+ mg Mailgun
33+ url string
34+ err error
35+ }
36+
37+ // ListAllDomainsKeys retrieves a set of domain keys from Mailgun.
38+ func (mg * Client ) ListAllDomainsKeys (opts * ListAllDomainsKeysOptions ) * AllDomainsKeysIterator {
39+ var limit int
40+ if opts != nil {
41+ limit = opts .Limit
42+ }
43+
44+ if limit == 0 {
45+ limit = 100
46+ }
47+ return & AllDomainsKeysIterator {
48+ mg : mg ,
49+ url : generateApiUrl (mg , 1 , dkimEndpoint ),
50+ ListAllDomainsKeysResponse : mtypes.ListAllDomainsKeysResponse {TotalCount : - 1 },
51+ limit : limit ,
52+ }
53+ }
54+
55+ // Err if an error occurred during iteration `Err()` will return non nil
56+ func (ri * AllDomainsKeysIterator ) Err () error {
57+ return ri .err
58+ }
59+
60+ // Next retrieves the next page of items from the api. Returns false when there
61+ // are no more pages to retrieve or if there was an error. Use `.Err()` to retrieve
62+ // the error
63+ func (ri * AllDomainsKeysIterator ) Next (ctx context.Context , items * []mtypes.DomainKey ) bool {
64+ if ri .err != nil {
65+ return false
66+ }
67+
68+ ri .err = ri .fetch (ctx , ri .Paging .Next , ri .limit )
69+ if ri .err != nil {
70+ return false
71+ }
72+
73+ cpy := make ([]mtypes.DomainKey , len (ri .Items ))
74+ copy (cpy , ri .Items )
75+ * items = cpy
76+ return len (ri .Items ) != 0
77+ }
78+
79+ // First retrieves the first page of items from the api. Returns false if there
80+ // was an error. It also sets the iterator object to the first page.
81+ // Use `.Err()` to retrieve the error.
82+ func (ri * AllDomainsKeysIterator ) First (ctx context.Context , items * []mtypes.DomainKey ) bool {
83+ if ri .err != nil {
84+ return false
85+ }
86+ ri .err = ri .fetch (ctx , ri .Paging .First , ri .limit )
87+ if ri .err != nil {
88+ return false
89+ }
90+ cpy := make ([]mtypes.DomainKey , len (ri .Items ))
91+ copy (cpy , ri .Items )
92+ * items = cpy
93+ return true
94+ }
95+
96+ // Last retrieves the last page of items from the api.
97+ // Calling Last() is invalid unless you first call First() or Next()
98+ // Returns false if there was an error. It also sets the iterator object
99+ // to the last page. Use `.Err()` to retrieve the error.
100+ func (ri * AllDomainsKeysIterator ) Last (ctx context.Context , items * []mtypes.DomainKey ) bool {
101+ if ri .err != nil {
102+ return false
103+ }
104+
105+ if ri .TotalCount == - 1 {
106+ return false
107+ }
108+
109+ ri .err = ri .fetch (ctx , ri .Paging .Last , ri .limit )
110+ if ri .err != nil {
111+ return false
112+ }
113+ cpy := make ([]mtypes.DomainKey , len (ri .Items ))
114+ copy (cpy , ri .Items )
115+ * items = cpy
116+ return true
117+ }
118+
119+ // Previous retrieves the previous page of items from the api. Returns false when there
120+ // are no more pages to retrieve or if there was an error. Use `.Err()` to retrieve
121+ // the error if any
122+ func (ri * AllDomainsKeysIterator ) Previous (ctx context.Context , items * []mtypes.DomainKey ) bool {
123+ if ri .err != nil {
124+ return false
125+ }
126+
127+ if ri .TotalCount == - 1 {
128+ return false
129+ }
130+
131+ ri .err = ri .fetch (ctx , ri .Paging .Previous , ri .limit )
132+ if ri .err != nil {
133+ return false
134+ }
135+ cpy := make ([]mtypes.DomainKey , len (ri .Items ))
136+ copy (cpy , ri .Items )
137+ * items = cpy
138+
139+ return len (ri .Items ) != 0
140+ }
141+
142+ func (ri * AllDomainsKeysIterator ) fetch (ctx context.Context , pageUrl string , limit int ) error {
143+ ri .Items = nil
144+ uri := ri .url
145+ if pageUrl != "" {
146+ uri = pageUrl
147+ }
148+ r := newHTTPRequest (uri )
149+
150+ r .setBasicAuth (basicAuthUser , ri .mg .APIKey ())
151+ r .setClient (ri .mg .HTTPClient ())
152+
153+ if limit != 0 {
154+ r .addParameter ("limit" , strconv .Itoa (limit ))
155+ }
156+
157+ return getResponseFromJSON (ctx , r , & ri .ListAllDomainsKeysResponse )
158+ }
159+
160+ // CreateDomainKey creates a domain key for the given domain
161+ func (mg * Client ) CreateDomainKey (ctx context.Context , domain , dkimSelector string , opts * CreateDomainKeyOptions ) (mtypes.DomainKey , error ) {
162+ r := newHTTPRequest (generateApiUrl (mg , 1 , dkimEndpoint ))
163+ r .setClient (mg .HTTPClient ())
164+ r .setBasicAuth (basicAuthUser , mg .APIKey ())
165+
166+ payload := newUrlEncodedPayload ()
167+ payload .addValue ("signing_domain" , domain )
168+ payload .addValue ("selector" , dkimSelector )
169+
170+ if opts .Bits != 0 {
171+ payload .addValue ("bits" , strconv .Itoa (opts .Bits ))
172+ }
173+
174+ if opts .PEM != "" {
175+ payload .addValue ("pem" , opts .PEM )
176+ }
177+
178+ var resp mtypes.DomainKey
179+ err := postResponseFromJSON (ctx , r , payload , & resp )
180+ return resp , err
181+ }
182+
183+ // DeleteDomainKey deletes a domain key from the given domain
184+ func (mg * Client ) DeleteDomainKey (ctx context.Context , domain , dkimSelector string ) error {
185+ r := newHTTPRequest (generateApiUrl (mg , 1 , dkimEndpoint ))
186+ r .setClient (mg .HTTPClient ())
187+ r .setBasicAuth (basicAuthUser , mg .APIKey ())
188+
189+ r .addParameter ("signing_domain" , domain )
190+ r .addParameter ("selector" , dkimSelector )
191+
192+ _ , err := makeDeleteRequest (ctx , r )
193+ return err
194+ }
195+
196+ // ActivateDomainKey deactivates a domain key for the given domain
197+ func (mg * Client ) ActivateDomainKey (ctx context.Context , domain , dkimSelector string ) error {
198+ uri := generateActivateDomainKeyApiUrl (domainsEndpoint , domain , dkimSelector )
199+
200+ r := newHTTPRequest (generateApiUrl (mg , 4 , uri ))
201+ r .setClient (mg .HTTPClient ())
202+ r .setBasicAuth (basicAuthUser , mg .APIKey ())
203+
204+ _ , err := makePutRequest (ctx , r , newUrlEncodedPayload ())
205+ return err
206+ }
207+
208+ // ListDomainKeys retrieves a set of domain keys from Mailgun.
209+ func (mg * Client ) ListDomainKeys (domain string ) * DomainKeysIterator {
210+ uri := generateListDomainKeysApiUrl (domainsEndpoint , domain )
211+
212+ return & DomainKeysIterator {
213+ mg : mg ,
214+ url : generateApiUrl (mg , 4 , uri ),
215+ ListDomainKeysResponse : mtypes.ListDomainKeysResponse {},
216+ }
217+ }
218+
219+ // Err if an error occurred during iteration `Err()` will return non nil
220+ func (ri * DomainKeysIterator ) Err () error {
221+ return ri .err
222+ }
223+
224+ // Next retrieves the next page of items from the api. Returns false when there
225+ // are no more pages to retrieve or if there was an error. Use `.Err()` to retrieve
226+ // the error
227+ func (ri * DomainKeysIterator ) Next (ctx context.Context , items * []mtypes.DomainKey ) bool {
228+ if ri .err != nil {
229+ return false
230+ }
231+
232+ ri .err = ri .fetch (ctx , ri .Paging .Next )
233+ if ri .err != nil {
234+ return false
235+ }
236+
237+ cpy := make ([]mtypes.DomainKey , len (ri .Items ))
238+ copy (cpy , ri .Items )
239+ * items = cpy
240+ return len (ri .Items ) != 0
241+ }
242+
243+ // First retrieves the first page of items from the api. Returns false if there
244+ // was an error. It also sets the iterator object to the first page.
245+ // Use `.Err()` to retrieve the error.
246+ func (ri * DomainKeysIterator ) First (ctx context.Context , items * []mtypes.DomainKey ) bool {
247+ if ri .err != nil {
248+ return false
249+ }
250+ ri .err = ri .fetch (ctx , ri .Paging .First )
251+ if ri .err != nil {
252+ return false
253+ }
254+ cpy := make ([]mtypes.DomainKey , len (ri .Items ))
255+ copy (cpy , ri .Items )
256+ * items = cpy
257+ return true
258+ }
259+
260+ // Last retrieves the last page of items from the api.
261+ // Calling Last() is invalid unless you first call First() or Next()
262+ // Returns false if there was an error. It also sets the iterator object
263+ // to the last page. Use `.Err()` to retrieve the error.
264+ func (ri * DomainKeysIterator ) Last (ctx context.Context , items * []mtypes.DomainKey ) bool {
265+ if ri .err != nil {
266+ return false
267+ }
268+
269+ ri .err = ri .fetch (ctx , ri .Paging .Last )
270+ if ri .err != nil {
271+ return false
272+ }
273+ cpy := make ([]mtypes.DomainKey , len (ri .Items ))
274+ copy (cpy , ri .Items )
275+ * items = cpy
276+ return true
277+ }
278+
279+ // Previous retrieves the previous page of items from the api. Returns false when there
280+ // are no more pages to retrieve or if there was an error. Use `.Err()` to retrieve
281+ // the error if any
282+ func (ri * DomainKeysIterator ) Previous (ctx context.Context , items * []mtypes.DomainKey ) bool {
283+ if ri .err != nil {
284+ return false
285+ }
286+
287+ ri .err = ri .fetch (ctx , ri .Paging .Previous )
288+ if ri .err != nil {
289+ return false
290+ }
291+ cpy := make ([]mtypes.DomainKey , len (ri .Items ))
292+ copy (cpy , ri .Items )
293+ * items = cpy
294+
295+ return len (ri .Items ) != 0
296+ }
297+
298+ func (ri * DomainKeysIterator ) fetch (ctx context.Context , pageUrl string ) error {
299+ ri .Items = nil
300+ uri := ri .url
301+ if pageUrl != "" {
302+ uri = pageUrl
303+ }
304+ r := newHTTPRequest (uri )
305+
306+ r .setBasicAuth (basicAuthUser , ri .mg .APIKey ())
307+ r .setClient (ri .mg .HTTPClient ())
308+
309+ return getResponseFromJSON (ctx , r , & ri .ListDomainKeysResponse )
310+ }
311+
312+ // DeactivateDomainKey deactivates a domain key for the given domain
313+ func (mg * Client ) DeactivateDomainKey (ctx context.Context , domain , dkimSelector string ) error {
314+ uri := generateDeactivateDomainKeyApiUrl (domainsEndpoint , domain , dkimSelector )
315+
316+ r := newHTTPRequest (generateApiUrl (mg , 4 , uri ))
317+ r .setClient (mg .HTTPClient ())
318+ r .setBasicAuth (basicAuthUser , mg .APIKey ())
319+
320+ _ , err := makePutRequest (ctx , r , newUrlEncodedPayload ())
321+ return err
322+ }
323+
324+ func (mg * Client ) UpdateDomainDkimAuthority (ctx context.Context , domain string , self bool ) (mtypes.UpdateDomainDkimAuthorityResponse , error ) {
325+ r := newHTTPRequest (generateApiUrl (mg , 3 , domainsEndpoint ) + "/" + domain + "/dkim_authority" )
326+ r .setClient (mg .HTTPClient ())
327+ r .setBasicAuth (basicAuthUser , mg .APIKey ())
328+
329+ payload := newUrlEncodedPayload ()
330+ payload .addValue ("self" , boolToString (self ))
331+
332+ var resp mtypes.UpdateDomainDkimAuthorityResponse
333+
334+ err := putResponseFromJSON (ctx , r , payload , & resp )
335+
336+ return resp , err
337+ }
338+
7339// UpdateDomainDkimSelector updates the DKIM selector for a domain
8340func (mg * Client ) UpdateDomainDkimSelector (ctx context.Context , domain , dkimSelector string ) error {
9341 r := newHTTPRequest (generateApiUrl (mg , 3 , domainsEndpoint ) + "/" + domain + "/dkim_selector" )
@@ -15,3 +347,18 @@ func (mg *Client) UpdateDomainDkimSelector(ctx context.Context, domain, dkimSele
15347 _ , err := makePutRequest (ctx , r , payload )
16348 return err
17349}
350+
351+ // generateActivateDomainKeyApiUrl renders a URL fragment relevant for deactivating a domain key
352+ func generateActivateDomainKeyApiUrl (endpoint , domain , dkimSelector string ) string {
353+ return fmt .Sprintf ("%s/%s/keys/%s/activate" , endpoint , domain , dkimSelector )
354+ }
355+
356+ // generateListDomainKeysApiUrl renders a URL fragment relevant for listing a domain's keys
357+ func generateListDomainKeysApiUrl (endpoint , domain string ) string {
358+ return fmt .Sprintf ("%s/%s/keys" , endpoint , domain )
359+ }
360+
361+ // generateDeactivateDomainKeyApiUrl renders a URL fragment relevant for deactivating a domain key
362+ func generateDeactivateDomainKeyApiUrl (endpoint , domain , dkimSelector string ) string {
363+ return fmt .Sprintf ("%s/%s/keys/%s/deactivate" , endpoint , domain , dkimSelector )
364+ }
0 commit comments