70 lines
1.6 KiB
Go
70 lines
1.6 KiB
Go
package dingtalk
|
|
|
|
import (
|
|
"ai_scheduler/internal/config"
|
|
"ai_scheduler/internal/data/constants"
|
|
"ai_scheduler/internal/pkg/l_request"
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/redis/go-redis/v9"
|
|
)
|
|
|
|
type Auth struct {
|
|
redis *redis.Client
|
|
cfg *config.Config
|
|
}
|
|
|
|
func NewAuth(cfg *config.Config, redis *redis.Client) *Auth {
|
|
return &Auth{
|
|
redis: redis,
|
|
cfg: cfg,
|
|
}
|
|
}
|
|
|
|
func (a *Auth) GetAccessToken(ctx context.Context, clientId string, clientSecret string) (accessToken string, err error) {
|
|
if clientId == "" {
|
|
return "", errors.New("clientId is empty")
|
|
}
|
|
token := a.redis.Get(ctx, a.getKey(clientId)).String()
|
|
if token == "" {
|
|
authInfo, _err := a.getNewAccessToken(ctx, clientId, clientSecret)
|
|
if _err != nil {
|
|
return "", _err
|
|
}
|
|
a.redis.SetEx(ctx, a.getKey(clientId), authInfo.AccessToken, time.Duration(authInfo.ExpiresIn-3600)*time.Second)
|
|
accessToken = authInfo.AccessToken
|
|
}
|
|
return
|
|
}
|
|
|
|
func (a *Auth) getKey(clientId string) string {
|
|
return a.cfg.Redis.Key + ":" + constants.DingTalkAuthBaseKeyPrefix + ":" + clientId
|
|
}
|
|
|
|
func (a *Auth) getNewAccessToken(ctx context.Context, clientId string, clientSecret string) (auth AuthInfo, err error) {
|
|
if clientId == "" || clientSecret == "" {
|
|
err = errors.New("clientId or clientSecret is empty")
|
|
return
|
|
}
|
|
|
|
req := l_request.Request{
|
|
Method: http.MethodPost,
|
|
Url: constants.GetDingTalkRequestUrl(constants.RequestUrlGetAccessToken, nil),
|
|
Data: map[string]string{
|
|
"appkey": clientId,
|
|
"appsecret": clientSecret,
|
|
},
|
|
}
|
|
res, err := req.Send()
|
|
if err != nil {
|
|
return
|
|
}
|
|
err = json.Unmarshal(res.Content, &auth)
|
|
|
|
return
|
|
}
|