init repo

This commit is contained in:
VaalaCat
2024-08-28 00:02:28 +08:00
committed by vaalacat
commit 13148b95e3
97 changed files with 10214 additions and 0 deletions

62
common/const.go Normal file
View File

@@ -0,0 +1,62 @@
package common
import "time"
const (
AuthorizationKey = "authorization"
SetAuthorizationKey = "x-set-authorization"
MsgKey = "msg"
DataKey = "data"
UserIDKey = "x-toyboom-userid"
UserNameKey = "x-toyboom-username"
CommandKey = "x-toyboom-command"
EndpointKey = "endpoint"
IpAddrKey = "ipaddr"
HeaderKey = "header"
MethodKey = "method"
UAKey = "User-Agent"
ContentTypeKey = "Content-Type"
TraceIDKey = "TraceID"
TokenKey = "token"
ErrKey = "err"
UserInfoKey = "x-toyboom-userinfo"
HostKey = "Host"
LogtoWebHookSignKey = "Logto-Signature-Sha-256"
NormalUIDKey = "uid"
)
const (
ErrInvalidRequest = "invalid request"
ErrUserInfoNotValid = "user info not valid"
ErrInternalError = "internal error"
ErrParamNotValid = "param not valid"
ErrDB = "database error"
ErrNotFound = "data not found"
ErrCodeNotFound = "code not found"
ErrCodeAlreadyUsed = "code already used"
)
const (
ReqSuccess = "success"
)
const (
TimeLayout = time.RFC3339
)
const (
StatusPending = "pending"
StatusSuccess = "success"
StatusFailed = "failed"
StatusDone = "done"
)
const (
CliTypeServer = "server"
CliTypeClient = "client"
)
const (
DefaultServerID = "default"
DefaultAdminUserID = 1
)

21
common/context.go Normal file
View File

@@ -0,0 +1,21 @@
package common
import (
"context"
"github.com/nose7en/ToyBoomServer/defs"
)
func GetUser(c context.Context) defs.UserGettable {
val := c.Value(UserInfoKey)
if val == nil {
return nil
}
u, ok := val.(defs.UserGettable)
if !ok {
return nil
}
return u
}

38
common/helper.go Normal file
View File

@@ -0,0 +1,38 @@
package common
import (
"context"
"fmt"
"github.com/nose7en/ToyBoomServer/defs"
"github.com/gin-gonic/gin"
)
func GlobalClientID(username, clientType, clientID string) string {
return fmt.Sprintf("%s.%s.%s", username, clientType, clientID)
}
func Wrapper[T ReqType, U RespType](handler func(context.Context, *T) (*U, error)) func(c *gin.Context) {
return func(c *gin.Context) {
Logger(c).Infof("request url: %s", c.Request.URL)
req, err := GetProtoRequest[T](c)
if err != nil {
Logger(c).WithError(err).Errorf("Failed to get request, url: %s", c.Request.URL)
ErrResp(c, &defs.CommonResponse{
Status: &defs.Status{Code: defs.RespCode_INVALID, Message: defs.RespMessage_INVALID},
}, err.Error())
return
}
resp, err := handler(c, req)
if err != nil {
Logger(c).WithError(err).Errorf("Failed to handle request, url: %s", c.Request.URL)
ErrResp(c, resp, err.Error())
return
}
OKResp(c, resp)
Logger(c).Infof("handle request success, response url: %s", c.Request.URL)
}
}

34
common/logger.go Normal file
View File

@@ -0,0 +1,34 @@
package common
import (
"context"
"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
)
func init() {
logrus.AddHook(&ObserveHook{})
}
func Logger(c context.Context) *logrus.Entry {
var uid, endpoint, header, method, traceid interface{}
if c != nil {
ginCtx, ok := c.(*gin.Context)
if ok {
uid = ginCtx.GetString(UserIDKey)
endpoint = ginCtx.Request.URL.Path
header = ginCtx.Request.Header
method = ginCtx.Request.Method
traceid = ginCtx.GetString(TraceIDKey)
}
}
logrus.SetFormatter(&logrus.JSONFormatter{})
return logrus.WithContext(c).
WithField(UserIDKey, uid).
WithField(EndpointKey, endpoint).
WithField(HeaderKey, header).
WithField(MethodKey, method).
WithField(TraceIDKey, traceid)
}

65
common/logger_remote.go Normal file
View File

@@ -0,0 +1,65 @@
package common
import (
"encoding/json"
"fmt"
"github.com/sirupsen/logrus"
)
type ObserveHook struct{}
func (h *ObserveHook) Levels() []logrus.Level {
return []logrus.Level{
logrus.ErrorLevel,
logrus.PanicLevel,
logrus.InfoLevel,
}
}
func (h *ObserveHook) Fire(entry *logrus.Entry) error {
go func() {
data := []map[string]interface{}{{
"_msg": entry.Message,
"_level": entry.Level,
"_time": entry.Time,
"_app": "sharkapi",
"_userid": entry.Data[UserIDKey],
"_endpoint": entry.Data[EndpointKey],
"_header": entry.Data[HeaderKey],
"_x_trace_id": entry.Data[TraceIDKey],
}}
if e, ok := entry.Data[logrus.ErrorKey].(error); ok {
data[0]["_err"] = e.Error()
}
c, err := json.Marshal(data)
if err != nil {
return
}
err = log2openOb(c)
if err != nil {
fmt.Printf("log2openOb error: %v", err.Error())
}
}()
return nil
}
func log2openOb(l []byte) error {
return nil
// cli := req.C() //.DevMode()
// resp, err := cli.R().SetBasicAuth(config.GetSettings().LogUser,
// config.GetSettings().LogKey).
// SetBody(l).
// SetHeader("Content-Type", "application/json").
// Post(config.GetSettings().LogEndpoint)
// if err != nil {
// return err
// }
// if resp.Response == nil {
// return errors.New("resp err")
// }
// return nil
}

34
common/request.go Normal file
View File

@@ -0,0 +1,34 @@
package common
import (
"github.com/nose7en/ToyBoomServer/defs"
"github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding"
)
type ReqType interface {
gin.H |
defs.CommonPaginationRequest | defs.CommonQueryPaginationRequest |
defs.CommonQueryRequest | defs.CommonRequest
}
func GetProtoRequest[T ReqType](c *gin.Context) (r *T, err error) {
r = new(T)
if c.Request.ContentLength == 0 {
return r, nil
}
if c.ContentType() == "application/x-protobuf" {
err = c.Copy().ShouldBindWith(r, binding.ProtoBuf)
if err != nil {
return nil, err
}
} else {
err = c.Copy().ShouldBindJSON(r)
if err != nil {
return nil, err
}
}
return r, nil
}

43
common/response.go Normal file
View File

@@ -0,0 +1,43 @@
package common
import (
"net/http"
"github.com/nose7en/ToyBoomServer/defs"
"github.com/gin-gonic/gin"
)
type RespType interface {
gin.H |
defs.CommonResponse | defs.GetUserInfoResponse |
defs.GetUserAuthTokenResponse
}
func OKResp[T RespType](c *gin.Context, origin *T) {
c.Header(TraceIDKey, c.GetString(TraceIDKey))
if c.ContentType() == "application/x-protobuf" {
c.ProtoBuf(http.StatusOK, origin)
} else {
c.JSON(http.StatusOK, OK(ReqSuccess).WithBody(origin))
}
}
func ErrResp[T RespType](c *gin.Context, origin *T, err string) {
c.Header(TraceIDKey, c.GetString(TraceIDKey))
if c.ContentType() == "application/x-protobuf" {
c.ProtoBuf(http.StatusInternalServerError, origin)
} else {
c.JSON(http.StatusOK, Err(err).WithBody(origin))
}
}
func ErrUnAuthorized(c *gin.Context, err string) {
c.Header(TraceIDKey, c.GetString(TraceIDKey))
if c.ContentType() == "application/x-protobuf" {
c.ProtoBuf(http.StatusUnauthorized,
&defs.CommonResponse{Status: &defs.Status{Code: defs.RespCode_UNAUTHORIZED, Message: defs.RespMessage_UNAUTHORIZED}})
} else {
c.JSON(http.StatusOK, Err(err))
}
}

55
common/result.go Normal file
View File

@@ -0,0 +1,55 @@
package common
import (
"github.com/gin-gonic/gin"
)
type Result struct {
Code int `json:"code,omitempty"`
Msg string `json:"msg,omitempty"`
Data gin.H `json:"data,omitempty"`
Body interface{} `json:"body,omitempty"`
}
func (r *Result) WithMsg(message string) *Result {
r.Msg = message
return r
}
func (r *Result) WithData(data gin.H) *Result {
r.Data = data
return r
}
func (r *Result) WithKeyValue(key string, value interface{}) *Result {
if r.Data == nil {
r.Data = gin.H{}
}
r.Data[key] = value
return r
}
func (r *Result) WithBody(body interface{}) *Result {
r.Body = body
return r
}
func newResult(code int, msg string) *Result {
return &Result{
Code: code,
Msg: msg,
Data: nil,
}
}
func OK(msg string) *Result {
return newResult(200, msg)
}
func Err(msg string) *Result {
return newResult(500, msg)
}
func UnAuth(msg string) *Result {
return newResult(401, msg)
}