gocron/internal/routers/routers.go

316 lines
7.4 KiB
Go
Raw Normal View History

2017-03-24 05:06:53 +00:00
package routers
2017-03-24 09:55:44 +00:00
import (
2018-05-13 14:48:37 +00:00
"io"
"log"
"net/http"
2018-01-30 11:26:04 +00:00
"strconv"
"strings"
"time"
2017-09-16 09:58:33 +00:00
"github.com/go-macaron/binding"
"github.com/go-macaron/gzip"
"github.com/go-macaron/toolbox"
2018-03-25 05:12:12 +00:00
"github.com/ouqiang/gocron/internal/modules/app"
"github.com/ouqiang/gocron/internal/modules/logger"
"github.com/ouqiang/gocron/internal/modules/utils"
"github.com/ouqiang/gocron/internal/routers/host"
"github.com/ouqiang/gocron/internal/routers/install"
"github.com/ouqiang/gocron/internal/routers/loginlog"
"github.com/ouqiang/gocron/internal/routers/manage"
"github.com/ouqiang/gocron/internal/routers/task"
"github.com/ouqiang/gocron/internal/routers/tasklog"
"github.com/ouqiang/gocron/internal/routers/user"
2018-05-13 14:48:37 +00:00
"github.com/rakyll/statik/fs"
2017-09-16 09:58:33 +00:00
"gopkg.in/macaron.v1"
2018-05-13 14:48:37 +00:00
_ "github.com/ouqiang/gocron/internal/statik"
2017-03-24 09:55:44 +00:00
)
2017-03-24 05:06:53 +00:00
2018-05-20 07:24:31 +00:00
const (
urlPrefix = "/api"
staticDir = "public"
)
2018-05-13 14:48:37 +00:00
var statikFS http.FileSystem
func init() {
var err error
statikFS, err = fs.New()
if err != nil {
log.Fatal(err)
}
}
2018-05-20 07:24:31 +00:00
// Register 路由注册
2017-03-24 05:06:53 +00:00
func Register(m *macaron.Macaron) {
2018-05-02 12:41:41 +00:00
m.SetURLPrefix(urlPrefix)
2017-09-16 09:58:33 +00:00
// 所有GET方法自动注册HEAD方法
m.SetAutoHead(true)
m.Get("/", func(ctx *macaron.Context) {
2018-05-13 14:48:37 +00:00
file, err := statikFS.Open("/index.html")
if err != nil {
logger.Error("读取首页文件失败: %s", err)
ctx.WriteHeader(http.StatusInternalServerError)
return
}
2018-05-20 07:24:31 +00:00
2018-05-13 14:48:37 +00:00
io.Copy(ctx.Resp, file)
})
2017-09-16 09:58:33 +00:00
// 系统安装
m.Group("/install", func() {
m.Post("/store", binding.Bind(install.InstallForm{}), install.Store)
2018-05-26 03:16:36 +00:00
m.Get("/status", func(ctx *macaron.Context) string {
jsonResp := utils.JsonResponse{}
return jsonResp.Success("", app.Installed)
})
2017-09-16 09:58:33 +00:00
})
2017-04-07 01:13:36 +00:00
2017-09-16 09:58:33 +00:00
// 用户
m.Group("/user", func() {
2017-10-01 13:49:46 +00:00
m.Get("", user.Index)
2018-05-02 12:41:41 +00:00
m.Get("/:id", user.Detail)
2017-10-01 13:49:46 +00:00
m.Post("/store", binding.Bind(user.UserForm{}), user.Store)
m.Post("/remove/:id", user.Remove)
2017-09-16 09:58:33 +00:00
m.Post("/login", user.ValidateLogin)
2017-10-01 13:49:46 +00:00
m.Post("/enable/:id", user.Enable)
m.Post("/disable/:id", user.Disable)
m.Post("/editMyPassword", user.UpdateMyPassword)
m.Post("/editPassword/:id", user.UpdatePassword)
2017-09-16 09:58:33 +00:00
})
2017-04-07 01:13:36 +00:00
2017-09-16 09:58:33 +00:00
// 定时任务
m.Group("/task", func() {
m.Post("/store", binding.Bind(task.TaskForm{}), task.Store)
2018-05-02 12:41:41 +00:00
m.Get("/:id", task.Detail)
2017-09-16 09:58:33 +00:00
m.Get("", task.Index)
m.Get("/log", tasklog.Index)
m.Post("/log/clear", tasklog.Clear)
m.Post("/log/stop", tasklog.Stop)
2017-09-16 09:58:33 +00:00
m.Post("/remove/:id", task.Remove)
m.Post("/enable/:id", task.Enable)
m.Post("/disable/:id", task.Disable)
m.Get("/run/:id", task.Run)
})
2017-04-07 01:13:36 +00:00
2017-09-16 09:58:33 +00:00
// 主机
m.Group("/host", func() {
2018-05-02 12:41:41 +00:00
m.Get("/:id", host.Detail)
2017-09-16 09:58:33 +00:00
m.Post("/store", binding.Bind(host.HostForm{}), host.Store)
m.Get("", host.Index)
m.Get("/all", host.All)
2017-09-16 09:58:33 +00:00
m.Get("/ping/:id", host.Ping)
m.Post("/remove/:id", host.Remove)
})
2017-04-23 09:00:47 +00:00
2017-09-16 09:58:33 +00:00
// 管理
2018-05-02 12:41:41 +00:00
m.Group("/system", func() {
2017-09-16 09:58:33 +00:00
m.Group("/slack", func() {
m.Get("", manage.Slack)
m.Post("/update", manage.UpdateSlack)
2017-09-16 09:58:33 +00:00
m.Post("/channel", manage.CreateSlackChannel)
m.Post("/channel/remove/:id", manage.RemoveSlackChannel)
})
m.Group("/mail", func() {
m.Get("", manage.Mail)
m.Post("/update", binding.Bind(manage.MailServerForm{}), manage.UpdateMail)
2017-09-16 09:58:33 +00:00
m.Post("/user", manage.CreateMailUser)
m.Post("/user/remove/:id", manage.RemoveMailUser)
})
m.Group("/webhook", func() {
m.Get("", manage.WebHook)
m.Post("/update", manage.UpdateWebHook)
})
2017-09-16 09:58:33 +00:00
m.Get("/login-log", loginlog.Index)
})
2017-04-28 03:54:46 +00:00
2017-09-16 09:58:33 +00:00
// API
2018-05-02 12:41:41 +00:00
m.Group("/v1", func() {
2017-09-16 09:58:33 +00:00
m.Post("/tasklog/remove/:id", tasklog.Remove)
m.Post("/task/enable/:id", task.Enable)
m.Post("/task/disable/:id", task.Disable)
}, apiAuth)
2017-05-04 02:47:14 +00:00
2017-09-16 09:58:33 +00:00
// 404错误
2018-05-02 12:41:41 +00:00
m.NotFound(func(ctx *macaron.Context) string {
jsonResp := utils.JsonResponse{}
return jsonResp.Failure(utils.NotFound, "您访问的页面不存在")
2017-09-16 09:58:33 +00:00
})
// 50x错误
2018-05-02 12:41:41 +00:00
m.InternalServerError(func(ctx *macaron.Context) string {
jsonResp := utils.JsonResponse{}
return jsonResp.Failure(utils.ServerError, "服务器内部错误, 请稍后再试")
2017-09-16 09:58:33 +00:00
})
2017-04-13 09:35:59 +00:00
}
// 中间件注册
func RegisterMiddleware(m *macaron.Macaron) {
2017-09-16 09:58:33 +00:00
m.Use(macaron.Logger())
m.Use(macaron.Recovery())
if macaron.Env != macaron.DEV {
m.Use(gzip.Gziper())
}
2018-05-13 14:48:37 +00:00
m.Use(
macaron.Static(
"",
macaron.StaticOptions{
Prefix: staticDir,
FileSystem: statikFS,
},
),
)
2018-05-02 12:41:41 +00:00
if macaron.Env == macaron.DEV {
m.Use(toolbox.Toolboxer(m))
}
m.Use(macaron.Renderer())
m.Use(checkAppInstall)
2018-05-07 13:57:19 +00:00
m.Use(ipAuth)
2018-05-02 12:41:41 +00:00
m.Use(userAuth)
m.Use(urlAuth)
2017-04-23 09:00:47 +00:00
}
2017-05-10 09:58:05 +00:00
// region 自定义中间件
2018-05-02 12:41:41 +00:00
/** 检测应用是否已安装 **/
func checkAppInstall(ctx *macaron.Context) {
2018-05-07 13:57:19 +00:00
if app.Installed {
2018-05-02 12:41:41 +00:00
return
}
2018-05-26 03:16:36 +00:00
if strings.HasPrefix(ctx.Req.URL.Path, "/install") || ctx.Req.URL.Path == "/" {
return
2018-05-02 12:41:41 +00:00
}
jsonResp := utils.JsonResponse{}
data := jsonResp.Failure(utils.AppNotInstall, "应用未安装")
ctx.Write([]byte(data))
2017-04-23 09:00:47 +00:00
}
// IP验证, 通过反向代理访问gocron需设置Header X-Real-IP才能获取到客户端真实IP
2017-09-16 09:58:33 +00:00
func ipAuth(ctx *macaron.Context) {
2018-05-07 13:57:19 +00:00
if !app.Installed {
return
}
2017-09-16 09:58:33 +00:00
allowIpsStr := app.Setting.AllowIps
if allowIpsStr == "" {
return
}
clientIp := ctx.RemoteAddr()
allowIps := strings.Split(allowIpsStr, ",")
2018-05-02 12:41:41 +00:00
if utils.InStringSlice(allowIps, clientIp) {
return
2017-09-16 09:58:33 +00:00
}
2018-05-02 12:41:41 +00:00
logger.Warnf("非法IP访问-%s", clientIp)
jsonResp := utils.JsonResponse{}
data := jsonResp.Failure(utils.UnauthorizedError, "您无权限访问")
ctx.Write([]byte(data))
}
2017-04-23 09:00:47 +00:00
// 用户认证
2018-05-02 12:41:41 +00:00
func userAuth(ctx *macaron.Context) {
2018-05-07 13:57:19 +00:00
if !app.Installed {
return
}
2018-05-02 12:41:41 +00:00
user.RestoreToken(ctx)
if user.IsLogin(ctx) {
2017-09-16 09:58:33 +00:00
return
}
uri := strings.TrimRight(ctx.Req.URL.Path, "/")
if strings.HasPrefix(uri, "/v1") {
return
}
2018-05-26 03:16:36 +00:00
excludePaths := []string{"", "/user/login", "/install/status"}
2017-09-16 09:58:33 +00:00
for _, path := range excludePaths {
if uri == path {
2018-05-02 12:41:41 +00:00
return
2017-09-16 09:58:33 +00:00
}
}
2018-05-02 12:41:41 +00:00
jsonResp := utils.JsonResponse{}
data := jsonResp.Failure(utils.AuthError, "认证失败")
ctx.Write([]byte(data))
2017-04-23 09:00:47 +00:00
}
// URL权限验证
2018-05-02 12:41:41 +00:00
func urlAuth(ctx *macaron.Context) {
2018-05-07 13:57:19 +00:00
if !app.Installed {
return
}
2018-05-02 12:41:41 +00:00
if user.IsAdmin(ctx) {
return
}
2018-05-02 12:41:41 +00:00
uri := strings.TrimRight(ctx.Req.URL.Path, "/")
if strings.HasPrefix(uri, "/v1") {
2017-12-25 15:55:23 +00:00
return
}
// 普通用户允许访问的URL地址
allowPaths := []string{
"",
2018-05-26 03:16:36 +00:00
"/install/status",
"/task",
"/task/log",
"/host",
"/user/login",
"/user/editMyPassword",
}
for _, path := range allowPaths {
if path == uri {
return
}
}
2018-05-02 12:41:41 +00:00
jsonResp := utils.JsonResponse{}
2018-05-02 12:41:41 +00:00
data := jsonResp.Failure(utils.UnauthorizedError, "您无权限访问")
ctx.Write([]byte(data))
2017-04-02 02:19:52 +00:00
}
2017-05-23 07:16:39 +00:00
/** API接口签名验证 **/
2017-09-16 09:58:33 +00:00
func apiAuth(ctx *macaron.Context) {
2018-05-07 13:57:19 +00:00
if !app.Installed {
return
}
2017-09-16 09:58:33 +00:00
if !app.Setting.ApiSignEnable {
return
}
apiKey := strings.TrimSpace(app.Setting.ApiKey)
apiSecret := strings.TrimSpace(app.Setting.ApiSecret)
json := utils.JsonResponse{}
if apiKey == "" || apiSecret == "" {
msg := json.CommonFailure("使用API前, 请先配置密钥")
ctx.Write([]byte(msg))
return
}
currentTimestamp := time.Now().Unix()
time := ctx.QueryInt64("time")
if time <= 0 {
msg := json.CommonFailure("参数time不能为空")
ctx.Write([]byte(msg))
return
}
if time < (currentTimestamp - 1800) {
msg := json.CommonFailure("time无效")
ctx.Write([]byte(msg))
return
}
sign := ctx.QueryTrim("sign")
if sign == "" {
msg := json.CommonFailure("参数sign不能为空")
ctx.Write([]byte(msg))
return
}
raw := apiKey + strconv.FormatInt(time, 10) + strings.TrimSpace(ctx.Req.URL.Path) + apiSecret
realSign := utils.Md5(raw)
if sign != realSign {
msg := json.CommonFailure("签名验证失败")
ctx.Write([]byte(msg))
return
}
2017-05-23 07:16:39 +00:00
}
// endregion