Skip to content

Commit

Permalink
Merge pull request #104 from LucienShui/feature/temp_expiration
Browse files Browse the repository at this point in the history
Add ExpireCount and ExpireMinute in temporary, optimize logging code
  • Loading branch information
LucienShui authored Aug 19, 2021
2 parents a96a091 + 9ba5389 commit a8baed5
Show file tree
Hide file tree
Showing 11 changed files with 110 additions and 138 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
# PasteMe Go Backend

![GitHub go.mod Go version](https://img.shields.io/github/go-mod/go-version/PasteUs/PasteMeGoBackend)
[![Go Test](https://github.com/PasteUs/PasteMeGoBackend/actions/workflows/test.yml/badge.svg)](https://github.com/PasteUs/PasteMeGoBackend/actions/workflows/test.yml)
[![GitHub release (latest SemVer)](https://img.shields.io/github/v/release/PasteUs/PasteMeGoBackend?color=white&label=Latest&sort=semver)](https://github.com/PasteUs/PasteMeGoBackend/releases)
[![Docker Image Version (latest semver)](https://img.shields.io/docker/v/pasteme/go-backend?label=Docker%20Hub&sort=semver)](https://hub.docker.com/repository/docker/pasteme/go-backend)
[![Docker Image Version (latest semver)](https://img.shields.io/docker/v/pasteme/go-backend?label=Docker%20Hub&sort=semver)](https://hub.docker.com/r/pasteme/go-backend)

Using `Gin` and `Gorm`.

Expand Down
2 changes: 1 addition & 1 deletion gotest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ clear() {

if [[ ${#} == 1 ]]; then
if [[ ${1} == "clear" ]]; then
find "${PWD}" -name "*.log" -exec rm -f {} \;
find "${PWD}" -name "*.log" -exec rm -f {} \; && find "${PWD}" -name "*.db" -exec rm -f {} \;
exit ${?}
fi
clear "${1}"
Expand Down
19 changes: 9 additions & 10 deletions handler/paste/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@ package paste
import "errors"

var (
ErrEmptyExpireType = errors.New("empty expire_type or expiration")
ErrZeroExpiration = errors.New("zero expiration")
ErrExpirationGreaterThanMonth = errors.New("expiration greater than a month")
ErrExpirationGreaterThanMaxCount = errors.New("expiration greater than max count")
ErrInvalidExpireType = errors.New("invalid expire_type")
ErrEmptyContent = errors.New("empty content")
ErrEmptyLang = errors.New("empty lang")
ErrQueryDBFailed = errors.New("query from db failed")
ErrSaveFailed = errors.New("save failed")
ErrUnauthorized = errors.New("unauthorized")
ErrZeroExpireMinute = errors.New("zero expire time")
ErrZeroExpireCount = errors.New("zero expire count")
ErrExpireMinuteGreaterThanMonth = errors.New("expire minute greater than a month")
ErrExpireCountGreaterThanMaxCount = errors.New("expire count greater than max count")
ErrEmptyContent = errors.New("empty content")
ErrEmptyLang = errors.New("empty lang")
ErrQueryDBFailed = errors.New("query from db failed")
ErrSaveFailed = errors.New("save failed")
ErrUnauthorized = errors.New("unauthorized")
)
43 changes: 19 additions & 24 deletions handler/paste/paste.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import (
type requestBody struct {
*model.AbstractPaste
SelfDestruct bool `json:"self_destruct"`
ExpireType string `json:"expire_type"`
Expiration uint64 `json:"expiration"`
ExpireMinute uint64 `json:"expire_minute"`
ExpireCount uint64 `json:"expire_count"`
}

func validator(body requestBody) error {
Expand All @@ -28,37 +28,32 @@ func validator(body requestBody) error {
}

if body.SelfDestruct {
if body.ExpireType == "" {
return ErrEmptyExpireType
if body.ExpireMinute <= 0 {
return ErrZeroExpireMinute
}
if body.Expiration <= 0 {
return ErrZeroExpiration
if body.ExpireCount <= 0 {
return ErrZeroExpireCount
}

if body.ExpireType == model.EnumTime {
if body.Expiration > model.OneMonth {
return ErrExpirationGreaterThanMonth
}
} else if body.ExpireType == model.EnumCount {
if body.Expiration > model.MaxCount {
return ErrExpirationGreaterThanMaxCount
}
} else {
return ErrInvalidExpireType
if body.ExpireMinute > model.OneMonth {
return ErrExpireMinuteGreaterThanMonth
}
if body.ExpireCount > model.MaxCount {
return ErrExpireCountGreaterThanMaxCount
}
}
return nil
}

func authenticator(body requestBody) error {
if body.Username == "nobody" {
if body.Username == session.Nobody {
if !body.SelfDestruct {
return ErrUnauthorized
}
if body.ExpireType == model.EnumCount && body.Expiration > 1 {
if body.ExpireCount > 1 {
return ErrUnauthorized
}
if body.ExpireType == model.EnumTime && body.Expiration > 3 {
if body.ExpireMinute > 5 {
return ErrUnauthorized
}
}
Expand All @@ -70,7 +65,7 @@ func Create(context *gin.Context) {

body := requestBody{
AbstractPaste: &model.AbstractPaste{
ClientIP: context.ClientIP(),
ClientIP: context.ClientIP(),
Username: username,
},
}
Expand Down Expand Up @@ -111,8 +106,8 @@ func Create(context *gin.Context) {
if body.SelfDestruct {
paste = &model.Temporary{
AbstractPaste: body.AbstractPaste,
ExpireType: body.ExpireType,
Expiration: body.Expiration,
ExpireMinute: body.ExpireMinute,
ExpireCount: body.ExpireCount,
}
} else {
paste = &model.Permanent{AbstractPaste: body.AbstractPaste}
Expand All @@ -128,8 +123,8 @@ func Create(context *gin.Context) {
}

context.JSON(http.StatusCreated, gin.H{
"status": http.StatusCreated,
"key": paste.GetKey(),
"status": http.StatusCreated,
"key": paste.GetKey(),
})
}

Expand Down
52 changes: 23 additions & 29 deletions handler/paste/paste_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,11 +120,9 @@ var (
func creatTestCaseGenerator() map[string]testCase {
testCaseMap := map[string]testCase{}

for _, pasteType := range []string{"permanent", "temporary_count", "temporary_time"} {
for _, pasteType := range []string{"permanent", "temporary"} {
for _, password := range []string{"", "_with_password"} {
s := strings.Split(pasteType, "_")
expireType := s[len(s)-1]
username := "nobody"
username := session.Nobody
if pasteType == "permanent" {
username = "unittest"
}
Expand All @@ -140,8 +138,8 @@ func creatTestCaseGenerator() map[string]testCase {
"lang": "python",
"password": password,
"self_destruct": pasteType != "permanent",
"expire_type": expireType,
"expiration": 1,
"expire_minute": 1,
"expire_count": 1,
},
map[string]string{},
"127.0.0.1:10086", "POST"},
Expand All @@ -153,13 +151,13 @@ func creatTestCaseGenerator() map[string]testCase {

for _, name := range []string{
"bind_failed", "empty_lang", "empty_content",
"zero_expiration", "empty_expire_type", "other_expire_type",
"zero_expire_count", "zero_expire_minute",
"month_expiration", "big_expiration", // "db_locked",
} {
var (
expectedStatus uint = http.StatusBadRequest
expiration interface{} = model.OneMonth
expireType = "time"
expireMinute interface{} = model.OneMonth
expireCount = 1
content = "print('Hello World!')"
lang = "python"
message = ""
Expand All @@ -173,24 +171,20 @@ func creatTestCaseGenerator() map[string]testCase {
content = ""
message = ErrEmptyContent.Error()
case "bind_failed":
expiration = "1"
expireMinute = "1"
message = "wrong param type"
case "zero_expiration":
expiration = 0
message = ErrZeroExpiration.Error()
case "empty_expire_type":
expireType = ""
message = ErrEmptyExpireType.Error()
case "other_expire_type":
expireType = "other"
message = ErrInvalidExpireType.Error()
case "zero_expire_count":
expireCount = 0
message = ErrZeroExpireCount.Error()
case "zero_expire_minute":
expireMinute = 0
message = ErrZeroExpireMinute.Error()
case "month_expiration":
expiration = model.OneMonth + 1
message = ErrExpirationGreaterThanMonth.Error()
expireMinute = model.OneMonth + 1
message = ErrExpireMinuteGreaterThanMonth.Error()
case "big_expiration":
expireType = "count"
expiration = model.MaxCount + 1
message = ErrExpirationGreaterThanMaxCount.Error()
expireCount = model.MaxCount + 1
message = ErrExpireCountGreaterThanMaxCount.Error()
case "db_locked":
expectedStatus = http.StatusInternalServerError
message = ErrQueryDBFailed.Error()
Expand All @@ -199,15 +193,15 @@ func creatTestCaseGenerator() map[string]testCase {
testCaseMap[name] = testCase{
name,
Input{map[string]string{
"username": "nobody",
"username": session.Nobody,
},
map[string]interface{}{
"content": content,
"lang": lang,
"password": "",
"self_destruct": true,
"expire_type": expireType,
"expiration": expiration,
"expire_minute": expireMinute,
"expire_count": expireCount,
},
map[string]string{},
"127.0.0.1:10086", "POST"},
Expand Down Expand Up @@ -242,7 +236,7 @@ func TestCreate(t *testing.T) {
func getTestCaseGenerator() map[string]testCase {
testCaseMap := map[string]testCase{}

for _, pasteType := range []string{"permanent", "temporary_count", "temporary_time"} {
for _, pasteType := range []string{"permanent", "temporary"} {
passwordList := []string{"", "_with_password"}

if pasteType == "permanent" {
Expand Down Expand Up @@ -296,7 +290,7 @@ func getTestCaseGenerator() map[string]testCase {
status uint
message string
header = map[string]string{"Accept": "application/json"}
username = "nobody"
username = session.Nobody
content string
)

Expand Down
15 changes: 8 additions & 7 deletions handler/session/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ import (

var (
IdentityKey = "username"
Nobody = "nobody"
AuthMiddleware *JWTMiddleware
)

func authenticator(c *gin.Context) (interface{}, error) {
func authenticator(c *gin.Context) (interface{}, error) {
var body user.User
if err := c.ShouldBind(&body); err != nil {
return "", jwt.ErrMissingLoginValues
Expand All @@ -39,13 +40,13 @@ func init() {
var err error
AuthMiddleware = &JWTMiddleware{
jwt.GinJWTMiddleware{
Realm: "pasteme",
Key: []byte(config.Config.Secret),
Timeout: time.Hour,
MaxRefresh: time.Hour,
IdentityKey: IdentityKey,
Realm: "pasteme",
Key: []byte(config.Config.Secret),
Timeout: time.Hour,
MaxRefresh: time.Hour,
IdentityKey: IdentityKey,
Authenticator: authenticator,
PayloadFunc: payloadFunc,
PayloadFunc: payloadFunc,
TokenLookup: "cookie: token",
TokenHeadName: "PasteMe",
},
Expand Down
2 changes: 1 addition & 1 deletion handler/session/jwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ func (mw *JWTMiddleware) MiddlewareFunc(disableAboard bool) gin.HandlerFunc {

func (mw *JWTMiddleware) unauthorized(disableAboard bool, c *gin.Context, code int, message string) {
if disableAboard {
c.Set(mw.IdentityKey, "nobody")
c.Set(mw.IdentityKey, Nobody)
c.Next()
} else {
c.Header("WWW-Authenticate", "JWT realm="+mw.Realm)
Expand Down
54 changes: 29 additions & 25 deletions logging/logging.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,6 @@ import (
"go.uber.org/zap"
)

var logger *zap.Logger

func init() {
config := zap.NewProductionConfig()

config.OutputPaths = append(config.OutputPaths, "pasteme.log")

lgr, _ := config.Build(zap.AddCaller(), zap.AddCallerSkip(1))
logger = lgr
}

func exportField(requests *gin.Context) []zap.Field {
var result []zap.Field
result = append(result, zap.String("ip", requests.ClientIP()))
Expand All @@ -42,22 +31,37 @@ func loggerPreprocess(fields []interface{}) []zap.Field {
return result
}

func Info(msg string, a ...interface{}) {
fields := loggerPreprocess(a)
logger.Info(msg, fields...)
}
type loggerFunc func(string, ...interface{})

func Warn(msg string, a ...interface{}) {
fields := loggerPreprocess(a)
logger.Warn(msg, fields...)
func getLogger(log func(string, ...zap.Field)) loggerFunc {
return func(msg string, a ...interface{}) {
log(msg, loggerPreprocess(a)...)
}
}

func Error(msg string, a ...interface{}) {
fields := loggerPreprocess(a)
logger.Error(msg, fields...)
}

func Panic(msg string, a ...interface{}) {
fields := loggerPreprocess(a)
logger.Panic(msg, fields...)
var (
logger *zap.Logger
Debug loggerFunc
Info loggerFunc
Warn loggerFunc
Error loggerFunc
Fatal loggerFunc
Panic loggerFunc
)

func init() {
config := zap.NewProductionConfig()

config.OutputPaths = append(config.OutputPaths, "pasteme.log")

lgr, _ := config.Build(zap.AddCaller(), zap.AddCallerSkip(1))
logger = lgr

Debug = getLogger(logger.Debug)
Info = getLogger(logger.Info)
Warn = getLogger(logger.Warn)
Error = getLogger(logger.Error)
Fatal = getLogger(logger.Fatal)
Panic = getLogger(logger.Panic)
}
3 changes: 3 additions & 0 deletions model/dao/dao.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"github.com/jinzhu/gorm"
_ "github.com/mattn/go-sqlite3"
"go.uber.org/zap"
"os"
)

func format(
Expand All @@ -32,6 +33,8 @@ func init() {
var err error
if config.Config.Database.Type != "mysql" {
sqlitePath := flag.DataDir + "pasteme.db"
pwd, _ := os.Getwd()
logging.Info("using sqlite", zap.String("database_type", config.Config.Database.Type), zap.String("work_dir", pwd))
if DB, err = gorm.Open("sqlite3", sqlitePath); err != nil {
logging.Panic("sqlite connect failed", zap.String("sqlite_path", sqlitePath), zap.String("err", err.Error()))
return
Expand Down
Loading

0 comments on commit a8baed5

Please sign in to comment.