Полная зачистка legacy + закрытие fix24.1/fix24.2 + обновление логотипа
This commit is contained in:
@@ -0,0 +1,321 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"hy2xs-admin/dao"
|
||||
"hy2xs-admin/model/bo"
|
||||
"hy2xs-admin/model/constant"
|
||||
"hy2xs-admin/model/dto"
|
||||
"hy2xs-admin/model/entity"
|
||||
"hy2xs-admin/model/vo"
|
||||
"hy2xs-admin/util"
|
||||
"time"
|
||||
)
|
||||
|
||||
func Login(username string, plainPassword string) (string, bool, error) {
|
||||
account, err := dao.GetAdminUser("username = ? and status = 1", username)
|
||||
if err != nil {
|
||||
return "", false, err
|
||||
}
|
||||
|
||||
verified, legacy := util.VerifyPassword(plainPassword, *account.PasswordHash)
|
||||
if !verified {
|
||||
return "", false, errors.New(constant.WrongPassword)
|
||||
}
|
||||
|
||||
if legacy {
|
||||
hash, hashErr := util.HashPassword(plainPassword)
|
||||
if hashErr == nil {
|
||||
_ = dao.UpdateAdminUser([]int64{*account.Id}, map[string]interface{}{"password_hash": hash})
|
||||
}
|
||||
}
|
||||
|
||||
accountBo := bo.AccountBo{
|
||||
Id: *account.Id,
|
||||
Username: *account.Username,
|
||||
Roles: []string{"admin"},
|
||||
Deleted: 0,
|
||||
}
|
||||
token, tokenErr := GenToken(accountBo)
|
||||
if tokenErr != nil {
|
||||
return "", false, tokenErr
|
||||
}
|
||||
|
||||
requirePasswordChange := legacy
|
||||
if account.ForcePasswordChange != nil {
|
||||
requirePasswordChange = *account.ForcePasswordChange != 0
|
||||
}
|
||||
return token, requirePasswordChange, nil
|
||||
}
|
||||
|
||||
func PagePeer(peerPageDto dto.PeerPageDto) ([]entity.Account, int64, error) {
|
||||
peers, total, err := dao.PagePeer(peerPageDto)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
accounts := make([]entity.Account, 0, len(peers))
|
||||
for _, p := range peers {
|
||||
role := "user"
|
||||
acc := entity.Account{
|
||||
BaseEntity: p.BaseEntity,
|
||||
Username: p.Name,
|
||||
ConPass: p.SecretCiphertext,
|
||||
Quota: p.QuotaBytes,
|
||||
Download: p.DownloadBytes,
|
||||
Upload: p.UploadBytes,
|
||||
ExpireTime: p.ExpiresAt,
|
||||
KickUtilTime: p.BannedUntil,
|
||||
DeviceNo: p.MaxDevices,
|
||||
Role: &role,
|
||||
Deleted: p.Disabled,
|
||||
ConAt: p.LastConnectionAt,
|
||||
Remark: p.Remark,
|
||||
}
|
||||
accounts = append(accounts, acc)
|
||||
}
|
||||
return accounts, total, nil
|
||||
}
|
||||
|
||||
func SavePeer(account entity.Account) error {
|
||||
if account.Username == nil || *account.Username == "" {
|
||||
return errors.New(constant.InvalidError)
|
||||
}
|
||||
secret := ""
|
||||
if account.ConPass != nil && *account.ConPass != "" {
|
||||
secret = *account.ConPass
|
||||
} else {
|
||||
generated, genErr := util.RandomString(24)
|
||||
if genErr != nil {
|
||||
return genErr
|
||||
}
|
||||
secret = fmt.Sprintf("%s.%s", *account.Username, generated)
|
||||
}
|
||||
authId, authErr := util.RandomString(18)
|
||||
if authErr != nil {
|
||||
return authErr
|
||||
}
|
||||
secretDigest := util.PeerSecretDigest(secret)
|
||||
peer := entity.Peer{
|
||||
Name: account.Username,
|
||||
Remark: account.Remark,
|
||||
AuthId: &authId,
|
||||
SecretDigest: &secretDigest,
|
||||
SecretCiphertext: &secret,
|
||||
QuotaBytes: account.Quota,
|
||||
ExpiresAt: account.ExpireTime,
|
||||
MaxDevices: account.DeviceNo,
|
||||
Disabled: account.Deleted,
|
||||
}
|
||||
_, err := dao.SavePeer(peer)
|
||||
return err
|
||||
}
|
||||
|
||||
func DeletePeer(ids []int64) error {
|
||||
return dao.DeletePeer(ids)
|
||||
}
|
||||
|
||||
func UpdatePeer(account entity.Account) error {
|
||||
updates := map[string]interface{}{}
|
||||
if account.Username != nil && *account.Username != "" {
|
||||
updates["username"] = *account.Username
|
||||
}
|
||||
_ = account.Pass
|
||||
if account.ConPass != nil && *account.ConPass != "" {
|
||||
updates["secret_ciphertext"] = *account.ConPass
|
||||
updates["secret_digest"] = util.PeerSecretDigest(*account.ConPass)
|
||||
}
|
||||
if account.Quota != nil {
|
||||
updates["quota_bytes"] = *account.Quota
|
||||
}
|
||||
if account.ExpireTime != nil {
|
||||
updates["expires_at"] = *account.ExpireTime
|
||||
}
|
||||
if account.Download != nil {
|
||||
updates["download_bytes"] = *account.Download
|
||||
}
|
||||
if account.Upload != nil {
|
||||
updates["upload_bytes"] = *account.Upload
|
||||
}
|
||||
if account.DeviceNo != nil {
|
||||
updates["max_devices"] = *account.DeviceNo
|
||||
}
|
||||
if account.Deleted != nil {
|
||||
updates["disabled"] = *account.Deleted
|
||||
}
|
||||
if account.LoginAt != nil && *account.LoginAt > 0 {
|
||||
updates["login_at"] = *account.LoginAt
|
||||
}
|
||||
if account.ConAt != nil && *account.ConAt > 0 {
|
||||
updates["last_connection_at"] = *account.ConAt
|
||||
}
|
||||
if account.Remark != nil {
|
||||
updates["remark"] = *account.Remark
|
||||
}
|
||||
return dao.UpdatePeer([]int64{*account.Id}, updates)
|
||||
}
|
||||
|
||||
func ResetTraffic(id int64) error {
|
||||
return dao.UpdatePeer([]int64{id}, map[string]interface{}{"download_bytes": 0, "upload_bytes": 0})
|
||||
}
|
||||
|
||||
func ExistPeerName(username string, id int64) bool {
|
||||
var err error
|
||||
if id != 0 {
|
||||
_, err = dao.GetPeer("name = ? and id != ?", username, id)
|
||||
} else {
|
||||
_, err = dao.GetPeer("name = ?", username)
|
||||
}
|
||||
if err != nil {
|
||||
if err.Error() == constant.WrongPassword {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func GetPeer(id int64) (entity.Account, error) {
|
||||
peer, err := dao.GetPeer("id = ?", id)
|
||||
if err != nil {
|
||||
return entity.Account{}, err
|
||||
}
|
||||
role := "user"
|
||||
return entity.Account{
|
||||
BaseEntity: peer.BaseEntity,
|
||||
Username: peer.Name,
|
||||
ConPass: peer.SecretCiphertext,
|
||||
Quota: peer.QuotaBytes,
|
||||
Download: peer.DownloadBytes,
|
||||
Upload: peer.UploadBytes,
|
||||
ExpireTime: peer.ExpiresAt,
|
||||
DeviceNo: peer.MaxDevices,
|
||||
KickUtilTime: peer.BannedUntil,
|
||||
ConAt: peer.LastConnectionAt,
|
||||
Deleted: peer.Disabled,
|
||||
Remark: peer.Remark,
|
||||
Role: &role,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func GetAdminAccount(id int64) (entity.AdminUser, error) {
|
||||
return dao.GetAdminUser("id = ?", id)
|
||||
}
|
||||
|
||||
func ListExportPeer() ([]bo.AccountExport, error) {
|
||||
peers, err := dao.ListPeer("1=1")
|
||||
if err != nil {
|
||||
return nil, errors.New(constant.SysError)
|
||||
}
|
||||
var accountExports []bo.AccountExport
|
||||
for _, item := range peers {
|
||||
role := "user"
|
||||
conPass := ""
|
||||
if item.SecretCiphertext != nil {
|
||||
conPass = *item.SecretCiphertext
|
||||
}
|
||||
accountExport := bo.AccountExport{
|
||||
Id: *item.Id,
|
||||
Username: *item.Name,
|
||||
Pass: "",
|
||||
ConPass: conPass,
|
||||
Quota: *item.QuotaBytes,
|
||||
Download: *item.DownloadBytes,
|
||||
Upload: *item.UploadBytes,
|
||||
ExpireTime: *item.ExpiresAt,
|
||||
DeviceNo: *item.MaxDevices,
|
||||
KickUtilTime: *item.BannedUntil,
|
||||
Role: role,
|
||||
Deleted: *item.Disabled,
|
||||
CreateTime: *item.CreateTime,
|
||||
UpdateTime: *item.UpdateTime,
|
||||
LoginAt: 0,
|
||||
ConAt: *item.LastConnectionAt,
|
||||
Remark: *item.Remark,
|
||||
}
|
||||
accountExports = append(accountExports, accountExport)
|
||||
}
|
||||
return accountExports, nil
|
||||
}
|
||||
|
||||
func ReleaseKickPeer(id int64) error {
|
||||
return dao.UpdatePeer([]int64{id}, map[string]interface{}{"banned_until": 0})
|
||||
}
|
||||
|
||||
func UpsertPeer(accounts []entity.Account) error {
|
||||
for _, account := range accounts {
|
||||
if account.Id != nil && *account.Id > 0 {
|
||||
if err := UpdatePeer(account); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
if err := SavePeer(account); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetAdminInfo(c *gin.Context) (vo.AccountInfoVo, error) {
|
||||
myClaims, err := ParseToken(GetToken(c))
|
||||
if err != nil {
|
||||
return vo.AccountInfoVo{}, err
|
||||
}
|
||||
if myClaims.Admin.Deleted != 0 {
|
||||
return vo.AccountInfoVo{}, errors.New("this account has been disabled")
|
||||
}
|
||||
admin, err := dao.GetAdminUser("id = ?", myClaims.Admin.Id)
|
||||
if err != nil {
|
||||
return vo.AccountInfoVo{}, err
|
||||
}
|
||||
if admin.Status != nil && *admin.Status == 0 {
|
||||
return vo.AccountInfoVo{}, errors.New("this account has been disabled")
|
||||
}
|
||||
return vo.AccountInfoVo{
|
||||
Id: myClaims.Admin.Id,
|
||||
Username: myClaims.Admin.Username,
|
||||
Roles: myClaims.Admin.Roles,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func UpdatePeerLastConnectionAt(id int64, conAt int64) error {
|
||||
return dao.UpdatePeer([]int64{id}, map[string]interface{}{"last_connection_at": conAt})
|
||||
}
|
||||
|
||||
func UpdateAdminLastLoginAt(id int64, loginAt int64) error {
|
||||
return dao.UpdateAdminUser([]int64{id}, map[string]interface{}{"last_login_at": loginAt})
|
||||
}
|
||||
|
||||
func ChangeAdminPassword(c *gin.Context, oldPassword string, newPassword string) error {
|
||||
info, err := GetAdminInfo(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
admin, err := dao.GetAdminUser("id = ?", info.Id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if admin.PasswordHash == nil {
|
||||
return errors.New(constant.SysError)
|
||||
}
|
||||
verified, _ := util.VerifyPassword(oldPassword, *admin.PasswordHash)
|
||||
if !verified {
|
||||
return errors.New(constant.WrongPassword)
|
||||
}
|
||||
hash, hashErr := util.HashPassword(newPassword)
|
||||
if hashErr != nil {
|
||||
return hashErr
|
||||
}
|
||||
nowMs := time.Now().UnixMilli()
|
||||
currentTokenVersion := int64(1)
|
||||
if admin.TokenVersion != nil && *admin.TokenVersion > 0 {
|
||||
currentTokenVersion = *admin.TokenVersion
|
||||
}
|
||||
return dao.UpdateAdminUser([]int64{info.Id}, map[string]interface{}{
|
||||
"password_hash": hash,
|
||||
"force_password_change": 0,
|
||||
"password_changed_at": nowMs,
|
||||
"token_version": currentTokenVersion + 1,
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user