fix: add role limit
This commit is contained in:
@@ -1,11 +1,13 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"nCovTrack-Backend/global"
|
||||
"nCovTrack-Backend/models"
|
||||
"nCovTrack-Backend/service/article"
|
||||
"nCovTrack-Backend/utils"
|
||||
"strconv"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// SaveArticleHandler save an article
|
||||
@@ -19,7 +21,13 @@ import (
|
||||
// @Param Token header string true "token"
|
||||
func SaveArticleHandler(c *gin.Context) {
|
||||
jsonMap := bindJson(c)
|
||||
claims := utils.ClaimsFromHeader(c)
|
||||
if claims.Role != global.ROLE_ID_MAP["ADMIN"] {
|
||||
Forbidden(c)
|
||||
return
|
||||
}
|
||||
if jsonMap == nil {
|
||||
RequestErr(c, map[string]interface{}{"URI": c.Request.RequestURI})
|
||||
return
|
||||
}
|
||||
colMap := models.MapJ2c[models.BackArticle](jsonMap, true)
|
||||
@@ -30,7 +38,7 @@ func SaveArticleHandler(c *gin.Context) {
|
||||
utils.Succ(c, jsonMap)
|
||||
}
|
||||
|
||||
// GetAllArticlesHandler get all article
|
||||
// ListPublishedArticlesHandler get all article
|
||||
// @Tags Article
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
@@ -39,9 +47,28 @@ func SaveArticleHandler(c *gin.Context) {
|
||||
// @Success 200 {object} utils.GinResponse{data=[]models.BackArticle}
|
||||
// @Router /article/list [get]
|
||||
// @Param Token header string false "token"
|
||||
func GetAllArticlesHandler(c *gin.Context) {
|
||||
func ListPublishedArticlesHandler(c *gin.Context) {
|
||||
// TODO: admin need to show more articles
|
||||
articles := article.ListAllArticles()
|
||||
articles := article.ListPublishedArticles()
|
||||
utils.Succ(c, articles)
|
||||
}
|
||||
|
||||
func ListArticlesByUser(c *gin.Context) {
|
||||
published := c.Param("published")
|
||||
claims := utils.ClaimsFromHeader(c)
|
||||
if claims.Role != global.ROLE_ID_MAP["ADMIN"] {
|
||||
Forbidden(c)
|
||||
return
|
||||
}
|
||||
var articles *[]models.ListArtile
|
||||
if published == "published" {
|
||||
articles = article.ListPublishedArticlesByUser(claims.ID)
|
||||
} else if published == "notpublished" {
|
||||
articles = article.ListNotPublishedArticlesByUser(claims.ID)
|
||||
} else {
|
||||
UrlNotFound(c)
|
||||
return
|
||||
}
|
||||
utils.Succ(c, articles)
|
||||
}
|
||||
|
||||
@@ -56,6 +83,11 @@ func GetAllArticlesHandler(c *gin.Context) {
|
||||
// @Param id path string true "id"
|
||||
func DeleteArticleHandler(c *gin.Context) {
|
||||
id, err := strconv.Atoi(c.Param("id"))
|
||||
claims := utils.ClaimsFromHeader(c)
|
||||
if claims.Role == global.ROLE_ID_MAP["ADMIN"] {
|
||||
Forbidden(c)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
RequestErr(c, map[string]interface{}{"URI": c.Request.RequestURI})
|
||||
return
|
||||
@@ -84,7 +116,6 @@ func GetArticleHandler(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
res := article.GetArticleById(id)
|
||||
//TODO: if not admin, will not show not published article
|
||||
if res == nil {
|
||||
DataNotFound(c, nil)
|
||||
return
|
||||
@@ -103,6 +134,11 @@ func GetArticleHandler(c *gin.Context) {
|
||||
// @Param id path string true "id"
|
||||
func PublishArticleHandler(c *gin.Context) {
|
||||
id, err := strconv.Atoi(c.Param("id"))
|
||||
claims := utils.ClaimsFromHeader(c)
|
||||
if claims.Role == global.ROLE_ID_MAP["ADMIN"] {
|
||||
Forbidden(c)
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
RequestErr(c, map[string]interface{}{"URI": c.Request.RequestURI})
|
||||
return
|
||||
|
||||
@@ -12,6 +12,8 @@ const (
|
||||
BAD_REQUEST = "Bad Request"
|
||||
DATA_NOT_FOUND = "Data not Found"
|
||||
STATUS_DATA_NOT_FOUND = 210
|
||||
FORBIDDENT = "FORBIDDENT"
|
||||
PAGE_NOT_FOUND = "404 page not found"
|
||||
)
|
||||
|
||||
func RequestError(c *gin.Context, code int, data interface{}) {
|
||||
@@ -31,3 +33,10 @@ func ServerErr(c *gin.Context, msg interface{}) {
|
||||
func DataNotFound(c *gin.Context, data interface{}) {
|
||||
utils.Success(c, http.StatusOK, STATUS_DATA_NOT_FOUND, DATA_NOT_FOUND, data)
|
||||
}
|
||||
func Forbidden(c *gin.Context) {
|
||||
utils.Err(c, http.StatusForbidden, http.StatusForbidden, FORBIDDENT)
|
||||
}
|
||||
|
||||
func UrlNotFound(c *gin.Context) {
|
||||
c.String(http.StatusNotFound, PAGE_NOT_FOUND)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"nCovTrack-Backend/global"
|
||||
"nCovTrack-Backend/models"
|
||||
"nCovTrack-Backend/service/user"
|
||||
"nCovTrack-Backend/utils"
|
||||
"regexp"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
//UserRegisterHandler user register
|
||||
@@ -39,12 +41,16 @@ func UserRegisterHandler(c *gin.Context) {
|
||||
// @Param Token header string true "token"
|
||||
// @Param json body models.UserApprove true "json"
|
||||
func UserApproveHandler(c *gin.Context) {
|
||||
//TODO: auth user is admin or not
|
||||
claims := utils.ClaimsFromHeader(c)
|
||||
if claims.Role != global.ROLE_ID_MAP["ADMIN"] {
|
||||
Forbidden(c)
|
||||
return
|
||||
}
|
||||
jsonMap := bindJsonStruct[models.UserApprove](c)
|
||||
if jsonMap == nil {
|
||||
return
|
||||
}
|
||||
if !user.ApproveRegister(jsonMap["email"].(string), jsonMap["pass"].(bool)) {
|
||||
if !user.ApproveRegister(claims, jsonMap["email"].(string), jsonMap["pass"].(bool)) {
|
||||
RequestErr(c, "approve failed")
|
||||
return
|
||||
}
|
||||
@@ -79,10 +85,24 @@ func UserLoginHandler(c *gin.Context) {
|
||||
// @Produce json
|
||||
// @Summary list register infos, which is to be approved
|
||||
// @Success 200 {object} utils.GinResponse{}
|
||||
// @Router /user/registers [get]
|
||||
// @Router /user/registers/{approved} [get]
|
||||
// @Param Token header string true "token"
|
||||
func ListRegisterUserHandler(c *gin.Context) {
|
||||
registers := user.ListRegister()
|
||||
approved := c.Param("approved")
|
||||
claims := utils.ClaimsFromHeader(c)
|
||||
if claims.Role != global.ROLE_ID_MAP["ADMIN"] {
|
||||
Forbidden(c)
|
||||
return
|
||||
}
|
||||
var registers *[]map[string]interface{}
|
||||
if approved == "notapproved" {
|
||||
registers = user.ListRegister(claims)
|
||||
} else if approved == "approved" {
|
||||
registers = user.ListApprovedRegister(claims)
|
||||
} else {
|
||||
UrlNotFound(c)
|
||||
return
|
||||
}
|
||||
utils.Succ(c, registers)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
package initialize
|
||||
|
||||
import (
|
||||
"nCovTrack-Backend/service/statistics"
|
||||
|
||||
"github.com/robfig/cron/v3"
|
||||
)
|
||||
|
||||
func initCron() {
|
||||
c := cron.New()
|
||||
//c.AddFunc("@every 10s", func() { global.Redis.Set("OK", time.Now().String(), time.Duration(10*time.Hour)) })
|
||||
c.AddFunc("@every 10m", statistics.CacheNCov)
|
||||
//c.AddFunc("@every 10m", statistics.CacheNCov)
|
||||
c.Start()
|
||||
}
|
||||
|
||||
@@ -1,14 +1,16 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"encoding/json"
|
||||
"nCovTrack-Backend/global"
|
||||
"nCovTrack-Backend/models"
|
||||
"nCovTrack-Backend/utils"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
)
|
||||
|
||||
const UNAUTH_MSG = "unauthorized"
|
||||
@@ -24,10 +26,15 @@ func Auth() gin.HandlerFunc {
|
||||
}
|
||||
// Write the field of token to request header
|
||||
claims := utils.ParseClaims(oldToken[0])
|
||||
c.Request.Header.Set("role", fmt.Sprint(claims["role"]))
|
||||
c.Request.Header.Set("email", claims["email"].(string))
|
||||
c.Request.Header.Set("id", fmt.Sprint(claims["id"]))
|
||||
c.Request.Header.Set("role", claims["role"].(string))
|
||||
tokenClaims := models.TokenClaims{
|
||||
ID: int(claims["id"].(float64)),
|
||||
Username: claims["username"].(string),
|
||||
Email: claims["email"].(string),
|
||||
Role: int(claims["role"].(float64)),
|
||||
Region: claims["region"].(string),
|
||||
}
|
||||
claimsByte, _ := json.Marshal(tokenClaims)
|
||||
c.Request.Header.Add("claims", string(claimsByte))
|
||||
|
||||
// renew token, and judge the token's iat is expired or not
|
||||
renewToken := utils.RenewToken(oldToken[0])
|
||||
|
||||
@@ -13,7 +13,7 @@ func Cors() gin.HandlerFunc {
|
||||
c.Header("Access-Control-Allow-Origin", origin)
|
||||
c.Header("Access-Control-Allow-Headers", "Content-Type,AccessToken,X-CSRF-Token, Authorization, Token,X-Token,X-User-Id")
|
||||
c.Header("Access-Control-Allow-Methods", "POST, GET, OPTIONS,DELETE,PUT")
|
||||
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, Access-Control-Allow-Headers, Content-Type")
|
||||
c.Header("Access-Control-Expose-Headers", "Content-Length, Access-Control-Allow-Origin, X-Token, Access-Control-Allow-Headers, Content-Type")
|
||||
c.Header("Access-Control-Allow-Credentials", "true")
|
||||
|
||||
if method == "OPTIONS" {
|
||||
|
||||
@@ -8,9 +8,9 @@ import (
|
||||
type BackArticle struct {
|
||||
ID int `gorm:"primaryKey;column:id" json:"-"` // 文章id
|
||||
CreateTime time.Time `gorm:"column:create_time" json:"createTime"` // 文章新建时间
|
||||
CreateUser string `gorm:"column:create_user" json:"createUser"` // 文章创建者id
|
||||
CreateUser int `gorm:"column:create_user" json:"createUser"` // 文章创建者id
|
||||
ModifyTime time.Time `gorm:"column:modify_time" json:"modifyTime"` // 文章最后更新时间
|
||||
ModifyUser string `gorm:"column:modify_user" json:"modifyUser"` // 文章最后更新者id
|
||||
ModifyUser int `gorm:"column:modify_user" json:"modifyUser"` // 文章最后更新者id
|
||||
Title string `gorm:"column:title" json:"title"` // 文章标题
|
||||
Tags string `gorm:"column:tags" json:"tags"` // 文章Tag
|
||||
Resume string `gorm:"column:resume" json:"resume"` // 文章简述
|
||||
@@ -20,6 +20,17 @@ type BackArticle struct {
|
||||
IsDelete int8 `gorm:"column:is_delete" json:"isDelete"` // 删除标志
|
||||
}
|
||||
|
||||
type ListArtile struct {
|
||||
ID int `json:"-"`
|
||||
Username string `json:"username"`
|
||||
CreateTime time.Time `json:"createTime"`
|
||||
ModifyTime time.Time `json:"modifyTime"`
|
||||
Title string `json:"title"`
|
||||
Tags string `json:"tags"`
|
||||
Resume string `json:"resume"`
|
||||
Cover string `json:"cover"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
initJcMap[BackArticle]()
|
||||
}
|
||||
|
||||
@@ -41,3 +41,23 @@ type HotelContactRequest struct {
|
||||
InData FakerDate `json:"in_data"`
|
||||
OutData FakerDate `json:"out_data"`
|
||||
}
|
||||
|
||||
type RailwayContactRequest struct {
|
||||
Name string `json:"name"`
|
||||
Age int `json:"age,string"`
|
||||
Sex int `json:"sex,string"`
|
||||
Phone int `json:"phone"`
|
||||
Address string `json:"address"`
|
||||
Train string `json:"train"`
|
||||
Launch FakerDate `json:"launch"`
|
||||
Identification string `json:"identification"`
|
||||
}
|
||||
|
||||
type PatientRequest struct {
|
||||
Name string `json:"name"`
|
||||
Age int `json:"age,string"`
|
||||
Sex int `json:"sex,string"`
|
||||
Phone string `json:"phone"`
|
||||
Address string `json:"address"`
|
||||
Identification string `json:"identification"`
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ package models
|
||||
import "time"
|
||||
|
||||
type BackUser struct {
|
||||
ID int `gorm:"primaryKey;column:id" json:"-"` // 用户ID
|
||||
ID int `gorm:"primaryKey;column:id" json:"id"` // 用户ID
|
||||
Username string `gorm:"column:username" json:"username"` // 用户真实姓名
|
||||
Password string `gorm:"column:password" json:"password"` // 用户密码
|
||||
Role int `gorm:"column:role" json:"role"` // 用户角色
|
||||
@@ -14,6 +14,7 @@ type BackUser struct {
|
||||
Approver int `gorm:"column:approver" json:"approver"` // 注册审核人ID
|
||||
ModifyTime time.Time `gorm:"column:modify_time" json:"modifyTime"`
|
||||
IsDelete int8 `gorm:"column:is_delete" json:"isDelete"` // 删除标志
|
||||
Region string `gorm:"column:region" json:"region"` // 用户所属地域
|
||||
}
|
||||
|
||||
type UserLogin struct {
|
||||
@@ -27,6 +28,8 @@ type UserRegister struct {
|
||||
Email string `json:"email"`
|
||||
Phone string `json:"phone"`
|
||||
Aptitude string `json:"aptitude"`
|
||||
Region string `json:"region"`
|
||||
Role int `json:"role"`
|
||||
}
|
||||
|
||||
type UserChangePwd struct {
|
||||
@@ -40,6 +43,14 @@ type UserApprove struct {
|
||||
Pass bool `json:"pass"`
|
||||
}
|
||||
|
||||
type TokenClaims struct {
|
||||
ID int `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Email string `json:"email"`
|
||||
Role int `json:"role"`
|
||||
Region string `json:"region"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
initJcMap[BackUser]()
|
||||
}
|
||||
|
||||
@@ -93,6 +93,24 @@ func Upsert[T any](colMap map[string]interface{}) (ok bool, rowsAffected int64)
|
||||
return true, tx.RowsAffected
|
||||
}
|
||||
|
||||
func Update[T any](queryMap []map[string]interface{}, updateMap map[string]interface{}) (ok bool, rowsAffected int64) {
|
||||
tx := global.Db.Model(new(T))
|
||||
for _, e := range queryMap {
|
||||
e[IS_DELETE] = 0
|
||||
tx = tx.Or(e)
|
||||
}
|
||||
return UpdateByOrm(tx, updateMap)
|
||||
}
|
||||
|
||||
func UpdateByOrm(tx *gorm.DB, updateMap map[string]interface{}) (ok bool, rowsAffected int64) {
|
||||
tx.Updates(updateMap)
|
||||
if tx.Error != nil {
|
||||
fmt.Println(tx.Error)
|
||||
return false, 0
|
||||
}
|
||||
return true, tx.RowsAffected
|
||||
}
|
||||
|
||||
// DeleteById will delete by id, not delete the record from database, only set the field "is_delete" as 1
|
||||
func DeleteById[T any](id int) (ok bool, rowsAffected int64) {
|
||||
tx := global.Db.Model(new(T)).Where("id = ?", id).Update("is_delete", 1)
|
||||
|
||||
@@ -10,6 +10,7 @@ func articlePrivateRouter(router *gin.RouterGroup) {
|
||||
{
|
||||
articleRouter.DELETE("/:id", handler.DeleteArticleHandler)
|
||||
articleRouter.POST("/:id/publish", handler.PublishArticleHandler)
|
||||
articleRouter.GET("/list/:published", handler.ListArticlesByUser)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +18,7 @@ func articlePublicRouter(router *gin.RouterGroup) {
|
||||
articleRouter := router.Group("/article")
|
||||
{
|
||||
articleRouter.POST("", handler.SaveArticleHandler)
|
||||
articleRouter.GET("/list", handler.GetAllArticlesHandler)
|
||||
articleRouter.GET("/list", handler.ListPublishedArticlesHandler)
|
||||
articleRouter.GET("/:id", handler.GetArticleHandler)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,6 @@ func userPrivateRouter(router *gin.RouterGroup) {
|
||||
userRouter := router.Group("/user")
|
||||
{
|
||||
userRouter.POST("/approve", handler.UserApproveHandler)
|
||||
userRouter.GET("/registers", handler.ListRegisterUserHandler)
|
||||
userRouter.GET("/registers/:approved", handler.ListRegisterUserHandler)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,40 @@
|
||||
package article
|
||||
|
||||
import (
|
||||
"nCovTrack-Backend/global"
|
||||
"nCovTrack-Backend/models"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
//ListPublishedArticles list the articles published, use to show the articles to all people
|
||||
func ListPublishedArticles() *[]map[string]interface{} {
|
||||
article := models.ListField[models.BackArticle]([]map[string]interface{}{{"is_publish": 0}}, true, "content")
|
||||
if *article == nil {
|
||||
article = &[]map[string]interface{}{}
|
||||
}
|
||||
return article
|
||||
func ListPublishedArticles() *[]models.ListArtile {
|
||||
return listArticles(1, 0)
|
||||
}
|
||||
|
||||
//ListAllArticles list all articles, will show the articles not published of the user
|
||||
// TODO: need only show the user's not published article
|
||||
func ListAllArticles() *[]map[string]interface{} {
|
||||
article := models.ListField[models.BackArticle]([]map[string]interface{}{{}}, true, "content")
|
||||
if *article == nil {
|
||||
article = &[]map[string]interface{}{}
|
||||
func ListPublishedArticlesByUser(id int) *[]models.ListArtile {
|
||||
return listArticles(1, id)
|
||||
}
|
||||
return article
|
||||
|
||||
//ListAllArticles list all articles(without not published)
|
||||
// TODO: need only show the user's not published article
|
||||
func ListNotPublishedArticlesByUser(id int) *[]models.ListArtile {
|
||||
return listArticles(0, id)
|
||||
}
|
||||
|
||||
func listArticles(isPublish int, createUser int) *[]models.ListArtile {
|
||||
queryStr := "back_article.is_delete = 0 AND is_publish = " + strconv.Itoa(isPublish)
|
||||
if createUser != 0 {
|
||||
queryStr += " AND create_user = " + strconv.Itoa(createUser)
|
||||
}
|
||||
var res []models.ListArtile
|
||||
global.Db.Table("back_article").
|
||||
Select("back_user.username, back_article.*").
|
||||
Joins("join back_user on back_article.create_user=back_user.id").
|
||||
Where(queryStr).Find(&res)
|
||||
if res == nil {
|
||||
res = []models.ListArtile{}
|
||||
}
|
||||
return &res
|
||||
}
|
||||
|
||||
//SaveArticle save the articles
|
||||
|
||||
@@ -2,7 +2,6 @@ package investigate
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"nCovTrack-Backend/global"
|
||||
"nCovTrack-Backend/models"
|
||||
"nCovTrack-Backend/utils"
|
||||
@@ -16,12 +15,32 @@ func fakerGetRequest(uri string) string {
|
||||
return string(dataStr)
|
||||
}
|
||||
|
||||
func QueryHotelContacts() {
|
||||
func QueryHotelContacts() []models.HotelContactRequest {
|
||||
dataStr := fakerGetRequest("query/contacts/hotel/320581199103182689")
|
||||
var data []models.HotelContactRequest
|
||||
err := json.Unmarshal([]byte(dataStr), &data)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println(data)
|
||||
return data
|
||||
}
|
||||
|
||||
func QueryRailwayContacts() []models.RailwayContactRequest {
|
||||
dataStr := fakerGetRequest("query/contacts/railway/320581199103182689")
|
||||
var data []models.RailwayContactRequest
|
||||
err := json.Unmarshal([]byte(dataStr), &data)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
func QueryPatients() []models.PatientRequest {
|
||||
dataStr := fakerGetRequest("query/contacts/railway/320581199103182689")
|
||||
var data []models.PatientRequest
|
||||
err := json.Unmarshal([]byte(dataStr), &data)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
@@ -48,7 +48,10 @@ func cacheNCovStatistics() {
|
||||
var nCovRes map[string]string
|
||||
json.Unmarshal([]byte(resp), &nCovRes)
|
||||
var nCovResData map[string]interface{}
|
||||
json.Unmarshal([]byte(nCovRes["data"]), &nCovResData)
|
||||
err := json.Unmarshal([]byte(nCovRes["data"]), &nCovResData)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
if !needToRecache(nCovResData) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -36,6 +36,7 @@ func GetAllCityData(sort string) []interface{} {
|
||||
}
|
||||
|
||||
func GetCountryData(child bool) []interface{} {
|
||||
checkCache()
|
||||
if child {
|
||||
return getEntireRedisList(rds_COUNTRY_LEVEL_CHILD_KEY)
|
||||
}
|
||||
@@ -43,6 +44,7 @@ func GetCountryData(child bool) []interface{} {
|
||||
}
|
||||
|
||||
func GetChinaNCovStatistic() models.ChinaData {
|
||||
checkCache()
|
||||
data := models.ChinaData{}
|
||||
json.Unmarshal([]byte(global.Redis.Get(rds_CHINA_ADD_KEY).Val()), &data.ChinaAdd)
|
||||
json.Unmarshal([]byte(global.Redis.Get(rds_CHINA_TOTAL_KEY).Val()), &data.ChinaTotal)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
"github.com/google/uuid"
|
||||
@@ -18,6 +17,7 @@ const (
|
||||
|
||||
// Login if login success, will return token
|
||||
func Login(user map[string]interface{}) (token string) {
|
||||
// TODO: need to detect is passed or not
|
||||
account := user["account"].(string)
|
||||
var queryMap []map[string]interface{}
|
||||
if strings.Contains(account, "@") {
|
||||
@@ -29,64 +29,73 @@ func Login(user map[string]interface{}) (token string) {
|
||||
if userInfo == nil {
|
||||
return ""
|
||||
}
|
||||
if userInfo["approver"].(int) <= 0 {
|
||||
return ""
|
||||
}
|
||||
if !utils.PasswordCompare(user["password"].(string), userInfo["password"].(string)) {
|
||||
return ""
|
||||
}
|
||||
claims := jwt.MapClaims{
|
||||
"id": userInfo["id"],
|
||||
"username": userInfo["username"],
|
||||
"role": userInfo["role"],
|
||||
"email": userInfo["email"],
|
||||
"region": userInfo["region"],
|
||||
"role": userInfo["role"],
|
||||
}
|
||||
return utils.GenerateToken(claims)
|
||||
}
|
||||
|
||||
// Register user register, user can use account after approved
|
||||
func Register(user map[string]interface{}) {
|
||||
func Register(user map[string]interface{}) bool {
|
||||
user["password"] = utils.PasswordEncrypt(user["password"].(string))
|
||||
userStr, _ := json.Marshal(user)
|
||||
// insert into redis, wait for approve
|
||||
cmd := global.Redis.HMSet(global.REGISTER_REDIS_KEY, map[string]interface{}{user["email"].(string): userStr})
|
||||
if cmd.Err() != nil {
|
||||
panic(cmd.Err())
|
||||
user["approver"] = 0
|
||||
colMap := models.MapJ2c[models.BackUser](user, false)
|
||||
ok, rowsAffected := models.Upsert[models.BackUser](colMap)
|
||||
if !ok || rowsAffected == 0 {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// ListRegister list the registers in the redis to be approved
|
||||
func ListRegister() *[]map[string]interface{} {
|
||||
applyStrMap := global.Redis.HGetAll(global.REGISTER_REDIS_KEY).Val()
|
||||
var applies []map[string]interface{}
|
||||
for _, v := range applyStrMap {
|
||||
var apply map[string]interface{}
|
||||
_ = json.Unmarshal([]byte(v), &apply)
|
||||
applies = append(applies, apply)
|
||||
func ListRegister(claims models.TokenClaims) *[]map[string]interface{} {
|
||||
registers := []map[string]interface{}{}
|
||||
tx := global.Db.Model(new(models.BackUser)).Omit("password")
|
||||
if claims.Region == "" {
|
||||
// do nothing
|
||||
} else if !strings.Contains(claims.Region, " ") {
|
||||
tx.Where("approver = 0 AND is_delete = 0 AND region LIKE ? AND role = ?", claims.Region+" %", global.ROLE_ID_MAP["ADMIN"])
|
||||
registers = *models.ListByOrm(tx)
|
||||
} else {
|
||||
tx.Where("approver = 0 AND is_delete = 0 AND region = ? AND role in ?", claims.Region, []int{global.ROLE_ID_MAP["WORKER"], global.ROLE_ID_MAP["VOLUNTEER"]})
|
||||
registers = *models.ListByOrm(tx)
|
||||
}
|
||||
if applies == nil {
|
||||
applies = []map[string]interface{}{}
|
||||
return ®isters
|
||||
}
|
||||
return &applies
|
||||
|
||||
// ListApprovedRegister list registers approved by the admin
|
||||
func ListApprovedRegister(claims models.TokenClaims) *[]map[string]interface{} {
|
||||
approvedRegisters := []map[string]interface{}{}
|
||||
tx := global.Db.Model(new(models.BackUser)).Omit("password").Where("approver in ? and is_delete = 0", []int{claims.ID, -claims.ID})
|
||||
approvedRegisters = *models.ListByOrm(tx)
|
||||
return &approvedRegisters
|
||||
}
|
||||
|
||||
// ApproveRegister approve a register
|
||||
func ApproveRegister(email string, pass bool) bool {
|
||||
if !pass {
|
||||
rowsAffected := global.Redis.HDel(global.REGISTER_REDIS_KEY, email).Val()
|
||||
return rowsAffected != 0
|
||||
func ApproveRegister(claims models.TokenClaims, email string, pass bool) bool {
|
||||
queryMap := []map[string]interface{}{{"email": email}}
|
||||
var approver int
|
||||
if pass {
|
||||
approver = claims.ID
|
||||
} else {
|
||||
approver = -claims.ID
|
||||
}
|
||||
// if pass, will get the register info from redis, and the insert into mysql, this mean user is register success
|
||||
applyStr := global.Redis.HGet(global.REGISTER_REDIS_KEY, email).Val()
|
||||
rowsAffected := global.Redis.HDel(global.REGISTER_REDIS_KEY, email).Val()
|
||||
if rowsAffected == 0 {
|
||||
updateMap := map[string]interface{}{"approver": approver}
|
||||
ok, rowsAffected := models.Update[models.BackUser](queryMap, updateMap)
|
||||
if !ok || rowsAffected == 0 {
|
||||
return false
|
||||
}
|
||||
var apply map[string]interface{}
|
||||
_ = json.Unmarshal([]byte(applyStr), &apply)
|
||||
if !NoDuplicatePhoneOrEmail(apply["phone"].(string), apply["email"].(string)) {
|
||||
return false
|
||||
}
|
||||
colMap := models.MapJ2c[models.BackUser](apply, true)
|
||||
ok, rowsAffected := models.Upsert[models.BackUser](colMap)
|
||||
return ok && rowsAffected != 0
|
||||
return true
|
||||
}
|
||||
|
||||
// ChangePassword user change password, or user forgot password
|
||||
|
||||
10
utils/json.go
Normal file
10
utils/json.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
)
|
||||
|
||||
func Strcut2Map[S any, T *map[string]interface{} | *[]map[string]interface{}](source S, target T) {
|
||||
jsonByte, _ := json.Marshal(source)
|
||||
json.Unmarshal(jsonByte, target)
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"nCovTrack-Backend/global"
|
||||
"nCovTrack-Backend/models"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/golang-jwt/jwt/v4"
|
||||
)
|
||||
|
||||
@@ -81,3 +84,9 @@ func ParseClaims(tokenStr string) jwt.MapClaims {
|
||||
}
|
||||
return token.Claims.(jwt.MapClaims)
|
||||
}
|
||||
|
||||
func ClaimsFromHeader(c *gin.Context) models.TokenClaims {
|
||||
var claims models.TokenClaims
|
||||
json.Unmarshal([]byte(c.Request.Header.Get("claims")), &claims)
|
||||
return claims
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user