2022-11-11 15:35:02 +08:00
package model
import (
"errors"
"message-pusher/common"
2022-11-22 11:04:06 +08:00
"strings"
2022-11-11 15:35:02 +08:00
)
2022-11-22 11:04:06 +08:00
// User if you add sensitive fields, don't forget to clean them in setupLogin function.
// Otherwise, the sensitive information will be saved on local storage in plain text!
2022-11-11 15:35:02 +08:00
type User struct {
2022-11-11 22:05:31 +08:00
Id int `json:"id"`
Username string `json:"username" gorm:"unique;index" validate:"max=12"`
Password string `json:"password" gorm:"not null;" validate:"min=8,max=20"`
DisplayName string `json:"display_name" gorm:"index" validate:"max=20"`
Role int `json:"role" gorm:"type:int;default:1"` // admin, common
Status int `json:"status" gorm:"type:int;default:1"` // enabled, disabled
2022-11-22 17:52:44 +08:00
Token string `json:"token"`
2022-11-11 22:05:31 +08:00
Email string `json:"email" gorm:"index" validate:"max=50"`
GitHubId string `json:"github_id" gorm:"column:github_id;index"`
WeChatId string `json:"wechat_id" gorm:"column:wechat_id;index"`
2022-11-22 11:04:06 +08:00
VerificationCode string `json:"verification_code" gorm:"-:all"` // this field is only for Email verification, don't save it to database!
2022-11-11 22:05:31 +08:00
Channel string `json:"channel"`
WeChatTestAccountId string `json:"wechat_test_account_id" gorm:"column:wechat_test_account_id"`
WeChatTestAccountSecret string `json:"wechat_test_account_secret" gorm:"column:wechat_test_account_secret"`
WeChatTestAccountTemplateId string `json:"wechat_test_account_template_id" gorm:"column:wechat_test_account_template_id"`
WeChatTestAccountOpenId string `json:"wechat_test_account_open_id" gorm:"column:wechat_test_account_open_id"`
WeChatTestAccountVerificationToken string `json:"wechat_test_account_verification_token" gorm:"column:wechat_test_account_verification_token"`
WeChatCorpAccountId string `json:"wechat_corp_account_id" gorm:"column:wechat_corp_account_id"`
2022-11-22 17:52:44 +08:00
WeChatCorpAccountAgentSecret string `json:"wechat_corp_account_agent_secret" gorm:"column:wechat_corp_account_agent_secret"`
2022-11-11 22:05:31 +08:00
WeChatCorpAccountAgentId string `json:"wechat_corp_account_agent_id" gorm:"column:wechat_corp_account_agent_id"`
WeChatCorpAccountUserId string `json:"wechat_corp_account_user_id" gorm:"column:wechat_corp_account_user_id"`
2022-11-22 17:52:44 +08:00
WeChatCorpAccountClientType string `json:"wechat_corp_account_client_type" gorm:"column:wechat_corp_account_client_type;default=plugin"`
2022-11-25 12:04:36 +08:00
CorpWebhookURL string `json:"corp_webhook_url" gorm:"corp_webhook_url"`
2022-11-22 09:09:15 +08:00
LarkWebhookURL string `json:"lark_webhook_url"`
LarkWebhookSecret string `json:"lark_webhook_secret"`
2022-11-22 09:50:50 +08:00
DingWebhookURL string `json:"ding_webhook_url"`
DingWebhookSecret string `json:"ding_webhook_secret"`
2022-11-23 17:30:49 +08:00
BarkServer string `json:"bark_server"`
BarkSecret string `json:"bark_secret"`
2022-12-07 16:06:36 +08:00
ClientSecret string `json:"client_secret"`
2022-12-21 18:33:00 +08:00
TelegramBotToken string `json:"telegram_bot_token"`
TelegramChatId string `json:"telegram_chat_id"`
2023-01-10 18:32:04 +08:00
DiscordWebhookURL string `json:"discord_webhook_url"`
2022-11-11 15:35:02 +08:00
}
func GetMaxUserId () int {
var user User
DB . Last ( & user )
return user . Id
}
2022-11-22 11:04:06 +08:00
func GetAllUsers ( startIdx int , num int ) ( users [] * User , err error ) {
err = DB . Order ( "id desc" ). Limit ( num ). Offset ( startIdx ). Select ([] string { "id" , "username" , "display_name" , "role" , "status" , "email" }). Find ( & users ). Error
2022-11-11 15:35:02 +08:00
return users , err
}
2022-11-18 17:17:53 +08:00
func GetAllUsersWithSecrets () ( users [] * User , err error ) {
2022-12-15 11:31:27 +08:00
err = DB . Where ( "status = ?" , common . UserStatusEnabled ). Where ( "wechat_test_account_id != '' or wechat_corp_account_id != ''" ). Find ( & users ). Error
2022-11-18 17:17:53 +08:00
return users , err
}
2022-11-11 15:35:02 +08:00
func SearchUsers ( keyword string ) ( users [] * User , err error ) {
err = DB . Select ([] string { "id" , "username" , "display_name" , "role" , "status" , "email" }). Where ( "id = ? or username LIKE ? or email LIKE ? or display_name LIKE ?" , keyword , keyword + "%" , keyword + "%" , keyword + "%" ). Find ( & users ). Error
return users , err
}
func GetUserById ( id int , selectAll bool ) ( * User , error ) {
2022-11-25 16:48:20 +08:00
if id == 0 {
return nil , errors . New ( "id 为空!" )
}
2022-11-11 15:35:02 +08:00
user := User { Id : id }
var err error = nil
if selectAll {
err = DB . First ( & user , "id = ?" , id ). Error
} else {
2022-11-22 17:52:44 +08:00
err = DB . Select ([] string { "id" , "username" , "display_name" , "role" , "status" , "email" , "wechat_id" , "github_id" ,
"channel" , "token" ,
"wechat_test_account_id" , "wechat_test_account_template_id" , "wechat_test_account_open_id" ,
"wechat_corp_account_id" , "wechat_corp_account_agent_id" , "wechat_corp_account_user_id" , "wechat_corp_account_client_type" ,
2023-01-10 18:32:04 +08:00
"corp_webhook_url" , "lark_webhook_url" , "ding_webhook_url" , "bark_server" , "telegram_chat_id" , "discord_webhook_url" ,
2022-11-22 17:52:44 +08:00
}). First ( & user , "id = ?" , id ). Error
2022-11-11 15:35:02 +08:00
}
return & user , err
}
func DeleteUserById ( id int ) ( err error ) {
2022-11-25 16:48:20 +08:00
if id == 0 {
return errors . New ( "id 为空!" )
}
2022-11-11 15:35:02 +08:00
user := User { Id : id }
2022-11-22 12:44:41 +08:00
return user . Delete ()
2022-11-11 15:35:02 +08:00
}
func ( user * User ) Insert () error {
var err error
if user . Password != "" {
user . Password , err = common . Password2Hash ( user . Password )
if err != nil {
return err
}
}
err = DB . Create ( user ). Error
return err
}
func ( user * User ) Update ( updatePassword bool ) error {
var err error
if updatePassword {
user . Password , err = common . Password2Hash ( user . Password )
if err != nil {
return err
}
}
err = DB . Model ( user ). Updates ( user ). Error
return err
}
func ( user * User ) Delete () error {
2022-11-25 16:48:20 +08:00
if user . Id == 0 {
return errors . New ( "id 为空!" )
}
2022-11-22 12:44:41 +08:00
err := DB . Delete ( user ). Error
2022-11-11 15:35:02 +08:00
return err
}
// ValidateAndFill check password & user status
func ( user * User ) ValidateAndFill () ( err error ) {
// When querying with struct, GORM will only query with non-zero fields,
// that means if your field’ s value is 0, '', false or other zero values,
// it won’ t be used to build query conditions
password := user . Password
2022-11-25 16:48:20 +08:00
if user . Username == "" || password == "" {
return errors . New ( "用户名或密码为空" )
2022-11-22 11:04:06 +08:00
}
2022-11-11 15:35:02 +08:00
DB . Where ( User { Username : user . Username }). First ( user )
okay := common . ValidatePasswordAndHash ( password , user . Password )
if ! okay || user . Status != common . UserStatusEnabled {
2022-11-22 11:04:06 +08:00
return errors . New ( "用户名或密码错误,或用户已被封禁" )
2022-11-11 15:35:02 +08:00
}
return nil
}
2022-11-25 16:48:20 +08:00
func ( user * User ) FillUserById () error {
if user . Id == 0 {
return errors . New ( "id 为空!" )
}
2022-11-11 15:35:02 +08:00
DB . Where ( User { Id : user . Id }). First ( user )
2022-11-25 16:48:20 +08:00
return nil
2022-11-11 15:35:02 +08:00
}
2022-11-25 16:48:20 +08:00
func ( user * User ) FillUserByEmail () error {
if user . Email == "" {
return errors . New ( "email 为空!" )
}
2022-11-11 15:35:02 +08:00
DB . Where ( User { Email : user . Email }). First ( user )
2022-11-25 16:48:20 +08:00
return nil
2022-11-11 15:35:02 +08:00
}
2022-11-25 16:48:20 +08:00
func ( user * User ) FillUserByGitHubId () error {
if user . GitHubId == "" {
return errors . New ( "GitHub id 为空!" )
}
2022-11-11 15:35:02 +08:00
DB . Where ( User { GitHubId : user . GitHubId }). First ( user )
2022-11-25 16:48:20 +08:00
return nil
2022-11-11 15:35:02 +08:00
}
2022-11-25 16:48:20 +08:00
func ( user * User ) FillUserByWeChatId () error {
if user . WeChatId == "" {
return errors . New ( "WeChat id 为空!" )
}
2022-11-11 15:35:02 +08:00
DB . Where ( User { WeChatId : user . WeChatId }). First ( user )
2022-11-25 16:48:20 +08:00
return nil
2022-11-11 15:35:02 +08:00
}
2022-11-25 16:48:20 +08:00
func ( user * User ) FillUserByUsername () error {
if user . Username == "" {
return errors . New ( "username 为空!" )
}
2022-11-11 15:35:02 +08:00
DB . Where ( User { Username : user . Username }). First ( user )
2022-11-25 16:48:20 +08:00
return nil
2022-11-11 15:35:02 +08:00
}
2022-11-22 11:04:06 +08:00
func ValidateUserToken ( token string ) ( user * User ) {
if token == "" {
return nil
}
token = strings . Replace ( token , "Bearer " , "" , 1 )
user = & User {}
if DB . Where ( "token = ?" , token ). First ( user ). RowsAffected == 1 {
return user
}
return nil
}
2022-11-11 15:35:02 +08:00
func IsEmailAlreadyTaken ( email string ) bool {
return DB . Where ( "email = ?" , email ). Find ( & User {}). RowsAffected == 1
}
func IsWeChatIdAlreadyTaken ( wechatId string ) bool {
return DB . Where ( "wechat_id = ?" , wechatId ). Find ( & User {}). RowsAffected == 1
}
func IsGitHubIdAlreadyTaken ( githubId string ) bool {
return DB . Where ( "github_id = ?" , githubId ). Find ( & User {}). RowsAffected == 1
}
func IsUsernameAlreadyTaken ( username string ) bool {
return DB . Where ( "username = ?" , username ). Find ( & User {}). RowsAffected == 1
}
func ResetUserPasswordByEmail ( email string , password string ) error {
2022-11-25 16:48:20 +08:00
if email == "" || password == "" {
return errors . New ( "邮箱地址或密码为空!" )
}
2022-11-11 15:35:02 +08:00
hashedPassword , err := common . Password2Hash ( password )
if err != nil {
return err
}
err = DB . Model ( & User {}). Where ( "email = ?" , email ). Update ( "password" , hashedPassword ). Error
return err
}