Browse Source

feat: Add callback api. (#45)

tags/v0.1.0
Asklv GitHub 3 years ago
parent
commit
edaf892de9
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
29 changed files with 541 additions and 95 deletions
  1. +76
    -0
      server/internal/api/callback.go
  2. +2
    -1
      server/internal/api/mail.go
  3. +4
    -0
      server/internal/common/code.go
  4. +4
    -0
      server/internal/common/msg.go
  5. +174
    -0
      server/internal/common/response/callback.go
  6. +12
    -11
      server/internal/common/response/response.go
  7. +9
    -9
      server/internal/config/config.go
  8. +4
    -3
      server/internal/conn/client/mail.go
  9. +10
    -7
      server/internal/conn/client/minio.go
  10. +4
    -3
      server/internal/conn/db/mysql.go
  11. +5
    -4
      server/internal/conn/db/redis.go
  12. +1
    -1
      server/internal/middleware/cros.go
  13. +11
    -9
      server/internal/middleware/frequency_control.go
  14. +6
    -7
      server/internal/middleware/hooks/global_hook.go
  15. +1
    -1
      server/internal/middleware/hooks/init.go
  16. +6
    -5
      server/internal/middleware/hooks/mail_hook.go
  17. +5
    -4
      server/internal/middleware/hooks/url_trie/hook.go
  18. +5
    -5
      server/internal/middleware/hooks/url_trie/trie.go
  19. +3
    -2
      server/internal/middleware/jwt.go
  20. +1
    -1
      server/internal/models/base.go
  21. +1
    -1
      server/internal/models/user.go
  22. +83
    -0
      server/internal/param/callback.go
  23. +13
    -0
      server/internal/router/router.go
  24. +5
    -4
      server/internal/service/init.go
  25. +2
    -2
      server/internal/service/mail.go
  26. +77
    -0
      server/openim-config.yaml
  27. +2
    -1
      server/pkg/log/fileline_hook.go
  28. +13
    -12
      server/pkg/log/logrus.go
  29. +2
    -2
      server/pkg/server/server.go

+ 76
- 0
server/internal/api/callback.go View File

@@ -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 := &param.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) {
}

+ 2
- 1
server/internal/api/mail.go View File

@@ -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


+ 4
- 0
server/internal/common/code.go View File

@@ -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
)

+ 4
- 0
server/internal/common/msg.go View File

@@ -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.


+ 174
- 0
server/internal/common/response/callback.go View File

@@ -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,
)
}

+ 12
- 11
server/internal/common/response/response.go View File

@@ -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)
}

+ 9
- 9
server/internal/config/config.go View File

@@ -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"`


+ 4
- 3
server/internal/conn/client/mail.go View File

@@ -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()



+ 10
- 7
server/internal/conn/client/minio.go View File

@@ -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{})



+ 4
- 3
server/internal/conn/db/mysql.go View File

@@ -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...)
}


+ 5
- 4
server/internal/conn/db/redis.go View File

@@ -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()


+ 1
- 1
server/internal/middleware/cros.go View File

@@ -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", "*")


+ 11
- 9
server/internal/middleware/frequency_control.go View File

@@ -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()


+ 6
- 7
server/internal/middleware/hooks/global_hook.go View File

@@ -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()
}

+ 1
- 1
server/internal/middleware/hooks/init.go View File

@@ -14,6 +14,6 @@

package hooks

// InitHooks manual import hooks packages and do init
// InitHooks manual import hooks packages and do init.
func InitHooks() {
}

+ 6
- 5
server/internal/middleware/hooks/mail_hook.go View File

@@ -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()
}

+ 5
- 4
server/internal/middleware/hooks/url_trie/hook.go View File

@@ -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


+ 5
- 5
server/internal/middleware/hooks/url_trie/trie.go View File

@@ -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



+ 3
- 2
server/internal/middleware/jwt.go View File

@@ -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")


+ 1
- 1
server/internal/models/base.go View File

@@ -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"`


+ 1
- 1
server/internal/models/user.go View File

@@ -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"`


+ 83
- 0
server/internal/param/callback.go View File

@@ -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"`
}

+ 13
- 0
server/internal/router/router.go View File

@@ -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


+ 5
- 4
server/internal/service/init.go View File

@@ -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(),


+ 2
- 2
server/internal/service/mail.go View File

@@ -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...")
}

+ 77
- 0
server/openim-config.yaml View File

@@ -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

+ 2
- 1
server/pkg/log/fileline_hook.go View File

@@ -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{}


+ 13
- 12
server/pkg/log/logrus.go View File

@@ -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,


+ 2
- 2
server/pkg/server/server.go View File

@@ -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)



Loading…
Cancel
Save