From b5d3f43f8c73ab6e1a00ad6dd851660005cc065f Mon Sep 17 00:00:00 2001 From: Soul_Cai <5113047+CooCoode@users.noreply.github.com> Date: Wed, 26 Mar 2025 11:30:57 +0800 Subject: [PATCH 1/4] feat: add ds chat --- cmd/apiserver/main.go | 6 ++ config.yml.example | 4 ++ internal/config/config.go | 6 ++ internal/sdk/ds_chat_client.go | 91 +++++++++++++++++++++++++ internal/sdk/spp_client.go | 2 + internal_inject/user/user.controller.go | 70 +++++++++++++++++++ 6 files changed, 179 insertions(+) create mode 100644 internal/sdk/ds_chat_client.go diff --git a/cmd/apiserver/main.go b/cmd/apiserver/main.go index f35c82e6..19b11a72 100644 --- a/cmd/apiserver/main.go +++ b/cmd/apiserver/main.go @@ -154,6 +154,12 @@ func main() { panic(err) } + // setup DS chat API client + err = sdk.InitDsChatClient(cfg.DsChatConfig.BaseUrl, cfg.DsChatConfig.AuthKey) + if err != nil { + panic(err) + } + // Setup zerolog zerolog.TimeFieldFormat = zerolog.TimeFormatUnix zerolog.ErrorStackMarshaler = pkgerrors.MarshalStack diff --git a/config.yml.example b/config.yml.example index 42ba86fe..288e19d4 100644 --- a/config.yml.example +++ b/config.yml.example @@ -66,3 +66,7 @@ snsInvite: entityId: 2 entityName: 新手公会 applicant: 0x4564d5a8Bb409272F1FB4ae4c8b45fC0eaFd709D + +dsChatConfig: + baseUrl: http://localhost:3000 + authKey: TyUcDRDCAKvPkeEMNYEdbVZNA7fwEUCu diff --git a/internal/config/config.go b/internal/config/config.go index a7df1c0c..415e624f 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -29,6 +29,7 @@ type Config struct { Admin adminData `json:"admin" yaml:"admin"` QuickAccounting QuickAccounting `json:"quickAccounting" yaml:"quickAccounting"` SnsInvite SnsInvite `json:"snsInvite" yaml:"snsInvite"` + DsChatConfig DsChatConfig `json:"dsChatConfig" yaml:"dsChatConfig"` } type ( @@ -122,6 +123,11 @@ type ( EntityName string `json:"entityName" yaml:"entityName"` Applicant string `json:"applicant" yaml:"applicant"` } + + DsChatConfig struct { + BaseUrl string `json:"baseUrl" yaml:"baseUrl"` + AuthKey string `json:"authKey" yaml:"authKey"` + } ) func LoadConfig(configPath string) *Config { diff --git a/internal/sdk/ds_chat_client.go b/internal/sdk/ds_chat_client.go new file mode 100644 index 00000000..7e44e0a5 --- /dev/null +++ b/internal/sdk/ds_chat_client.go @@ -0,0 +1,91 @@ +package sdk + +import ( + "encoding/json" + "fmt" + "net/http" + + "github.com/rs/zerolog/log" + "github.com/theseed-labs/os-backend/internal/common" +) + +type DsChatResponse struct { + ApiKey string `json:"apiKey"` +} + +type DsChatClient struct { + ApiBase string `json:"api_base"` + AuthKey string `json:"auth_key"` +} + +var dsChatClient *DsChatClient + +func InitDsChatClient(apiBase string, authKey string) error { + dsChatClient = &DsChatClient{ + ApiBase: apiBase, + AuthKey: authKey, + } + return nil +} + +func GetDsChatClient() *DsChatClient { + return dsChatClient +} + +func (c *DsChatClient) Auth(wallet string) (*DsChatResponse, error) { + _wallet := common.FormatUserWallet(wallet) + endpoint := fmt.Sprintf("%s/os/auth/%s", c.ApiBase, _wallet) + log.Debug().Msgf("update spp profile, endpoint %s", endpoint) + + req, err := http.NewRequest("POST", endpoint, nil) + if err != nil { + return nil, err + } + + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", c.AuthKey)) + req.Header.Set("Content-Type", "application/json") + + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + res := DsChatResponse{} + err = json.NewDecoder(resp.Body).Decode(&res) + if err != nil { + return nil, err + } + + return &res, nil +} + +func (c *DsChatClient) Refersh(wallet string) (*DsChatResponse, error) { + _wallet := common.FormatUserWallet(wallet) + endpoint := fmt.Sprintf("%s/os/refresh/%s", c.ApiBase, _wallet) + log.Debug().Msgf("update spp profile, endpoint %s", endpoint) + + req, err := http.NewRequest("POST", endpoint, nil) + if err != nil { + return nil, err + } + + req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", c.AuthKey)) + req.Header.Set("Content-Type", "application/json") + + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + res := DsChatResponse{} + err = json.NewDecoder(resp.Body).Decode(&res) + if err != nil { + return nil, err + } + + return &res, nil +} diff --git a/internal/sdk/spp_client.go b/internal/sdk/spp_client.go index 5830d55a..20efa118 100644 --- a/internal/sdk/spp_client.go +++ b/internal/sdk/spp_client.go @@ -52,6 +52,8 @@ type SeepassResponse struct { } `json:"sbt"` SocialAccounts []interface{} `json:"social_accounts"` + + DsApiKey string `json:"ds_api_key"` } type ProfileSocialAccount struct { diff --git a/internal_inject/user/user.controller.go b/internal_inject/user/user.controller.go index 02217c6e..81e9a4a2 100644 --- a/internal_inject/user/user.controller.go +++ b/internal_inject/user/user.controller.go @@ -77,6 +77,68 @@ func Register(fatherGroup *gin.RouterGroup) { userAuthGroup.POST("/leave_metaforo_group", user.LeaveMetaforoGroup) userAuthGroup.POST("/prepare_metaforo", user.PrepareMetaforoData) userAuthGroup.GET("/level", user.UserLvl) + userAuthGroup.POST("/refresh/dsapikey", user.RefreshDsApiKey) + userAuthGroup.POST("/auth/dschat", user.AuthDsChat) +} + +func (ctrl *UserController) AuthDsChat(ctx *gin.Context) { + user, _ := api.ForContextUserAndDB(ctx) + if user == nil { + ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("user need to login"))) + return + } + sppClient := sdk.GetSppClient() + seepassResp, err := api.GetCachedSeepassData(sppClient, user.Wallet, false) + if err != nil { + sdk.LogServerErrorToSentry(ctx, err) + ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("seepass data error"))) + return + } + + if len(seepassResp.Sns) > 0 { + dsChatClient := sdk.GetDsChatClient() + res, err := dsChatClient.Auth(user.Wallet) + if err != nil { + sdk.LogServerErrorToSentry(ctx, err) + ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("dschat auth error"))) + return + } + ctx.JSON(http.StatusOK, api.Success(res)) + return + } else { + ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("you don't have sns"))) + return + } +} + +func (ctrl *UserController) RefreshDsApiKey(ctx *gin.Context) { + user, _ := api.ForContextUserAndDB(ctx) + if user == nil { + ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("user need to login"))) + return + } + sppClient := sdk.GetSppClient() + seepassResp, err := api.GetCachedSeepassData(sppClient, user.Wallet, false) + if err != nil { + sdk.LogServerErrorToSentry(ctx, err) + ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("seepass data error"))) + return + } + + if len(seepassResp.Sns) > 0 { + dsChatClient := sdk.GetDsChatClient() + res, err := dsChatClient.Refersh(user.Wallet) + if err != nil { + sdk.LogServerErrorToSentry(ctx, err) + ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("dschat refresh error"))) + return + } + ctx.JSON(http.StatusOK, api.Success(res)) + return + } else { + ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("you don't have sns"))) + return + } } func (ctrl *UserController) RefreshNonce(ctx *gin.Context) { @@ -336,6 +398,14 @@ func (ctrl *UserController) Detail(ctx *gin.Context) { sppClient := sdk.GetSppClient() seepassResp, err := api.GetCachedSeepassData(sppClient, user.Wallet, false) if err == nil { + if len(seepassResp.Sns) > 0 { + dsChatClient := sdk.GetDsChatClient() + res, err := dsChatClient.Auth(user.Wallet) + if err == nil { + seepassResp.DsApiKey = res.ApiKey + } + } + ctx.JSON(http.StatusOK, api.Success(seepassResp)) return } From ed3572b50003d885cf76b3a382f8460d6bd44a0e Mon Sep 17 00:00:00 2001 From: Soul_Cai <5113047+CooCoode@users.noreply.github.com> Date: Wed, 26 Mar 2025 12:22:52 +0800 Subject: [PATCH 2/4] fix: change check --- internal_inject/user/user.controller.go | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/internal_inject/user/user.controller.go b/internal_inject/user/user.controller.go index 81e9a4a2..16c63228 100644 --- a/internal_inject/user/user.controller.go +++ b/internal_inject/user/user.controller.go @@ -81,6 +81,15 @@ func Register(fatherGroup *gin.RouterGroup) { userAuthGroup.POST("/auth/dschat", user.AuthDsChat) } +func findString(slice []string, target string) (int, bool) { + for i, s := range slice { + if s == target { + return i, true // 返回索引和存在标记 + } + } + return -1, false // 未找到 +} + func (ctrl *UserController) AuthDsChat(ctx *gin.Context) { user, _ := api.ForContextUserAndDB(ctx) if user == nil { @@ -95,7 +104,8 @@ func (ctrl *UserController) AuthDsChat(ctx *gin.Context) { return } - if len(seepassResp.Sns) > 0 { + _, ok := findString(seepassResp.Roles, "SEEDAO_MEMBER") + if ok { dsChatClient := sdk.GetDsChatClient() res, err := dsChatClient.Auth(user.Wallet) if err != nil { @@ -125,7 +135,8 @@ func (ctrl *UserController) RefreshDsApiKey(ctx *gin.Context) { return } - if len(seepassResp.Sns) > 0 { + _, ok := findString(seepassResp.Roles, "SEEDAO_MEMBER") + if ok { dsChatClient := sdk.GetDsChatClient() res, err := dsChatClient.Refersh(user.Wallet) if err != nil { @@ -398,7 +409,8 @@ func (ctrl *UserController) Detail(ctx *gin.Context) { sppClient := sdk.GetSppClient() seepassResp, err := api.GetCachedSeepassData(sppClient, user.Wallet, false) if err == nil { - if len(seepassResp.Sns) > 0 { + _, ok := findString(seepassResp.Roles, "SEEDAO_MEMBER") + if ok { dsChatClient := sdk.GetDsChatClient() res, err := dsChatClient.Auth(user.Wallet) if err == nil { From d202886112d8bc10e685034dc20b96c088c28fdd Mon Sep 17 00:00:00 2001 From: Soul_Cai <5113047+CooCoode@users.noreply.github.com> Date: Thu, 27 Mar 2025 15:16:27 +0800 Subject: [PATCH 3/4] fix: change notice need a sns --- internal_inject/user/user.controller.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal_inject/user/user.controller.go b/internal_inject/user/user.controller.go index 16c63228..3c2958c6 100644 --- a/internal_inject/user/user.controller.go +++ b/internal_inject/user/user.controller.go @@ -100,7 +100,7 @@ func (ctrl *UserController) AuthDsChat(ctx *gin.Context) { seepassResp, err := api.GetCachedSeepassData(sppClient, user.Wallet, false) if err != nil { sdk.LogServerErrorToSentry(ctx, err) - ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("seepass data error"))) + ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("you need has a sns"))) return } @@ -116,7 +116,7 @@ func (ctrl *UserController) AuthDsChat(ctx *gin.Context) { ctx.JSON(http.StatusOK, api.Success(res)) return } else { - ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("you don't have sns"))) + ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("you need has a sns"))) return } } @@ -131,7 +131,7 @@ func (ctrl *UserController) RefreshDsApiKey(ctx *gin.Context) { seepassResp, err := api.GetCachedSeepassData(sppClient, user.Wallet, false) if err != nil { sdk.LogServerErrorToSentry(ctx, err) - ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("seepass data error"))) + ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("you need has a sns"))) return } @@ -147,7 +147,7 @@ func (ctrl *UserController) RefreshDsApiKey(ctx *gin.Context) { ctx.JSON(http.StatusOK, api.Success(res)) return } else { - ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("you don't have sns"))) + ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("you need has a sns"))) return } } From b40977cd55be04d2ee1c204b513f0edaa17a1c2c Mon Sep 17 00:00:00 2001 From: Soul_Cai <5113047+CooCoode@users.noreply.github.com> Date: Wed, 9 Apr 2025 21:38:43 +0800 Subject: [PATCH 4/4] fix: change the notice --- internal_inject/user/user.controller.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/internal_inject/user/user.controller.go b/internal_inject/user/user.controller.go index 3c2958c6..f8e30390 100644 --- a/internal_inject/user/user.controller.go +++ b/internal_inject/user/user.controller.go @@ -100,7 +100,7 @@ func (ctrl *UserController) AuthDsChat(ctx *gin.Context) { seepassResp, err := api.GetCachedSeepassData(sppClient, user.Wallet, false) if err != nil { sdk.LogServerErrorToSentry(ctx, err) - ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("you need has a sns"))) + ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("you need become seedao member"))) return } @@ -116,7 +116,7 @@ func (ctrl *UserController) AuthDsChat(ctx *gin.Context) { ctx.JSON(http.StatusOK, api.Success(res)) return } else { - ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("you need has a sns"))) + ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("you need become seedao member"))) return } } @@ -131,7 +131,7 @@ func (ctrl *UserController) RefreshDsApiKey(ctx *gin.Context) { seepassResp, err := api.GetCachedSeepassData(sppClient, user.Wallet, false) if err != nil { sdk.LogServerErrorToSentry(ctx, err) - ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("you need has a sns"))) + ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("you need become seedao member"))) return } @@ -147,7 +147,7 @@ func (ctrl *UserController) RefreshDsApiKey(ctx *gin.Context) { ctx.JSON(http.StatusOK, api.Success(res)) return } else { - ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("you need has a sns"))) + ctx.JSON(http.StatusInternalServerError, api.ServerError(errors.New("you need become seedao member"))) return } }