fixes #34 「动态指令」多行指令会被当作一行执行
fixes #32 会话无法维持,1分钟左右自动断开 fixes #31 更新"资产"会清空"标签" fixes #13 建议添加用户权限功能、隐藏授权账户信息
This commit is contained in:
@ -49,7 +49,7 @@ func LoginEndpoint(c echo.Context) error {
|
||||
return Fail(c, -1, "您输入的账号或密码不正确")
|
||||
}
|
||||
|
||||
if user.TOTPSecret != "" {
|
||||
if user.TOTPSecret != "" && user.TOTPSecret != "-" {
|
||||
return Fail(c, 0, "")
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,11 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/labstack/echo/v4"
|
||||
"github.com/sirupsen/logrus"
|
||||
"next-terminal/pkg/global"
|
||||
"next-terminal/pkg/model"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@ -12,6 +14,12 @@ func ErrorHandler(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
|
||||
if err := next(c); err != nil {
|
||||
|
||||
if he, ok := err.(*echo.HTTPError); ok {
|
||||
message := fmt.Sprintf("%v", he.Message)
|
||||
return Fail(c, he.Code, message)
|
||||
}
|
||||
|
||||
return Fail(c, 0, err.Error())
|
||||
}
|
||||
return nil
|
||||
@ -21,9 +29,6 @@ func ErrorHandler(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
func Auth(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
|
||||
urls := []string{"download", "recording", "login", "static", "favicon", "logo"}
|
||||
permissionUrls := H{
|
||||
"/users": "admin",
|
||||
}
|
||||
|
||||
return func(c echo.Context) error {
|
||||
// 路由拦截 - 登录身份、资源权限判断等
|
||||
@ -43,14 +48,6 @@ func Auth(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return Fail(c, 401, "您的登录信息已失效,请重新登录后再试。")
|
||||
}
|
||||
|
||||
for url := range permissionUrls {
|
||||
if strings.HasPrefix(c.Request().RequestURI, url) {
|
||||
if authorization.(Authorization).User.Type != permissionUrls[url] {
|
||||
return Fail(c, 403, "permission denied")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if authorization.(Authorization).Remember {
|
||||
// 记住登录有效期两周
|
||||
global.Cache.Set(token, authorization, time.Hour*time.Duration(24*14))
|
||||
@ -61,3 +58,16 @@ func Auth(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return next(c)
|
||||
}
|
||||
}
|
||||
|
||||
func Admin(next echo.HandlerFunc) echo.HandlerFunc {
|
||||
return func(c echo.Context) error {
|
||||
|
||||
account, _ := GetCurrentAccount(c)
|
||||
|
||||
if account.Type != model.TypeAdmin {
|
||||
return Fail(c, 403, "permission denied")
|
||||
}
|
||||
|
||||
return next(c)
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package api
|
||||
import (
|
||||
"github.com/labstack/echo/v4"
|
||||
"next-terminal/pkg/model"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type RU struct {
|
||||
@ -12,8 +11,14 @@ type RU struct {
|
||||
ResourceIds []string `json:"resourceIds"`
|
||||
}
|
||||
|
||||
func ResourceGetAssignEndPoint(c echo.Context) error {
|
||||
resourceId := c.Param("id")
|
||||
type UR struct {
|
||||
ResourceId string `json:"resourceId"`
|
||||
ResourceType string `json:"resourceType"`
|
||||
UserIds []string `json:"userIds"`
|
||||
}
|
||||
|
||||
func RSGetSharersEndPoint(c echo.Context) error {
|
||||
resourceId := c.QueryParam("resourceId")
|
||||
userIds, err := model.FindUserIdsByResourceId(resourceId)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -21,13 +26,15 @@ func ResourceGetAssignEndPoint(c echo.Context) error {
|
||||
return Success(c, userIds)
|
||||
}
|
||||
|
||||
func ResourceOverwriteAssignEndPoint(c echo.Context) error {
|
||||
resourceId := c.Param("id")
|
||||
userIds := c.QueryParam("userIds")
|
||||
resourceType := c.QueryParam("type")
|
||||
uIds := strings.Split(userIds, ",")
|
||||
func RSOverwriteSharersEndPoint(c echo.Context) error {
|
||||
var ur UR
|
||||
if err := c.Bind(&ur); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
model.OverwriteUserIdsByResourceId(resourceId, resourceType, uIds)
|
||||
if err := model.OverwriteUserIdsByResourceId(ur.ResourceId, ur.ResourceType, ur.UserIds); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return Success(c, "")
|
||||
}
|
@ -44,20 +44,22 @@ func SetupRoutes() *echo.Echo {
|
||||
|
||||
users := e.Group("/users")
|
||||
{
|
||||
users.POST("", UserCreateEndpoint)
|
||||
users.POST("", Admin(UserCreateEndpoint))
|
||||
users.GET("/paging", UserPagingEndpoint)
|
||||
users.PUT("/:id", UserUpdateEndpoint)
|
||||
users.DELETE("/:id", UserDeleteEndpoint)
|
||||
users.GET("/:id", UserGetEndpoint)
|
||||
users.PUT("/:id", Admin(UserUpdateEndpoint))
|
||||
users.DELETE("/:id", Admin(UserDeleteEndpoint))
|
||||
users.GET("/:id", Admin(UserGetEndpoint))
|
||||
users.POST("/:id/change-password", Admin(UserChangePasswordEndpoint))
|
||||
users.POST("/:id/reset-totp", Admin(UserResetTotpEndpoint))
|
||||
}
|
||||
|
||||
userGroups := e.Group("/user-groups")
|
||||
{
|
||||
userGroups.POST("", UserGroupCreateEndpoint)
|
||||
userGroups.GET("/paging", UserGroupPagingEndpoint)
|
||||
userGroups.PUT("/:id", UserGroupUpdateEndpoint)
|
||||
userGroups.DELETE("/:id", UserGroupDeleteEndpoint)
|
||||
userGroups.GET("/:id", UserGroupGetEndpoint)
|
||||
userGroups.POST("", Admin(UserGroupCreateEndpoint))
|
||||
userGroups.GET("/paging", Admin(UserGroupPagingEndpoint))
|
||||
userGroups.PUT("/:id", Admin(UserGroupUpdateEndpoint))
|
||||
userGroups.DELETE("/:id", Admin(UserGroupDeleteEndpoint))
|
||||
userGroups.GET("/:id", Admin(UserGroupGetEndpoint))
|
||||
//userGroups.POST("/:id/members", UserGroupAddMembersEndpoint)
|
||||
//userGroups.DELETE("/:id/members/:memberId", UserGroupDelMembersEndpoint)
|
||||
}
|
||||
@ -71,7 +73,7 @@ func SetupRoutes() *echo.Echo {
|
||||
assets.PUT("/:id", AssetUpdateEndpoint)
|
||||
assets.DELETE("/:id", AssetDeleteEndpoint)
|
||||
assets.GET("/:id", AssetGetEndpoint)
|
||||
assets.POST("/:id/change-owner", AssetChangeOwnerEndpoint)
|
||||
assets.POST("/:id/change-owner", Admin(AssetChangeOwnerEndpoint))
|
||||
}
|
||||
|
||||
e.GET("/tags", AssetTagsEndpoint)
|
||||
@ -83,7 +85,7 @@ func SetupRoutes() *echo.Echo {
|
||||
commands.PUT("/:id", CommandUpdateEndpoint)
|
||||
commands.DELETE("/:id", CommandDeleteEndpoint)
|
||||
commands.GET("/:id", CommandGetEndpoint)
|
||||
commands.POST("/:id/change-owner", CommandChangeOwnerEndpoint)
|
||||
commands.POST("/:id/change-owner", Admin(CommandChangeOwnerEndpoint))
|
||||
}
|
||||
|
||||
credentials := e.Group("/credentials")
|
||||
@ -94,7 +96,7 @@ func SetupRoutes() *echo.Echo {
|
||||
credentials.PUT("/:id", CredentialUpdateEndpoint)
|
||||
credentials.DELETE("/:id", CredentialDeleteEndpoint)
|
||||
credentials.GET("/:id", CredentialGetEndpoint)
|
||||
credentials.POST("/:id/change-owner", CredentialChangeOwnerEndpoint)
|
||||
credentials.POST("/:id/change-owner", Admin(CredentialChangeOwnerEndpoint))
|
||||
}
|
||||
|
||||
sessions := e.Group("/sessions")
|
||||
@ -102,7 +104,7 @@ func SetupRoutes() *echo.Echo {
|
||||
sessions.POST("", SessionCreateEndpoint)
|
||||
sessions.GET("/paging", SessionPagingEndpoint)
|
||||
sessions.POST("/:id/content", SessionContentEndpoint)
|
||||
sessions.POST("/:id/discontent", SessionDiscontentEndpoint)
|
||||
sessions.POST("/:id/discontent", Admin(SessionDiscontentEndpoint))
|
||||
sessions.POST("/:id/resize", SessionResizeEndpoint)
|
||||
sessions.POST("/:id/upload", SessionUploadEndpoint)
|
||||
sessions.GET("/:id/download", SessionDownloadEndpoint)
|
||||
@ -111,20 +113,20 @@ func SetupRoutes() *echo.Echo {
|
||||
sessions.DELETE("/:id/rmdir", SessionRmDirEndpoint)
|
||||
sessions.DELETE("/:id/rm", SessionRmEndpoint)
|
||||
sessions.DELETE("/:id", SessionDeleteEndpoint)
|
||||
sessions.GET("/:id/recording", SessionRecordingEndpoint)
|
||||
sessions.GET("/:id/recording", Admin(SessionRecordingEndpoint))
|
||||
sessions.GET("/:id", SessionGetEndpoint)
|
||||
}
|
||||
|
||||
resources := e.Group("/resources")
|
||||
resourceSharers := e.Group("/resource-sharers")
|
||||
{
|
||||
resources.GET("/:id/assign", ResourceGetAssignEndPoint)
|
||||
resources.POST("/:id/assign", ResourceOverwriteAssignEndPoint)
|
||||
resources.POST("/remove", ResourceRemoveByUserIdAssignEndPoint)
|
||||
resources.POST("/add", ResourceAddByUserIdAssignEndPoint)
|
||||
resourceSharers.GET("/sharers", RSGetSharersEndPoint)
|
||||
resourceSharers.POST("/overwrite-sharers", RSOverwriteSharersEndPoint)
|
||||
resourceSharers.POST("/remove-resources", Admin(ResourceRemoveByUserIdAssignEndPoint))
|
||||
resourceSharers.POST("/add-resources", Admin(ResourceAddByUserIdAssignEndPoint))
|
||||
}
|
||||
|
||||
e.GET("/properties", PropertyGetEndpoint)
|
||||
e.PUT("/properties", PropertyUpdateEndpoint)
|
||||
e.PUT("/properties", Admin(PropertyUpdateEndpoint))
|
||||
|
||||
e.GET("/overview/counter", OverviewCounterEndPoint)
|
||||
e.GET("/overview/sessions", OverviewSessionPoint)
|
||||
@ -174,15 +176,16 @@ func GetCurrentAccount(c echo.Context) (model.User, bool) {
|
||||
}
|
||||
|
||||
func HasPermission(c echo.Context, owner string) bool {
|
||||
// 检测是否为创建者
|
||||
// 检测是否登录
|
||||
account, found := GetCurrentAccount(c)
|
||||
if !found {
|
||||
return false
|
||||
}
|
||||
// 检测是否为管理人员
|
||||
if model.TypeAdmin == account.Type {
|
||||
return true
|
||||
}
|
||||
|
||||
// 检测是否为所有者
|
||||
if owner == account.ID {
|
||||
return true
|
||||
}
|
||||
|
@ -103,6 +103,15 @@ func CloseSessionById(sessionId string, code int, reason string) {
|
||||
CloseSessionByWebSocket(tun.WebSocket, code, reason)
|
||||
}
|
||||
|
||||
s, err := model.FindSessionById(sessionId)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if s.Status == model.Disconnected {
|
||||
return
|
||||
}
|
||||
|
||||
global.Store.Del(sessionId)
|
||||
session := model.Session{}
|
||||
session.ID = sessionId
|
||||
|
@ -27,7 +27,6 @@ func UserCreateEndpoint(c echo.Context) error {
|
||||
if err := model.CreateNewUser(&item); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return Success(c, item)
|
||||
}
|
||||
|
||||
@ -89,3 +88,27 @@ func UserGetEndpoint(c echo.Context) error {
|
||||
|
||||
return Success(c, item)
|
||||
}
|
||||
|
||||
func UserChangePasswordEndpoint(c echo.Context) error {
|
||||
id := c.Param("id")
|
||||
password := c.QueryParam("password")
|
||||
|
||||
passwd, err := utils.Encoder.Encode([]byte(password))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
u := &model.User{
|
||||
Password: string(passwd),
|
||||
}
|
||||
model.UpdateUserById(u, id)
|
||||
return Success(c, "")
|
||||
}
|
||||
|
||||
func UserResetTotpEndpoint(c echo.Context) error {
|
||||
id := c.Param("id")
|
||||
u := &model.User{
|
||||
TOTPSecret: "-",
|
||||
}
|
||||
model.UpdateUserById(u, id)
|
||||
return Success(c, "")
|
||||
}
|
||||
|
Reference in New Issue
Block a user