diff --git a/server/internal/api/callback.go b/server/internal/api/callback.go new file mode 100644 index 0000000..ba3bb06 --- /dev/null +++ b/server/internal/api/callback.go @@ -0,0 +1,76 @@ +// Copyright © 2023 OpenIM open source community. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package api + +import ( + "fmt" + "net/http" + + "github.com/OpenIMSDK/OpenKF/server/internal/common" + "github.com/OpenIMSDK/OpenKF/server/internal/common/response" + "github.com/OpenIMSDK/OpenKF/server/internal/param" + "github.com/gin-gonic/gin" +) + +// OpenIMCallback +// @Tags openim +// @Summary OpenIMCallback +// @Description Support OpenIM callback +// @Produce application/json +// @Success 200 {object} response.Response{msg=string} "Success" +// @Router /api/v1/openim/callback [post]. +func OpenIMCallback(c *gin.Context) { + param := ¶m.OpenIMCallbackCommand{} + err := c.ShouldBindQuery(param) + if err != nil { + // todo + response.FailWithCode(common.INVALID_PARAMS, c) + + return + } + + // redirect to the corresponding router + callbackURL := fmt.Sprintf("%s%s", c.Request.URL.Path, param.Command) + c.Request.URL.Path = callbackURL + c.Redirect(http.StatusTemporaryRedirect, callbackURL) +} + +// BeforeSendSingleMsg +func BeforeSendSingleMsg(c *gin.Context) { +} + +// AfterSendSingleMsg +func AfterSendSingleMsg(c *gin.Context) { +} + +// MsgModify +func MsgModify(c *gin.Context) { +} + +// UserOnline +func UserOnline(c *gin.Context) { +} + +// UserOffline +func UserOffline(c *gin.Context) { +} + +// OfflinePush +func OfflinePush(c *gin.Context) { +} + +// OnlinePush +func OnlinePush(c *gin.Context) { +} diff --git a/server/internal/api/mail.go b/server/internal/api/mail.go index 7297619..5346a6a 100644 --- a/server/internal/api/mail.go +++ b/server/internal/api/mail.go @@ -15,12 +15,13 @@ package api import ( + "github.com/gin-gonic/gin" + "github.com/OpenIMSDK/OpenKF/server/internal/common" "github.com/OpenIMSDK/OpenKF/server/internal/common/response" "github.com/OpenIMSDK/OpenKF/server/internal/param" "github.com/OpenIMSDK/OpenKF/server/internal/service" "github.com/OpenIMSDK/OpenKF/server/pkg/log" - "github.com/gin-gonic/gin" ) // SendCode diff --git a/server/internal/common/code.go b/server/internal/common/code.go index 056ab8b..adaf05f 100644 --- a/server/internal/common/code.go +++ b/server/internal/common/code.go @@ -19,4 +19,8 @@ const ( SUCCESS = 200 ERROR = 500 INVALID_PARAMS = 400 + + // OpenIM callback code. + OPENIM_SERVER_ALLOW_ACTION = 0 + OPENIM_SERVER_DENY_ACTION = 1 ) diff --git a/server/internal/common/msg.go b/server/internal/common/msg.go index d1f0d19..663b756 100644 --- a/server/internal/common/msg.go +++ b/server/internal/common/msg.go @@ -19,6 +19,10 @@ var msg = map[int]string{ SUCCESS: "success", ERROR: "error", INVALID_PARAMS: "request params error", + + // OpenIM callback code + OPENIM_SERVER_ALLOW_ACTION: "OpenIM allow action", + OPENIM_SERVER_DENY_ACTION: "OpenIM deny action", } // GetMsg get the message by code. diff --git a/server/internal/common/response/callback.go b/server/internal/common/response/callback.go new file mode 100644 index 0000000..c200454 --- /dev/null +++ b/server/internal/common/response/callback.go @@ -0,0 +1,174 @@ +// Copyright © 2023 OpenIM open source community. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package response + +import ( + "net/http" + + "github.com/gin-gonic/gin" + + "github.com/OpenIMSDK/OpenKF/server/internal/common" +) + +// CommonCallbackResp Common callback response. +type CommonCallbackResp struct { + ActionCode int `json:"actionCode"` + ErrCode int32 `json:"errCode"` + ErrMsg string `json:"errMsg"` + ErrDlt string `json:"errDlt"` +} + +// NewCommonCallbackResp Create a new CommonCallbackResp. +func NewCommonCallbackResp(actionCode int, errCode int32, errMsg string, errDlt string, c *gin.Context) { + c.JSON(http.StatusOK, &CommonCallbackResp{ + ActionCode: actionCode, + ErrCode: errCode, + ErrMsg: errMsg, + ErrDlt: errDlt, + }) +} + +// CallbackBeforeSendSingleMsgResp Response body for BeforeSendSingleMsgCommand. +type CallbackBeforeSendSingleMsgResp struct { + CommonCallbackResp +} + +// CallbackBeforeSendSingleMsgRespSuccess CallbackBeforeSendSingleMsgResp success response. +func CallbackBeforeSendSingleMsgRespSuccess(c *gin.Context) { + NewCommonCallbackResp( + common.OPENIM_SERVER_ALLOW_ACTION, + common.OPENIM_SERVER_ALLOW_ACTION, + common.GetMsg(common.OPENIM_SERVER_ALLOW_ACTION), + "", // todo + c, + ) +} + +// CallbackBeforeSendSingleMsgRespFail CallbackBeforeSendSingleMsgResp fail response. +func CallbackBeforeSendSingleMsgRespFail(c *gin.Context) { + NewCommonCallbackResp( + common.OPENIM_SERVER_DENY_ACTION, + common.OPENIM_SERVER_ALLOW_ACTION, + common.GetMsg(common.OPENIM_SERVER_ALLOW_ACTION), + "", // todo + c, + ) +} + +// CallbackAfterSendSingleMsgResp Response body for AfterSendSingleMsgCommand. +type CallbackAfterSendSingleMsgResp struct { + CommonCallbackResp +} + +// CallbackAfterSendSingleMsgRespSuccess CallbackAfterSendSingleMsgResp success response. +func CallbackAfterSendSingleMsgRespSuccess(c *gin.Context) { + NewCommonCallbackResp( + common.OPENIM_SERVER_ALLOW_ACTION, + common.OPENIM_SERVER_ALLOW_ACTION, + common.GetMsg(common.OPENIM_SERVER_ALLOW_ACTION), + "", // todo + c, + ) +} + +// CallbackAfterSendSingleMsgRespFail CallbackAfterSendSingleMsgResp fail response. +func CallbackAfterSendSingleMsgRespFail(c *gin.Context) { + NewCommonCallbackResp( + common.OPENIM_SERVER_DENY_ACTION, + common.OPENIM_SERVER_ALLOW_ACTION, + common.GetMsg(common.OPENIM_SERVER_ALLOW_ACTION), + "", // todo + c, + ) +} + +// CallbackMsgModifyCommandResp Response body for MsgModifyCommand. +type CallbackMsgModifyCommandResp struct { + // todo: need to modify + CommonCallbackResp + Content *string `json:"content"` + RecvID *string `json:"recvID"` + GroupID *string `json:"groupID"` + ClientMsgID *string `json:"clientMsgID"` + ServerMsgID *string `json:"serverMsgID"` + SenderPlatformID *int32 `json:"senderPlatformID"` + SenderNickname *string `json:"senderNickname"` + SenderFaceURL *string `json:"senderFaceURL"` + SessionType *int32 `json:"sessionType"` + MsgFrom *int32 `json:"msgFrom"` + ContentType *int32 `json:"contentType"` + Status *int32 `json:"status"` + Options *map[string]bool `json:"options"` + OfflinePushInfo interface{} `json:"offlinePushInfo"` + // OfflinePushInfo *sdkws.OfflinePushInfo `json:"offlinePushInfo"` + AtUserIDList *[]string `json:"atUserIDList"` + MsgDataList *[]byte `json:"msgDataList"` + AttachedInfo *string `json:"attachedInfo"` + Ex *string `json:"ex"` +} + +// CallbackUserOnlineResp Response body for UserOnlineCommand. +type CallbackUserOnlineResp struct { + CommonCallbackResp +} + +// CallbackUserOnlineRespSuccess CallbackUserOnlineResp success response. +func CallbackUserOnlineRespSuccess(c *gin.Context) { + NewCommonCallbackResp( + common.OPENIM_SERVER_ALLOW_ACTION, + common.OPENIM_SERVER_ALLOW_ACTION, + common.GetMsg(common.OPENIM_SERVER_ALLOW_ACTION), + "", // todo + c, + ) +} + +// CallbackUserOnlineRespFail CallbackUserOnlineResp fail response. +func CallbackUserOnlineRespFail(c *gin.Context) { + NewCommonCallbackResp( + common.OPENIM_SERVER_DENY_ACTION, + common.OPENIM_SERVER_ALLOW_ACTION, + common.GetMsg(common.OPENIM_SERVER_ALLOW_ACTION), + "", // todo + c, + ) +} + +// CallbackUserOfflineResp Response body for UserOfflineCommand. +type CallbackUserOfflineResp struct { + CommonCallbackResp +} + +// CallbackUserOfflineRespSuccess CallbackUserOfflineResp success response. +func CallbackUserOfflineRespSuccess(c *gin.Context) { + NewCommonCallbackResp( + common.OPENIM_SERVER_ALLOW_ACTION, + common.OPENIM_SERVER_ALLOW_ACTION, + common.GetMsg(common.OPENIM_SERVER_ALLOW_ACTION), + "", // todo + c, + ) +} + +// CallbackUserOfflineRespFail CallbackUserOfflineResp fail response. +func CallbackUserOfflineRespFail(c *gin.Context) { + NewCommonCallbackResp( + common.OPENIM_SERVER_DENY_ACTION, + common.OPENIM_SERVER_ALLOW_ACTION, + common.GetMsg(common.OPENIM_SERVER_ALLOW_ACTION), + "", // todo + c, + ) +} diff --git a/server/internal/common/response/response.go b/server/internal/common/response/response.go index 177429e..b7a7de0 100644 --- a/server/internal/common/response/response.go +++ b/server/internal/common/response/response.go @@ -17,18 +17,19 @@ package response import ( "net/http" - "github.com/OpenIMSDK/OpenKF/server/internal/common" "github.com/gin-gonic/gin" + + "github.com/OpenIMSDK/OpenKF/server/internal/common" ) -// Response is a common struct for response +// Response is a common struct for response. type Response struct { Code int `json:"code"` Msg string `json:"msg"` Data interface{} `json:"data"` } -// NewResponse returns a new Response +// NewResponse returns a new Response. func NewResponse(code int, msg string, data interface{}, c *gin.Context) { c.JSON(http.StatusOK, &Response{ Code: code, @@ -37,42 +38,42 @@ func NewResponse(code int, msg string, data interface{}, c *gin.Context) { }) } -// Success returns a success response +// Success returns a success response. func Success(c *gin.Context) { NewResponse(common.SUCCESS, common.GetMsg(common.SUCCESS), nil, c) } -// SuccessWithData returns a success response with data +// SuccessWithData returns a success response with data. func SuccessWithData(data interface{}, c *gin.Context) { NewResponse(common.SUCCESS, common.GetMsg(common.SUCCESS), data, c) } -// SuccessWithCode returns a success response with code +// SuccessWithCode returns a success response with code. func SuccessWithCode(code int, c *gin.Context) { NewResponse(code, common.GetMsg(code), nil, c) } -// SuccessWithAll returns a success response with code and data +// SuccessWithAll returns a success response with code and data. func SuccessWithAll(code int, data interface{}, c *gin.Context) { NewResponse(code, common.GetMsg(code), data, c) } -// Fail returns a fail response +// Fail returns a fail response. func Fail(c *gin.Context) { NewResponse(common.ERROR, common.GetMsg(common.ERROR), nil, c) } -// FailWithData returns a fail response with data +// FailWithData returns a fail response with data. func FailWithData(data interface{}, c *gin.Context) { NewResponse(common.ERROR, common.GetMsg(common.ERROR), data, c) } -// FailWithCode returns a fail response with code +// FailWithCode returns a fail response with code. func FailWithCode(code int, c *gin.Context) { NewResponse(code, common.GetMsg(code), nil, c) } -// FailWithAll returns a fail response with code and data +// FailWithAll returns a fail response with code and data. func FailWithAll(code int, data interface{}, c *gin.Context) { NewResponse(code, common.GetMsg(code), data, c) } diff --git a/server/internal/config/config.go b/server/internal/config/config.go index f4c647d..6b141b9 100644 --- a/server/internal/config/config.go +++ b/server/internal/config/config.go @@ -14,10 +14,10 @@ package config -// Config global config instance +// Config global config instance. var Config *config -// ConfigInit init config +// ConfigInit init config. func ConfigInit(configPath string) { // init viper initViper(configPath) @@ -83,27 +83,27 @@ type config struct { Email Email } -// App config +// App config. type App struct { Version string `mapstructure:"version"` Debug bool `mapstructure:"debug"` LogFile string `mapstructure:"log_file"` } -// JWT config +// JWT config. type JWT struct { Secret string `mapstructure:"secret"` Issuer string `mapstructure:"issuer"` ExpireDays int `mapstructure:"expire_days"` } -// Server config +// Server config. type Server struct { Ip string `mapstructure:"ip"` Port int `mapstructure:"port"` } -// Mysql config +// Mysql config. type Mysql struct { Ip string `mapstructure:"ip"` Port int `mapstructure:"port"` @@ -115,7 +115,7 @@ type Mysql struct { MaxIdleConns int `mapstructure:"max_idle_conns"` } -// Redis config +// Redis config. type Redis struct { Ip string `mapstructure:"ip"` Port int `mapstructure:"port"` @@ -123,7 +123,7 @@ type Redis struct { Database int `mapstructure:"database"` } -// Minio config +// Minio config. type Minio struct { Ip string `mapstructure:"ip"` Port int `mapstructure:"port"` @@ -134,7 +134,7 @@ type Minio struct { Location string `mapstructure:"location"` } -// Email config +// Email config. type Email struct { Host string `mapstructure:"host"` Port int `mapstructure:"port"` diff --git a/server/internal/conn/client/mail.go b/server/internal/conn/client/mail.go index f235fe0..04056b0 100644 --- a/server/internal/conn/client/mail.go +++ b/server/internal/conn/client/mail.go @@ -18,14 +18,15 @@ import ( "fmt" "net/smtp" - "github.com/OpenIMSDK/OpenKF/server/internal/config" "github.com/jordan-wright/email" + + "github.com/OpenIMSDK/OpenKF/server/internal/config" ) // todo: use email connection pool to reduce the cost of creating a connection // link: https://github.com/jordan-wright/email#a-pool-of-reusable-connections -// SendEmail send email +// SendEmail send email. func SendEmail(to string, subject string, body string) error { email := email.NewEmail() @@ -46,7 +47,7 @@ func SendEmail(to string, subject string, body string) error { return nil } -// SendHtmlEmail send html email +// SendHtmlEmail send html email. func SendHtmlEmail(to string, subject string, html string) error { email := email.NewEmail() diff --git a/server/internal/conn/client/minio.go b/server/internal/conn/client/minio.go index fdebc17..ead6e76 100644 --- a/server/internal/conn/client/minio.go +++ b/server/internal/conn/client/minio.go @@ -19,16 +19,19 @@ import ( "fmt" "io" - "github.com/OpenIMSDK/OpenKF/server/internal/config" - "github.com/OpenIMSDK/OpenKF/server/pkg/log" "github.com/minio/minio-go/v7" "github.com/minio/minio-go/v7/pkg/credentials" + + "github.com/OpenIMSDK/OpenKF/server/internal/config" + "github.com/OpenIMSDK/OpenKF/server/pkg/log" ) -var _minioClient *minio.Client -var _bucket string +var ( + _minioClient *minio.Client + _bucket string +) -// InitMinio init minio client +// InitMinio init minio client. func InitMinio() { endpoint := fmt.Sprintf("%s:%d", config.Config.Minio.Ip, config.Config.Minio.Port) accessKeyID := config.Config.Minio.AccessKeyId @@ -66,14 +69,14 @@ func InitMinio() { _minioClient = minioClient } -// PutObject put object to minio +// PutObject put object to minio. func PutObject(objectName string, r io.Reader, objectSize int64) error { _, err := _minioClient.PutObject(context.Background(), _bucket, objectName, r, objectSize, minio.PutObjectOptions{ContentType: "application/octet-stream"}) return err } -// GetObject get object from minio +// GetObject get object from minio. func GetObject(objectName string) (io.Reader, error) { object, err := _minioClient.GetObject(context.Background(), _bucket, objectName, minio.GetObjectOptions{}) diff --git a/server/internal/conn/db/mysql.go b/server/internal/conn/db/mysql.go index 293ee9d..80eb4af 100644 --- a/server/internal/conn/db/mysql.go +++ b/server/internal/conn/db/mysql.go @@ -18,18 +18,19 @@ import ( "fmt" "time" - "github.com/OpenIMSDK/OpenKF/server/internal/config" - "github.com/OpenIMSDK/OpenKF/server/pkg/log" "gorm.io/driver/mysql" "gorm.io/gorm" "gorm.io/gorm/logger" + + "github.com/OpenIMSDK/OpenKF/server/internal/config" + "github.com/OpenIMSDK/OpenKF/server/pkg/log" ) var d *gorm.DB type writer struct{} -// Write implement log writer interface +// Write implement log writer interface. func (w writer) Printf(format string, args ...interface{}) { fmt.Printf(format, args...) } diff --git a/server/internal/conn/db/redis.go b/server/internal/conn/db/redis.go index 24c845a..3e31b0d 100644 --- a/server/internal/conn/db/redis.go +++ b/server/internal/conn/db/redis.go @@ -18,14 +18,15 @@ import ( "context" "fmt" + "github.com/go-redis/redis/v8" + "github.com/OpenIMSDK/OpenKF/server/internal/config" "github.com/OpenIMSDK/OpenKF/server/pkg/log" - "github.com/go-redis/redis/v8" ) var r *redis.Client -// InitRedisDB init redis client +// InitRedisDB init redis client. func InitRedisDB() { r = redis.NewClient(&redis.Options{ Addr: fmt.Sprintf("%s:%d", config.Config.Redis.Ip, config.Config.Redis.Port), @@ -40,12 +41,12 @@ func InitRedisDB() { } } -// GetRedis get redis client instance +// GetRedis get redis client instance. func GetRedis() *redis.Client { return r } -// CloseRedis close redis client instance +// CloseRedis close redis client instance. func CloseRedis() { if r != nil { err := r.Close() diff --git a/server/internal/middleware/cros.go b/server/internal/middleware/cros.go index 7be9008..fa31fc8 100644 --- a/server/internal/middleware/cros.go +++ b/server/internal/middleware/cros.go @@ -20,7 +20,7 @@ import ( "github.com/gin-gonic/gin" ) -// EnableCROS enable cros +// EnableCROS enable cros. func EnableCROS() gin.HandlerFunc { return func(c *gin.Context) { // c.Writer.Header().Set("Access-Control-Allow-Origin", "*") diff --git a/server/internal/middleware/frequency_control.go b/server/internal/middleware/frequency_control.go index 6cc124f..7369e01 100644 --- a/server/internal/middleware/frequency_control.go +++ b/server/internal/middleware/frequency_control.go @@ -7,16 +7,16 @@ import ( "github.com/gin-gonic/gin" ) -// define rate limit struct +// define rate limit struct. type frequencyControlByTokenBucket struct { - refreshRate float64 // 令牌的刷新速率 - capacity int64 // bucket's capacity - tokens float64 // tokens' count - lastToken time.Time //latest time token stored + refreshRate float64 // token refresh rate + capacity int64 // bucket capacity + tokens float64 // token count + lastToken time.Time // latest time token stored mtx sync.Mutex // mutex } -// allow frequency +// allow frequency. func (tb *frequencyControlByTokenBucket) Allow() bool { tb.mtx.Lock() defer tb.mtx.Unlock() @@ -30,13 +30,14 @@ func (tb *frequencyControlByTokenBucket) Allow() bool { if tb.tokens >= 1 { tb.tokens-- tb.lastToken = now + return true } - + return false } -// LimitHandler registried a middle ware to use +// LimitHandler registried a middle ware to use. func LimitHandler(maxConn int, refreshRate float64) gin.HandlerFunc { tb := &frequencyControlByTokenBucket{ capacity: int64(maxConn), @@ -44,11 +45,12 @@ func LimitHandler(maxConn int, refreshRate float64) gin.HandlerFunc { tokens: 0, lastToken: time.Now(), } + return func(c *gin.Context) { if !tb.Allow() { c.String(503, "Too many request") c.Abort() - + return } c.Next() diff --git a/server/internal/middleware/hooks/global_hook.go b/server/internal/middleware/hooks/global_hook.go index 13f18c9..0780984 100644 --- a/server/internal/middleware/hooks/global_hook.go +++ b/server/internal/middleware/hooks/global_hook.go @@ -17,9 +17,9 @@ package hooks import ( "fmt" - urltrie "github.com/OpenIMSDK/OpenKF/server/internal/middleware/hooks/url_trie" - "github.com/OpenIMSDK/OpenKF/server/pkg/log" "github.com/gin-gonic/gin" + + urltrie "github.com/OpenIMSDK/OpenKF/server/internal/middleware/hooks/url_trie" ) func init() { @@ -27,23 +27,22 @@ func init() { fmt.Println("RegisterHook", "Register Hook[GlobalHook] success...") } -// GlobalHook implement urltrie.Hook +// GlobalHook implement urltrie.Hook. type GlobalHook struct { urltrie.Hook } -// Pattern return pattern +// Pattern return pattern. func (h GlobalHook) Pattern() string { return "/*" } -// BeforeRun do something before controller run +// BeforeRun do something before controller run. func (h GlobalHook) BeforeRun(c *gin.Context) { - log.Debugf("GlobalHook", "path: %v", c.Request.URL.Path) c.Next() } -// AfterRun do something after controller run +// AfterRun do something after controller run. func (h GlobalHook) AfterRun(c *gin.Context) { c.Next() } diff --git a/server/internal/middleware/hooks/init.go b/server/internal/middleware/hooks/init.go index 47caa85..fa7765f 100644 --- a/server/internal/middleware/hooks/init.go +++ b/server/internal/middleware/hooks/init.go @@ -14,6 +14,6 @@ package hooks -// InitHooks manual import hooks packages and do init +// InitHooks manual import hooks packages and do init. func InitHooks() { } diff --git a/server/internal/middleware/hooks/mail_hook.go b/server/internal/middleware/hooks/mail_hook.go index d1eaf0e..394e8ad 100644 --- a/server/internal/middleware/hooks/mail_hook.go +++ b/server/internal/middleware/hooks/mail_hook.go @@ -17,9 +17,10 @@ package hooks import ( "fmt" + "github.com/gin-gonic/gin" + urltrie "github.com/OpenIMSDK/OpenKF/server/internal/middleware/hooks/url_trie" "github.com/OpenIMSDK/OpenKF/server/pkg/log" - "github.com/gin-gonic/gin" ) func init() { @@ -27,23 +28,23 @@ func init() { fmt.Println("RegisterHook", "Register Hook[MailHook] success...") } -// MailHook implement urltrie.Hook +// MailHook implement urltrie.Hook. type MailHook struct { urltrie.Hook } -// Pattern return pattern +// Pattern return pattern. func (h MailHook) Pattern() string { return "/api/v1/register/email/code" } -// BeforeRun do something before controller run +// BeforeRun do something before controller run. func (h MailHook) BeforeRun(c *gin.Context) { log.Debugf("GlobalHook", "path: %v", c.Request.URL.Path) c.Next() } -// AfterRun do something after controller run +// AfterRun do something after controller run. func (h MailHook) AfterRun(c *gin.Context) { c.Next() } diff --git a/server/internal/middleware/hooks/url_trie/hook.go b/server/internal/middleware/hooks/url_trie/hook.go index 1acd765..2bcd7a9 100644 --- a/server/internal/middleware/hooks/url_trie/hook.go +++ b/server/internal/middleware/hooks/url_trie/hook.go @@ -17,23 +17,24 @@ package urltrie import ( "net/url" - "github.com/OpenIMSDK/OpenKF/server/pkg/log" "github.com/gin-gonic/gin" + + "github.com/OpenIMSDK/OpenKF/server/pkg/log" ) -// Mapping for store url pattern and hook +// Mapping for store url pattern and hook. var hookTrie *Trie func init() { hookTrie = NewTrie() } -// RegisterHook register url & hook to trie +// RegisterHook register url & hook to trie. func RegisterHook(hook Hook) { hookTrie.Insert(hook.Pattern(), hook) } -// RunHook enable hook for interceptor +// RunHook enable hook for interceptor. func RunHook() gin.HandlerFunc { return func(c *gin.Context) { raw := c.Request.URL.Path diff --git a/server/internal/middleware/hooks/url_trie/trie.go b/server/internal/middleware/hooks/url_trie/trie.go index cbae866..6fbe24f 100644 --- a/server/internal/middleware/hooks/url_trie/trie.go +++ b/server/internal/middleware/hooks/url_trie/trie.go @@ -20,7 +20,7 @@ import ( "github.com/gin-gonic/gin" ) -// Hook for interceptor +// Hook for interceptor. type Hook interface { // Register with url pattern // Support * wildcard, you can use it like this: @@ -46,12 +46,12 @@ type node struct { isEnd bool } -// Trie is a tree for url +// Trie is a tree for url. type Trie struct { root *node } -// NewTrie returns a new Trie +// NewTrie returns a new Trie. func NewTrie() *Trie { return &Trie{ root: &node{ @@ -60,7 +60,7 @@ func NewTrie() *Trie { } } -// Insert insert url with hooks +// Insert insert url with hooks. func (t *Trie) Insert(url string, hooks ...Hook) { current := t.root @@ -94,7 +94,7 @@ func (t *Trie) Insert(url string, hooks ...Hook) { current.hooks = append(current.hooks, hooks...) } -// Match match url with hooks +// Match match url with hooks. func (t *Trie) Match(url string) ([]Hook, bool) { current := t.root diff --git a/server/internal/middleware/jwt.go b/server/internal/middleware/jwt.go index bf8d44f..fd4e78a 100644 --- a/server/internal/middleware/jwt.go +++ b/server/internal/middleware/jwt.go @@ -18,11 +18,12 @@ import ( "net/http" "strings" - "github.com/OpenIMSDK/OpenKF/server/pkg/utils" "github.com/gin-gonic/gin" + + "github.com/OpenIMSDK/OpenKF/server/pkg/utils" ) -// EnableAuth enable auth middleware +// EnableAuth enable auth middleware. func EnableAuth() gin.HandlerFunc { return func(c *gin.Context) { token := c.GetHeader("Authorization") diff --git a/server/internal/models/base.go b/server/internal/models/base.go index 62b6e8a..4ef1525 100644 --- a/server/internal/models/base.go +++ b/server/internal/models/base.go @@ -16,7 +16,7 @@ package models import "time" -// Model base model +// Model base model. type Model struct { ID uint `gorm:"primary_key" json:"id"` CreatedAt time.Time `json:"created_at"` diff --git a/server/internal/models/user.go b/server/internal/models/user.go index a51f12f..be33217 100644 --- a/server/internal/models/user.go +++ b/server/internal/models/user.go @@ -14,7 +14,7 @@ package models -// User user model +// User user model. type User struct { Model Username string `json:"username" gorm:"type:varchar(20);not null;unique"` diff --git a/server/internal/param/callback.go b/server/internal/param/callback.go new file mode 100644 index 0000000..6b26e21 --- /dev/null +++ b/server/internal/param/callback.go @@ -0,0 +1,83 @@ +// Copyright © 2023 OpenIM open source community. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package param + +// OpenIMCallbackCommand OpenIM callback request command. +type OpenIMCallbackCommand struct { + Command string `form:"command" json:"command"` +} + +// CommonCallbackReq Common callback request command. +type CommonCallbackReq struct { + SendID string `json:"sendID"` + CallbackCommand string `json:"callbackCommand"` + ServerMsgID string `json:"serverMsgID"` + ClientMsgID string `json:"clientMsgID"` + OperationID string `json:"operationID"` + SenderPlatformID int32 `json:"senderPlatformID"` + SenderNickname string `json:"senderNickname"` + SessionType int32 `json:"sessionType"` + MsgFrom int32 `json:"msgFrom"` + ContentType int32 `json:"contentType"` + Status int32 `json:"status"` + CreateTime int64 `json:"createTime"` + Content string `json:"content"` + Seq uint32 `json:"seq"` + AtUserIDList []string `json:"atUserList"` + SenderFaceURL string `json:"faceURL"` + Ex string `json:"ex"` +} + +// CallbackBeforeSendSingleMsgReq Request body for BeforeSendSingleMsgCommand. +type CallbackBeforeSendSingleMsgReq struct { + CommonCallbackReq + RecvID string `json:"recvID"` +} + +// CallbackAfterSendSingleMsgReq Request body for AfterSendSingleMsgCommand. +type CallbackAfterSendSingleMsgReq struct { + CommonCallbackReq + RecvID string `json:"recvID"` +} + +// CallbackMsgModifyCommandReq Request body for MsgModifyCommand. +type CallbackMsgModifyCommandReq struct { + CommonCallbackReq +} + +// UserStatusBaseCallback Common user callback request command. +type UserStatusBaseCallback struct { + CallbackCommand string `json:"callbackCommand"` + OperationID string `json:"operationID"` + PlatformID int `json:"platformID"` + Platform string `json:"platform"` + UserID string `json:"userID"` +} + +// CallbackUserOnlineReq Request body for UserOnlineCommand. +type CallbackUserOnlineReq struct { + UserStatusBaseCallback + // Token string `json:"token"` + Seq int64 `json:"seq"` + IsAppBackground bool `json:"isAppBackground"` + ConnID string `json:"connID"` +} + +// CallbackUserOfflineReq Request body for UserOfflineCommand. +type CallbackUserOfflineReq struct { + UserStatusBaseCallback + Seq int64 `json:"seq"` + ConnID string `json:"connID"` +} diff --git a/server/internal/router/router.go b/server/internal/router/router.go index fe54b4f..16f5468 100644 --- a/server/internal/router/router.go +++ b/server/internal/router/router.go @@ -47,6 +47,19 @@ func InitRouter() *gin.Engine { register.POST("/email/code", api.SendCode) // register.POST("/github", api.GithubRegister) } + + // OpenIM callback api + command := apiv1.Group("/openim/callback") + { + command.POST("/", api.OpenIMCallback) + command.POST("/callbackBeforeSendSingleMsgCommand", api.BeforeSendSingleMsg) + command.POST("/callbackAfterSendSingleMsgCommand", api.AfterSendSingleMsg) + command.POST("/callbackMsgModifyCommand", api.MsgModify) + command.POST("/callbackUserOnlineCommand", api.UserOnline) + command.POST("/callbackUserOfflineCommand", api.UserOffline) + command.POST("/callbackOfflinePushCommand", api.OfflinePush) + command.POST("/callbackOnlinePushCommand", api.OnlinePush) + } } return r diff --git a/server/internal/service/init.go b/server/internal/service/init.go index eaa42c9..c01d367 100644 --- a/server/internal/service/init.go +++ b/server/internal/service/init.go @@ -17,13 +17,14 @@ package service import ( "context" - "github.com/OpenIMSDK/OpenKF/server/internal/conn/db" "github.com/gin-gonic/gin" "github.com/go-redis/redis/v8" "gorm.io/gorm" + + "github.com/OpenIMSDK/OpenKF/server/internal/conn/db" ) -// Service service +// Service service. type Service struct { // Context Ctx context.Context @@ -33,7 +34,7 @@ type Service struct { Cache *redis.Client } -// NewService return new service with context +// NewService return new service with context. func NewService() *Service { return &Service{ Ctx: context.Background(), @@ -42,7 +43,7 @@ func NewService() *Service { } } -// NewServiceWithGin return new service with gin context +// NewServiceWithGin return new service with gin context. func NewServiceWithGin(c *gin.Context) *Service { return &Service{ Ctx: c.Request.Context(), diff --git a/server/internal/service/mail.go b/server/internal/service/mail.go index 866dd37..4853cd0 100644 --- a/server/internal/service/mail.go +++ b/server/internal/service/mail.go @@ -22,7 +22,7 @@ import ( "github.com/OpenIMSDK/OpenKF/server/pkg/log" ) -// SendCode send code to email +// SendCode send code to email. func (svc *Service) SendCode(email string) (err error) { // check the code is exist cmd := svc.Cache.Get(svc.Ctx, "code:"+email) @@ -42,7 +42,7 @@ func (svc *Service) SendCode(email string) (err error) { return err } -// Test test +// Test test. func (svc *Service) Test() { log.Info("test...") } diff --git a/server/openim-config.yaml b/server/openim-config.yaml new file mode 100644 index 0000000..4bb737d --- /dev/null +++ b/server/openim-config.yaml @@ -0,0 +1,77 @@ +# Copyright © 2023 OpenIM open source community. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# diff config in OpenIM-Server +secret: openkf +callback: + url: http://127.0.0.1:10010/api/v1/openim/callback + beforeSendSingleMsg: + enable: true + timeout: 5 + failedContinue: true + afterSendSingleMsg: + enable: true + timeout: 5 + beforeSendGroupMsg: + enable: false + timeout: 5 + failedContinue: true + afterSendGroupMsg: + enable: false + timeout: 5 + msgModify: + enable: true + timeout: 5 + failedContinue: true + userOnline: + enable: true + timeout: 5 + userOffline: + enable: true + timeout: 5 + userKickOff: + enable: false + timeout: 5 + offlinePush: + enable: true + timeout: 5 + failedContinue: true + onlinePush: + enable: true + timeout: 5 + failedContinue: true + superGroupOnlinePush: + enable: false + timeout: 5 + failedContinue: true + beforeAddFriend: + enable: false + timeout: 5 + failedContinue: true + beforeCreateGroup: + enable: false + timeout: 5 + failedContinue: true + beforeMemberJoinGroup: + enable: false + timeout: 5 + failedContinue: true + beforeSetGroupMemberInfo: + enable: false + timeout: 5 + failedContinue: true + setMessageReactionExtensions: + enable: false + timeout: 5 + failedContinue: true \ No newline at end of file diff --git a/server/pkg/log/fileline_hook.go b/server/pkg/log/fileline_hook.go index 2d71940..8bb2329 100644 --- a/server/pkg/log/fileline_hook.go +++ b/server/pkg/log/fileline_hook.go @@ -18,8 +18,9 @@ import ( "runtime" "strings" - "github.com/OpenIMSDK/OpenKF/server/pkg/utils" "github.com/sirupsen/logrus" + + "github.com/OpenIMSDK/OpenKF/server/pkg/utils" ) type filelineHook struct{} diff --git a/server/pkg/log/logrus.go b/server/pkg/log/logrus.go index 0114e7c..29078d1 100644 --- a/server/pkg/log/logrus.go +++ b/server/pkg/log/logrus.go @@ -20,16 +20,17 @@ import ( "os" "time" - "github.com/OpenIMSDK/OpenKF/server/internal/config" nested "github.com/antonfisher/nested-logrus-formatter" rotatelogs "github.com/lestrrat-go/file-rotatelogs" "github.com/rifflock/lfshook" "github.com/sirupsen/logrus" + + "github.com/OpenIMSDK/OpenKF/server/internal/config" ) var _logger *logrus.Logger -// InitLogger init logger +// InitLogger init logger. func InitLogger() { _logger = loggerInit() } @@ -70,7 +71,7 @@ func loggerInit() *logrus.Logger { return logger } -// NewLfsHook add fileline hook +// NewLfsHook add fileline hook. func NewLfsHook(rotationTime time.Duration, maxRemainNum uint) logrus.Hook { lfsHook := lfshook.NewHook(lfshook.WriterMap{ logrus.DebugLevel: initRotateLogs(rotationTime, maxRemainNum), @@ -99,61 +100,61 @@ func initRotateLogs(rotationTime time.Duration, maxRemainNum uint) *rotatelogs.R } } -// GetLogger get logger instance +// GetLogger get logger instance. func GetLogger() *logrus.Logger { return _logger } -// Info log info +// Info log info. func Info(Operation string, args ...interface{}) { _logger.WithFields(logrus.Fields{ "Operation": Operation, }).Infoln(args...) } -// Error log error +// Error log error. func Error(Operation string, args ...interface{}) { _logger.WithFields(logrus.Fields{ "Operation": Operation, }).Errorln(args...) } -// Debug log debug +// Debug log debug. func Debug(Operation string, args ...interface{}) { _logger.WithFields(logrus.Fields{ "Operation": Operation, }).Debugln(args...) } -// Panic log panic +// Panic log panic. func Panic(Operation string, args ...interface{}) { _logger.WithFields(logrus.Fields{ "Operation": Operation, }).Panicln(args...) } -// Infof log info with format +// Infof log info with format. func Infof(Operation string, format string, args ...interface{}) { _logger.WithFields(logrus.Fields{ "Operation": Operation, }).Infof(format, args...) } -// Errorf log error with format +// Errorf log error with format. func Errorf(Operation string, format string, args ...interface{}) { _logger.WithFields(logrus.Fields{ "Operation": Operation, }).Errorf(format, args...) } -// Debugf log debug with format +// Debugf log debug with format. func Debugf(Operation string, format string, args ...interface{}) { _logger.WithFields(logrus.Fields{ "Operation": Operation, }).Debugf(format, args...) } -// Panicf log panic with format +// Panicf log panic with format. func Panicf(Operation string, format string, args ...interface{}) { _logger.WithFields(logrus.Fields{ "Operation": Operation, diff --git a/server/pkg/server/server.go b/server/pkg/server/server.go index 6ecf21e..cca7aaf 100644 --- a/server/pkg/server/server.go +++ b/server/pkg/server/server.go @@ -21,12 +21,12 @@ import ( "github.com/gin-gonic/gin" ) -// Server server interface +// Server server interface. type Server interface { ListenAndServe() error } -// InitServer init server +// InitServer init server. func InitServer(address string, r *gin.Engine) Server { server := endless.NewServer(address, r)