1
0
mirror of https://github.com/fumiama/paper-manager.git synced 2026-06-08 01:24:55 +08:00

finish upload avatar

This commit is contained in:
源文雨
2023-03-18 00:25:19 +08:00
parent cd571e9e25
commit a072cfe1cf
18 changed files with 268 additions and 72 deletions

27
backend/api/file.go Normal file
View File

@@ -0,0 +1,27 @@
package api
import (
"net/http"
"github.com/fumiama/paper-manager/backend/global"
"github.com/fumiama/paper-manager/backend/utils"
"github.com/sirupsen/logrus"
)
// FileHandler serves contents in global.FileFolder
func FileHandler(w http.ResponseWriter, r *http.Request) {
if !utils.IsMethod("GET", w, r) {
return
}
if r.URL.Path[0] != '/' {
r.URL.Path = "/" + r.URL.Path
}
fn := r.URL.Path[6:]
if fn == "" {
http.Error(w, "400 Bad Request: empty path", http.StatusBadRequest)
return
}
name := global.FileFolder + fn
logrus.Infoln("[file.FileHandler] serve", name)
http.ServeFile(w, r, name)
}

View File

@@ -52,9 +52,12 @@ func getLoginSalt(username string) (*saltinfo, error) {
return nil, errNoSuchUser
}
s, _ := loginstatus.Load(username)
if s != loginStatusNo {
if s == loginStatusYes {
return nil, errInvalidLoginStatus
}
if s >= loginStatusFailLast {
return nil, errTooManyFailedLogins
}
salt := loginsalts.Get(username)
if salt.count != nil {
if atomic.AddUintptr(salt.count, 1) >= maxSaltCount {

View File

@@ -9,13 +9,16 @@ import (
// Handler serves all backend /api call
func Handler(w http.ResponseWriter, r *http.Request) {
if r.URL.Path[0] != '/' {
r.URL.Path = "/" + r.URL.Path
}
if r.URL.Path == "/api/getLoginSalt" {
if !utils.IsMethod("GET", w, r) {
return
}
username := r.URL.Query().Get("username")
if username == "" {
http.Error(w, "400 Bad Request: empty username", http.StatusBadRequest)
writeresult(w, codeError, nil, "empty username", typeError)
return
}
salt, err := getLoginSalt(username)
@@ -58,6 +61,18 @@ func Handler(w http.ResponseWriter, r *http.Request) {
writeresult(w, codeSuccess, r, messageOk, typeSuccess)
return
}
if r.URL.Path == "/api/logout" {
if !utils.IsMethod("GET", w, r) {
return
}
err := logout(r.Header.Get("Authorization"))
if err != nil {
writeresult(w, codeError, nil, err.Error(), typeError)
return
}
writeresult(w, codeSuccess, nil, messageOk, typeSuccess)
return
}
if !utils.IsMethod("GET", w, r) {
return
}

98
backend/api/upload.go Normal file
View File

@@ -0,0 +1,98 @@
package api
import (
"bytes"
"io"
"net/http"
"os"
"strconv"
"strings"
"github.com/fumiama/imgsz"
"github.com/sirupsen/logrus"
"github.com/fumiama/paper-manager/backend/global"
"github.com/fumiama/paper-manager/backend/utils"
)
type upload struct {
Message string `json:"message"`
Code int `json:"code"`
URL string `json:"url"`
}
// UploadHandler receives uploaded files
func UploadHandler(w http.ResponseWriter, r *http.Request) {
if !utils.IsMethod("POST", w, r) {
return
}
token := r.Header.Get("Authorization")
user := usertokens.Get(token)
if user == nil {
writeresult(w, codeError, nil, errInvalidToken.Error(), typeError)
return
}
ff, h, err := r.FormFile("avatar")
if err == nil {
defer ff.Close()
ct := h.Header.Get("Content-Type")
un := h.Filename
logrus.Infoln("[file.UploadHandler] receive avatar, username:", un, "& mime:", ct)
if !strings.HasPrefix(ct, "image/") {
writeresult(w, codeError, nil, "invalid mimetype", typeError)
return
}
if un != user.Name {
writeresult(w, codeError, nil, "username mismatch", typeError)
return
}
err = os.MkdirAll(global.FileFolder+strconv.Itoa(*user.ID), 0755)
if err != nil {
writeresult(w, codeError, nil, err.Error(), typeError)
return
}
buf := bytes.NewBuffer(make([]byte, 0, h.Size))
_, err := io.Copy(buf, ff)
if err != nil {
writeresult(w, codeError, nil, err.Error(), typeError)
return
}
data := buf.Bytes()
_, format, err := imgsz.DecodeSize(buf)
if err != nil {
writeresult(w, codeError, nil, err.Error(), typeError)
return
}
userf := global.FileFolder + strconv.Itoa(*user.ID) + "/"
err = os.MkdirAll(userf, 0755)
if err != nil {
writeresult(w, codeError, nil, err.Error(), typeError)
return
}
avf := userf + "avatar." + format
err = os.WriteFile(avf, data, 0644)
if err != nil {
writeresult(w, codeError, nil, err.Error(), typeError)
return
}
err = global.UserDB.UpdateUserInfo(*user.ID, "", avf[6:], "")
if err != nil {
writeresult(w, codeError, nil, err.Error(), typeError)
return
}
writeresult(w, codeSuccess, &upload{
Message: messageOk,
Code: codeSuccess,
URL: avf[6:],
}, messageOk, typeSuccess)
user.Avtr = avf[6:]
usertokens.Set(token, user)
logrus.Infoln("[file.UploadHandler] save avatar to", avf[6:])
return
}
if err != http.ErrMissingFile {
writeresult(w, codeError, nil, err.Error(), typeError)
return
}
}

View File

@@ -2,10 +2,16 @@ package api
import (
"errors"
"strings"
"time"
"github.com/fumiama/paper-manager/backend/global"
)
const (
chineseDateLayout = "2006年01月02日15时04分05秒"
)
var (
errInvalidToken = errors.New("invalid token")
)
@@ -18,6 +24,9 @@ type getUserInfoResult struct {
Desc string `json:"desc"`
HomePath string `json:"homePath"`
Roles []role `json:"roles"`
Date string `json:"date"`
Last string `json:"last"`
Contact string `json:"contact"`
}
func getUserInfo(token string) (*getUserInfoResult, error) {
@@ -25,6 +34,16 @@ func getUserInfo(token string) (*getUserInfoResult, error) {
if user == nil {
return nil, errInvalidToken
}
cont := user.Cont
if len(cont) > 7 {
sb := strings.Builder{}
sb.WriteString(cont[:3])
for i := 0; i < len(cont)-7; i++ {
sb.WriteByte('*')
}
sb.WriteString(cont[len(cont)-4:])
cont = sb.String()
}
return &getUserInfoResult{
UserID: *user.ID,
Username: user.Name,
@@ -37,6 +56,19 @@ func getUserInfo(token string) (*getUserInfoResult, error) {
}
return "/dashboard/workbench"
}(),
Roles: []role{{RoleName: user.Role.Nick(), Value: user.Role.String()}},
Roles: []role{{RoleName: user.Role.Nick(), Value: user.Role.String()}},
Date: time.Unix(user.Date, 0).Format(chineseDateLayout),
Last: time.Unix(user.Last, 0).Format(chineseDateLayout),
Contact: cont,
}, nil
}
func logout(token string) error {
user := usertokens.Get(token)
if user == nil {
return errInvalidToken
}
loginstatus.Delete(user.Name)
usertokens.Delete(token)
return nil
}