mirror of https://github.com/sunface/rust-course
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
261 lines
7.8 KiB
261 lines
7.8 KiB
package user
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
"unicode/utf8"
|
|
|
|
"github.com/labstack/echo"
|
|
"go.uber.org/zap"
|
|
|
|
"github.com/go-rust/im.dev/internal/ecode"
|
|
"github.com/go-rust/im.dev/internal/misc"
|
|
"github.com/go-rust/im.dev/internal/utils"
|
|
"github.com/go-rust/im.dev/internal/utils/validate"
|
|
)
|
|
|
|
// InitUser insert preserve users
|
|
func InitUser() {
|
|
err := misc.CQL.Query(`INSERT INTO user (id,name,nickname,avatar,create_date,edit_date) VALUES (?,?,?,?,?,?)`,
|
|
"13269", "sunface", "Sunface", "https://avatars2.githubusercontent.com/u/7036754?s=460&v=4", time.Now().Unix(), 0).Exec()
|
|
if err != nil {
|
|
misc.Log.Warn("access database error", zap.Error(err))
|
|
}
|
|
}
|
|
|
|
// CheckUserExist checks user exist by given user id
|
|
func CheckUserExist(n string) bool {
|
|
var name string
|
|
err := misc.CQL.Query(`SELECT name FROM user where name=?`, n).Scan(&name)
|
|
if err != nil && err.Error() != misc.CQLNotFound {
|
|
misc.Log.Warn("access database error", zap.Error(err))
|
|
return false
|
|
}
|
|
|
|
if name != "" {
|
|
return true
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// Card returns user detail card info
|
|
func Card(c echo.Context) error {
|
|
uid := c.FormValue("uid")
|
|
if uid == "" {
|
|
return c.JSON(http.StatusBadRequest, misc.HTTPResp{
|
|
ErrCode: ecode.ParamInvalid,
|
|
Message: ecode.ParamInvalidMsg,
|
|
})
|
|
}
|
|
|
|
user := &User{}
|
|
q := misc.CQL.Query(`SELECT name,nickname,avatar,website,about,location,bg_color,text_color,looking_for_work,education,employer,
|
|
create_date FROM user WHERE id=?`, uid)
|
|
err := q.Scan(&user.Name, &user.NickName,
|
|
&user.Avatar, &user.Website, &user.About, &user.Location, &user.BgColor, &user.TextColor, &user.LookingForWork,
|
|
&user.Education, &user.Employer, &user.createDate)
|
|
|
|
if err != nil {
|
|
if err.Error() == misc.CQLNotFound {
|
|
return c.JSON(http.StatusNotFound, misc.HTTPResp{
|
|
ErrCode: ecode.NotFound,
|
|
Message: ecode.NotFoundMsg,
|
|
})
|
|
}
|
|
misc.Log.Warn("access database error", zap.Error(err))
|
|
return c.JSON(http.StatusInternalServerError, misc.HTTPResp{
|
|
ErrCode: ecode.DatabaseError,
|
|
Message: ecode.CommonErrorMsg,
|
|
})
|
|
}
|
|
|
|
user.CreateDate = utils.Time2ReadableString(time.Unix(user.createDate, 0))
|
|
if user.BgColor == "" {
|
|
user.BgColor = "#000"
|
|
}
|
|
if user.TextColor == "" {
|
|
user.TextColor = "#000"
|
|
}
|
|
return c.JSON(http.StatusOK, misc.HTTPResp{
|
|
Data: user,
|
|
})
|
|
}
|
|
|
|
// GetUserByID return the user info by user id
|
|
func GetUserByID(uid string) *Session {
|
|
sess := &Session{ID: uid}
|
|
|
|
err := misc.CQL.Query(`SELECT name,nickname,avatar FROM user WHERE id=?`, uid).Scan(&sess.Name, &sess.NickName, &sess.Avatar)
|
|
if err != nil && err.Error() != misc.CQLNotFound {
|
|
misc.Log.Warn("access database error", zap.Error(err))
|
|
return nil
|
|
}
|
|
|
|
return sess
|
|
}
|
|
|
|
// User holds all info of one user
|
|
type User struct {
|
|
//----account-----
|
|
ID string `json:"id"`
|
|
Name string `json:"name"`
|
|
Email string `json:"email,omitempty"`
|
|
//----profile-----
|
|
NickName string `json:"nickname"`
|
|
Avatar string `json:"avatar"`
|
|
Website string `json:"website"`
|
|
About string `json:"about"`
|
|
Location string `json:"location"`
|
|
BgColor string `json:"bg_color"`
|
|
TextColor string `json:"text_color"`
|
|
LookingForWork bool `json:"lfw"`
|
|
Education string `json:"education"`
|
|
Employer string `json:"employer"`
|
|
Skills string `json:"skills"`
|
|
AvailableFor string `json:"available_for"`
|
|
WorkingExp string `json:"working_exp"`
|
|
|
|
CreateDate string `json:"create_date"`
|
|
EditDate string `json:"edit_date"`
|
|
|
|
createDate int64
|
|
editDate int64
|
|
}
|
|
|
|
// Profile return user's detail profile
|
|
func Profile(c echo.Context) error {
|
|
sess := GetSession(c)
|
|
user := &User{}
|
|
q := misc.CQL.Query(`SELECT id,name,email,nickname,avatar,website,about,location,bg_color,text_color,looking_for_work,education,employer,skills,
|
|
available_for,working_exp,create_date,edit_date FROM user WHERE id=?`, sess.ID)
|
|
err := q.Scan(&user.ID, &user.Name, &user.Email, &user.NickName,
|
|
&user.Avatar, &user.Website, &user.About, &user.Location, &user.BgColor, &user.TextColor, &user.LookingForWork,
|
|
&user.Education, &user.Employer, &user.Skills, &user.AvailableFor, &user.WorkingExp, &user.createDate, &user.editDate)
|
|
|
|
if err != nil {
|
|
if err.Error() == misc.CQLNotFound {
|
|
return c.JSON(http.StatusNotFound, misc.HTTPResp{
|
|
ErrCode: ecode.NotFound,
|
|
Message: ecode.NotFoundMsg,
|
|
})
|
|
}
|
|
misc.Log.Warn("access database error", zap.Error(err))
|
|
return c.JSON(http.StatusInternalServerError, misc.HTTPResp{
|
|
ErrCode: ecode.DatabaseError,
|
|
Message: ecode.CommonErrorMsg,
|
|
})
|
|
}
|
|
|
|
user.CreateDate = utils.Time2ReadableString(time.Unix(user.createDate, 0))
|
|
if user.BgColor == "" {
|
|
user.BgColor = "#000"
|
|
}
|
|
if user.TextColor == "" {
|
|
user.TextColor = "#000"
|
|
}
|
|
return c.JSON(http.StatusOK, misc.HTTPResp{
|
|
Data: user,
|
|
})
|
|
}
|
|
|
|
// SetProfile set user profile
|
|
func SetProfile(c echo.Context) error {
|
|
u := c.FormValue("user")
|
|
user := &User{}
|
|
err := json.Unmarshal([]byte(u), &user)
|
|
if err != nil {
|
|
return c.JSON(http.StatusBadRequest, misc.HTTPResp{
|
|
ErrCode: ecode.ParamInvalid,
|
|
Message: ecode.ParamInvalidMsg,
|
|
})
|
|
}
|
|
|
|
err = validateProfile(user)
|
|
|
|
sess := GetSession(c)
|
|
q := misc.CQL.Query(`UPDATE user SET nickname=?,avatar=?,website=?,about=?,location=?,bg_color=?,
|
|
text_color=?,looking_for_work=?,education=?,employer=?,skills=?,available_for=?,working_exp=?,edit_date=? WHERE id=?`, user.NickName,
|
|
user.Avatar, user.Website, user.About, user.Location, user.BgColor, user.TextColor, user.LookingForWork, user.Education, user.Employer,
|
|
user.Skills, user.AvailableFor, user.WorkingExp, time.Now().Unix(), sess.ID)
|
|
err = q.Exec()
|
|
if err != nil {
|
|
misc.Log.Warn("access database error", zap.Error(err))
|
|
return c.JSON(http.StatusInternalServerError, misc.HTTPResp{
|
|
ErrCode: ecode.DatabaseError,
|
|
Message: ecode.CommonErrorMsg,
|
|
})
|
|
}
|
|
|
|
if err != nil {
|
|
return c.JSON(http.StatusBadRequest, misc.HTTPResp{
|
|
ErrCode: ecode.ParamInvalid,
|
|
Message: err.Error(),
|
|
})
|
|
}
|
|
|
|
return c.JSON(http.StatusOK, misc.HTTPResp{})
|
|
}
|
|
|
|
func validateProfile(user *User) error {
|
|
user.NickName = misc.Sanitizer.Sanitize(strings.TrimSpace(user.NickName))
|
|
if utf8.RuneCountInString(user.NickName) > 30 {
|
|
return errors.New("Display name too long")
|
|
}
|
|
|
|
user.About = misc.Sanitizer.Sanitize(strings.TrimSpace(user.About))
|
|
if utf8.RuneCountInString(user.About) > 500 {
|
|
return errors.New("About too long")
|
|
}
|
|
|
|
user.Website = misc.Sanitizer.Sanitize(strings.TrimSpace(user.Website))
|
|
if utf8.RuneCountInString(user.Website) > 30 || !validate.IsURL(user.Website) {
|
|
return errors.New("Website invalid or too long")
|
|
}
|
|
|
|
user.Location = misc.Sanitizer.Sanitize(strings.TrimSpace(user.Location))
|
|
if utf8.RuneCountInString(user.Location) > 30 {
|
|
return errors.New("About too long")
|
|
}
|
|
|
|
user.BgColor = strings.TrimSpace(user.BgColor)
|
|
if !validate.IsColor(user.BgColor) {
|
|
return errors.New("Invalid background color")
|
|
}
|
|
|
|
user.TextColor = strings.TrimSpace(user.TextColor)
|
|
if !validate.IsColor(user.TextColor) {
|
|
return errors.New("Invalid text color")
|
|
}
|
|
|
|
user.Education = misc.Sanitizer.Sanitize(strings.TrimSpace(user.Education))
|
|
if utf8.RuneCountInString(user.Education) > 500 {
|
|
return errors.New("Education too long")
|
|
}
|
|
|
|
user.Employer = misc.Sanitizer.Sanitize(strings.TrimSpace(user.Employer))
|
|
if utf8.RuneCountInString(user.Employer) > 500 {
|
|
return errors.New("Employer too long")
|
|
}
|
|
|
|
user.Skills = misc.Sanitizer.Sanitize(strings.TrimSpace(user.Skills))
|
|
if utf8.RuneCountInString(user.Skills) > 500 {
|
|
return errors.New("Skills too long")
|
|
}
|
|
|
|
user.AvailableFor = misc.Sanitizer.Sanitize(strings.TrimSpace(user.AvailableFor))
|
|
if utf8.RuneCountInString(user.Employer) > 500 {
|
|
return errors.New("Available for too long")
|
|
}
|
|
|
|
user.WorkingExp = misc.Sanitizer.Sanitize(strings.TrimSpace(user.WorkingExp))
|
|
if utf8.RuneCountInString(user.Employer) > 500 {
|
|
return errors.New("Working experience too long")
|
|
}
|
|
|
|
return nil
|
|
}
|