2017-03-24 05:06:53 +00:00
|
|
|
|
package routers
|
|
|
|
|
|
2017-03-24 09:55:44 +00:00
|
|
|
|
import (
|
2017-04-02 02:38:49 +00:00
|
|
|
|
"github.com/go-macaron/binding"
|
2017-04-07 01:22:00 +00:00
|
|
|
|
"github.com/ouqiang/gocron/routers/install"
|
2017-04-02 02:38:49 +00:00
|
|
|
|
"gopkg.in/macaron.v1"
|
2017-04-07 01:22:00 +00:00
|
|
|
|
"github.com/ouqiang/gocron/routers/task"
|
|
|
|
|
"github.com/ouqiang/gocron/routers/host"
|
2017-04-08 09:15:30 +00:00
|
|
|
|
"github.com/ouqiang/gocron/routers/tasklog"
|
2017-04-13 09:35:59 +00:00
|
|
|
|
"github.com/ouqiang/gocron/modules/utils"
|
|
|
|
|
"github.com/go-macaron/session"
|
|
|
|
|
"github.com/go-macaron/toolbox"
|
|
|
|
|
"strings"
|
|
|
|
|
"github.com/ouqiang/gocron/modules/app"
|
2017-04-23 06:11:53 +00:00
|
|
|
|
"github.com/ouqiang/gocron/modules/logger"
|
2017-04-23 09:00:47 +00:00
|
|
|
|
"github.com/ouqiang/gocron/routers/user"
|
|
|
|
|
"github.com/go-macaron/gzip"
|
2017-04-30 22:02:49 +00:00
|
|
|
|
"github.com/ouqiang/gocron/routers/manage"
|
|
|
|
|
"github.com/ouqiang/gocron/routers/loginlog"
|
2017-05-14 14:09:36 +00:00
|
|
|
|
"github.com/ouqiang/gocron/routers/delaytask"
|
2017-05-23 07:16:39 +00:00
|
|
|
|
"time"
|
|
|
|
|
"strconv"
|
2017-03-24 09:55:44 +00:00
|
|
|
|
)
|
2017-03-24 05:06:53 +00:00
|
|
|
|
|
2017-04-13 09:35:59 +00:00
|
|
|
|
// 静态文件目录
|
|
|
|
|
const StaticDir = "public"
|
|
|
|
|
|
2017-03-24 05:06:53 +00:00
|
|
|
|
// 路由注册
|
|
|
|
|
func Register(m *macaron.Macaron) {
|
2017-04-02 02:38:49 +00:00
|
|
|
|
// 所有GET方法,自动注册HEAD方法
|
|
|
|
|
m.SetAutoHead(true)
|
|
|
|
|
// 首页
|
2017-04-13 09:35:59 +00:00
|
|
|
|
m.Get("/", Home)
|
2017-04-02 02:38:49 +00:00
|
|
|
|
// 系统安装
|
|
|
|
|
m.Group("/install", func() {
|
2017-04-07 01:13:36 +00:00
|
|
|
|
m.Get("", install.Create)
|
|
|
|
|
m.Post("/store", binding.Bind(install.InstallForm{}), install.Store)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
// 用户
|
|
|
|
|
m.Group("/user", func() {
|
2017-04-23 09:00:47 +00:00
|
|
|
|
m.Get("/login", user.Login)
|
|
|
|
|
m.Post("/login", user.ValidateLogin)
|
|
|
|
|
m.Get("/logout", user.Logout)
|
2017-04-30 17:12:07 +00:00
|
|
|
|
m.Get("/editPassword", user.EditPassword)
|
|
|
|
|
m.Post("/editPassword", user.UpdatePassword)
|
2017-04-07 01:13:36 +00:00
|
|
|
|
})
|
|
|
|
|
|
2017-05-14 14:09:36 +00:00
|
|
|
|
// 定时任务
|
2017-04-07 01:13:36 +00:00
|
|
|
|
m.Group("/task", func() {
|
|
|
|
|
m.Get("/create", task.Create)
|
2017-04-07 09:26:46 +00:00
|
|
|
|
m.Post("/store", binding.Bind(task.TaskForm{}), task.Store)
|
2017-04-17 10:04:30 +00:00
|
|
|
|
m.Get("/edit/:id", task.Edit)
|
2017-04-08 09:15:30 +00:00
|
|
|
|
m.Get("", task.Index)
|
|
|
|
|
m.Get("/log", tasklog.Index)
|
2017-04-13 09:35:59 +00:00
|
|
|
|
m.Post("/log/clear", tasklog.Clear)
|
|
|
|
|
m.Post("/remove/:id", task.Remove)
|
|
|
|
|
m.Post("/enable/:id", task.Enable)
|
|
|
|
|
m.Post("/disable/:id", task.Disable)
|
2017-04-21 05:36:45 +00:00
|
|
|
|
m.Get("/run/:id", task.Run)
|
2017-04-07 01:13:36 +00:00
|
|
|
|
})
|
|
|
|
|
|
2017-05-14 14:09:36 +00:00
|
|
|
|
// 延时任务
|
|
|
|
|
m.Group("/delaytask", func() {
|
|
|
|
|
m.Get("", delaytask.Index)
|
|
|
|
|
})
|
|
|
|
|
|
2017-04-07 01:13:36 +00:00
|
|
|
|
// 主机
|
|
|
|
|
m.Group("/host", func() {
|
|
|
|
|
m.Get("/create", host.Create)
|
2017-04-20 01:36:42 +00:00
|
|
|
|
m.Get("/edit/:id", host.Edit)
|
|
|
|
|
m.Get("/ping/:id", host.Ping)
|
2017-04-07 09:26:46 +00:00
|
|
|
|
m.Post("/store", binding.Bind(host.HostForm{}), host.Store)
|
2017-04-08 09:15:30 +00:00
|
|
|
|
m.Get("", host.Index)
|
2017-04-13 09:35:59 +00:00
|
|
|
|
m.Post("/remove/:id", host.Remove)
|
2017-04-07 01:13:36 +00:00
|
|
|
|
})
|
2017-04-23 09:00:47 +00:00
|
|
|
|
|
2017-04-28 03:54:46 +00:00
|
|
|
|
// 管理
|
2017-04-30 22:02:49 +00:00
|
|
|
|
m.Group("/manage", func() {
|
2017-04-30 17:12:07 +00:00
|
|
|
|
m.Group("/slack", func() {
|
2017-04-30 22:02:49 +00:00
|
|
|
|
m.Get("/", manage.Slack)
|
|
|
|
|
m.Get("/edit", manage.EditSlack)
|
|
|
|
|
m.Post("/url", manage.UpdateSlackUrl)
|
|
|
|
|
m.Post("/channel", manage.CreateSlackChannel)
|
|
|
|
|
m.Post("/channel/remove/:id", manage.RemoveSlackChannel)
|
2017-04-28 03:54:46 +00:00
|
|
|
|
})
|
2017-04-30 17:12:07 +00:00
|
|
|
|
m.Group("/mail", func() {
|
2017-04-30 22:02:49 +00:00
|
|
|
|
m.Get("/", manage.Mail)
|
|
|
|
|
m.Get("/edit", manage.EditMail)
|
|
|
|
|
m.Post("/server", binding.Bind(manage.MailServerForm{}), manage.UpdateMailServer)
|
2017-05-12 02:42:03 +00:00
|
|
|
|
m.Post("/server/clear", manage.ClearMailServer)
|
2017-04-30 22:02:49 +00:00
|
|
|
|
m.Post("/user", manage.CreateMailUser)
|
|
|
|
|
m.Post("/user/remove/:id", manage.RemoveMailUser)
|
2017-04-30 17:12:07 +00:00
|
|
|
|
})
|
2017-04-30 22:02:49 +00:00
|
|
|
|
m.Get("/login-log", loginlog.Index)
|
2017-04-30 17:12:07 +00:00
|
|
|
|
})
|
2017-04-28 03:54:46 +00:00
|
|
|
|
|
2017-05-04 02:47:14 +00:00
|
|
|
|
// API
|
|
|
|
|
m.Group("/api/v1", func() {
|
2017-05-09 05:42:49 +00:00
|
|
|
|
m.Route("/tasklog/update-status", "GET,POST", tasklog.UpdateStatus)
|
2017-05-10 08:09:10 +00:00
|
|
|
|
m.Post("/tasklog/remove/:id", tasklog.Remove)
|
2017-05-15 14:52:47 +00:00
|
|
|
|
m.Post("/delaytask/push", delaytask.Create)
|
2017-05-16 03:03:28 +00:00
|
|
|
|
m.Post("/delaytask/log/remove/:id", delaytask.Remove)
|
2017-05-23 07:16:39 +00:00
|
|
|
|
}, apiAuth);
|
2017-05-04 02:47:14 +00:00
|
|
|
|
|
2017-04-23 09:00:47 +00:00
|
|
|
|
// 404错误
|
|
|
|
|
m.NotFound(func(ctx *macaron.Context) {
|
|
|
|
|
if isGetRequest(ctx) && !isAjaxRequest(ctx) {
|
|
|
|
|
ctx.Data["Title"] = "404 - NOT FOUND"
|
|
|
|
|
ctx.HTML(404, "error/404")
|
|
|
|
|
} else {
|
|
|
|
|
json := utils.JsonResponse{}
|
|
|
|
|
ctx.Resp.Write([]byte(json.Failure(utils.NotFound, "您访问的地址不存在")))
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
// 50x错误
|
|
|
|
|
m.InternalServerError(func(ctx *macaron.Context) {
|
|
|
|
|
logger.Debug("500错误")
|
|
|
|
|
if isGetRequest(ctx) && !isAjaxRequest(ctx) {
|
|
|
|
|
ctx.Data["Title"] = "500 - INTERNAL SERVER ERROR"
|
|
|
|
|
ctx.HTML(500, "error/500")
|
|
|
|
|
} else {
|
|
|
|
|
json := utils.JsonResponse{}
|
|
|
|
|
ctx.Resp.Write([]byte(json.Failure(utils.ServerError, "网站暂时无法访问,请稍后再试")))
|
|
|
|
|
}
|
|
|
|
|
})
|
2017-04-13 09:35:59 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 中间件注册
|
|
|
|
|
func RegisterMiddleware(m *macaron.Macaron) {
|
|
|
|
|
m.Use(macaron.Logger())
|
|
|
|
|
m.Use(macaron.Recovery())
|
2017-04-30 17:12:07 +00:00
|
|
|
|
if macaron.Env != macaron.DEV {
|
|
|
|
|
m.Use(gzip.Gziper())
|
|
|
|
|
}
|
2017-04-13 09:35:59 +00:00
|
|
|
|
m.Use(macaron.Static(StaticDir))
|
|
|
|
|
m.Use(macaron.Renderer(macaron.RenderOptions{
|
|
|
|
|
Directory: "templates",
|
|
|
|
|
Extensions: []string{".html"},
|
|
|
|
|
// 模板语法分隔符,默认为 ["{{", "}}"]
|
|
|
|
|
Delims: macaron.Delims{"{{{", "}}}"},
|
|
|
|
|
// 追加的 Content-Type 头信息,默认为 "UTF-8"
|
|
|
|
|
Charset: "UTF-8",
|
|
|
|
|
// 渲染具有缩进格式的 JSON,默认为不缩进
|
|
|
|
|
IndentJSON: true,
|
|
|
|
|
// 渲染具有缩进格式的 XML,默认为不缩进
|
|
|
|
|
IndentXML: true,
|
|
|
|
|
}))
|
2017-04-25 17:47:38 +00:00
|
|
|
|
m.Use(session.Sessioner(session.Options{
|
|
|
|
|
Provider: "file",
|
|
|
|
|
ProviderConfig: app.DataDir + "/sessions",
|
|
|
|
|
}))
|
2017-04-13 09:35:59 +00:00
|
|
|
|
m.Use(toolbox.Toolboxer(m))
|
2017-04-23 09:00:47 +00:00
|
|
|
|
checkAppInstall(m)
|
2017-05-04 08:50:41 +00:00
|
|
|
|
m.Use(func(ctx *macaron.Context, sess session.Store){
|
|
|
|
|
if app.Installed {
|
|
|
|
|
ipAuth(ctx)
|
|
|
|
|
userAuth(ctx, sess)
|
|
|
|
|
setShareData(ctx, sess)
|
|
|
|
|
}
|
|
|
|
|
})
|
2017-04-23 09:00:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-05-10 09:58:05 +00:00
|
|
|
|
// region 自定义中间件
|
|
|
|
|
|
|
|
|
|
/** 系统未安装,重定向到安装页面 **/
|
2017-04-23 09:00:47 +00:00
|
|
|
|
func checkAppInstall(m *macaron.Macaron) {
|
2017-04-13 09:35:59 +00:00
|
|
|
|
m.Use(func(ctx *macaron.Context) {
|
|
|
|
|
installUrl := "/install"
|
2017-04-22 15:39:33 +00:00
|
|
|
|
if strings.HasPrefix(ctx.Req.URL.Path, installUrl) {
|
2017-04-13 09:35:59 +00:00
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if !app.Installed {
|
|
|
|
|
ctx.Redirect(installUrl)
|
|
|
|
|
}
|
|
|
|
|
})
|
2017-04-23 09:00:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-05-04 06:02:50 +00:00
|
|
|
|
// IP验证, 通过反向代理访问gocron,需设置Header X-Real-IP才能获取到客户端真实IP
|
2017-05-04 08:50:41 +00:00
|
|
|
|
func ipAuth(ctx *macaron.Context) {
|
|
|
|
|
allowIpsStr := app.Setting.Key("allow_ips").String()
|
|
|
|
|
if allowIpsStr == "" {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
clientIp := ctx.RemoteAddr()
|
|
|
|
|
allowIps := strings.Split(allowIpsStr, ",")
|
|
|
|
|
if !utils.InStringSlice(allowIps, clientIp) {
|
|
|
|
|
logger.Warnf("非法IP访问-%s", clientIp)
|
|
|
|
|
ctx.Status(403)
|
|
|
|
|
}
|
2017-05-04 06:02:50 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-04-23 09:00:47 +00:00
|
|
|
|
// 用户认证
|
2017-05-04 08:50:41 +00:00
|
|
|
|
func userAuth(ctx *macaron.Context, sess session.Store) {
|
|
|
|
|
if user.IsLogin(sess) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
uri := ctx.Req.URL.Path
|
|
|
|
|
found := false
|
|
|
|
|
excludePaths := []string{"/install", "/user/login", "/api"}
|
|
|
|
|
for _, path := range excludePaths {
|
|
|
|
|
if strings.HasPrefix(uri, path) {
|
|
|
|
|
found = true
|
|
|
|
|
break
|
2017-04-23 09:00:47 +00:00
|
|
|
|
}
|
2017-05-04 08:50:41 +00:00
|
|
|
|
}
|
|
|
|
|
if !found {
|
|
|
|
|
ctx.Redirect("/user/login")
|
|
|
|
|
}
|
2017-04-23 09:00:47 +00:00
|
|
|
|
}
|
|
|
|
|
|
2017-05-10 09:58:05 +00:00
|
|
|
|
/** 设置共享数据 **/
|
2017-05-04 08:50:41 +00:00
|
|
|
|
func setShareData(ctx *macaron.Context, sess session.Store) {
|
|
|
|
|
ctx.Data["URI"] = ctx.Req.URL.Path
|
|
|
|
|
urlPath := strings.TrimPrefix(ctx.Req.URL.Path, "/")
|
|
|
|
|
paths := strings.Split(urlPath, "/")
|
|
|
|
|
ctx.Data["Controller"] = ""
|
|
|
|
|
ctx.Data["Action"] = ""
|
|
|
|
|
if len(paths) > 0 {
|
|
|
|
|
ctx.Data["Controller"] = paths[0]
|
|
|
|
|
}
|
|
|
|
|
if len(paths) > 1 {
|
|
|
|
|
ctx.Data["Action"] = paths[1]
|
|
|
|
|
}
|
|
|
|
|
ctx.Data["LoginUsername"] = user.Username(sess)
|
|
|
|
|
ctx.Data["LoginUid"] = user.Uid(sess)
|
|
|
|
|
ctx.Data["AppName"] = app.Setting.Key("app.name").String()
|
2017-04-02 02:19:52 +00:00
|
|
|
|
}
|
2017-04-08 09:15:30 +00:00
|
|
|
|
|
2017-05-23 07:16:39 +00:00
|
|
|
|
/** API接口签名验证 **/
|
|
|
|
|
func apiAuth(ctx *macaron.Context) {
|
|
|
|
|
apiSignEnable := app.Setting.Key("app.sign.enable").String()
|
|
|
|
|
apiSignEnable = strings.TrimSpace(apiSignEnable)
|
|
|
|
|
if apiSignEnable == "false" {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
apiKey := app.Setting.Key("api.key").String()
|
|
|
|
|
apiSecret := app.Setting.Key("api.secret").String()
|
|
|
|
|
apiKey = strings.TrimSpace(apiKey)
|
|
|
|
|
apiSecret = strings.TrimSpace(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
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// endregion
|
|
|
|
|
|
2017-04-08 09:15:30 +00:00
|
|
|
|
func isAjaxRequest(ctx *macaron.Context) bool {
|
|
|
|
|
req := ctx.Req.Header.Get("X-Requested-With")
|
|
|
|
|
if req == "XMLHttpRequest" {
|
|
|
|
|
return true
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func isGetRequest(ctx *macaron.Context) bool {
|
|
|
|
|
return ctx.Req.Method == "GET"
|
|
|
|
|
}
|