完成重构数据库操作代码

This commit is contained in:
dushixiang
2021-03-18 23:36:25 +08:00
parent 805fec4a67
commit 8380d7d857
44 changed files with 2292 additions and 2016 deletions

View File

@ -111,7 +111,7 @@ func LoginSuccess(c echo.Context, loginAccount LoginAccount, user model.User) (t
Remember: authorization.Remember,
}
if model.CreateNewLoginLog(&loginLog) != nil {
if loginLogRepository.Create(&loginLog) != nil {
return "", err
}
@ -179,7 +179,7 @@ func LogoutEndpoint(c echo.Context) error {
token := GetToken(c)
cacheKey := BuildCacheKeyByToken(token)
global.Cache.Delete(cacheKey)
err := model.Logout(token)
err := userService.Logout(token)
if err != nil {
return err
}

75
server/api/api.go Normal file
View File

@ -0,0 +1,75 @@
package api
import (
"github.com/labstack/echo/v4"
"next-terminal/server/constant"
"next-terminal/server/global"
"next-terminal/server/model"
)
type H map[string]interface{}
func Fail(c echo.Context, code int, message string) error {
return c.JSON(200, H{
"code": code,
"message": message,
})
}
func FailWithData(c echo.Context, code int, message string, data interface{}) error {
return c.JSON(200, H{
"code": code,
"message": message,
"data": data,
})
}
func Success(c echo.Context, data interface{}) error {
return c.JSON(200, H{
"code": 1,
"message": "success",
"data": data,
})
}
func NotFound(c echo.Context, message string) error {
return c.JSON(200, H{
"code": -1,
"message": message,
})
}
func GetToken(c echo.Context) string {
token := c.Request().Header.Get(Token)
if len(token) > 0 {
return token
}
return c.QueryParam(Token)
}
func GetCurrentAccount(c echo.Context) (model.User, bool) {
token := GetToken(c)
cacheKey := BuildCacheKeyByToken(token)
get, b := global.Cache.Get(cacheKey)
if b {
return get.(Authorization).User, true
}
return model.User{}, false
}
func HasPermission(c echo.Context, owner string) bool {
// 检测是否登录
account, found := GetCurrentAccount(c)
if !found {
return false
}
// 检测是否为管理人员
if constant.TypeAdmin == account.Type {
return true
}
// 检测是否为所有者
if owner == account.ID {
return true
}
return false
}

View File

@ -32,18 +32,18 @@ func AssetCreateEndpoint(c echo.Context) error {
item.ID = utils.UUID()
item.Created = utils.NowJsonTime()
if err := model.CreateNewAsset(&item); err != nil {
if err := assetRepository.Create(&item); err != nil {
return err
}
if err := model.UpdateAssetAttributes(item.ID, item.Protocol, m); err != nil {
if err := assetRepository.UpdateAttributes(item.ID, item.Protocol, m); err != nil {
return err
}
// 创建后自动检测资产是否存活
go func() {
active := utils.Tcping(item.IP, item.Port)
model.UpdateAssetActiveById(active, item.ID)
assetRepository.UpdateActiveById(active, item.ID)
}()
return Success(c, item)
@ -98,7 +98,7 @@ func AssetImportEndpoint(c echo.Context) error {
Owner: account.ID,
}
err := model.CreateNewAsset(&asset)
err := assetRepository.Create(&asset)
if err != nil {
errorCount++
m[strconv.Itoa(i)] = err.Error()
@ -107,7 +107,7 @@ func AssetImportEndpoint(c echo.Context) error {
// 创建后自动检测资产是否存活
go func() {
active := utils.Tcping(asset.IP, asset.Port)
model.UpdateAssetActiveById(active, asset.ID)
assetRepository.UpdateActiveById(active, asset.ID)
}()
}
}
@ -135,7 +135,7 @@ func AssetPagingEndpoint(c echo.Context) error {
field := c.QueryParam("field")
account, _ := GetCurrentAccount(c)
items, total, err := model.FindPageAsset(pageIndex, pageSize, name, protocol, tags, account, owner, sharer, userGroupId, ip, order, field)
items, total, err := assetRepository.Find(pageIndex, pageSize, name, protocol, tags, account, owner, sharer, userGroupId, ip, order, field)
if err != nil {
return err
}
@ -149,7 +149,7 @@ func AssetPagingEndpoint(c echo.Context) error {
func AssetAllEndpoint(c echo.Context) error {
protocol := c.QueryParam("protocol")
account, _ := GetCurrentAccount(c)
items, _ := model.FindAssetByConditions(protocol, account)
items, _ := assetRepository.FindByProtocolAndUser(protocol, account)
return Success(c, items)
}
@ -199,8 +199,10 @@ func AssetUpdateEndpoint(c echo.Context) error {
item.Description = "-"
}
model.UpdateAssetById(&item, id)
if err := model.UpdateAssetAttributes(id, item.Protocol, m); err != nil {
if err := assetRepository.UpdateById(&item, id); err != nil {
return err
}
if err := assetRepository.UpdateAttributes(id, item.Protocol, m); err != nil {
return err
}
@ -214,7 +216,7 @@ func AssetGetAttributeEndpoint(c echo.Context) error {
return err
}
attributeMap, err := model.FindAssetAttrMapByAssetId(assetId)
attributeMap, err := assetRepository.FindAssetAttrMapByAssetId(assetId)
if err != nil {
return err
}
@ -229,7 +231,7 @@ func AssetUpdateAttributeEndpoint(c echo.Context) error {
assetId := c.Param("id")
protocol := c.QueryParam("protocol")
err := model.UpdateAssetAttributes(assetId, protocol, m)
err := assetRepository.UpdateAttributes(assetId, protocol, m)
if err != nil {
return err
}
@ -243,11 +245,11 @@ func AssetDeleteEndpoint(c echo.Context) error {
if err := PreCheckAssetPermission(c, split[i]); err != nil {
return err
}
if err := model.DeleteAssetById(split[i]); err != nil {
if err := assetRepository.DeleteById(split[i]); err != nil {
return err
}
// 删除资产与用户的关系
if err := model.DeleteResourceSharerByResourceId(split[i]); err != nil {
if err := resourceSharerRepository.DeleteResourceSharerByResourceId(split[i]); err != nil {
return err
}
}
@ -262,10 +264,10 @@ func AssetGetEndpoint(c echo.Context) (err error) {
}
var item model.Asset
if item, err = model.FindAssetById(id); err != nil {
if item, err = assetRepository.FindById(id); err != nil {
return err
}
attributeMap, err := model.FindAssetAttrMapByAssetId(id)
attributeMap, err := assetRepository.FindAssetAttrMapByAssetId(id)
if err != nil {
return err
}
@ -281,19 +283,21 @@ func AssetTcpingEndpoint(c echo.Context) (err error) {
id := c.Param("id")
var item model.Asset
if item, err = model.FindAssetById(id); err != nil {
if item, err = assetRepository.FindById(id); err != nil {
return err
}
active := utils.Tcping(item.IP, item.Port)
model.UpdateAssetActiveById(active, item.ID)
if err := assetRepository.UpdateActiveById(active, item.ID); err != nil {
return err
}
return Success(c, active)
}
func AssetTagsEndpoint(c echo.Context) (err error) {
var items []string
if items, err = model.FindAssetTags(); err != nil {
if items, err = assetRepository.FindTags(); err != nil {
return err
}
return Success(c, items)
@ -307,12 +311,14 @@ func AssetChangeOwnerEndpoint(c echo.Context) (err error) {
}
owner := c.QueryParam("owner")
model.UpdateAssetById(&model.Asset{Owner: owner}, id)
if err := assetRepository.UpdateById(&model.Asset{Owner: owner}, id); err != nil {
return err
}
return Success(c, "")
}
func PreCheckAssetPermission(c echo.Context, id string) error {
item, err := model.FindAssetById(id)
item, err := assetRepository.FindById(id)
if err != nil {
return err
}

View File

@ -4,11 +4,9 @@ import (
"strconv"
"strings"
"next-terminal/server/global"
"next-terminal/server/model"
"github.com/labstack/echo/v4"
"github.com/sirupsen/logrus"
"next-terminal/server/global"
)
func LoginLogPagingEndpoint(c echo.Context) error {
@ -17,7 +15,7 @@ func LoginLogPagingEndpoint(c echo.Context) error {
userId := c.QueryParam("userId")
clientIp := c.QueryParam("clientIp")
items, total, err := model.FindPageLoginLog(pageIndex, pageSize, userId, clientIp)
items, total, err := loginLogRepository.Find(pageIndex, pageSize, userId, clientIp)
if err != nil {
return err
@ -35,11 +33,11 @@ func LoginLogDeleteEndpoint(c echo.Context) error {
for i := range split {
token := split[i]
global.Cache.Delete(token)
if err := model.Logout(token); err != nil {
if err := userService.Logout(token); err != nil {
logrus.WithError(err).Error("Cache Delete Failed")
}
}
if err := model.DeleteLoginLogByIdIn(split); err != nil {
if err := loginLogRepository.DeleteByIdIn(split); err != nil {
return err
}

View File

@ -1,12 +1,19 @@
package api
import (
"github.com/patrickmn/go-cache"
"github.com/sirupsen/logrus"
"gorm.io/gorm"
"net/http"
"next-terminal/server/constant"
"next-terminal/server/global"
"next-terminal/server/log"
"next-terminal/server/model"
"next-terminal/server/repository"
"next-terminal/server/service"
"next-terminal/server/utils"
"strconv"
"strings"
"time"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
@ -15,11 +22,32 @@ import (
const Token = "X-Auth-Token"
var (
userRepository repository.UserRepository
userRepository *repository.UserRepository
userGroupRepository *repository.UserGroupRepository
resourceSharerRepository *repository.ResourceSharerRepository
assetRepository *repository.AssetRepository
credentialRepository *repository.CredentialRepository
propertyRepository *repository.PropertyRepository
commandRepository *repository.CommandRepository
sessionRepository *repository.SessionRepository
numRepository *repository.NumRepository
accessSecurityRepository *repository.AccessSecurityRepository
jobRepository *repository.JobRepository
jobLogRepository *repository.JobLogRepository
loginLogRepository *repository.LoginLogRepository
jobService *service.JobService
propertyService *service.PropertyService
userService *service.UserService
sessionService *service.SessionService
)
func SetupRoutes(ur repository.UserRepository) *echo.Echo {
userRepository = ur
func SetupRoutes(db *gorm.DB) *echo.Echo {
InitRepository(db)
InitService()
InitDBData()
e := echo.New()
e.HideBanner = true
@ -178,69 +206,88 @@ func SetupRoutes(ur repository.UserRepository) *echo.Echo {
return e
}
type H map[string]interface{}
func InitRepository(db *gorm.DB) {
userRepository = repository.NewUserRepository(db)
userGroupRepository = repository.NewUserGroupRepository(db)
resourceSharerRepository = repository.NewResourceSharerRepository(db)
assetRepository = repository.NewAssetRepository(db)
credentialRepository = repository.NewCredentialRepository(db)
propertyRepository = repository.NewPropertyRepository(db)
commandRepository = repository.NewCommandRepository(db)
sessionRepository = repository.NewSessionRepository(db)
numRepository = repository.NewNumRepository(db)
accessSecurityRepository = repository.NewAccessSecurityRepository(db)
jobRepository = repository.NewJobRepository(db)
jobLogRepository = repository.NewJobLogRepository(db)
loginLogRepository = repository.NewLoginLogRepository(db)
}
func Fail(c echo.Context, code int, message string) error {
return c.JSON(200, H{
"code": code,
"message": message,
func InitService() {
jobService = service.NewJobService(jobRepository, jobLogRepository, assetRepository, credentialRepository)
propertyService = service.NewPropertyService(propertyRepository)
userService = service.NewUserService(userRepository)
sessionService = service.NewSessionService(sessionRepository)
}
func InitDBData() (err error) {
if err := propertyService.InitProperties(); err != nil {
return err
}
if err := userService.InitUser(); err != nil {
return err
}
if err := userService.FixedOnlineState(); err != nil {
return err
}
if err := jobService.InitJob(); err != nil {
return err
}
sessionService.Fix()
nums, _ := numRepository.FindAll()
if nums == nil || len(nums) == 0 {
for i := 0; i <= 30; i++ {
if err := numRepository.Create(&model.Num{I: strconv.Itoa(i)}); err != nil {
return err
}
}
}
return nil
}
func ResetPassword() error {
user, err := userRepository.FindByUsername(global.Config.ResetPassword)
if err != nil {
return err
}
password := "next-terminal"
passwd, err := utils.Encoder.Encode([]byte(password))
if err != nil {
return err
}
u := &model.User{
Password: string(passwd),
ID: user.ID,
}
if err := userRepository.Update(u); err != nil {
return err
}
logrus.Debugf("用户「%v」密码初始化为: %v", user.Username, password)
return nil
}
func SetupCache() *cache.Cache {
// 配置缓存器
mCache := cache.New(5*time.Minute, 10*time.Minute)
mCache.OnEvicted(func(key string, value interface{}) {
if strings.HasPrefix(key, Token) {
token := GetTokenFormCacheKey(key)
logrus.Debugf("用户Token「%v」过期", token)
err := userService.Logout(token)
if err != nil {
logrus.Errorf("退出登录失败 %v", err)
}
}
})
}
func FailWithData(c echo.Context, code int, message string, data interface{}) error {
return c.JSON(200, H{
"code": code,
"message": message,
"data": data,
})
}
func Success(c echo.Context, data interface{}) error {
return c.JSON(200, H{
"code": 1,
"message": "success",
"data": data,
})
}
func NotFound(c echo.Context, message string) error {
return c.JSON(200, H{
"code": -1,
"message": message,
})
}
func GetToken(c echo.Context) string {
token := c.Request().Header.Get(Token)
if len(token) > 0 {
return token
}
return c.QueryParam(Token)
}
func GetCurrentAccount(c echo.Context) (model.User, bool) {
token := GetToken(c)
cacheKey := BuildCacheKeyByToken(token)
get, b := global.Cache.Get(cacheKey)
if b {
return get.(Authorization).User, true
}
return model.User{}, false
}
func HasPermission(c echo.Context, owner string) bool {
// 检测是否登录
account, found := GetCurrentAccount(c)
if !found {
return false
}
// 检测是否为管理人员
if constant.TypeAdmin == account.Type {
return true
}
// 检测是否为所有者
if owner == account.ID {
return true
}
return false
return mCache
}

View File

@ -20,7 +20,7 @@ func SecurityCreateEndpoint(c echo.Context) error {
item.ID = utils.UUID()
item.Source = "管理员添加"
if err := model.CreateNewSecurity(&item); err != nil {
if err := accessSecurityRepository.Create(&item); err != nil {
return err
}
// 更新内存中的安全规则
@ -31,7 +31,7 @@ func SecurityCreateEndpoint(c echo.Context) error {
}
func ReloadAccessSecurity() error {
rules, err := model.FindAllAccessSecurities()
rules, err := accessSecurityRepository.FindAllAccessSecurities()
if err != nil {
return err
}
@ -58,7 +58,7 @@ func SecurityPagingEndpoint(c echo.Context) error {
order := c.QueryParam("order")
field := c.QueryParam("field")
items, total, err := model.FindPageSecurity(pageIndex, pageSize, ip, rule, order, field)
items, total, err := accessSecurityRepository.Find(pageIndex, pageSize, ip, rule, order, field)
if err != nil {
return err
}
@ -77,7 +77,7 @@ func SecurityUpdateEndpoint(c echo.Context) error {
return err
}
if err := model.UpdateSecurityById(&item, id); err != nil {
if err := accessSecurityRepository.UpdateById(&item, id); err != nil {
return err
}
// 更新内存中的安全规则
@ -93,7 +93,7 @@ func SecurityDeleteEndpoint(c echo.Context) error {
split := strings.Split(ids, ",")
for i := range split {
jobId := split[i]
if err := model.DeleteSecurityById(jobId); err != nil {
if err := accessSecurityRepository.DeleteById(jobId); err != nil {
return err
}
}
@ -107,7 +107,7 @@ func SecurityDeleteEndpoint(c echo.Context) error {
func SecurityGetEndpoint(c echo.Context) error {
id := c.Param("id")
item, err := model.FindSecurityById(id)
item, err := accessSecurityRepository.FindById(id)
if err != nil {
return err
}

62
server/api/ticker.go Normal file
View File

@ -0,0 +1,62 @@
package api
import (
"github.com/sirupsen/logrus"
"next-terminal/server/constant"
"strconv"
"time"
)
func SetupTicker() {
// 每隔一小时删除一次未使用的会话信息
unUsedSessionTicker := time.NewTicker(time.Minute * 60)
go func() {
for range unUsedSessionTicker.C {
sessions, _ := sessionRepository.FindByStatusIn([]string{constant.NoConnect, constant.Connecting})
if len(sessions) > 0 {
now := time.Now()
for i := range sessions {
if now.Sub(sessions[i].ConnectedTime.Time) > time.Hour*1 {
_ = sessionRepository.DeleteById(sessions[i].ID)
s := sessions[i].Username + "@" + sessions[i].IP + ":" + strconv.Itoa(sessions[i].Port)
logrus.Infof("会话「%v」ID「%v」超过1小时未打开已删除。", s, sessions[i].ID)
}
}
}
}
}()
// 每日凌晨删除超过时长限制的会话
timeoutSessionTicker := time.NewTicker(time.Hour * 24)
go func() {
for range timeoutSessionTicker.C {
property, err := propertyRepository.FindByName("session-saved-limit")
if err != nil {
return
}
if property.Value == "" || property.Value == "-" {
return
}
limit, err := strconv.Atoi(property.Value)
if err != nil {
return
}
sessions, err := sessionRepository.FindOutTimeSessions(limit)
if err != nil {
return
}
if len(sessions) > 0 {
var sessionIds []string
for i := range sessions {
sessionIds = append(sessionIds, sessions[i].ID)
}
err := sessionRepository.DeleteByIds(sessionIds)
if err != nil {
logrus.Errorf("删除离线会话失败 %v", err)
}
}
}
}()
}