package mailgun import ( "context" "fmt" "strconv" ) // A Credential structure describes a principle allowed to send or receive mail at the domain. type Credential struct { CreatedAt RFC2822Time `json:"created_at"` Login string `json:"login"` Password string `json:"password"` } type credentialsListResponse struct { // is -1 if Next() or First() have not been called TotalCount int `json:"total_count"` Items []Credential `json:"items"` } // Returned when a required parameter is missing. var ErrEmptyParam = fmt.Errorf("empty or illegal parameter") // ListCredentials returns the (possibly zero-length) list of credentials associated with your domain. func (mg *MailgunImpl) ListCredentials(opts *ListOptions) *CredentialsIterator { var limit int if opts != nil { limit = opts.Limit } if limit == 0 { limit = 100 } return &CredentialsIterator{ mg: mg, url: generateCredentialsUrl(mg, ""), credentialsListResponse: credentialsListResponse{TotalCount: -1}, limit: limit, } } type CredentialsIterator struct { credentialsListResponse limit int mg Mailgun offset int url string err error } // If an error occurred during iteration `Err()` will return non nil func (ri *CredentialsIterator) Err() error { return ri.err } // Offset returns the current offset of the iterator func (ri *CredentialsIterator) Offset() int { return ri.offset } // Next retrieves the next page of items from the api. Returns false when there // no more pages to retrieve or if there was an error. Use `.Err()` to retrieve // the error func (ri *CredentialsIterator) Next(ctx context.Context, items *[]Credential) bool { if ri.err != nil { return false } ri.err = ri.fetch(ctx, ri.offset, ri.limit) if ri.err != nil { return false } cpy := make([]Credential, len(ri.Items)) copy(cpy, ri.Items) *items = cpy if len(ri.Items) == 0 { return false } ri.offset = ri.offset + len(ri.Items) return true } // First retrieves the first page of items from the api. Returns false if there // was an error. It also sets the iterator object to the first page. // Use `.Err()` to retrieve the error. func (ri *CredentialsIterator) First(ctx context.Context, items *[]Credential) bool { if ri.err != nil { return false } ri.err = ri.fetch(ctx, 0, ri.limit) if ri.err != nil { return false } cpy := make([]Credential, len(ri.Items)) copy(cpy, ri.Items) *items = cpy ri.offset = len(ri.Items) return true } // Last retrieves the last page of items from the api. // Calling Last() is invalid unless you first call First() or Next() // Returns false if there was an error. It also sets the iterator object // to the last page. Use `.Err()` to retrieve the error. func (ri *CredentialsIterator) Last(ctx context.Context, items *[]Credential) bool { if ri.err != nil { return false } if ri.TotalCount == -1 { return false } ri.offset = ri.TotalCount - ri.limit if ri.offset < 0 { ri.offset = 0 } ri.err = ri.fetch(ctx, ri.offset, ri.limit) if ri.err != nil { return false } cpy := make([]Credential, len(ri.Items)) copy(cpy, ri.Items) *items = cpy return true } // Previous retrieves the previous page of items from the api. Returns false when there // no more pages to retrieve or if there was an error. Use `.Err()` to retrieve // the error if any func (ri *CredentialsIterator) Previous(ctx context.Context, items *[]Credential) bool { if ri.err != nil { return false } if ri.TotalCount == -1 { return false } ri.offset = ri.offset - (ri.limit * 2) if ri.offset < 0 { ri.offset = 0 } ri.err = ri.fetch(ctx, ri.offset, ri.limit) if ri.err != nil { return false } cpy := make([]Credential, len(ri.Items)) copy(cpy, ri.Items) *items = cpy if len(ri.Items) == 0 { return false } return true } func (ri *CredentialsIterator) fetch(ctx context.Context, skip, limit int) error { r := newHTTPRequest(ri.url) r.setBasicAuth(basicAuthUser, ri.mg.APIKey()) r.setClient(ri.mg.Client()) if skip != 0 { r.addParameter("skip", strconv.Itoa(skip)) } if limit != 0 { r.addParameter("limit", strconv.Itoa(limit)) } return getResponseFromJSON(ctx, r, &ri.credentialsListResponse) } // CreateCredential attempts to create associate a new principle with your domain. func (mg *MailgunImpl) CreateCredential(ctx context.Context, login, password string) error { if (login == "") || (password == "") { return ErrEmptyParam } r := newHTTPRequest(generateCredentialsUrl(mg, "")) r.setClient(mg.Client()) r.setBasicAuth(basicAuthUser, mg.APIKey()) p := newUrlEncodedPayload() p.addValue("login", login) p.addValue("password", password) _, err := makePostRequest(ctx, r, p) return err } // ChangeCredentialPassword attempts to alter the indicated credential's password. func (mg *MailgunImpl) ChangeCredentialPassword(ctx context.Context, login, password string) error { if (login == "") || (password == "") { return ErrEmptyParam } r := newHTTPRequest(generateCredentialsUrl(mg, login)) r.setClient(mg.Client()) r.setBasicAuth(basicAuthUser, mg.APIKey()) p := newUrlEncodedPayload() p.addValue("password", password) _, err := makePutRequest(ctx, r, p) return err } // DeleteCredential attempts to remove the indicated principle from the domain. func (mg *MailgunImpl) DeleteCredential(ctx context.Context, login string) error { if login == "" { return ErrEmptyParam } r := newHTTPRequest(generateCredentialsUrl(mg, login)) r.setClient(mg.Client()) r.setBasicAuth(basicAuthUser, mg.APIKey()) _, err := makeDeleteRequest(ctx, r) return err }