1
0
mirror of https://shylinux.com/x/ContextOS synced 2025-04-26 09:14:06 +08:00

add web.login.local

This commit is contained in:
shaoying 2019-09-16 22:01:27 +08:00
parent c370d7b4aa
commit 9c13c4ce53
12 changed files with 135 additions and 43 deletions

View File

@ -1,4 +1,4 @@
#! /bin/bash #! /bin/bash -i
# 日志配置 # 日志配置
export ctx_log=${ctx_log:="var/log"} export ctx_log=${ctx_log:="var/log"}
@ -45,7 +45,9 @@ install() {
*) GOARCH=386;; *) GOARCH=386;;
esac 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 target=install && [ -n "$1" ] && target=$1
${md5} ${ctx_app} && ./${ctx_app} upgrade ${target} || return ${md5} ${ctx_app} && ./${ctx_app} upgrade ${target} || return
@ -95,4 +97,3 @@ case $1 in
quit) action QUIT;; quit) action QUIT;;
term) action TERM term) action TERM
esac esac

View File

@ -4,5 +4,5 @@ var version = struct {
host string host string
self int self int
}{ }{
"2019-09-14 18:51:31", "com.mac", 494, "2019-09-16 21:57:16", "centos", 508,
} }

View File

@ -202,6 +202,9 @@ func (m *Message) Format(arg ...interface{}) string {
} }
return strings.Join(meta, " ") 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 { 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) return m.Set("detail", arg).target.Spawn(m, name, help).Begin(m).Start(m)

View File

@ -1143,7 +1143,8 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心",
m.Optionv("bio.args", arg) m.Optionv("bio.args", arg)
if help := fmt.Sprintf("scan %s", arg[0]); arg[0] == "stdio" { 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() m.Wait()
} else if p, f, e := open(m, arg[0]); e == nil { } else if p, f, e := open(m, arg[0]); e == nil {

View File

@ -89,7 +89,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
"type": "private", "ctx": "ssh", "cmd": "_route", "type": "private", "ctx": "ssh", "cmd": "_route",
"args": []interface{}{"_", "tcp.ifconfig"}, "inputs": []interface{}{ "args": []interface{}{"_", "tcp.ifconfig"}, "inputs": []interface{}{
map[string]interface{}{"type": "text", "name": "pod", "value": "", "imports": "plugin_pod"}, 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", 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) name := kit.Select(m.Conf("runtime", "user.name"), arg, 1)
work := kit.Select(m.Conf("runtime", "work.route"), arg, 2) 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.route", work)
m.Conf("runtime", "work.name", n) m.Conf("runtime", "work.name", n)
m.Echo(n) m.Echo(n)
} else { } 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]) m.Confv("flow", []string{m.Option("river"), "data", arg[1], "list", kit.Format(index), arg[i]}, arg[i+1])
} }
case "import": 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{}{} data := map[string]interface{}{}
extra := map[string]interface{}{} extra := map[string]interface{}{}
for k, v := range maps { for k, v := range maps {
m.Push(k, v)
data[k] = v data[k] = v
} }
json.Unmarshal(([]byte)(maps["extra"]), &data) json.Unmarshal(([]byte)(maps["extra"]), &data)
data["extra"] = extra 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 return
}}, }},
@ -601,9 +606,9 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
m.Append("node.name", m.Conf("runtime", "node.name")) m.Append("node.name", m.Conf("runtime", "node.name"))
m.Append("user.name", m.Conf("runtime", "user.name")) m.Append("user.name", m.Conf("runtime", "user.name"))
m.Append("work.name", m.Conf("runtime", "work.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("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.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) m.Echo(name).Back(m)
@ -675,6 +680,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
if len(arg) == 0 { if len(arg) == 0 {
return return
} }
// 同步异步 // 同步异步
sync := true sync := true
switch arg[0] { switch arg[0] {
@ -789,6 +795,8 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
// 设备验签 // 设备验签
m.Echo("node error of %s", m.Option("node.route")) m.Echo("node error of %s", m.Option("node.route"))
} else if arg[0] == "tool" {
m.Cmd("tool", arg[1:])
} else { } else {
// 执行命令 // 执行命令
m.Log("time", "check: %v", m.Format("cost")) m.Log("time", "check: %v", m.Format("cost"))
@ -1020,6 +1028,22 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心",
}) })
m.Table() 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: default:
if cert := m.Confm("work", arg[1]); len(arg) == 2 { if cert := m.Confm("work", arg[1]); len(arg) == 2 {
if cert != nil { if cert != nil {

View File

@ -93,12 +93,8 @@ func (web *WEB) Login(msg *ctx.Message, w http.ResponseWriter, r *http.Request)
if !msg.Has("username") || !msg.Options("username") { if !msg.Has("username") || !msg.Options("username") {
msg.Option("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.Options("username") && msg.Options("password") {
if msg.Cmds("aaa.auth", "username", msg.Option("username"), "password", msg.Option("password")) { if msg.Cmds("aaa.auth", "username", msg.Option("username"), "password", msg.Option("password")) {
msg.Log("info", "login: %s", msg.Option("username")) 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") { 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", "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"))) 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 return true
} }
func (web *WEB) HandleCmd(m *ctx.Message, key string, cmd *ctx.Command) { 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", "cert": "etc/cert.pem",
"key": "etc/key.pem", "key": "etc/key.pem",
"site": "", "site": "",
"index": "/code/", "index": "/chat/",
}, Help: "服务配置"}, }, Help: "服务配置"},
"route": &ctx.Config{Name: "route", Value: map[string]interface{}{ "route": &ctx.Config{Name: "route", Value: map[string]interface{}{
"index": "/render", "index": "/render",
@ -384,6 +389,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
}, },
}, Help: "功能配置"}, }, Help: "功能配置"},
"login": &ctx.Config{Name: "login", Value: map[string]interface{}{ "login": &ctx.Config{Name: "login", Value: map[string]interface{}{
"local": true,
"check": true, "check": true,
"sess_void": false, "sess_void": false,
"cas_uuid": "email", "cas_uuid": "email",

View File

@ -9,7 +9,7 @@ import (
var Index = &ctx.Context{Name: "chat", Help: "会议中心", var Index = &ctx.Context{Name: "chat", Help: "会议中心",
Caches: map[string]*ctx.Cache{}, Caches: map[string]*ctx.Cache{},
Configs: map[string]*ctx.Config{ 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{}{ "componet": &ctx.Config{Name: "componet", Value: map[string]interface{}{
"index": []interface{}{ "index": []interface{}{
map[string]interface{}{"name": "chat", map[string]interface{}{"name": "chat",
@ -24,7 +24,7 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心",
}, },
map[string]interface{}{"name": "header", map[string]interface{}{"name": "header",
"tmpl": "fieldset", "view": "Header", "init": "initHeader", "tmpl": "fieldset", "view": "Header", "init": "initHeader",
"title": "shylinux 天行健,君子以自强不息", "ctx": "web.chat", "cmd": "login",
}, },
map[string]interface{}{"name": "ocean", map[string]interface{}{"name": "ocean",
@ -154,7 +154,7 @@ var Index = &ctx.Context{Name: "chat", Help: "会议中心",
return 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{}) { 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) 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() m.Sort("name").Sort("update_time", "time_r").Table()
return return
} }

View File

@ -1,16 +1,13 @@
fun meet "第一眼" public \ fun meet "第一眼" public \
text "love" name table imports plugin_table \ text "love" name table imports plugin_table \
text "" name when \ text "date" name when \
text "" name where \ text "" name where \
button "操作" button "操作"
if $2 == "" if $2 == "" || $3 == ""
copy ssh.data show _ copy ssh.data show _
return return
end end
if $3 == ""
return "meet miss"
end
copy ssh.data insert _ when _ where __ copy ssh.data insert _ when _ where __
end end

View File

@ -155,3 +155,12 @@ func UnMarshalm(data string) map[string]interface{} {
res, _ := UnMarshal(data).(map[string]interface{}) res, _ := UnMarshal(data).(map[string]interface{})
return res return res
} }
func IsLocalIP(ip string) bool {
if strings.HasPrefix(ip, "127") {
return true
}
if ip == "::1" {
return true
}
return false
}

View File

@ -26,6 +26,7 @@ var page = Page({
sizes.source == undefined && (sizes.source = page.source.clientHeight); sizes.source == undefined && (sizes.source = page.source.clientHeight);
(sizes.action == -1 || sizes.source == 0) && (sizes.action = height, sizes.source = 0) (sizes.action == -1 || sizes.source == 0) && (sizes.action = height, sizes.source = 0)
width -= page.river.offsetWidth+page.storm.offsetWidth width -= page.river.offsetWidth+page.storm.offsetWidth
page.action.Pane.Size(width, sizes.action) page.action.Pane.Size(width, sizes.action)
page.source.Pane.Size(width, sizes.source) page.source.Pane.Size(width, sizes.source)
@ -370,23 +371,35 @@ var page = Page({
Action: { Action: {
"聊天": function(event, value) { "聊天": function(event, value) {
page.onlayout(event, page.conf.layout) page.onlayout(event, page.conf.layout)
page.onlayout(event)
page.onlayout(event)
}, },
"办公": function(event, value) { "办公": function(event, value) {
page.onlayout(event, page.conf.layout) page.onlayout(event, page.conf.layout)
page.onlayout(event, {river: 0, action:300, source:60}) page.onlayout(event, {river: 0, action:300, source:60})
page.onlayout(event)
page.onlayout(event)
}, },
"工作": function(event, value) { "工作": function(event, value) {
page.onlayout(event, page.conf.layout) page.onlayout(event, page.conf.layout)
page.onlayout(event, {river:0, action:-1, source:60}) page.onlayout(event, {river:0, action:-1, source:60})
page.onlayout(event)
page.onlayout(event)
}, },
"最高": function(event, value) { "最高": function(event, value) {
page.onlayout(event, {action: -1}) page.onlayout(event, {action: -1})
page.onlayout(event)
page.onlayout(event)
}, },
"最宽": function(event, value) { "最宽": function(event, value) {
page.onlayout(event, {river:0, storm:0}) page.onlayout(event, {river:0, storm:0})
page.onlayout(event)
page.onlayout(event)
}, },
"最大": function(event, value) { "最大": function(event, value) {
page.onlayout(event, {header:0, footer:0, river:0, action: -1, storm:0}) page.onlayout(event, {header:0, footer:0, river:0, action: -1, storm:0})
page.onlayout(event)
page.onlayout(event)
}, },
"刷新": function(event, value) { "刷新": function(event, value) {
@ -586,8 +599,6 @@ var page = Page({
page.onaction[item] && page.onaction[item](event, item, value, 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.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.action.Pane.Layout(ctx.Search("layout")? ctx.Search("layout"): kit.device.isMobile? "办公": "工作")
page.onlayout(event)
}, },
}) })

View File

@ -712,6 +712,11 @@ function Plugin(page, pane, field, runs) {
cb(event, action, item.type, name, item) cb(event, action, item.type, name, item)
}: cb) }: 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.name) && (item.title = item.title || item.name)
item.title && (item.placeholder = item.title) item.title && (item.placeholder = item.title)

View File

@ -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 下载完成后会自动启动context
windows下的GitBash中如果自动启动失败则需要手动启动一下。 windows下的GitBash中如果自动启动失败则需要手动启动一下,如下命令
``` ```
$ cd context && bin/boot.sh $ cd context && bin/boot.sh
``` ```
启动后context就是一种交互式的shell可以执行各种内部命令和系统本地命令。 ### 使用
如下查看当前目录与当目录下的文件。 启动后context提供了一种交互式的shell直接可以执行各种内部命令和本地命令。
如下查看当前目录与相关目录下的文件。
``` ```
0[22:21:19]nfs> pwd 0[22:21:19]nfs> pwd
/home/homework/context /home/homework/context
@ -38,10 +42,36 @@ $ cd context && bin/boot.sh
time size line path time size line path
2019-09-12 22:21:18 103 5 bin/ 2019-09-12 22:21:18 103 5 bin/
2019-09-12 22:20:40 72 3 etc/ 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/ 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脚本。否则会找不到相关文件。*
## 基本功能
除了命令行交互,还可以访问<http://localhost:9095>,用浏览器进行操作。
context启动后默认监听9095端口启动网页服务。
进入下载目录,可以看到的有八个文件。 进入下载目录,可以看到的有八个文件。