feat: inital commit
This commit is contained in:
163
pkg/mailcow/main.go
Normal file
163
pkg/mailcow/main.go
Normal file
@@ -0,0 +1,163 @@
|
||||
package mailcow
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
ConstAPIKeyHeaderName = "X-API-Key" //nolint:gosec
|
||||
)
|
||||
|
||||
type client struct {
|
||||
httpClient *http.Client
|
||||
baseURL string
|
||||
apiKey string
|
||||
}
|
||||
|
||||
func New(
|
||||
httpClient *http.Client,
|
||||
baseURL,
|
||||
apiKey string,
|
||||
) Client {
|
||||
return &client{
|
||||
baseURL: baseURL,
|
||||
apiKey: apiKey,
|
||||
httpClient: httpClient,
|
||||
}
|
||||
}
|
||||
|
||||
type Client interface {
|
||||
GetMailboxes(ctx context.Context) ([]Mailbox, error)
|
||||
GetAppPasswords(ctx context.Context, username string) ([]AppPassword, error)
|
||||
DeleteAppPasswords(ctx context.Context, ids []int) error
|
||||
CreateAppPassword(ctx context.Context, username, appname, password, protocols string) error
|
||||
}
|
||||
|
||||
func (c *client) GetMailboxes(ctx context.Context) ([]Mailbox, error) {
|
||||
reqURL, err := url.JoinPath(c.baseURL, "api/v1/get/mailbox/all")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, reqURL, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Add(ConstAPIKeyHeaderName, c.apiKey)
|
||||
resp, err := c.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("unexpected status: %s", resp.Status)
|
||||
}
|
||||
mb := make([]Mailbox, 0)
|
||||
if err := json.NewDecoder(resp.Body).Decode(&mb); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return mb, nil
|
||||
}
|
||||
|
||||
func (c *client) GetAppPasswords(ctx context.Context, username string) ([]AppPassword, error) {
|
||||
reqURL, err := url.JoinPath(c.baseURL, "/api/v1/get/app-passwd/all", username)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodGet, reqURL, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.Header.Add(ConstAPIKeyHeaderName, c.apiKey)
|
||||
resp, err := c.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("unexpected status: %s", resp.Status)
|
||||
}
|
||||
ap := make([]AppPassword, 0)
|
||||
if err := json.NewDecoder(resp.Body).Decode(&ap); err != nil {
|
||||
if strings.HasPrefix(err.Error(), "json: cannot unmarshal object into Go value of type []") {
|
||||
return []AppPassword{}, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
return ap, nil
|
||||
}
|
||||
|
||||
func (c *client) DeleteAppPasswords(ctx context.Context, ids []int) error {
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
reqURL, err := url.JoinPath(c.baseURL, "api/v1/delete/app-passwd")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
reqBytes, err := json.Marshal(ids)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, reqURL, bytes.NewBuffer(reqBytes))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Add(ConstAPIKeyHeaderName, c.apiKey)
|
||||
req.Header.Add("Content-Type", "application/json")
|
||||
resp, err := c.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("unexpected status: %s", resp.Status)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *client) CreateAppPassword(ctx context.Context, username, appname, password, protocols string) error {
|
||||
reqURL, err := url.JoinPath(c.baseURL, "api/v1/add/app-passwd")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
reqStruct := struct {
|
||||
Username string `json:"username"`
|
||||
AppName string `json:"app_name"`
|
||||
Password string `json:"app_passwd"`
|
||||
Password2 string `json:"app_passwd2"`
|
||||
Active string `json:"active"`
|
||||
Protocols string `json:"protocols"`
|
||||
}{
|
||||
Username: username,
|
||||
AppName: appname,
|
||||
Password: password,
|
||||
Password2: password,
|
||||
Active: "1",
|
||||
Protocols: protocols,
|
||||
}
|
||||
reqBytes, err := json.Marshal(reqStruct)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req, err := http.NewRequestWithContext(ctx, http.MethodPost, reqURL, bytes.NewBuffer(reqBytes))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
req.Header.Add(ConstAPIKeyHeaderName, c.apiKey)
|
||||
req.Header.Add("Content-Type", "application/json")
|
||||
resp, err := c.httpClient.Do(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return fmt.Errorf("unexpected status: %s", resp.Status)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
21
pkg/mailcow/structs.go
Normal file
21
pkg/mailcow/structs.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package mailcow
|
||||
|
||||
type Mailbox struct {
|
||||
Username string `json:"username"`
|
||||
Active int `json:"active"`
|
||||
ActiveInt int `json:"active_int"`
|
||||
Domain string `json:"domain"`
|
||||
Name string `json:"name"`
|
||||
LocalPart string `json:"local_part"`
|
||||
}
|
||||
|
||||
func (mb *Mailbox) IsActive() bool {
|
||||
return mb.Active == 1 && mb.ActiveInt == 1
|
||||
}
|
||||
|
||||
type AppPassword struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Mailbox string `json:"mailbox"`
|
||||
Domain string `json:"domain"`
|
||||
}
|
||||
Reference in New Issue
Block a user