dev (#239)
* 优化图标和LOGO * 修改登录页面动画的速度为3 * 增加对websocket的异常处理 * 修复了用户组和用户名唯一判断错误的问题 * 提示版本号 * 修复readme错别字 * 修复单词拼写错误的问题 * 修复代码格式 * 修改Windows资产属性名称 * Docker 打包流程增加 upx 压缩 * 升级依赖文件,修改sqlite驱动为 github.com/glebarez/sqlite * 修复第一次查询「授权令牌」的错误 * 移除无关代码 * 修改docker打包脚本 * 增加打包脚本 * 增加微信群 * 修复单词拼写错误的问题 * 修复代码格式 * 修改Windows资产属性名称 * Docker 打包流程增加 upx 压缩 * 修改docker打包脚本 * - 替换 sqlite 驱动为 github.com/glebarez/sqlite - 修复数据库锁定的问题 - 修复部分代码不完善的问题 - 修复策略显示不完整的问题 - 修复编辑文件换行符的问题 - 优化guacd连接
This commit is contained in:
@ -19,14 +19,9 @@ type accessTokenService struct {
|
||||
baseService
|
||||
}
|
||||
|
||||
func (service accessTokenService) FindByUserId(userId string) (model.AccessToken, error) {
|
||||
return repository.AccessTokenRepository.FindByUserId(context.TODO(), userId)
|
||||
}
|
||||
|
||||
func (service accessTokenService) GenAccessToken(userId string) error {
|
||||
return env.GetDB().Transaction(func(tx *gorm.DB) error {
|
||||
ctx := service.Context(tx)
|
||||
|
||||
user, err := repository.UserRepository.FindById(ctx, userId)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -119,7 +119,7 @@ func (s assetService) FindByIdAndDecrypt(c context.Context, id string) (model.As
|
||||
func (s assetService) CheckStatus(accessGatewayId string, ip string, port int) (active bool, err error) {
|
||||
if accessGatewayId != "" && accessGatewayId != "-" {
|
||||
g, e1 := GatewayService.GetGatewayAndReconnectById(accessGatewayId)
|
||||
if err != nil {
|
||||
if e1 != nil {
|
||||
return false, e1
|
||||
}
|
||||
|
||||
@ -141,7 +141,7 @@ func (s assetService) CheckStatus(accessGatewayId string, ip string, port int) (
|
||||
return active, err
|
||||
}
|
||||
|
||||
func (s assetService) Create(m echo.Map) (model.Asset, error) {
|
||||
func (s assetService) Create(ctx context.Context, m echo.Map) (model.Asset, error) {
|
||||
|
||||
data, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
@ -156,29 +156,36 @@ func (s assetService) Create(m echo.Map) (model.Asset, error) {
|
||||
item.Created = utils.NowJsonTime()
|
||||
item.Active = true
|
||||
|
||||
return item, env.GetDB().Transaction(func(tx *gorm.DB) error {
|
||||
c := s.Context(tx)
|
||||
if s.InTransaction(ctx) {
|
||||
return item, s.create(ctx, item, m)
|
||||
} else {
|
||||
return item, env.GetDB().Transaction(func(tx *gorm.DB) error {
|
||||
c := s.Context(tx)
|
||||
return s.create(c, item, m)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
if err := s.Encrypt(&item, config.GlobalCfg.EncryptionPassword); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := repository.AssetRepository.Create(c, &item); err != nil {
|
||||
return err
|
||||
}
|
||||
func (s assetService) create(c context.Context, item model.Asset, m echo.Map) error {
|
||||
if err := s.Encrypt(&item, config.GlobalCfg.EncryptionPassword); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := repository.AssetRepository.Create(c, &item); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := repository.AssetRepository.UpdateAttributes(c, item.ID, item.Protocol, m); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := repository.AssetRepository.UpdateAttributes(c, item.ID, item.Protocol, m); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
go func() {
|
||||
active, _ := s.CheckStatus(item.AccessGatewayId, item.IP, item.Port)
|
||||
|
||||
if item.Active != active {
|
||||
_ = repository.AssetRepository.UpdateActiveById(context.TODO(), active, item.ID)
|
||||
}
|
||||
}()
|
||||
return nil
|
||||
})
|
||||
//go func() {
|
||||
// active, _ := s.CheckStatus(item.AccessGatewayId, item.IP, item.Port)
|
||||
//
|
||||
// if item.Active != active {
|
||||
// _ = repository.AssetRepository.UpdateActiveById(context.TODO(), active, item.ID)
|
||||
// }
|
||||
//}()
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s assetService) DeleteById(id string) error {
|
||||
|
@ -128,12 +128,12 @@ func (service backupService) Export() (error, *dto.Backup) {
|
||||
|
||||
func (service backupService) Import(backup *dto.Backup) error {
|
||||
return env.GetDB().Transaction(func(tx *gorm.DB) error {
|
||||
c := service.Context(tx)
|
||||
ctx := service.Context(tx)
|
||||
var userIdMapping = make(map[string]string)
|
||||
if len(backup.Users) > 0 {
|
||||
for _, item := range backup.Users {
|
||||
oldId := item.ID
|
||||
exist, err := repository.UserRepository.ExistByUsername(c, item.Username)
|
||||
exist, err := repository.UserRepository.ExistByUsername(ctx, item.Username)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -144,7 +144,7 @@ func (service backupService) Import(backup *dto.Backup) error {
|
||||
newId := utils.UUID()
|
||||
item.ID = newId
|
||||
item.Password = utils.GenPassword()
|
||||
if err := repository.UserRepository.Create(c, &item); err != nil {
|
||||
if err := repository.UserRepository.Create(ctx, &item); err != nil {
|
||||
return err
|
||||
}
|
||||
userIdMapping[oldId] = newId
|
||||
@ -163,7 +163,7 @@ func (service backupService) Import(backup *dto.Backup) error {
|
||||
}
|
||||
}
|
||||
|
||||
userGroup, err := UserGroupService.Create(item.Name, members)
|
||||
userGroup, err := UserGroupService.Create(ctx, item.Name, members)
|
||||
if err != nil {
|
||||
if errors.Is(constant.ErrNameAlreadyUsed, err) {
|
||||
// 删除名称重复的用户组
|
||||
@ -187,7 +187,7 @@ func (service backupService) Import(backup *dto.Backup) error {
|
||||
item.ID = utils.UUID()
|
||||
item.Owner = owner
|
||||
item.Created = utils.NowJsonTime()
|
||||
if err := repository.StorageRepository.Create(c, &item); err != nil {
|
||||
if err := repository.StorageRepository.Create(ctx, &item); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -200,7 +200,7 @@ func (service backupService) Import(backup *dto.Backup) error {
|
||||
newId := utils.UUID()
|
||||
item.ID = newId
|
||||
item.Created = utils.NowJsonTime()
|
||||
if err := repository.StrategyRepository.Create(c, &item); err != nil {
|
||||
if err := repository.StrategyRepository.Create(ctx, &item); err != nil {
|
||||
return err
|
||||
}
|
||||
strategyIdMapping[oldId] = newId
|
||||
@ -210,7 +210,7 @@ func (service backupService) Import(backup *dto.Backup) error {
|
||||
if len(backup.AccessSecurities) > 0 {
|
||||
for _, item := range backup.AccessSecurities {
|
||||
item.ID = utils.UUID()
|
||||
if err := repository.SecurityRepository.Create(c, &item); err != nil {
|
||||
if err := repository.SecurityRepository.Create(ctx, &item); err != nil {
|
||||
return err
|
||||
}
|
||||
// 更新内存中的安全规则
|
||||
@ -231,7 +231,7 @@ func (service backupService) Import(backup *dto.Backup) error {
|
||||
newId := utils.UUID()
|
||||
item.ID = newId
|
||||
item.Created = utils.NowJsonTime()
|
||||
if err := repository.GatewayRepository.Create(c, &item); err != nil {
|
||||
if err := repository.GatewayRepository.Create(ctx, &item); err != nil {
|
||||
return err
|
||||
}
|
||||
accessGatewayIdMapping[oldId] = newId
|
||||
@ -242,7 +242,7 @@ func (service backupService) Import(backup *dto.Backup) error {
|
||||
for _, item := range backup.Commands {
|
||||
item.ID = utils.UUID()
|
||||
item.Created = utils.NowJsonTime()
|
||||
if err := repository.CommandRepository.Create(c, &item); err != nil {
|
||||
if err := repository.CommandRepository.Create(ctx, &item); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -254,7 +254,7 @@ func (service backupService) Import(backup *dto.Backup) error {
|
||||
oldId := item.ID
|
||||
newId := utils.UUID()
|
||||
item.ID = newId
|
||||
if err := CredentialService.Create(&item); err != nil {
|
||||
if err := CredentialService.Create(ctx, &item); err != nil {
|
||||
return err
|
||||
}
|
||||
credentialIdMapping[oldId] = newId
|
||||
@ -282,7 +282,7 @@ func (service backupService) Import(backup *dto.Backup) error {
|
||||
}
|
||||
|
||||
oldId := m["id"].(string)
|
||||
asset, err := AssetService.Create(m)
|
||||
asset, err := AssetService.Create(ctx, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -299,7 +299,7 @@ func (service backupService) Import(backup *dto.Backup) error {
|
||||
strategyId := strategyIdMapping[item.StrategyId]
|
||||
resourceId := assetIdMapping[item.ResourceId]
|
||||
|
||||
if err := repository.ResourceSharerRepository.AddSharerResources(userGroupId, userId, strategyId, item.ResourceType, []string{resourceId}); err != nil {
|
||||
if err := UserService.AddSharerResources(ctx, userGroupId, userId, strategyId, item.ResourceType, []string{resourceId}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -311,6 +311,7 @@ func (service backupService) Import(backup *dto.Backup) error {
|
||||
continue
|
||||
}
|
||||
|
||||
item.ID = utils.UUID()
|
||||
resourceIds := strings.Split(item.ResourceIds, ",")
|
||||
if len(resourceIds) > 0 {
|
||||
var newResourceIds = make([]string, 0)
|
||||
@ -319,7 +320,7 @@ func (service backupService) Import(backup *dto.Backup) error {
|
||||
}
|
||||
item.ResourceIds = strings.Join(newResourceIds, ",")
|
||||
}
|
||||
if err := JobService.Create(&item); err != nil {
|
||||
if err := JobService.Create(ctx, &item); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -14,3 +14,8 @@ type baseService struct {
|
||||
func (service baseService) Context(db *gorm.DB) context.Context {
|
||||
return context.WithValue(context.TODO(), constant.DB, db)
|
||||
}
|
||||
|
||||
func (service baseService) InTransaction(ctx context.Context) bool {
|
||||
_, ok := ctx.Value(constant.DB).(*gorm.DB)
|
||||
return ok
|
||||
}
|
||||
|
@ -99,8 +99,8 @@ func (s credentialService) Decrypt(item *model.Credential, password []byte) erro
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s credentialService) FindByIdAndDecrypt(c context.Context, id string) (o model.Credential, err error) {
|
||||
credential, err := repository.CredentialRepository.FindById(c, id)
|
||||
func (s credentialService) FindByIdAndDecrypt(ctx context.Context, id string) (o model.Credential, err error) {
|
||||
credential, err := repository.CredentialRepository.FindById(ctx, id)
|
||||
if err != nil {
|
||||
return o, err
|
||||
}
|
||||
@ -110,10 +110,10 @@ func (s credentialService) FindByIdAndDecrypt(c context.Context, id string) (o m
|
||||
return credential, nil
|
||||
}
|
||||
|
||||
func (s credentialService) Create(item *model.Credential) error {
|
||||
func (s credentialService) Create(ctx context.Context, item *model.Credential) error {
|
||||
// 加密密码之后进行存储
|
||||
if err := s.Encrypt(item, config.GlobalCfg.EncryptionPassword); err != nil {
|
||||
return err
|
||||
}
|
||||
return repository.CredentialRepository.Create(context.TODO(), item)
|
||||
return repository.CredentialRepository.Create(ctx, item)
|
||||
}
|
||||
|
@ -103,7 +103,7 @@ func (r jobService) InitJob() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r jobService) Create(o *model.Job) (err error) {
|
||||
func (r jobService) Create(ctx context.Context, o *model.Job) (err error) {
|
||||
|
||||
if o.Status == constant.JobStatusRunning {
|
||||
j, err := getJob(o)
|
||||
@ -117,7 +117,7 @@ func (r jobService) Create(o *model.Job) (err error) {
|
||||
o.CronJobId = int(jobId)
|
||||
}
|
||||
|
||||
return repository.JobRepository.Create(context.TODO(), o)
|
||||
return repository.JobRepository.Create(ctx, o)
|
||||
}
|
||||
|
||||
func (r jobService) DeleteJobById(id string) error {
|
||||
|
@ -2,6 +2,7 @@ package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/smtp"
|
||||
|
||||
"next-terminal/server/constant"
|
||||
@ -27,7 +28,7 @@ func (r mailService) SendMail(to, subject, text string) {
|
||||
}
|
||||
|
||||
e := email.NewEmail()
|
||||
e.From = "Next Terminal <" + username + ">"
|
||||
e.From = fmt.Sprintf("%s <%s>", constant.AppName, username)
|
||||
e.To = []string{to}
|
||||
e.Subject = subject
|
||||
e.Text = []byte(text)
|
||||
|
@ -17,161 +17,63 @@ type propertyService struct {
|
||||
baseService
|
||||
}
|
||||
|
||||
var deprecatedPropertyNames = []string{
|
||||
guacd.EnableDrive,
|
||||
guacd.DrivePath,
|
||||
guacd.DriveName,
|
||||
guacd.DisableGlyphCaching,
|
||||
guacd.CreateRecordingPath,
|
||||
}
|
||||
|
||||
var defaultProperties = map[string]string{
|
||||
guacd.EnableRecording: "true",
|
||||
guacd.FontName: "menlo",
|
||||
guacd.FontSize: "12",
|
||||
guacd.ColorScheme: "gray-black",
|
||||
guacd.EnableWallpaper: "true",
|
||||
guacd.EnableTheming: "true",
|
||||
guacd.EnableFontSmoothing: "true",
|
||||
guacd.EnableFullWindowDrag: "true",
|
||||
guacd.EnableDesktopComposition: "true",
|
||||
guacd.EnableMenuAnimations: "true",
|
||||
guacd.DisableBitmapCaching: "false",
|
||||
guacd.DisableOffscreenCaching: "false",
|
||||
"cron-log-saved-limit": "360",
|
||||
"login-log-saved-limit": "360",
|
||||
"session-saved-limit": "360",
|
||||
"user-default-storage-size": "5120",
|
||||
}
|
||||
|
||||
func (service propertyService) InitProperties() error {
|
||||
propertyMap := repository.PropertyRepository.FindAllMap(context.TODO())
|
||||
|
||||
if len(propertyMap[guacd.EnableRecording]) == 0 {
|
||||
property := model.Property{
|
||||
Name: guacd.EnableRecording,
|
||||
Value: "true",
|
||||
}
|
||||
if err := repository.PropertyRepository.Create(context.TODO(), &property); err != nil {
|
||||
for name, value := range defaultProperties {
|
||||
if err := service.CreateIfAbsent(propertyMap, name, value); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(propertyMap[guacd.CreateRecordingPath]) == 0 {
|
||||
property := model.Property{
|
||||
Name: guacd.CreateRecordingPath,
|
||||
Value: "true",
|
||||
}
|
||||
if err := repository.PropertyRepository.Create(context.TODO(), &property); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if len(propertyMap[guacd.FontName]) == 0 {
|
||||
func (service propertyService) CreateIfAbsent(propertyMap map[string]string, name, value string) error {
|
||||
if len(propertyMap[name]) == 0 {
|
||||
property := model.Property{
|
||||
Name: guacd.FontName,
|
||||
Value: "menlo",
|
||||
}
|
||||
if err := repository.PropertyRepository.Create(context.TODO(), &property); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(propertyMap[guacd.FontSize]) == 0 {
|
||||
property := model.Property{
|
||||
Name: guacd.FontSize,
|
||||
Value: "12",
|
||||
}
|
||||
if err := repository.PropertyRepository.Create(context.TODO(), &property); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(propertyMap[guacd.ColorScheme]) == 0 {
|
||||
property := model.Property{
|
||||
Name: guacd.ColorScheme,
|
||||
Value: "gray-black",
|
||||
}
|
||||
if err := repository.PropertyRepository.Create(context.TODO(), &property); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(propertyMap[guacd.EnableWallpaper]) == 0 {
|
||||
property := model.Property{
|
||||
Name: guacd.EnableWallpaper,
|
||||
Value: "false",
|
||||
}
|
||||
if err := repository.PropertyRepository.Create(context.TODO(), &property); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(propertyMap[guacd.EnableTheming]) == 0 {
|
||||
property := model.Property{
|
||||
Name: guacd.EnableTheming,
|
||||
Value: "false",
|
||||
}
|
||||
if err := repository.PropertyRepository.Create(context.TODO(), &property); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(propertyMap[guacd.EnableFontSmoothing]) == 0 {
|
||||
property := model.Property{
|
||||
Name: guacd.EnableFontSmoothing,
|
||||
Value: "false",
|
||||
}
|
||||
if err := repository.PropertyRepository.Create(context.TODO(), &property); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(propertyMap[guacd.EnableFullWindowDrag]) == 0 {
|
||||
property := model.Property{
|
||||
Name: guacd.EnableFullWindowDrag,
|
||||
Value: "false",
|
||||
}
|
||||
if err := repository.PropertyRepository.Create(context.TODO(), &property); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(propertyMap[guacd.EnableDesktopComposition]) == 0 {
|
||||
property := model.Property{
|
||||
Name: guacd.EnableDesktopComposition,
|
||||
Value: "false",
|
||||
}
|
||||
if err := repository.PropertyRepository.Create(context.TODO(), &property); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(propertyMap[guacd.EnableMenuAnimations]) == 0 {
|
||||
property := model.Property{
|
||||
Name: guacd.EnableMenuAnimations,
|
||||
Value: "false",
|
||||
}
|
||||
if err := repository.PropertyRepository.Create(context.TODO(), &property); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(propertyMap[guacd.DisableBitmapCaching]) == 0 {
|
||||
property := model.Property{
|
||||
Name: guacd.DisableBitmapCaching,
|
||||
Value: "false",
|
||||
}
|
||||
if err := repository.PropertyRepository.Create(context.TODO(), &property); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(propertyMap[guacd.DisableOffscreenCaching]) == 0 {
|
||||
property := model.Property{
|
||||
Name: guacd.DisableOffscreenCaching,
|
||||
Value: "false",
|
||||
}
|
||||
if err := repository.PropertyRepository.Create(context.TODO(), &property); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(propertyMap[guacd.DisableGlyphCaching]) > 0 {
|
||||
if err := repository.PropertyRepository.DeleteByName(context.TODO(), guacd.DisableGlyphCaching); err != nil {
|
||||
return err
|
||||
Name: name,
|
||||
Value: value,
|
||||
}
|
||||
return repository.PropertyRepository.Create(context.TODO(), &property)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (service propertyService) DeleteDeprecatedProperty() error {
|
||||
propertyMap := repository.PropertyRepository.FindAllMap(context.TODO())
|
||||
if propertyMap[guacd.EnableDrive] != "" {
|
||||
if err := repository.PropertyRepository.DeleteByName(context.TODO(), guacd.DriveName); err != nil {
|
||||
return err
|
||||
for _, name := range deprecatedPropertyNames {
|
||||
if propertyMap[name] == "" {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if propertyMap[guacd.DrivePath] != "" {
|
||||
if err := repository.PropertyRepository.DeleteByName(context.TODO(), guacd.DrivePath); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if propertyMap[guacd.DriveName] != "" {
|
||||
if err := repository.PropertyRepository.DeleteByName(context.TODO(), guacd.DriveName); err != nil {
|
||||
if err := repository.PropertyRepository.DeleteByName(context.TODO(), name); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
@ -4,11 +4,14 @@ import (
|
||||
"bufio"
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"next-terminal/server/config"
|
||||
@ -33,7 +36,7 @@ func (service storageService) InitStorages() error {
|
||||
userId := users[i].ID
|
||||
_, err := repository.StorageRepository.FindByOwnerIdAndDefault(context.TODO(), userId, true)
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
err = service.CreateStorageByUser(&users[i])
|
||||
err = service.CreateStorageByUser(context.TODO(), &users[i])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -58,7 +61,7 @@ func (service storageService) InitStorages() error {
|
||||
}
|
||||
|
||||
if !userExist {
|
||||
if err := service.DeleteStorageById(storage.ID, true); err != nil {
|
||||
if err := service.DeleteStorageById(context.TODO(), storage.ID, true); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@ -75,14 +78,29 @@ func (service storageService) InitStorages() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (service storageService) CreateStorageByUser(user *model.User) error {
|
||||
func (service storageService) CreateStorageByUser(c context.Context, user *model.User) error {
|
||||
drivePath := service.GetBaseDrivePath()
|
||||
var limitSize int64 = -1
|
||||
property, err := repository.PropertyRepository.FindByName(c, "user-default-storage-size")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
limitSize, err = strconv.ParseInt(property.Value, 10, 64)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
limitSize = limitSize * 1024 * 1024
|
||||
if limitSize < 0 {
|
||||
limitSize = -1
|
||||
}
|
||||
|
||||
storage := model.Storage{
|
||||
ID: user.ID,
|
||||
Name: user.Nickname + "的默认空间",
|
||||
IsShare: false,
|
||||
IsDefault: true,
|
||||
LimitSize: -1,
|
||||
LimitSize: limitSize,
|
||||
Owner: user.ID,
|
||||
Created: utils.NowJsonTime(),
|
||||
}
|
||||
@ -91,8 +109,9 @@ func (service storageService) CreateStorageByUser(user *model.User) error {
|
||||
return err
|
||||
}
|
||||
log.Infof("创建storage:「%v」文件夹: %v", storage.Name, storageDir)
|
||||
err := repository.StorageRepository.Create(context.TODO(), &storage)
|
||||
err = repository.StorageRepository.Create(c, &storage)
|
||||
if err != nil {
|
||||
_ = os.RemoveAll(storageDir)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@ -135,9 +154,9 @@ func (service storageService) GetBaseDrivePath() string {
|
||||
return config.GlobalCfg.Guacd.Drive
|
||||
}
|
||||
|
||||
func (service storageService) DeleteStorageById(id string, force bool) error {
|
||||
func (service storageService) DeleteStorageById(c context.Context, id string, force bool) error {
|
||||
drivePath := service.GetBaseDrivePath()
|
||||
storage, err := repository.StorageRepository.FindById(context.TODO(), id)
|
||||
storage, err := repository.StorageRepository.FindById(c, id)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil
|
||||
@ -152,7 +171,7 @@ func (service storageService) DeleteStorageById(id string, force bool) error {
|
||||
if err := os.RemoveAll(path.Join(drivePath, id)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := repository.StorageRepository.DeleteById(context.TODO(), id); err != nil {
|
||||
if err := repository.StorageRepository.DeleteById(c, id); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
@ -229,14 +248,20 @@ func (service storageService) StorageEdit(file string, fileContent string, stora
|
||||
return nil
|
||||
}
|
||||
|
||||
func (service storageService) StorageDownload(c echo.Context, remoteFile, storageId string) error {
|
||||
func (service storageService) StorageDownload(c echo.Context, file, storageId string) error {
|
||||
drivePath := service.GetBaseDrivePath()
|
||||
if strings.Contains(remoteFile, "../") {
|
||||
if strings.Contains(file, "../") {
|
||||
return errors.New("非法请求 :(")
|
||||
}
|
||||
// 获取带后缀的文件名称
|
||||
filenameWithSuffix := path.Base(remoteFile)
|
||||
return c.Attachment(path.Join(path.Join(drivePath, storageId), remoteFile), filenameWithSuffix)
|
||||
filenameWithSuffix := path.Base(file)
|
||||
p := path.Join(path.Join(drivePath, storageId), file)
|
||||
//log.Infof("download %v", p)
|
||||
c.Response().Header().Set("Content-Disposition", fmt.Sprintf("attachment; filename=%s", filenameWithSuffix))
|
||||
c.Response().Header().Set("Content-Type", "application/octet-stream")
|
||||
|
||||
http.ServeFile(c.Response(), c.Request(), p)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (service storageService) StorageLs(remoteDir, storageId string) (error, []File) {
|
||||
|
@ -90,31 +90,31 @@ func (service userService) FixUserOnlineState() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (service userService) Logout(token string) {
|
||||
cache.TokenManager.Delete(token)
|
||||
}
|
||||
|
||||
func (service userService) LogoutByToken(token string) (err error) {
|
||||
return env.GetDB().Transaction(func(tx *gorm.DB) error {
|
||||
c := service.Context(tx)
|
||||
loginLog, err := repository.LoginLogRepository.FindById(c, token)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cache.TokenManager.Delete(token)
|
||||
|
||||
loginLogForUpdate := &model.LoginLog{LogoutTime: utils.NowJsonTime(), ID: token}
|
||||
err = repository.LoginLogRepository.Update(c, loginLogForUpdate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
loginLogs, err := repository.LoginLogRepository.FindAliveLoginLogsByUsername(c, loginLog.Username)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(loginLogs) == 0 {
|
||||
err = repository.UserRepository.UpdateOnlineByUsername(c, loginLog.Username, false)
|
||||
}
|
||||
loginLog, err := repository.LoginLogRepository.FindById(context.TODO(), token)
|
||||
if err != nil {
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
loginLogForUpdate := &model.LoginLog{LogoutTime: utils.NowJsonTime(), ID: token}
|
||||
err = repository.LoginLogRepository.Update(context.TODO(), loginLogForUpdate)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
loginLogs, err := repository.LoginLogRepository.FindAliveLoginLogsByUsername(context.TODO(), loginLog.Username)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(loginLogs) == 0 {
|
||||
err = repository.UserRepository.UpdateOnlineByUsername(context.TODO(), loginLog.Username, false)
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
func (service userService) LogoutById(c context.Context, id string) error {
|
||||
@ -130,13 +130,26 @@ func (service userService) LogoutById(c context.Context, id string) error {
|
||||
|
||||
for j := range loginLogs {
|
||||
token := loginLogs[j].ID
|
||||
if err := service.LogoutByToken(token); err != nil {
|
||||
return err
|
||||
}
|
||||
service.Logout(token)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (service userService) GetUserLoginToken(c context.Context, username string) ([]string, error) {
|
||||
|
||||
loginLogs, err := repository.LoginLogRepository.FindAliveLoginLogsByUsername(c, username)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var tokens []string
|
||||
for j := range loginLogs {
|
||||
token := loginLogs[j].ID
|
||||
tokens = append(tokens, token)
|
||||
}
|
||||
return tokens, nil
|
||||
}
|
||||
|
||||
func (service userService) OnEvicted(token string, value interface{}) {
|
||||
|
||||
if strings.HasPrefix(token, "forever") {
|
||||
@ -144,30 +157,24 @@ func (service userService) OnEvicted(token string, value interface{}) {
|
||||
} else {
|
||||
log.Debugf("用户Token「%v」过期", token)
|
||||
err := service.LogoutByToken(token)
|
||||
if err != nil {
|
||||
if err != nil && !errors.Is(gorm.ErrRecordNotFound, err) {
|
||||
log.Errorf("退出登录失败 %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (service userService) UpdateStatusById(id string, status string) error {
|
||||
return env.GetDB().Transaction(func(tx *gorm.DB) error {
|
||||
c := service.Context(tx)
|
||||
if c.Value(constant.DB) == nil {
|
||||
c = context.WithValue(c, constant.DB, env.GetDB())
|
||||
if constant.StatusDisabled == status {
|
||||
// 将该用户下线
|
||||
if err := service.LogoutById(context.TODO(), id); err != nil {
|
||||
return err
|
||||
}
|
||||
if constant.StatusDisabled == status {
|
||||
// 将该用户下线
|
||||
if err := service.LogoutById(c, id); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
u := model.User{
|
||||
ID: id,
|
||||
Status: status,
|
||||
}
|
||||
return repository.UserRepository.Update(c, &u)
|
||||
})
|
||||
}
|
||||
u := model.User{
|
||||
ID: id,
|
||||
Status: status,
|
||||
}
|
||||
return repository.UserRepository.Update(context.TODO(), &u)
|
||||
|
||||
}
|
||||
|
||||
@ -231,13 +238,19 @@ func (service userService) CreateUser(user model.User) (err error) {
|
||||
if err := repository.UserRepository.Create(c, &user); err != nil {
|
||||
return err
|
||||
}
|
||||
err = StorageService.CreateStorageByUser(&user)
|
||||
err = StorageService.CreateStorageByUser(c, &user)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if user.Mail != "" {
|
||||
go MailService.SendMail(user.Mail, "[Next Terminal] 注册通知", "你好,"+user.Nickname+"。管理员为你注册了账号:"+user.Username+" 密码:"+password)
|
||||
subject := fmt.Sprintf("%s 注册通知", constant.AppName)
|
||||
text := fmt.Sprintf(`您好,%s。
|
||||
管理员为你开通了账户。
|
||||
账号:%s
|
||||
密码:%s
|
||||
`, user.Username, user.Username, password)
|
||||
go MailService.SendMail(user.Mail, subject, text)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
@ -245,16 +258,19 @@ func (service userService) CreateUser(user model.User) (err error) {
|
||||
}
|
||||
|
||||
func (service userService) DeleteUserById(userId string) error {
|
||||
return env.GetDB().Transaction(func(tx *gorm.DB) error {
|
||||
user, err := repository.UserRepository.FindById(context.TODO(), userId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
username := user.Username
|
||||
// 下线该用户
|
||||
loginTokens, err := service.GetUserLoginToken(context.TODO(), username)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = env.GetDB().Transaction(func(tx *gorm.DB) error {
|
||||
c := service.Context(tx)
|
||||
// 下线该用户
|
||||
if err := service.LogoutById(c, userId); err != nil {
|
||||
return err
|
||||
}
|
||||
// 删除用户
|
||||
if err := repository.UserRepository.DeleteById(c, userId); err != nil {
|
||||
return err
|
||||
}
|
||||
// 删除用户与用户组的关系
|
||||
if err := repository.UserGroupMemberRepository.DeleteByUserId(c, userId); err != nil {
|
||||
return err
|
||||
@ -264,19 +280,37 @@ func (service userService) DeleteUserById(userId string) error {
|
||||
return err
|
||||
}
|
||||
// 删除用户的默认磁盘空间
|
||||
if err := StorageService.DeleteStorageById(userId, true); err != nil {
|
||||
if err := StorageService.DeleteStorageById(c, userId, true); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 删除用户
|
||||
if err := repository.UserRepository.DeleteById(c, userId); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, token := range loginTokens {
|
||||
service.Logout(token)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (service userService) DeleteLoginLogs(tokens []string) error {
|
||||
if len(tokens) > 0 {
|
||||
for _, token := range tokens {
|
||||
// 手动触发用户退出登录
|
||||
if err := service.LogoutByToken(token); err != nil {
|
||||
return err
|
||||
}
|
||||
// 移除缓存中的token
|
||||
service.Logout(token)
|
||||
// 删除登录日志
|
||||
if err := repository.LoginLogRepository.DeleteById(context.TODO(), token); err != nil {
|
||||
return err
|
||||
}
|
||||
@ -337,3 +371,37 @@ func (service userService) UpdateUser(id string, user model.User) error {
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
func (service userService) AddSharerResources(ctx context.Context, userGroupId, userId, strategyId, resourceType string, resourceIds []string) error {
|
||||
if service.InTransaction(ctx) {
|
||||
return service.addSharerResources(ctx, resourceIds, userGroupId, userId, strategyId, resourceType)
|
||||
} else {
|
||||
return env.GetDB().Transaction(func(tx *gorm.DB) error {
|
||||
ctx2 := service.Context(tx)
|
||||
return service.addSharerResources(ctx2, resourceIds, userGroupId, userId, strategyId, resourceType)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (service userService) addSharerResources(ctx context.Context, resourceIds []string, userGroupId string, userId string, strategyId string, resourceType string) error {
|
||||
for i := range resourceIds {
|
||||
resourceId := resourceIds[i]
|
||||
// 保证同一个资产只能分配给一个用户或者组
|
||||
id := utils.Sign([]string{resourceId, resourceType, userId, userGroupId})
|
||||
if err := repository.ResourceSharerRepository.DeleteById(ctx, id); err != nil {
|
||||
return err
|
||||
}
|
||||
rs := &model.ResourceSharer{
|
||||
ID: id,
|
||||
ResourceId: resourceId,
|
||||
ResourceType: resourceType,
|
||||
StrategyId: strategyId,
|
||||
UserId: userId,
|
||||
UserGroupId: userGroupId,
|
||||
}
|
||||
if err := repository.ResourceSharerRepository.AddSharerResource(ctx, rs); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -13,11 +13,12 @@ import (
|
||||
)
|
||||
|
||||
type userGroupService struct {
|
||||
baseService
|
||||
}
|
||||
|
||||
func (service userGroupService) DeleteById(userGroupId string) error {
|
||||
return env.GetDB().Transaction(func(tx *gorm.DB) error {
|
||||
c := context.WithValue(context.TODO(), constant.DB, tx)
|
||||
c := service.Context(tx)
|
||||
// 删除用户组
|
||||
if err := repository.UserGroupRepository.DeleteById(c, userGroupId); err != nil {
|
||||
return err
|
||||
@ -34,8 +35,8 @@ func (service userGroupService) DeleteById(userGroupId string) error {
|
||||
})
|
||||
}
|
||||
|
||||
func (service userGroupService) Create(name string, members []string) (model.UserGroup, error) {
|
||||
exist, err := repository.UserGroupRepository.ExistByName(context.TODO(), name)
|
||||
func (service userGroupService) Create(ctx context.Context, name string, members []string) (model.UserGroup, error) {
|
||||
exist, err := repository.UserGroupRepository.ExistByName(ctx, name)
|
||||
if err != nil {
|
||||
return model.UserGroup{}, err
|
||||
}
|
||||
@ -51,26 +52,33 @@ func (service userGroupService) Create(name string, members []string) (model.Use
|
||||
Name: name,
|
||||
}
|
||||
|
||||
return userGroup, env.GetDB().Transaction(func(tx *gorm.DB) error {
|
||||
c := context.WithValue(context.TODO(), constant.DB, tx)
|
||||
if err := repository.UserGroupRepository.Create(c, &userGroup); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(members) > 0 {
|
||||
for _, member := range members {
|
||||
userGroupMember := model.UserGroupMember{
|
||||
ID: utils.Sign([]string{userGroupId, member}),
|
||||
UserId: member,
|
||||
UserGroupId: userGroupId,
|
||||
}
|
||||
if err := repository.UserGroupMemberRepository.Create(c, &userGroupMember); err != nil {
|
||||
return err
|
||||
}
|
||||
if service.InTransaction(ctx) {
|
||||
return userGroup, service.create(ctx, userGroup, members, userGroupId)
|
||||
} else {
|
||||
return userGroup, env.GetDB().Transaction(func(tx *gorm.DB) error {
|
||||
c := service.Context(tx)
|
||||
return service.create(c, userGroup, members, userGroupId)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (service userGroupService) create(c context.Context, userGroup model.UserGroup, members []string, userGroupId string) error {
|
||||
if err := repository.UserGroupRepository.Create(c, &userGroup); err != nil {
|
||||
return err
|
||||
}
|
||||
if len(members) > 0 {
|
||||
for _, member := range members {
|
||||
userGroupMember := model.UserGroupMember{
|
||||
ID: utils.Sign([]string{userGroupId, member}),
|
||||
UserId: member,
|
||||
UserGroupId: userGroupId,
|
||||
}
|
||||
if err := repository.UserGroupMemberRepository.Create(c, &userGroupMember); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (service userGroupService) Update(userGroupId string, name string, members []string) (err error) {
|
||||
@ -91,7 +99,7 @@ func (service userGroupService) Update(userGroupId string, name string, members
|
||||
}
|
||||
|
||||
return env.GetDB().Transaction(func(tx *gorm.DB) error {
|
||||
c := context.WithValue(context.TODO(), constant.DB, tx)
|
||||
c := service.Context(tx)
|
||||
userGroup := model.UserGroup{
|
||||
ID: userGroupId,
|
||||
Name: name,
|
||||
|
Reference in New Issue
Block a user