next-terminal/server/app/middleware/auth.go
2022-10-23 20:05:13 +08:00

139 lines
3.4 KiB
Go

package middleware
import (
"next-terminal/server/common/nt"
"strings"
"next-terminal/server/api"
"next-terminal/server/dto"
"next-terminal/server/global/cache"
"next-terminal/server/service"
"github.com/labstack/echo/v4"
"github.com/ucarion/urlpath"
)
var anonymousUrls = []string{"/login", "/static", "/favicon.ico", "/logo.svg", "/branding"}
var allowUrls = []urlpath.Path{
urlpath.New("/account/info"),
urlpath.New("/share-sessions/:id"),
urlpath.New("/sessions"),
urlpath.New("/sessions/:id/tunnel"),
urlpath.New("/sessions/:id/connect"),
urlpath.New("/sessions/:id/resize"),
urlpath.New("/sessions/:id/stats"),
urlpath.New("/sessions/:id/ls"),
urlpath.New("/sessions/:id/download"),
urlpath.New("/sessions/:id/upload"),
urlpath.New("/sessions/:id/edit"),
urlpath.New("/sessions/:id/mkdir"),
urlpath.New("/sessions/:id/rm"),
urlpath.New("/sessions/:id/rename"),
urlpath.New("/sessions/:id/ssh"),
}
func Auth(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
uri := c.Request().RequestURI
if uri == "/" || strings.HasPrefix(uri, "/#") {
return next(c)
}
// 路由拦截 - 登录身份、资源权限判断等
for i := range anonymousUrls {
if strings.HasPrefix(uri, anonymousUrls[i]) {
return next(c)
}
}
token := api.GetToken(c)
if token == "" {
return api.Fail(c, 401, "您的登录信息已失效,请重新登录后再试。")
}
v, found := cache.TokenManager.Get(token)
if !found {
return api.Fail(c, 401, "您的登录信息已失效,请重新登录后再试。")
}
authorization := v.(dto.Authorization)
if strings.EqualFold(nt.LoginToken, authorization.Type) {
if authorization.Remember {
// 记住登录有效期两周
cache.TokenManager.Set(token, authorization, cache.RememberMeExpiration)
} else {
cache.TokenManager.Set(token, authorization, cache.NotRememberExpiration)
}
}
if strings.HasPrefix(uri, "/account") {
return next(c)
}
if strings.HasPrefix(uri, "/worker") {
return next(c)
}
// 放行接入相关接口
uri = strings.Split(uri, "?")[0]
for _, url := range allowUrls {
_, ok := url.Match(uri)
if ok {
return next(c)
}
}
account, _ := api.GetCurrentAccount(c)
if service.UserService.IsSuperAdmin(account.ID) {
return next(c)
}
var roles []string
v, ok := cache.UserRolesManager.Get(account.ID)
if ok {
roles = v.([]string)
if len(roles) == 0 {
roles, _ = service.RoleService.GetRolesByUserId(account.ID)
cache.UserRolesManager.SetDefault(account.ID, roles)
}
} else {
roles, _ = service.RoleService.GetRolesByUserId(account.ID)
cache.UserRolesManager.SetDefault(account.ID, roles)
}
urlPath := c.Request().URL.Path
for _, role := range roles {
menus := service.RoleService.GetMenuListByRole(role)
for _, menu := range menus {
permissions := service.MenuService.GetPermissionByMenu(menu)
for _, perm := range permissions {
_, ok := perm.Match(urlPath)
if ok {
return next(c)
}
}
}
}
return api.Fail(c, 403, "permission denied")
}
}
func Admin(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
account, found := api.GetCurrentAccount(c)
if !found {
return api.Fail(c, 401, "您的登录信息已失效,请重新登录后再试。")
}
if account.Type != nt.TypeAdmin {
return api.Fail(c, 403, "permission denied.")
}
return next(c)
}
}