chore: move '/internal/pkg' to '/pkg'

This commit is contained in:
Fu Diwei
2025-06-17 15:54:21 +08:00
parent 30840bbba5
commit 205275b52d
611 changed files with 693 additions and 693 deletions

View File

@@ -0,0 +1,102 @@
package mattermost
import (
"context"
"errors"
"fmt"
"log/slog"
"strings"
"github.com/go-resty/resty/v2"
"github.com/usual2970/certimate/pkg/core"
)
type NotifierProviderConfig struct {
// Mattermost 服务地址。
ServerUrl string `json:"serverUrl"`
// Mattermost 用户名。
Username string `json:"username"`
// Mattermost 密码。
Password string `json:"password"`
// Mattermost 频道 ID。
ChannelId string `json:"channelId"`
}
type NotifierProvider struct {
config *NotifierProviderConfig
logger *slog.Logger
httpClient *resty.Client
}
var _ core.Notifier = (*NotifierProvider)(nil)
func NewNotifierProvider(config *NotifierProviderConfig) (*NotifierProvider, error) {
if config == nil {
return nil, errors.New("the configuration of the notifier provider is nil")
}
client := resty.New()
return &NotifierProvider{
config: config,
logger: slog.Default(),
httpClient: client,
}, nil
}
func (n *NotifierProvider) SetLogger(logger *slog.Logger) {
if logger == nil {
n.logger = slog.New(slog.DiscardHandler)
} else {
n.logger = logger
}
}
func (n *NotifierProvider) Notify(ctx context.Context, subject string, message string) (*core.NotifyResult, error) {
serverUrl := strings.TrimRight(n.config.ServerUrl, "/")
// REF: https://developers.mattermost.com/api-documentation/#/operations/Login
loginReq := n.httpClient.R().
SetContext(ctx).
SetHeader("Content-Type", "application/json").
SetHeader("User-Agent", "certimate").
SetBody(map[string]any{
"login_id": n.config.Username,
"password": n.config.Password,
})
loginResp, err := loginReq.Post(fmt.Sprintf("%s/api/v4/users/login", serverUrl))
if err != nil {
return nil, fmt.Errorf("mattermost api error: failed to send request: %w", err)
} else if loginResp.IsError() {
return nil, fmt.Errorf("mattermost api error: unexpected status code: %d, resp: %s", loginResp.StatusCode(), loginResp.String())
} else if loginResp.Header().Get("Token") == "" {
return nil, fmt.Errorf("mattermost api error: received empty login token")
}
// REF: https://developers.mattermost.com/api-documentation/#/operations/CreatePost
postReq := n.httpClient.R().
SetContext(ctx).
SetHeader("Authorization", "Bearer "+loginResp.Header().Get("Token")).
SetHeader("Content-Type", "application/json").
SetHeader("User-Agent", "certimate").
SetBody(map[string]any{
"channel_id": n.config.ChannelId,
"props": map[string]interface{}{
"attachments": []map[string]interface{}{
{
"title": subject,
"text": message,
},
},
},
})
postResp, err := postReq.Post(fmt.Sprintf("%s/api/v4/posts", serverUrl))
if err != nil {
return nil, fmt.Errorf("mattermost api error: failed to send request: %w", err)
} else if postResp.IsError() {
return nil, fmt.Errorf("mattermost api error: unexpected status code: %d, resp: %s", postResp.StatusCode(), postResp.String())
}
return &core.NotifyResult{}, nil
}

View File

@@ -0,0 +1,74 @@
package mattermost_test
import (
"context"
"flag"
"fmt"
"strings"
"testing"
provider "github.com/usual2970/certimate/pkg/core/notifier/providers/mattermost"
)
const (
mockSubject = "test_subject"
mockMessage = "test_message"
)
var (
fServerUrl string
fChannelId string
fUsername string
fPassword string
)
func init() {
argsPrefix := "CERTIMATE_NOTIFIER_MATTERMOST_"
flag.StringVar(&fServerUrl, argsPrefix+"SERVERURL", "", "")
flag.StringVar(&fChannelId, argsPrefix+"CHANNELID", "", "")
flag.StringVar(&fUsername, argsPrefix+"USERNAME", "", "")
flag.StringVar(&fPassword, argsPrefix+"PASSWORD", "", "")
}
/*
Shell command to run this test:
go test -v ./mattermost_test.go -args \
--CERTIMATE_NOTIFIER_MATTERMOST_SERVERURL="https://example.com/your-server-url" \
--CERTIMATE_NOTIFIER_MATTERMOST_CHANNELID="your-chanel-id" \
--CERTIMATE_NOTIFIER_MATTERMOST_USERNAME="your-username" \
--CERTIMATE_NOTIFIER_MATTERMOST_PASSWORD="your-password"
*/
func TestNotify(t *testing.T) {
flag.Parse()
t.Run("Notify", func(t *testing.T) {
t.Log(strings.Join([]string{
"args:",
fmt.Sprintf("SERVERURL: %v", fServerUrl),
fmt.Sprintf("CHANNELID: %v", fChannelId),
fmt.Sprintf("USERNAME: %v", fUsername),
fmt.Sprintf("PASSWORD: %v", fPassword),
}, "\n"))
notifier, err := provider.NewNotifierProvider(&provider.NotifierProviderConfig{
ServerUrl: fServerUrl,
ChannelId: fChannelId,
Username: fUsername,
Password: fPassword,
})
if err != nil {
t.Errorf("err: %+v", err)
return
}
res, err := notifier.Notify(context.Background(), mockSubject, mockMessage)
if err != nil {
t.Errorf("err: %+v", err)
return
}
t.Logf("ok: %v", res)
})
}