From 9c13c4ce538dfd5aeb1b617623911c92f40f7926 Mon Sep 17 00:00:00 2001 From: shaoying Date: Mon, 16 Sep 2019 22:01:27 +0800 Subject: [PATCH] add web.login.local --- bin/boot.sh | 15 +++++----- src/contexts/cli/version.go | 2 +- src/contexts/ctx/misc.go | 3 ++ src/contexts/nfs/nfs.go | 3 +- src/contexts/ssh/ssh.go | 40 ++++++++++++++++++++------ src/contexts/web/web.go | 20 ++++++++----- src/examples/chat/chat.go | 11 +++++-- src/plugin/love/index.shy | 7 ++--- src/toolkit/misc.go | 9 ++++++ usr/librarys/chat.js | 15 ++++++++-- usr/librarys/example.js | 5 ++++ usr/local/wiki/自然/编程/index.md | 48 +++++++++++++++++++++++++------ 12 files changed, 135 insertions(+), 43 deletions(-) diff --git a/bin/boot.sh b/bin/boot.sh index 460ad30a..f553bc78 100755 --- a/bin/boot.sh +++ b/bin/boot.sh @@ -1,4 +1,4 @@ -#! /bin/bash +#! /bin/bash -i # 日志配置 export ctx_log=${ctx_log:="var/log"} @@ -45,7 +45,9 @@ install() { *) GOARCH=386;; esac - curl -o ${ctx_app} "$ctx_dev/publish/${ctx_app}?GOOS=$GOOS&GOARCH=$GOARCH" &>/dev/null && chmod a+x ${ctx_app} || return + echo + echo + curl -o ${ctx_app} "$ctx_dev/publish/${ctx_app}?GOOS=$GOOS&GOARCH=$GOARCH" && chmod a+x ${ctx_app} || return target=install && [ -n "$1" ] && target=$1 ${md5} ${ctx_app} && ./${ctx_app} upgrade ${target} || return @@ -67,10 +69,10 @@ action() { hup() { echo "term hup"; } log() { echo -e $*; } -log "bin:$ctx_bin" -log "box:$ctx_box" -log "dev:$ctx_dev" -log "ups:$ctx_ups" +log "bin: $ctx_bin" +log "box: $ctx_box" +log "dev: $ctx_dev" +log "ups: $ctx_ups" case $1 in help) echo @@ -95,4 +97,3 @@ case $1 in quit) action QUIT;; term) action TERM esac - diff --git a/src/contexts/cli/version.go b/src/contexts/cli/version.go index 232822a3..86427f55 100644 --- a/src/contexts/cli/version.go +++ b/src/contexts/cli/version.go @@ -4,5 +4,5 @@ var version = struct { host string self int }{ - "2019-09-14 18:51:31", "com.mac", 494, + "2019-09-16 21:57:16", "centos", 508, } diff --git a/src/contexts/ctx/misc.go b/src/contexts/ctx/misc.go index a21d5987..7f889826 100644 --- a/src/contexts/ctx/misc.go +++ b/src/contexts/ctx/misc.go @@ -202,6 +202,9 @@ func (m *Message) Format(arg ...interface{}) string { } return strings.Join(meta, " ") } +func (m *Message) Err(str string, arg ...interface{}) { + m.Echo("").Echo("error: ").Echo(str, arg...) +} func (m *Message) Start(name string, help string, arg ...string) bool { return m.Set("detail", arg).target.Spawn(m, name, help).Begin(m).Start(m) diff --git a/src/contexts/nfs/nfs.go b/src/contexts/nfs/nfs.go index 3a5ca7d4..6756ae99 100644 --- a/src/contexts/nfs/nfs.go +++ b/src/contexts/nfs/nfs.go @@ -1143,7 +1143,8 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", m.Optionv("bio.args", arg) if help := fmt.Sprintf("scan %s", arg[0]); arg[0] == "stdio" { - m.Put("option", "bio.in", os.Stdin).Put("option", "bio.out", os.Stdout).Start(arg[0], help, "scan", arg[0]) + m.Put("option", "bio.in", os.Stdin).Put("option", "bio.out", os.Stdout) + m.Start(arg[0], help, "scan", arg[0]) m.Wait() } else if p, f, e := open(m, arg[0]); e == nil { diff --git a/src/contexts/ssh/ssh.go b/src/contexts/ssh/ssh.go index a02c3fb5..45791d94 100644 --- a/src/contexts/ssh/ssh.go +++ b/src/contexts/ssh/ssh.go @@ -89,7 +89,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", "type": "private", "ctx": "ssh", "cmd": "_route", "args": []interface{}{"_", "tcp.ifconfig"}, "inputs": []interface{}{ map[string]interface{}{"type": "text", "name": "pod", "value": "", "imports": "plugin_pod"}, - map[string]interface{}{"type": "button", "value": "查看"}, + map[string]interface{}{"type": "button", "value": "查看", "action": "auto"}, }, }, map[string]interface{}{"name": "proc", "help": "proc", @@ -279,12 +279,12 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", name := kit.Select(m.Conf("runtime", "user.name"), arg, 1) work := kit.Select(m.Conf("runtime", "work.route"), arg, 2) - if n := m.Cmdx("ssh._route", work, "_check", "work", name, m.Conf("runtime", "user.route")); n != "" { + if n := m.Cmdx("ssh._route", work, "_check", "work", "create", name, m.Conf("runtime", "user.route")); n != "" { m.Conf("runtime", "work.route", work) m.Conf("runtime", "work.name", n) m.Echo(n) } else { - m.Echo("error: %s from %s", name, work) + m.Err("%s from %s", name, work) } // 共享用户 @@ -535,18 +535,23 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", m.Confv("flow", []string{m.Option("river"), "data", arg[1], "list", kit.Format(index), arg[i]}, arg[i+1]) } case "import": - m.Cmd("nfs.import", arg[2:]).Table(func(maps map[string]string, lists []string, line int) { + msg := m.Cmd("nfs.import", arg[2:]) + id := m.Confi("flow", []string{m.Option("river"), "data", arg[1], "meta", "count"}) + msg.Table(func(maps map[string]string) { data := map[string]interface{}{} extra := map[string]interface{}{} for k, v := range maps { + m.Push(k, v) data[k] = v } json.Unmarshal(([]byte)(maps["extra"]), &data) data["extra"] = extra + id++ + data["id"] = id - m.Confv("flow", []string{m.Option("river"), "data", arg[1], "list", "-2"}, map[string]interface{}{}) - + m.Confv("flow", []string{m.Option("river"), "data", arg[1], "list", "-2"}, data) }) + m.Confi("flow", []string{m.Option("river"), "data", arg[1], "meta", "count"}, id) } return }}, @@ -601,9 +606,9 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", m.Append("node.name", m.Conf("runtime", "node.name")) m.Append("user.name", m.Conf("runtime", "user.name")) m.Append("work.name", m.Conf("runtime", "work.name")) - m.Append("node.route", m.Conf("runtime", "node.route")) - m.Append("user.route", m.Conf("runtime", "user.route")) m.Append("work.route", m.Conf("runtime", "work.route")) + m.Append("user.route", m.Conf("runtime", "user.route")) + m.Append("node.route", m.Conf("runtime", "node.route")) m.Append("work.script", m.Cmdx("nfs.load", path.Join(m.Conf("cli.publish", "path"), kit.Select("hello", arg[3]), "local.shy"))) m.Echo(name).Back(m) @@ -675,6 +680,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", if len(arg) == 0 { return } + // 同步异步 sync := true switch arg[0] { @@ -789,6 +795,8 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", // 设备验签 m.Echo("node error of %s", m.Option("node.route")) + } else if arg[0] == "tool" { + m.Cmd("tool", arg[1:]) } else { // 执行命令 m.Log("time", "check: %v", m.Format("cost")) @@ -1020,6 +1028,22 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", }) m.Table() + case "create": + name := arg[2] + if user := m.Conf("work", []string{name, "user"}); user != "" && user != arg[3] { + for i := 1; i < 100; i++ { + name = fmt.Sprintf("%s%02d", arg[2], i) + if user := m.Conf("work", []string{name, "user"}); user == "" || user == arg[3] { + break + } + name = "" + } + } + if name != "" { + m.Conf("work", name, map[string]interface{}{"create_time": m.Time(), "user": arg[3]}) + m.Echo(name) + } + default: if cert := m.Confm("work", arg[1]); len(arg) == 2 { if cert != nil { diff --git a/src/contexts/web/web.go b/src/contexts/web/web.go index 05f31adf..24193e09 100644 --- a/src/contexts/web/web.go +++ b/src/contexts/web/web.go @@ -93,12 +93,8 @@ func (web *WEB) Login(msg *ctx.Message, w http.ResponseWriter, r *http.Request) if !msg.Has("username") || !msg.Options("username") { msg.Option("username", "") } - // if msg.Confs("skip_login", msg.Option("path")) { - // return true - // } - // defer func() { - // msg.Log("info", "access: %s", msg.Option("access", msg.Cmdx("aaa.sess", "access"))) - // }() + + // 用户登录 if msg.Options("username") && msg.Options("password") { if msg.Cmds("aaa.auth", "username", msg.Option("username"), "password", msg.Option("password")) { msg.Log("info", "login: %s", msg.Option("username")) @@ -126,10 +122,19 @@ func (web *WEB) Login(msg *ctx.Message, w http.ResponseWriter, r *http.Request) } } + // 用户访问 if msg.Log("info", "sessid: %s", msg.Option("sessid")); msg.Options("sessid") { msg.Log("info", "username: %s", msg.Option("username", msg.Cmd("aaa.sess", "user").Append("meta"))) msg.Log("info", "userrole: %v", msg.Option("userrole", msg.Cmd("aaa.user", "role").Append("meta"))) } + + // 本地用户 + if !msg.Options("username") && kit.IsLocalIP(msg.Option("remote_ip")) && msg.Confs("web.login", "local") { + msg.Cmd("aaa.role", "root", "user", msg.Cmdx("ssh.work", "create")) + msg.Log("info", "%s: %s", msg.Option("remote_ip"), msg.Option("username", msg.Conf("runtime", "work.name"))) + http.SetCookie(w, &http.Cookie{Name: "sessid", Value: msg.Option("sessid", msg.Cmdx("aaa.user", "session", "select")), Path: "/"}) + } + return true } func (web *WEB) HandleCmd(m *ctx.Message, key string, cmd *ctx.Command) { @@ -372,7 +377,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", "cert": "etc/cert.pem", "key": "etc/key.pem", "site": "", - "index": "/code/", + "index": "/chat/", }, Help: "服务配置"}, "route": &ctx.Config{Name: "route", Value: map[string]interface{}{ "index": "/render", @@ -384,6 +389,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", }, }, Help: "功能配置"}, "login": &ctx.Config{Name: "login", Value: map[string]interface{}{ + "local": true, "check": true, "sess_void": false, "cas_uuid": "email", diff --git a/src/examples/chat/chat.go b/src/examples/chat/chat.go index 66a4f594..68253ed9 100644 --- a/src/examples/chat/chat.go +++ b/src/examples/chat/chat.go @@ -9,7 +9,7 @@ import ( var Index = &ctx.Context{Name: "chat", Help: "会议中心", Caches: map[string]*ctx.Cache{}, Configs: map[string]*ctx.Config{ - "login": &ctx.Config{Name: "login", Value: map[string]interface{}{"check": "false"}, Help: "默认组件"}, + "login": &ctx.Config{Name: "login", Value: map[string]interface{}{"check": false, "local": true}, Help: "默认组件"}, "componet": &ctx.Config{Name: "componet", Value: map[string]interface{}{ "index": []interface{}{ map[string]interface{}{"name": "chat", @@ -24,7 +24,7 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心", }, map[string]interface{}{"name": "header", "tmpl": "fieldset", "view": "Header", "init": "initHeader", - "title": "shylinux 天行健,君子以自强不息", + "ctx": "web.chat", "cmd": "login", }, map[string]interface{}{"name": "ocean", @@ -154,7 +154,7 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心", return } - m.Cmdx(".steam", h, "spawn", "favor") + m.Cmdx(".steam", h, "spawn", "index") // 分发群聊 m.Confm("flow", []string{h, "user"}, func(key string, value map[string]interface{}) { @@ -198,6 +198,11 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心", m.Push("count", 0) } }) + if !m.Appends("key") { + m.Cmd(".ocean", "spawn", "", "hello", m.Option("username")) + m.Cmdy(".river") + return + } m.Sort("name").Sort("update_time", "time_r").Table() return } diff --git a/src/plugin/love/index.shy b/src/plugin/love/index.shy index e4058fd2..e080ae22 100644 --- a/src/plugin/love/index.shy +++ b/src/plugin/love/index.shy @@ -1,16 +1,13 @@ fun meet "第一眼" public \ text "love" name table imports plugin_table \ - text "" name when \ + text "date" name when \ text "" name where \ button "操作" - if $2 == "" + if $2 == "" || $3 == "" copy ssh.data show _ return end - if $3 == "" - return "meet miss" - end copy ssh.data insert _ when _ where __ end diff --git a/src/toolkit/misc.go b/src/toolkit/misc.go index 3fcf67d7..b5c7624d 100644 --- a/src/toolkit/misc.go +++ b/src/toolkit/misc.go @@ -155,3 +155,12 @@ func UnMarshalm(data string) map[string]interface{} { res, _ := UnMarshal(data).(map[string]interface{}) return res } +func IsLocalIP(ip string) bool { + if strings.HasPrefix(ip, "127") { + return true + } + if ip == "::1" { + return true + } + return false +} diff --git a/usr/librarys/chat.js b/usr/librarys/chat.js index c4b9c853..eed9fbe3 100644 --- a/usr/librarys/chat.js +++ b/usr/librarys/chat.js @@ -26,6 +26,7 @@ var page = Page({ sizes.source == undefined && (sizes.source = page.source.clientHeight); (sizes.action == -1 || sizes.source == 0) && (sizes.action = height, sizes.source = 0) width -= page.river.offsetWidth+page.storm.offsetWidth + page.action.Pane.Size(width, sizes.action) page.source.Pane.Size(width, sizes.source) @@ -370,23 +371,35 @@ var page = Page({ Action: { "聊天": function(event, value) { page.onlayout(event, page.conf.layout) + page.onlayout(event) + page.onlayout(event) }, "办公": function(event, value) { page.onlayout(event, page.conf.layout) page.onlayout(event, {river: 0, action:300, source:60}) + page.onlayout(event) + page.onlayout(event) }, "工作": function(event, value) { page.onlayout(event, page.conf.layout) page.onlayout(event, {river:0, action:-1, source:60}) + page.onlayout(event) + page.onlayout(event) }, "最高": function(event, value) { page.onlayout(event, {action: -1}) + page.onlayout(event) + page.onlayout(event) }, "最宽": function(event, value) { page.onlayout(event, {river:0, storm:0}) + page.onlayout(event) + page.onlayout(event) }, "最大": function(event, value) { page.onlayout(event, {header:0, footer:0, river:0, action: -1, storm:0}) + page.onlayout(event) + page.onlayout(event) }, "刷新": function(event, value) { @@ -586,8 +599,6 @@ var page = Page({ page.onaction[item] && page.onaction[item](event, item, value, page) }) page.river.Pane.Show(), page.pane = page.action, page.plugin = kit.Selector(page.action, "fieldset")[0] - page.onlayout(event) page.action.Pane.Layout(ctx.Search("layout")? ctx.Search("layout"): kit.device.isMobile? "办公": "工作") - page.onlayout(event) }, }) diff --git a/usr/librarys/example.js b/usr/librarys/example.js index 2b960a9b..49eed353 100644 --- a/usr/librarys/example.js +++ b/usr/librarys/example.js @@ -712,6 +712,11 @@ function Plugin(page, pane, field, runs) { cb(event, action, item.type, name, item) }: cb) }); + switch (item.value) { + case "date": + item.value = kit.format_date(new Date()) + break + } (item.title || item.name) && (item.title = item.title || item.name) item.title && (item.placeholder = item.title) diff --git a/usr/local/wiki/自然/编程/index.md b/usr/local/wiki/自然/编程/index.md index bab48705..a13a01f7 100644 --- a/usr/local/wiki/自然/编程/index.md +++ b/usr/local/wiki/自然/编程/index.md @@ -14,22 +14,26 @@ context是以分布式的方式,进行程序的开发。 消灭所有中间环节,让几行代码的小函数,就可以成为独立的应用,从而实现软件的快速开发与快速传播,将任意一行代码的价值,放大成千上万倍。 ## 下载安装 -在Linux或Mac上,可以直接用脚本下载, -在Windows上,可以先安装 [GitBash](https://www.git-scm.com/download/),然后在GitBash中执行命令下载。 +### 下载 +在Linux或Mac上,可以直接用命令下载, +在Windows上,推荐先安装 [GitBash](https://www.git-scm.com/download/),然后在GitBash中执行命令下载。 ``` -$ curl https://shylinux.com/publish/boot.sh | bash -s install context +$ export ctx_dev=https://shylinux.com; curl $ctx_dev/publish/boot.sh | bash -s install context ``` +*install后面的参数context,就是指定的下载目录,如不指定,会把相关文件下载到当前目录。* -install后面的参数context,就是指定的下载目录,如不指定,会把相关文件下载到当前目录。 +*ctx_dev环境变量指定服务器地址,所以可以自行搭建服务器。* +### 启动 下载完成后,会自动启动context, -windows下的GitBash中,如果自动启动失败,则需要手动启动一下。 +windows下的GitBash中,如果自动启动失败,则需要手动启动一下,如下命令。 ``` $ cd context && bin/boot.sh ``` -启动后context,就是一种交互式的shell,可以执行各种内部命令和系统本地命令。 -如下查看当前目录与当目录下的文件。 +### 使用 +启动后context,提供了一种交互式的shell,直接可以执行各种内部命令和本地命令。 +如下查看当前目录与相关目录下的文件。 ``` 0[22:21:19]nfs> pwd /home/homework/context @@ -38,10 +42,36 @@ $ cd context && bin/boot.sh time size line path 2019-09-12 22:21:18 103 5 bin/ 2019-09-12 22:20:40 72 3 etc/ -2019-09-12 22:21:18 50 2 usr/ 2019-09-12 22:20:40 55 3 var/ -2[22:21:20]nfs> +2019-09-12 22:21:18 50 2 usr/ + +2[20:51:21]nfs> dir bin +time size line path +2019-09-16 20:51:14 18782016 5209 bin/bench +2019-09-16 20:51:14 2634 99 bin/boot.sh +2019-09-16 20:51:14 125 5 bin/node.sh +2019-09-16 20:51:14 96 6 bin/user.sh +2019-09-16 20:51:14 147 9 bin/zone.sh + +3[20:51:22]nfs> dir etc +time size line path +2019-09-16 20:51:14 339 11 etc/common.shy +2019-09-16 20:51:14 244 11 etc/exit.shy +2019-09-16 20:51:14 297 18 etc/init.shy + +4[22:21:20]nfs> ``` +- bin目录,就是各种启动脚本与命令 +- etc目录,就是各种配置脚本 +- var目录,就是各种输出文件,如日志与缓存文件 +- usr目录,就是各种前端文件与数据,如js、css文件 + +*如需要自行启动context,必须在当前目录,然后运行bin/boot.sh脚本。否则会找不到相关文件。* + +## 基本功能 + +除了命令行交互,还可以访问,用浏览器进行操作。 +context启动后,默认监听9095端口,启动网页服务。 进入下载目录,可以看到的有八个文件。