| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651 | package controllerimport (	"encoding/json"	"github.com/gin-contrib/sessions"	"github.com/gin-gonic/gin"	"github.com/google/uuid"	"message-pusher/channel"	"message-pusher/common"	"message-pusher/model"	"net/http"	"strconv"	"strings")type LoginRequest struct {	Username string `json:"username"`	Password string `json:"password"`}func Login(c *gin.Context) {	if !common.PasswordLoginEnabled {		c.JSON(http.StatusOK, gin.H{			"message": "管理员关闭了密码登录",			"success": false,		})		return	}	var loginRequest LoginRequest	err := json.NewDecoder(c.Request.Body).Decode(&loginRequest)	if err != nil {		c.JSON(http.StatusOK, gin.H{			"message": "无效的参数",			"success": false,		})		return	}	username := loginRequest.Username	password := loginRequest.Password	if username == "" || password == "" {		c.JSON(http.StatusOK, gin.H{			"message": "无效的参数",			"success": false,		})		return	}	user := model.User{		Username: username,		Password: password,	}	err = user.ValidateAndFill()	if err != nil {		c.JSON(http.StatusOK, gin.H{			"message": err.Error(),			"success": false,		})		return	}	setupLogin(&user, c)}// setup session & cookies and then return user infofunc setupLogin(user *model.User, c *gin.Context) {	session := sessions.Default(c)	session.Set("id", user.Id)	session.Set("username", user.Username)	session.Set("role", user.Role)	session.Set("status", user.Status)	err := session.Save()	if err != nil {		c.JSON(http.StatusOK, gin.H{			"message": "无法保存会话信息,请重试",			"success": false,		})		return	}	user.Password = ""	user.Token = ""	c.JSON(http.StatusOK, gin.H{		"message": "",		"success": true,		"data":    user,	})}func Logout(c *gin.Context) {	session := sessions.Default(c)	session.Clear()	err := session.Save()	if err != nil {		c.JSON(http.StatusOK, gin.H{			"message": err.Error(),			"success": false,		})		return	}	c.JSON(http.StatusOK, gin.H{		"message": "",		"success": true,	})}func Register(c *gin.Context) {	if !common.RegisterEnabled {		c.JSON(http.StatusOK, gin.H{			"message": "管理员关闭了新用户注册",			"success": false,		})		return	}	if !common.PasswordRegisterEnabled {		c.JSON(http.StatusOK, gin.H{			"message": "管理员关闭了通过密码进行注册,请使用第三方账户验证的形式进行注册",			"success": false,		})		return	}	var user model.User	err := json.NewDecoder(c.Request.Body).Decode(&user)	if err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": "无效的参数",		})		return	}	if err := common.Validate.Struct(&user); err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": "输入不合法 " + err.Error(),		})		return	}	if common.EmailVerificationEnabled {		if user.Email == "" || user.VerificationCode == "" {			c.JSON(http.StatusOK, gin.H{				"success": false,				"message": "管理员开启了邮箱验证,请输入邮箱地址和验证码",			})			return		}		if !common.VerifyCodeWithKey(user.Email, user.VerificationCode, common.EmailVerificationPurpose) {			c.JSON(http.StatusOK, gin.H{				"success": false,				"message": "验证码错误或已过期",			})			return		}	}	cleanUser := model.User{		Username:    user.Username,		Password:    user.Password,		DisplayName: user.Username,	}	if common.EmailVerificationEnabled {		cleanUser.Email = user.Email	}	if err := cleanUser.Insert(); err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": err.Error(),		})		return	}	c.JSON(http.StatusOK, gin.H{		"success": true,		"message": "",	})	return}func GetAllUsers(c *gin.Context) {	p, _ := strconv.Atoi(c.Query("p"))	if p < 0 {		p = 0	}	users, err := model.GetAllUsers(p*common.ItemsPerPage, common.ItemsPerPage)	if err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": err.Error(),		})		return	}	c.JSON(http.StatusOK, gin.H{		"success": true,		"message": "",		"data":    users,	})	return}func SearchUsers(c *gin.Context) {	keyword := c.Query("keyword")	users, err := model.SearchUsers(keyword)	if err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": err.Error(),		})		return	}	c.JSON(http.StatusOK, gin.H{		"success": true,		"message": "",		"data":    users,	})	return}func GetUser(c *gin.Context) {	id, err := strconv.Atoi(c.Param("id"))	if err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": err.Error(),		})		return	}	user, err := model.GetUserById(id, false)	if err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": err.Error(),		})		return	}	myRole := c.GetInt("role")	if myRole <= user.Role {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": "无权获取同级或更高等级用户的信息",		})		return	}	c.JSON(http.StatusOK, gin.H{		"success": true,		"message": "",		"data":    user,	})	return}func GenerateToken(c *gin.Context) {	id := c.GetInt("id")	user, err := model.GetUserById(id, true)	if err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": err.Error(),		})		return	}	user.Token = uuid.New().String()	user.Token = strings.Replace(user.Token, "-", "", -1)	if model.DB.Where("token = ?", user.Token).First(user).RowsAffected != 0 {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": "请重试,系统生成的 UUID 竟然重复了!",		})		return	}	if err := user.Update(false); err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": err.Error(),		})		return	}	c.JSON(http.StatusOK, gin.H{		"success": true,		"message": "",		"data":    user.Token,	})	return}func GetSelf(c *gin.Context) {	id := c.GetInt("id")	user, err := model.GetUserById(id, false)	if err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": err.Error(),		})		return	}	c.JSON(http.StatusOK, gin.H{		"success": true,		"message": "",		"data":    user,	})	return}func UpdateUser(c *gin.Context) {	var updatedUser model.User	err := json.NewDecoder(c.Request.Body).Decode(&updatedUser)	if err != nil || updatedUser.Id == 0 {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": "无效的参数",		})		return	}	if updatedUser.Password == "" {		updatedUser.Password = "$I_LOVE_U" // make Validator happy :)	}	if err := common.Validate.Struct(&updatedUser); err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": "输入不合法 " + err.Error(),		})		return	}	originUser, err := model.GetUserById(updatedUser.Id, false)	if err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": err.Error(),		})		return	}	myRole := c.GetInt("role")	if myRole <= originUser.Role {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": "无权更新同权限等级或更高权限等级的用户信息",		})		return	}	if myRole <= updatedUser.Role {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": "无权将其他用户权限等级提升到大于等于自己的权限等级",		})		return	}	if updatedUser.Password == "$I_LOVE_U" {		updatedUser.Password = "" // rollback to what it should be	}	// We only allow admin change those fields.	cleanUser := model.User{		Id:          updatedUser.Id,		Username:    updatedUser.Username,		Password:    updatedUser.Password,		DisplayName: updatedUser.DisplayName,	}	updatePassword := cleanUser.Password != ""	if err := cleanUser.Update(updatePassword); err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": err.Error(),		})		return	}	c.JSON(http.StatusOK, gin.H{		"success": true,		"message": "",	})	return}func UpdateSelf(c *gin.Context) {	var user model.User	err := json.NewDecoder(c.Request.Body).Decode(&user)	if err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": "无效的参数",		})		return	}	if user.Password == "" {		user.Password = "$I_LOVE_U" // make Validator happy :)	}	if err := common.Validate.Struct(&user); err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": "输入不合法 " + err.Error(),		})		return	}	originUser, err := model.GetUserById(c.GetInt("id"), true)	if err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": err.Error(),		})		return	}	cleanUser := model.User{		Id:                                 c.GetInt("id"),		Username:                           user.Username,		Password:                           user.Password,		DisplayName:                        user.DisplayName,		Token:                              user.Token,		Channel:                            user.Channel,		WeChatTestAccountId:                user.WeChatTestAccountId,		WeChatTestAccountSecret:            user.WeChatTestAccountSecret,		WeChatTestAccountTemplateId:        user.WeChatTestAccountTemplateId,		WeChatTestAccountOpenId:            user.WeChatTestAccountOpenId,		WeChatTestAccountVerificationToken: user.WeChatTestAccountVerificationToken,		WeChatCorpAccountId:                user.WeChatCorpAccountId,		WeChatCorpAccountAgentSecret:       user.WeChatCorpAccountAgentSecret,		WeChatCorpAccountAgentId:           user.WeChatCorpAccountAgentId,		WeChatCorpAccountUserId:            user.WeChatCorpAccountUserId,		WeChatCorpAccountClientType:        user.WeChatCorpAccountClientType,		LarkWebhookURL:                     user.LarkWebhookURL,		LarkWebhookSecret:                  user.LarkWebhookSecret,		DingWebhookURL:                     user.DingWebhookURL,		DingWebhookSecret:                  user.DingWebhookSecret,		BarkServer:                         user.BarkServer,		BarkSecret:                         user.BarkSecret,	}	channel.TokenStoreUpdateUser(&cleanUser, originUser)	if user.Password == "$I_LOVE_U" {		user.Password = "" // rollback to what it should be		cleanUser.Password = ""	}	updatePassword := user.Password != ""	if err := cleanUser.Update(updatePassword); err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": err.Error(),		})		return	}	c.JSON(http.StatusOK, gin.H{		"success": true,		"message": "",	})	return}func DeleteUser(c *gin.Context) {	id, err := strconv.Atoi(c.Param("id"))	if err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": err.Error(),		})		return	}	originUser, err := model.GetUserById(id, false)	if err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": err.Error(),		})		return	}	myRole := c.GetInt("role")	if myRole <= originUser.Role {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": "无权删除同权限等级或更高权限等级的用户",		})		return	}	channel.TokenStoreRemoveUser(originUser)	err = model.DeleteUserById(id)	if err != nil {		c.JSON(http.StatusOK, gin.H{			"success": true,			"message": "",		})		return	}}func DeleteSelf(c *gin.Context) {	id := c.GetInt("id")	user := model.User{Id: id}	user.FillUserById()	channel.TokenStoreRemoveUser(&user)	err := model.DeleteUserById(id)	if err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": err.Error(),		})		return	}	c.JSON(http.StatusOK, gin.H{		"success": true,		"message": "",	})	return}func CreateUser(c *gin.Context) {	var user model.User	err := json.NewDecoder(c.Request.Body).Decode(&user)	if err != nil || user.Username == "" || user.Password == "" {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": "无效的参数",		})		return	}	if user.DisplayName == "" {		user.DisplayName = user.Username	}	myRole := c.GetInt("role")	if user.Role >= myRole {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": "无法创建权限大于等于自己的用户",		})		return	}	// Even for admin users, we cannot fully trust them!	cleanUser := model.User{		Username:    user.Username,		Password:    user.Password,		DisplayName: user.DisplayName,	}	if err := cleanUser.Insert(); err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": err.Error(),		})		return	}	c.JSON(http.StatusOK, gin.H{		"success": true,		"message": "",	})	return}type ManageRequest struct {	Username string `json:"username"`	Action   string `json:"action"`}// ManageUser Only admin user can do thisfunc ManageUser(c *gin.Context) {	var req ManageRequest	err := json.NewDecoder(c.Request.Body).Decode(&req)	if err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": "无效的参数",		})		return	}	user := model.User{		Username: req.Username,	}	// Fill attributes	model.DB.Where(&user).First(&user)	if user.Id == 0 {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": "用户不存在",		})		return	}	myRole := c.GetInt("role")	if myRole <= user.Role {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": "无权更新同权限等级或更高权限等级的用户信息",		})		return	}	switch req.Action {	case "disable":		user.Status = common.UserStatusDisabled	case "enable":		user.Status = common.UserStatusEnabled	case "delete":		if err := user.Delete(); err != nil {			c.JSON(http.StatusOK, gin.H{				"success": false,				"message": err.Error(),			})			return		}	case "promote":		if myRole != common.RoleRootUser {			c.JSON(http.StatusOK, gin.H{				"success": false,				"message": "普通管理员用户无法提升其他用户为管理员",			})			return		}		user.Role = common.RoleAdminUser	case "demote":		user.Role = common.RoleCommonUser	}	if err := user.Update(false); err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": err.Error(),		})		return	}	clearUser := model.User{		Role:   user.Role,		Status: user.Status,	}	c.JSON(http.StatusOK, gin.H{		"success": true,		"message": "",		"data":    clearUser,	})	return}func EmailBind(c *gin.Context) {	email := c.Query("email")	code := c.Query("code")	if !common.VerifyCodeWithKey(email, code, common.EmailVerificationPurpose) {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": "验证码错误或已过期",		})		return	}	id := c.GetInt("id")	user := model.User{		Id: id,	}	user.FillUserById()	user.Email = email	// no need to check if this email already taken, because we have used verification code to check it	err := user.Update(false)	if err != nil {		c.JSON(http.StatusOK, gin.H{			"success": false,			"message": err.Error(),		})		return	}	c.JSON(http.StatusOK, gin.H{		"success": true,		"message": "",	})	return}
 |