diff --git a/src/contexts/aaa/aaa.go b/src/contexts/aaa/aaa.go index b67587e6..5aa4b830 100644 --- a/src/contexts/aaa/aaa.go +++ b/src/contexts/aaa/aaa.go @@ -16,6 +16,7 @@ import ( "io/ioutil" "math/big" "math/rand" + "strings" "time" ) @@ -450,7 +451,7 @@ var Index = &ctx.Context{Name: "aaa", Help: "认证中心", }}, "md5": &ctx.Command{Name: "md5 content", Help: "数字摘要", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if aaa, ok := m.Target().Server.(*AAA); m.Assert(ok) { - h := md5.Sum(aaa.Input(arg[0])) + h := md5.Sum(aaa.Input(strings.Join(arg, ""))) m.Echo(hex.EncodeToString(h[:])) } }}, diff --git a/src/contexts/cli/cli.go b/src/contexts/cli/cli.go index 3e2f99e5..c3ef3011 100644 --- a/src/contexts/cli/cli.go +++ b/src/contexts/cli/cli.go @@ -619,12 +619,12 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", return } - m.Confv("source_list", -1, map[string]interface{}{ - "source_time": m.Time(), - "source_ctx": m.Option("current_ctx"), - "source_cmd": strings.Join(arg, " "), - }) - + // m.Confv("source_list", -1, map[string]interface{}{ + // "source_time": m.Time(), + // "source_ctx": m.Option("current_ctx"), + // "source_cmd": strings.Join(arg, " "), + // }) + // if m.Options("current_ctx") { args := []string{"context", m.Option("current_ctx")} arg = append(args, arg...) diff --git a/src/contexts/web/web.go b/src/contexts/web/web.go index 488c3fc9..d55fff6d 100644 --- a/src/contexts/web/web.go +++ b/src/contexts/web/web.go @@ -18,6 +18,7 @@ import ( "path/filepath" "runtime" "strings" + "time" ) type MUX interface { @@ -113,16 +114,14 @@ func (web *WEB) HandleCmd(m *ctx.Message, key string, cmd *ctx.Command) { if k == "ticket" { m.Log("info", "hide ticket %v %v %v %v", k, v, r.URL, r.Header.Get("index_path")) uri, _ := r.URL.Parse(r.Header.Get("index_path")) - http.Redirect(w, r, uri.Path, http.StatusTemporaryRedirect) + http.Redirect(w, r, uri.Path+"?workflow="+uri.Query().Get("workflow"), http.StatusTemporaryRedirect) return } } if msg.Confs("cas_url") { if !cas.IsAuthenticated(r) && !msg.Confs("skip_cas") { - r.URL.Path = r.Header.Get("index_path") - w.Header().Add("Access-Control-Allow-Origin", "*") - w.Header().Add("Vary", "*") + r.URL, _ = r.URL.Parse(r.Header.Get("index_path")) cas.RedirectToLogin(w, r) return } @@ -324,6 +323,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", "protocol": &ctx.Config{Name: "protocol", Value: "http", Help: "服务协议"}, "cert": &ctx.Config{Name: "cert", Value: "etc/cert.pem", Help: "路由数量"}, "key": &ctx.Config{Name: "key", Value: "etc/key.pem", Help: "路由数量"}, + "site": &ctx.Config{Name: "site", Value: "", Help: "网站地址"}, "cas_url": &ctx.Config{Name: "cas_url", Value: "", Help: "模板路径"}, "library_dir": &ctx.Config{Name: "library_dir", Value: "usr/librarys", Help: "模板路径"}, @@ -349,6 +349,12 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", map[string]interface{}{"componet_name": "tail", "template": "tail"}, }, }, Help: "组件列表"}, + + "workflow": &ctx.Config{Name: "workflow", Value: map[string]interface{}{}, Help: "默认组件"}, + "workflow_view": &ctx.Config{Name: "workflow_view", Value: map[string]interface{}{ + "base": []interface{}{"key", "share", "comment", "creator", "create_time", "modify_time", "commands"}, + "link": []interface{}{"share", "comment", "creator", "link"}, + }, Help: "默认组件"}, }, Commands: map[string]*ctx.Command{ "client": &ctx.Command{Name: "client address [output [editor]]", Help: "添加浏览器配置, address: 默认地址, output: 输出路径, editor: 编辑器", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { @@ -838,6 +844,44 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", m.Appendv("login", login) m.Echo(sessid) }}, + "workflow": &ctx.Command{Name: "workflow", Help: "任务列表", Form: map[string]int{"view": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + flow := m.Confv("workflow").(map[string]interface{}) + if len(arg) > 0 && arg[0] == "delete" { + delete(flow, arg[1]) + arg = arg[2:] + } + + if len(arg) == 0 { + view := "base" + if m.Has("view") { + view = m.Option("view") + } + for _, v := range flow { + val := v.(map[string]interface{}) + for _, k := range m.Confv("workflow_view", view).([]interface{}) { + switch v := val[k.(string)].(type) { + case map[string]interface{}: + b, _ := json.Marshal(v) + m.Add("append", "commands", string(b)) + case nil: + m.Add("append", k.(string), "") + default: + m.Add("append", k.(string), v) + } + } + } + m.Table() + return + } + + if len(arg) > 1 { + m.Confv("workflow", strings.Split(arg[0], "."), arg[1]) + } + + msg := m.Spawn().Put("option", "_cache", flow).Cmd("trans", "_cache", arg[0]) + m.Copy(msg, "append").Copy(msg, "result") + }}, + "/upload": &ctx.Command{Name: "/upload", Help: "上传文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { r := m.Optionv("request").(*http.Request) f, h, e := r.FormFile("upload") @@ -913,7 +957,43 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", } } - m.Log("info", "group: %v, name: %v, right: %v", group, order, right) + protected := false + workflow, ok := m.Confv("workflow", m.Option("workflow")).(map[string]interface{}) + if right { + if !ok { // 创建工作流 + create_time := time.Now().Format(m.Conf("time_format")) + id := m.Option("workflow") + if id == "" { + id = m.Sess("aaa").Cmd("md5", m.Option("remote_addr"), create_time).Result(0) + } + m.Confv("workflow", id, map[string]interface{}{ + "remote_addr": m.Option("remote_addr"), + "modify_time": create_time, + "create_time": create_time, + "creator": m.Option("username"), + "share": "protected", + "link": fmt.Sprintf("%s?workflow=%s", m.Conf("site"), id), + "comment": "default flow", + "key": id, + "commands": map[string]interface{}{}, + }) + + m.Append("redirect", fmt.Sprintf("?workflow=%s", id)) + return + } + + if workflow["creator"].(string) != m.Option("username") { + switch workflow["share"].(string) { + case "private": + return + case "protected": + protected = true + case "public": + } + } + } + m.Log("info", "group: %v, order: %v, right: %v, share: %v", group, order, right, workflow["share"]) + for count := 0; count == 0; group, order, right = "login", "", true { for _, v := range m.Confv("componet", group).([]interface{}) { val := v.(map[string]interface{}) @@ -972,6 +1052,10 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", } args := []string{} + if val["componet_cmd"] != nil { + args = append(args, val["componet_cmd"].(string)) + } + if val["arguments"] != nil { for _, v := range val["arguments"].([]interface{}) { switch value := v.(type) { @@ -983,7 +1067,12 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", if order != "" || (val["pre_run"] != nil && val["pre_run"].(bool)) { if val["componet_cmd"] != nil { - msg.Cmd(val["componet_cmd"], args) + if !protected { + m.Confv("workflow", []interface{}{m.Option("workflow"), "commands", m.Option("componet_name_order")}, args[1:]) + m.Confv("workflow", []interface{}{m.Option("workflow"), "modify_time"}, time.Now().Format(m.Conf("time_format"))) + } + + msg.Cmd(args) if msg.Options("download_file") { m.Append("page_redirect", fmt.Sprintf("/download/%s", msg.Sess("nfs").Copy(msg, "append").Copy(msg, "result").Cmd("export", msg.Option("download_file")).Result(0))) diff --git a/usr/librarys/code.js b/usr/librarys/code.js index 85b552c7..3da7e64f 100644 --- a/usr/librarys/code.js +++ b/usr/librarys/code.js @@ -49,12 +49,44 @@ function add_sort(append, field, cb) { if (tr.childNodes[i].innerText.startsWith(field)) { typeof cb == "function" && cb(event) } + var has = document.querySelector("td.clip") + has && (has.className = "") + target.className = "clip" copy_to_clipboard(target.innerText) } } } } } +function del_command(target) { + var can_remove = false + var order = -1 + for (var p = target; p.parentElement && p.tagName != "FIELDSET"; p = p.parentElement) { + if (p.tagName == "FORM" && p.dataset["componet_name_alias"]) { + can_remove = true + order = p.dataset["componet_name_order"] + } + } + if (p && can_remove) { + p.parentElement.removeChild(p) + } + + for (;order < code.ncommand; order++) { + var input = document.querySelector("form.option.command"+order+" input[name=cmd]") + if (input) { + input.focus() + return + } + } + for (;order >= 0; order--) { + var input = document.querySelector("form.option.command"+(order? order: "")+" input[name=cmd]") + code.ncommand = order+1 + if (input) { + input.focus() + return + } + } +} function add_command() { var name = "command"+code.ncommand++ @@ -66,6 +98,7 @@ function add_command() { "dataset": { "componet_group": "index", "componet_name": "command", + "componet_workflow": context.Search("workflow"), "componet_name_alias": name, "componet_name_order": code.ncommand-1, } @@ -79,6 +112,7 @@ function add_command() { add_sort(append_child(fieldset, "table", {"className": "append "+name})) append_child(append_child(fieldset, "code", {"className": "result "+name}), "pre") + return fieldset } function send_command(form, cb) { @@ -473,33 +507,7 @@ function onaction(event, action) { add_command() break case "q": - var can_remove = false - var order = -1 - for (var p = target; p.parentElement && p.tagName != "FIELDSET"; p = p.parentElement) { - if (p.tagName == "FORM" && p.dataset["componet_name_alias"]) { - can_remove = true - order = p.dataset["componet_name_order"] - } - } - if (p && can_remove) { - p.parentElement.removeChild(p) - } - - for (;order < code.ncommand; order++) { - var input = document.querySelector("form.option.command"+order+" input[name=cmd]") - if (input) { - input.focus() - return - } - } - for (;order >= 0; order--) { - var input = document.querySelector("form.option.command"+(order? order: "")+" input[name=cmd]") - code.ncommand = order+1 - if (input) { - input.focus() - return - } - } + del_command(event.target) break } } @@ -657,6 +665,9 @@ function init_command() { insert_button(append, "exec", function(event) { send_command(option) }) + insert_button(append, "add", function(event) { + add_command() + }) } function init_userinfo() { @@ -670,6 +681,38 @@ function init_userinfo() { }) } +function init_workflow() { + var max = 0 + for (var k in workflow.commands) { + if (parseInt(k) > max) { + max = parseInt(k) + } + } + + if (workflow.commands[""]) { + var option = document.querySelector("form.option.command") + var cmd = option.querySelector("input[name=cmd]") + cmd.value = workflow.commands[""].join(" ") + check_option(option) + } + + for (var i = 1; i <= max; i++) { + var fieldset = add_command() + if (workflow.commands[i]) { + var cmd = fieldset.querySelector("input[name=cmd]") + cmd.value = workflow.commands[i].join(" ") + var option = fieldset.querySelector("form.option") + check_option(option) + var option = fieldset.querySelector("form.option") + } + } +} + +function init_control() { + var option = document.querySelector("form.option.command") + var append = document.querySelector("table.append.command") +} + window.onload = function() { init_option() init_append() @@ -678,5 +721,7 @@ window.onload = function() { init_context() init_command() init_userinfo() + init_workflow() + init_control() } diff --git a/usr/template/code/code.tmpl b/usr/template/code/code.tmpl index 998ea449..370ab9e5 100644 --- a/usr/template/code/code.tmpl +++ b/usr/template/code/code.tmpl @@ -84,6 +84,9 @@ padding-left: 10px; padding-right: 20px; } + table.append td.clip { + background-color:red; + } code.result pre { color:white; font-size:14px; @@ -100,6 +103,10 @@ + {{end}} {{define "void"}}{{end}} @@ -126,6 +133,7 @@