use tango instead of xweb for web interface
@@ -6,7 +6,7 @@ port=2121
|
||||
[web]
|
||||
enable=true
|
||||
listen=:8181
|
||||
ssl=true
|
||||
tls=false
|
||||
|
||||
[admin]
|
||||
user=admin
|
||||
|
||||
6
main.go
@@ -83,9 +83,11 @@ func main() {
|
||||
weblisten, _ := cfg.GetValue("web", "listen")
|
||||
admin, _ := cfg.GetValue("admin", "user")
|
||||
pass, _ := cfg.GetValue("admin", "pass")
|
||||
ssl, _ := cfg.Bool("web", "ssl")
|
||||
tls, _ := cfg.Bool("web", "tls")
|
||||
certFile, _ := cfg.GetValue("web", "certFile")
|
||||
keyFile, _ := cfg.GetValue("web", "keyFile")
|
||||
|
||||
go web.Web(weblisten, "static", "templates", admin, pass, ssl)
|
||||
go web.Web(weblisten, "static", "templates", admin, pass, tls, certFile, keyFile)
|
||||
}
|
||||
|
||||
ftpName, _ := cfg.GetValue("server", "name")
|
||||
|
||||
|
Before Width: | Height: | Size: 193 KiB After Width: | Height: | Size: 193 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 7.8 KiB After Width: | Height: | Size: 7.8 KiB |
|
Before Width: | Height: | Size: 715 B After Width: | Height: | Size: 715 B |
|
Before Width: | Height: | Size: 575 B After Width: | Height: | Size: 575 B |
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 9.1 KiB After Width: | Height: | Size: 9.1 KiB |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
|
Before Width: | Height: | Size: 8.2 KiB After Width: | Height: | Size: 8.2 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
|
Before Width: | Height: | Size: 3.5 KiB After Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
|
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 206 KiB After Width: | Height: | Size: 206 KiB |
|
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.1 KiB |
|
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 7.0 KiB |
|
Before Width: | Height: | Size: 406 KiB After Width: | Height: | Size: 406 KiB |
13
templates/base/base.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
{{template "head" .}}
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
{{template "nav" .}}
|
||||
{{template "body" .}}
|
||||
</div>
|
||||
{{template "footer" .}}
|
||||
</body>
|
||||
</html>
|
||||
11
templates/base/common.html
Normal file
@@ -0,0 +1,11 @@
|
||||
{{define "head"}}
|
||||
{{template "base/head.html" .}}
|
||||
{{end}}
|
||||
|
||||
{{define "nav"}}
|
||||
{{template "base/nav.html" .}}
|
||||
{{end}}
|
||||
|
||||
{{define "footer"}}
|
||||
{{template "base/foot.html" .}}
|
||||
{{end}}
|
||||
7
templates/base/common_nohead.html
Normal file
@@ -0,0 +1,7 @@
|
||||
{{define "nav"}}
|
||||
{{template "base/nav.html" .}}
|
||||
{{end}}
|
||||
|
||||
{{define "footer"}}
|
||||
{{template "base/foot.html" .}}
|
||||
{{end}}
|
||||
8
templates/base/head.html
Normal file
@@ -0,0 +1,8 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="/public/css/bootstrap-theme.css"/>
|
||||
<link href="/public/css/bootstrap.css" rel="stylesheet">
|
||||
<script src="/public/js/jquery.min.js"></script>
|
||||
<script src="/public/js/bootstrap.js"></script>
|
||||
<link rel="stylesheet" href="/public/css/bootstrap-theme.css" />
|
||||
@@ -17,14 +17,14 @@
|
||||
</div>
|
||||
<div class="collapse navbar-collapse" role="navigation" id="navbar-collapse">
|
||||
<ul class="nav navbar-nav">
|
||||
{{if IsAdmin}}
|
||||
<li{{if isCurModule 1}} class="active"{{end}}><a href="/user">用户管理</a></li>
|
||||
<li{{if isCurModule 2}} class="active"{{end}}><a href="/group">组管理</a></li>
|
||||
<li{{if isCurModule 3}} class="active"{{end}}><a href="/perm">权限管理</a></li>
|
||||
{{if .IsAdmin}}
|
||||
<li{{if call .isCurModule 1}} class="active"{{end}}><a href="/user">用户管理</a></li>
|
||||
<li{{if call .isCurModule 2}} class="active"{{end}}><a href="/group">组管理</a></li>
|
||||
<li{{if call .isCurModule 3}} class="active"{{end}}><a href="/perm">权限管理</a></li>
|
||||
{{end}}
|
||||
</ul>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li{{if isCurModule 4}} class="active"{{end}}><a href="/user/chgpass">修改密码</a></li>
|
||||
<li{{if call .isCurModule 4}} class="active"{{end}}><a href="/user/chgpass">修改密码</a></li>
|
||||
<li><a href="/logout">退出 </a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -1,14 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
{{include "head.html"}}
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
{{include "nav.html"}}
|
||||
<div style="padding:10px;padding-top:60px">
|
||||
{{template "base/base.html" .}}
|
||||
{{template "base/common.html" .}}
|
||||
|
||||
{{define "body"}}
|
||||
<div style="padding:10px;padding-top:60px">
|
||||
<form class="form-horizontal" method="post">
|
||||
{{XsrfFormHtml}}
|
||||
{{.XsrfFormHtml}}
|
||||
<legend>添加组</legend>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="inputEmail">组名称:</label>
|
||||
@@ -22,7 +18,4 @@
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{include "foot.html"}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
@@ -1,11 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
{{include "head.html"}}
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
{{include "nav.html"}}
|
||||
{{template "base/base.html" .}}
|
||||
{{template "base/common.html" .}}
|
||||
|
||||
{{define "body"}}
|
||||
<div style="padding:10px;padding-top:60px">
|
||||
<div class="row"><legend>修改组:{{.T.user.Name}}</legend></div>
|
||||
<div class="row">
|
||||
@@ -40,7 +36,4 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{include "foot.html"}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
@@ -1,11 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
{{include "head.html"}}
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
{{include "nav.html"}}
|
||||
{{template "base/base.html" .}}
|
||||
{{template "base/common.html" .}}
|
||||
|
||||
{{define "body"}}
|
||||
<div class="text-right" style="padding:10px;padding-top:60px"><a href="/group/add" class="btn btn-large btn-primary">添加</a>
|
||||
</div>
|
||||
<table class="table table-bordered table-hover">
|
||||
@@ -24,7 +20,4 @@
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{include "foot.html"}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
@@ -1,9 +0,0 @@
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<link rel="stylesheet" href="{{StaticUrl "css/bootstrap-theme.css"}}"/>
|
||||
<link href="{{StaticUrl "css/bootstrap.css"}}" rel="stylesheet">
|
||||
<script src="{{StaticUrl "js/jquery.min.js"}}"></script>
|
||||
<script src="{{StaticUrl "js/bootstrap.js"}}"></script>
|
||||
<link rel="stylesheet" href="{{StaticUrl "css/bootstrap-theme.css"}}" />
|
||||
<!--<link rel="stylesheet" href="{{StaticUrl "css/font-awesome.min.css"}}" />-->
|
||||
@@ -1,7 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
{{include "head.html"}}
|
||||
{{template "base/head.html" .}}
|
||||
<style type="text/css">
|
||||
body {
|
||||
padding-top: 40px;
|
||||
@@ -39,11 +39,11 @@
|
||||
<body>
|
||||
<div class="container">
|
||||
<form class="form-signin" method="post">
|
||||
{{XsrfFormHtml}}
|
||||
{{.XsrfFormHtml}}
|
||||
<h2 class="form-signin-heading">GoFtp管理系统</h2>
|
||||
<input name="name" type="text" class="input-block-level" placeholder="账号">
|
||||
<input name="pass" type="password" class="input-block-level" placeholder="密码">
|
||||
<input type="submit" value="登录" class="btn btn-large btn-primary"> <font color=red>{{.T.msg}}</font>
|
||||
<input type="submit" value="登录" class="btn btn-large btn-primary"> <font color=red>{{.msg}}</font>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
{{include "head.html"}}
|
||||
{{template "base/base.html" .}}
|
||||
{{template "base/common_nohead.html" .}}
|
||||
|
||||
{{define "head"}}
|
||||
{{template "base/head.html"}}
|
||||
<script>
|
||||
function updateGroup(name, newgroup) {
|
||||
$.ajax({
|
||||
@@ -56,13 +57,12 @@ $(function() {
|
||||
})
|
||||
})
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
{{include "nav.html"}}
|
||||
<div class="row" style="padding:10px;padding-top:60px">
|
||||
{{end}}
|
||||
|
||||
{{define "body"}}
|
||||
<div class="row" style="padding:10px;padding-top:60px">
|
||||
<div class="col-md-10">
|
||||
当前目录:{{.T.path}}
|
||||
当前目录:{{.path}}
|
||||
</div>
|
||||
<div class="col-md-2 text-right">
|
||||
</div>
|
||||
@@ -74,14 +74,14 @@ $(function() {
|
||||
<th>权限(Others)</th><th>操作</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{$parent := .T.parent}}
|
||||
{{if ne .T.path "/"}}
|
||||
{{$parent := .parent}}
|
||||
{{if ne .path "/"}}
|
||||
<tr><td colspan="8"><a href="/perm/?path={{$parent}}">..</a></td>
|
||||
</tr>
|
||||
{{end}}
|
||||
{{$users := .T.users}}
|
||||
{{$groups := .T.groups}}
|
||||
{{range .T.infos}}
|
||||
{{$users := .users}}
|
||||
{{$groups := .groups}}
|
||||
{{range .infos}}
|
||||
<tr><td>
|
||||
{{$name := .Name}}
|
||||
{{$owner := .Owner}}
|
||||
@@ -102,17 +102,14 @@ $(function() {
|
||||
<option{{if eq $group .}} selected{{end}}>{{.}}</option>
|
||||
{{end}}
|
||||
</select></td>
|
||||
<td><input id="owner_r_{{$name}}" class="check" type="checkbox"{{if hasPerm .Mode 1 "r"}} checked{{end}}> r
|
||||
<input id="owner_w_{{$name}}" class="check" type="checkbox"{{if hasPerm .Mode 2 "w"}} checked{{end}}> w</td>
|
||||
<td><input id="group_r_{{$name}}" class="check" type="checkbox"{{if hasPerm .Mode 4 "r"}} checked{{end}}> r
|
||||
<input id="group_w_{{$name}}" class="check" type="checkbox"{{if hasPerm .Mode 5 "w"}} checked{{end}}> w</td>
|
||||
<td><input id="other_r_{{$name}}" class="check" type="checkbox"{{if hasPerm .Mode 7 "r"}} checked{{end}}> r
|
||||
<input id="other_w_{{$name}}" class="check" type="checkbox"{{if hasPerm .Mode 8 "w"}} checked{{end}}> w</td>
|
||||
<td><input id="owner_r_{{$name}}" class="check" type="checkbox"{{if call $.hasPerm .Mode 1 "r"}} checked{{end}}> r
|
||||
<input id="owner_w_{{$name}}" class="check" type="checkbox"{{if call $.hasPerm .Mode 2 "w"}} checked{{end}}> w</td>
|
||||
<td><input id="group_r_{{$name}}" class="check" type="checkbox"{{if call $.hasPerm .Mode 4 "r"}} checked{{end}}> r
|
||||
<input id="group_w_{{$name}}" class="check" type="checkbox"{{if call $.hasPerm .Mode 5 "w"}} checked{{end}}> w</td>
|
||||
<td><input id="other_r_{{$name}}" class="check" type="checkbox"{{if call $.hasPerm .Mode 7 "r"}} checked{{end}}> r
|
||||
<input id="other_w_{{$name}}" class="check" type="checkbox"{{if call $.hasPerm .Mode 8 "w"}} checked{{end}}> w</td>
|
||||
<td> </td></tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{include "foot.html"}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
@@ -1,14 +1,10 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
{{include "head.html"}}
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
{{include "nav.html"}}
|
||||
<div style="padding:10px;padding-top:60px">
|
||||
{{template "base/base.html" .}}
|
||||
{{template "base/common.html" .}}
|
||||
|
||||
{{define "body"}}
|
||||
<div style="padding:10px;padding-top:60px">
|
||||
<form class="form-horizontal" method="post">
|
||||
{{XsrfFormHtml}}
|
||||
{{.XsrfFormHtml}}
|
||||
<legend>添加账号</legend>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="inputEmail">账号名称:</label>
|
||||
@@ -28,7 +24,4 @@
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{include "foot.html"}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
@@ -1,18 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
{{include "head.html"}}
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
{{include "nav.html"}}
|
||||
<div style="padding:10px;padding-top:60px">
|
||||
{{template "base/base.html" .}}
|
||||
{{template "base/common.html" .}}
|
||||
|
||||
{{define "body"}}
|
||||
<div style="padding:10px;padding-top:60px">
|
||||
<form class="form-horizontal" method="post">
|
||||
{{XsrfFormHtml}}
|
||||
{{.XsrfFormHtml}}
|
||||
<legend>修改密码</legend>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="inputEmail">账号名称:</label>
|
||||
<div class="controls"><input type="text" name="name" readonly value="{{session "userId"}}" />
|
||||
<div class="controls"><input type="text" name="name" readonly value="{{.userId}}" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
@@ -28,7 +24,4 @@
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{include "foot.html"}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
@@ -1,25 +1,21 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
{{include "head.html"}}
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
{{include "nav.html"}}
|
||||
<div style="padding:10px;padding-top:60px">
|
||||
{{template "base/base.html" .}}
|
||||
{{template "base/common.html" .}}
|
||||
|
||||
{{define "body"}}
|
||||
<div style="padding:10px;padding-top:60px">
|
||||
<form class="form-horizontal" method="post">
|
||||
{{XsrfFormHtml}}
|
||||
<legend>修改账号:{{.T.user.Name}}</legend>
|
||||
{{.XsrfFormHtml}}
|
||||
<legend>修改账号:{{.user.Name}}</legend>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="inputEmail">账号名称:</label>
|
||||
<div class="controls">
|
||||
<input type="text" name="name" value="{{.T.user.Name}}"/>
|
||||
<input type="text" name="name" value="{{.user.Name}}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label class="control-label" for="inputEmail">
|
||||
账号密码:</label>
|
||||
<div class="controls"><input type="password" name="pass" value="{{.T.user.Pass}}"/>
|
||||
<div class="controls"><input type="password" name="pass" value="{{.user.Pass}}"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
@@ -29,7 +25,4 @@
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{{include "foot.html"}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
@@ -1,11 +1,7 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-cn">
|
||||
<head>
|
||||
{{include "head.html"}}
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
{{include "nav.html"}}
|
||||
{{template "base/base.html" .}}
|
||||
{{template "base/common.html" .}}
|
||||
|
||||
{{define "body"}}
|
||||
<div class="text-right" style="padding:10px;padding-top:60px"><a href="/user/add" class="btn btn-large btn-primary">添加</a>
|
||||
</div>
|
||||
<table class="table table-bordered table-hover">
|
||||
@@ -13,8 +9,8 @@
|
||||
<th>用户名</th><th>创建时间</th><th>操作</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{$admin := .T.admin}}
|
||||
{{range .T.users}}
|
||||
{{$admin := .admin}}
|
||||
{{range .users}}
|
||||
<tr><td>{{.Name}}</td><td></td>
|
||||
<td>
|
||||
{{if ne .Name $admin}}
|
||||
@@ -24,7 +20,4 @@
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{include "foot.html"}}
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
164
web/actions.go
@@ -1,76 +1,134 @@
|
||||
package web
|
||||
|
||||
import "github.com/go-xweb/xweb"
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/lunny/tango"
|
||||
"github.com/tango-contrib/binding"
|
||||
"github.com/tango-contrib/renders"
|
||||
"github.com/tango-contrib/session"
|
||||
"github.com/tango-contrib/xsrf"
|
||||
)
|
||||
|
||||
var _ auther = new(BaseAction)
|
||||
|
||||
type BaseAction struct {
|
||||
*xweb.Action
|
||||
renders.Renderer
|
||||
session.Session
|
||||
tango.Ctx
|
||||
binding.Binder
|
||||
curModule int
|
||||
}
|
||||
|
||||
func (a *BaseAction) AskLogin() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type BaseAuthAction struct {
|
||||
BaseAction
|
||||
}
|
||||
|
||||
func (a *BaseAuthAction) AskLogin() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (a *BaseAction) IsLogin() bool {
|
||||
s := a.GetSession("userId")
|
||||
return s != nil
|
||||
id := a.Session.Get("userId")
|
||||
fmt.Println(id)
|
||||
return id != nil
|
||||
}
|
||||
|
||||
func (a *BaseAction) SetLogin(user string) {
|
||||
a.Session.Set("userId", user)
|
||||
}
|
||||
|
||||
func (a *BaseAction) LoginUserId() string {
|
||||
userId := a.Session.Get("userId")
|
||||
if userId == nil {
|
||||
return ""
|
||||
}
|
||||
return userId.(string)
|
||||
}
|
||||
|
||||
func (a *BaseAction) Logout() {
|
||||
a.Session.Del("userId")
|
||||
}
|
||||
|
||||
func (a *BaseAction) IsAdmin() bool {
|
||||
s := a.GetSession("userId")
|
||||
s := a.Session.Get("userId")
|
||||
return s != nil && s.(string) == adminUser
|
||||
}
|
||||
|
||||
func (a *BaseAction) Init() {
|
||||
a.AddTmplVars(&xweb.T{
|
||||
"IsLogin": a.IsLogin,
|
||||
"IsAdmin": a.IsAdmin,
|
||||
})
|
||||
func (a *BaseAction) Render(tmpl string, vars ...renders.T) error {
|
||||
var t = renders.T{
|
||||
"IsLogin": a.IsLogin(),
|
||||
"IsAdmin": a.IsAdmin(),
|
||||
"isCurModule": func(module int) bool {
|
||||
return module == a.curModule
|
||||
},
|
||||
}
|
||||
if len(vars) > 0 {
|
||||
t.Merge(vars[0])
|
||||
}
|
||||
return a.Renderer.Render(tmpl, t)
|
||||
}
|
||||
|
||||
type MainAction struct {
|
||||
BaseAction
|
||||
|
||||
get xweb.Mapper `xweb:"/"`
|
||||
login xweb.Mapper
|
||||
logout xweb.Mapper
|
||||
}
|
||||
|
||||
func (a *MainAction) Get() error {
|
||||
return a.Go("get", &UserAction{})
|
||||
func (a *MainAction) Get() {
|
||||
a.Redirect("/user")
|
||||
}
|
||||
|
||||
func (a *MainAction) Logout() {
|
||||
a.DelSession("userId")
|
||||
type LoginAction struct {
|
||||
BaseAction
|
||||
xsrf.Checker
|
||||
}
|
||||
|
||||
func (a *LoginAction) Get() error {
|
||||
return a.Render("login.html", renders.T{
|
||||
"XsrfFormHtml": a.Checker.XsrfFormHtml(),
|
||||
})
|
||||
}
|
||||
|
||||
func (a *LoginAction) Post() error {
|
||||
var user User
|
||||
errs := a.Bind(&user)
|
||||
if errs.Len() > 0 {
|
||||
return errs[0]
|
||||
}
|
||||
|
||||
if user.Name == "" || user.Pass == "" {
|
||||
return a.Render("login.html", renders.T{
|
||||
"msg": "用户名或者密码错误",
|
||||
})
|
||||
}
|
||||
|
||||
p, err := DB.GetUser(user.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if p != user.Pass {
|
||||
return a.Render("login.html", renders.T{
|
||||
"msg": "用户名或者密码错误",
|
||||
})
|
||||
}
|
||||
|
||||
a.SetLogin(user.Name)
|
||||
if a.IsAdmin() {
|
||||
a.Redirect("/user")
|
||||
return nil
|
||||
}
|
||||
a.Redirect("/user/chgpass")
|
||||
return nil
|
||||
}
|
||||
|
||||
type LogoutAction struct {
|
||||
BaseAuthAction
|
||||
}
|
||||
|
||||
func (a *LogoutAction) Get() {
|
||||
a.Logout()
|
||||
a.Redirect("/")
|
||||
}
|
||||
|
||||
func (a *MainAction) Login() error {
|
||||
if a.Method() == "GET" {
|
||||
return a.Render("login.html")
|
||||
} else if a.Method() == "POST" {
|
||||
user := new(User)
|
||||
err := a.MapForm(user, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if user.Name == "" || user.Pass == "" {
|
||||
return a.Render("login.html", &xweb.T{
|
||||
"msg": "用户名或者密码错误",
|
||||
})
|
||||
}
|
||||
|
||||
p, err := DB.GetUser(user.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if p != user.Pass {
|
||||
return a.Render("login.html", &xweb.T{
|
||||
"msg": "用户名或者密码错误",
|
||||
})
|
||||
}
|
||||
|
||||
a.SetSession("userId", user.Name)
|
||||
if a.IsAdmin() {
|
||||
return a.Go("get", &UserAction{})
|
||||
}
|
||||
return a.Go("chgpass", &UserAction{})
|
||||
}
|
||||
return xweb.NotSupported()
|
||||
}
|
||||
|
||||
85
web/group.go
@@ -1,22 +1,20 @@
|
||||
package web
|
||||
|
||||
import "github.com/go-xweb/xweb"
|
||||
import (
|
||||
"github.com/tango-contrib/renders"
|
||||
"github.com/tango-contrib/xsrf"
|
||||
)
|
||||
|
||||
type GroupBaseAction struct {
|
||||
BaseAuthAction
|
||||
}
|
||||
|
||||
func (c *GroupBaseAction) Before() {
|
||||
c.curModule = GROUP_MODULE
|
||||
}
|
||||
|
||||
type GroupAction struct {
|
||||
BaseAction
|
||||
|
||||
get xweb.Mapper `xweb:"/"`
|
||||
add xweb.Mapper
|
||||
edit xweb.Mapper
|
||||
del xweb.Mapper
|
||||
}
|
||||
|
||||
func (c *GroupAction) Init() {
|
||||
c.AddTmplVar("isCurModule", c.IsCurModule)
|
||||
}
|
||||
|
||||
func (c *GroupAction) IsCurModule(module int) bool {
|
||||
return GROUP_MODULE == module
|
||||
GroupBaseAction
|
||||
}
|
||||
|
||||
func (c *GroupAction) Get() error {
|
||||
@@ -25,30 +23,42 @@ func (c *GroupAction) Get() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.Render("group/list.html", &xweb.T{
|
||||
return c.Render("group/list.html", renders.T{
|
||||
"groups": groups,
|
||||
"admin": adminUser,
|
||||
})
|
||||
}
|
||||
|
||||
func (c *GroupAction) Add() error {
|
||||
if c.Method() == "GET" {
|
||||
return c.Render("group/add.html")
|
||||
} else if c.Method() == "POST" {
|
||||
name := c.GetString("name")
|
||||
err := DB.AddGroup(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.Go("get")
|
||||
}
|
||||
return xweb.NotSupported()
|
||||
type GroupAddAction struct {
|
||||
GroupBaseAction
|
||||
xsrf.Checker
|
||||
}
|
||||
|
||||
func (c *GroupAction) Edit() error {
|
||||
name := c.GetString("name")
|
||||
func (c *GroupAddAction) Get() error {
|
||||
return c.Render("group/add.html", renders.T{
|
||||
"XsrfFormHtml": c.Checker.XsrfFormHtml(),
|
||||
})
|
||||
}
|
||||
|
||||
func (c *GroupAddAction) Post() error {
|
||||
name := c.Form("name")
|
||||
err := DB.AddGroup(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Redirect("/group")
|
||||
return nil
|
||||
}
|
||||
|
||||
type GroupEditAction struct {
|
||||
GroupBaseAction
|
||||
}
|
||||
|
||||
func (c *GroupEditAction) Get() error {
|
||||
name := c.Form("name")
|
||||
if name == "" {
|
||||
return c.Go("get")
|
||||
c.Redirect("/group")
|
||||
return nil
|
||||
}
|
||||
var selUsers []string
|
||||
err := DB.GroupUser(name, &selUsers)
|
||||
@@ -73,17 +83,22 @@ func (c *GroupAction) Edit() error {
|
||||
otherUsers = append(otherUsers, user.Name)
|
||||
}
|
||||
}
|
||||
return c.Render("group/edit.html", &xweb.T{
|
||||
return c.Render("group/edit.html", renders.T{
|
||||
"selUsers": selUsers,
|
||||
"otherUsers": otherUsers,
|
||||
})
|
||||
}
|
||||
|
||||
func (c *GroupAction) Del() error {
|
||||
name := c.GetString("name")
|
||||
type GroupDelAction struct {
|
||||
GroupBaseAction
|
||||
}
|
||||
|
||||
func (c *GroupDelAction) Get() error {
|
||||
name := c.Form("name")
|
||||
err := DB.DelGroup(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.Go("get")
|
||||
c.Redirect("/group")
|
||||
return nil
|
||||
}
|
||||
|
||||
96
web/perm.go
@@ -5,36 +5,28 @@ import (
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"github.com/go-xweb/xweb"
|
||||
"github.com/goftp/server"
|
||||
"github.com/tango-contrib/renders"
|
||||
)
|
||||
|
||||
type PermAction struct {
|
||||
BaseAction
|
||||
|
||||
get xweb.Mapper `xweb:"/"`
|
||||
add xweb.Mapper
|
||||
edit xweb.Mapper
|
||||
del xweb.Mapper
|
||||
updateOwner xweb.Mapper
|
||||
updateGroup xweb.Mapper
|
||||
updatePerm xweb.Mapper
|
||||
}
|
||||
|
||||
func (c *PermAction) Init() {
|
||||
c.AddTmplVar("isCurModule", c.IsCurModule)
|
||||
}
|
||||
|
||||
func (c *PermAction) IsCurModule(module int) bool {
|
||||
return PERM_MODULE == module
|
||||
}
|
||||
|
||||
func hasPerm(mode os.FileMode, idx int, rOrW string) bool {
|
||||
return string(mode.String()[idx]) == rOrW
|
||||
}
|
||||
|
||||
type PermBaseAction struct {
|
||||
BaseAuthAction
|
||||
}
|
||||
|
||||
func (c *PermBaseAction) Before() {
|
||||
c.curModule = PERM_MODULE
|
||||
}
|
||||
|
||||
type PermAction struct {
|
||||
PermBaseAction
|
||||
}
|
||||
|
||||
func (c *PermAction) Get() error {
|
||||
p := c.GetString("path")
|
||||
p := c.Form("path")
|
||||
var pathinfos = make([]server.FileInfo, 0)
|
||||
var err error
|
||||
var parent string
|
||||
@@ -67,7 +59,7 @@ func (c *PermAction) Get() error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.Render("perm/list.html", &xweb.T{
|
||||
return c.Render("perm/list.html", renders.T{
|
||||
"parent": parent,
|
||||
"path": p,
|
||||
"infos": pathinfos,
|
||||
@@ -77,9 +69,37 @@ func (c *PermAction) Get() error {
|
||||
})
|
||||
}
|
||||
|
||||
func (c *PermAction) UpdateGroup() {
|
||||
name := c.GetString("name")
|
||||
newgroup := c.GetString("newgroup")
|
||||
type PermAddAction struct {
|
||||
PermBaseAction
|
||||
}
|
||||
|
||||
func (p *PermAddAction) Get() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type PermEditAction struct {
|
||||
PermBaseAction
|
||||
}
|
||||
|
||||
func (p *PermEditAction) Get() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type PermDelAction struct {
|
||||
PermBaseAction
|
||||
}
|
||||
|
||||
func (p *PermDelAction) Get() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
type PermUpdateGroup struct {
|
||||
PermBaseAction
|
||||
}
|
||||
|
||||
func (c *PermUpdateGroup) Get() {
|
||||
name := c.Form("name")
|
||||
newgroup := c.Form("newgroup")
|
||||
|
||||
if name == "" || newgroup == "" {
|
||||
c.ServeJson(map[string]string{"status": "0", "error": "empty params"})
|
||||
@@ -100,9 +120,13 @@ func (c *PermAction) UpdateGroup() {
|
||||
c.ServeJson(map[string]string{"status": "1"})
|
||||
}
|
||||
|
||||
func (c *PermAction) UpdateOwner() {
|
||||
name := c.GetString("name")
|
||||
newowner := c.GetString("newowner")
|
||||
type PermUpdateOwner struct {
|
||||
PermBaseAction
|
||||
}
|
||||
|
||||
func (c *PermUpdateOwner) Get() {
|
||||
name := c.Form("name")
|
||||
newowner := c.Form("newowner")
|
||||
|
||||
if name == "" || newowner == "" {
|
||||
c.ServeJson(map[string]string{"status": "0", "error": "empty params"})
|
||||
@@ -123,11 +147,15 @@ func (c *PermAction) UpdateOwner() {
|
||||
c.ServeJson(map[string]string{"status": "1"})
|
||||
}
|
||||
|
||||
func (c *PermAction) UpdatePerm() {
|
||||
name := c.GetString("name")
|
||||
typ := c.GetString("typ")
|
||||
right := c.GetString("right")
|
||||
has := c.GetString("has")
|
||||
type PermUpdatePerm struct {
|
||||
PermBaseAction
|
||||
}
|
||||
|
||||
func (c *PermUpdatePerm) Get() {
|
||||
name := c.Form("name")
|
||||
typ := c.Form("typ")
|
||||
right := c.Form("right")
|
||||
has := c.Form("has")
|
||||
|
||||
if name == "" || typ == "" || right == "" || has == "" {
|
||||
c.ServeJson(map[string]string{"status": "0", "error": "empty params"})
|
||||
|
||||
204
web/user.go
@@ -1,54 +1,20 @@
|
||||
package web
|
||||
|
||||
import "github.com/go-xweb/xweb"
|
||||
import (
|
||||
"github.com/tango-contrib/renders"
|
||||
"github.com/tango-contrib/xsrf"
|
||||
)
|
||||
|
||||
type UserBaseAction struct {
|
||||
BaseAuthAction
|
||||
}
|
||||
|
||||
func (c *UserBaseAction) Before() {
|
||||
c.curModule = USER_MODULE
|
||||
}
|
||||
|
||||
type UserAction struct {
|
||||
BaseAction
|
||||
|
||||
get xweb.Mapper `xweb:"/"`
|
||||
add xweb.Mapper
|
||||
edit xweb.Mapper
|
||||
del xweb.Mapper
|
||||
chgpass xweb.Mapper
|
||||
|
||||
module int
|
||||
}
|
||||
|
||||
func (c *UserAction) Init() {
|
||||
c.module = USER_MODULE
|
||||
c.AddTmplVar("isCurModule", c.IsCurModule)
|
||||
}
|
||||
|
||||
func (c *UserAction) IsCurModule(module int) bool {
|
||||
return c.module == module
|
||||
}
|
||||
|
||||
func (c *UserAction) Chgpass() error {
|
||||
c.module = CHGPASS_MODULE
|
||||
if c.Method() == "GET" {
|
||||
user := c.GetSession("userId")
|
||||
_, err := DB.GetUser(user.(string))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.Render("user/chgpass.html", &xweb.T{
|
||||
"user": user,
|
||||
})
|
||||
} else if c.Method() == "POST" {
|
||||
var user User
|
||||
err := c.MapForm(&user, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = DB.ChgPass(user.Name, user.Pass)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return c.Go("chgpass")
|
||||
}
|
||||
|
||||
return xweb.NotSupported()
|
||||
UserBaseAction
|
||||
}
|
||||
|
||||
func (a *UserAction) Get() error {
|
||||
@@ -58,62 +24,118 @@ func (a *UserAction) Get() error {
|
||||
return err
|
||||
}
|
||||
|
||||
return a.Render("user/list.html", &xweb.T{
|
||||
return a.Render("user/list.html", renders.T{
|
||||
"users": users,
|
||||
"admin": adminUser,
|
||||
})
|
||||
}
|
||||
|
||||
func (a *UserAction) Add() error {
|
||||
if a.Method() == "GET" {
|
||||
return a.Render("user/add.html")
|
||||
} else if a.Method() == "POST" {
|
||||
user := new(User)
|
||||
err := a.MapForm(user, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = DB.AddUser(user.Name, user.Pass)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return a.Go("get")
|
||||
}
|
||||
return xweb.NotSupported()
|
||||
type ChgPassAction struct {
|
||||
UserBaseAction
|
||||
xsrf.Checker
|
||||
}
|
||||
|
||||
func (a *UserAction) Edit() error {
|
||||
if a.Method() == "GET" {
|
||||
name := a.GetString("name")
|
||||
pass, err := DB.GetUser(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return a.Render("user/edit.html", &xweb.T{
|
||||
"user": &User{name, pass},
|
||||
})
|
||||
} else if a.Method() == "POST" {
|
||||
user := new(User)
|
||||
err := a.MapForm(user, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = DB.ChgPass(user.Name, user.Pass)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return a.Go("get")
|
||||
}
|
||||
return xweb.NotSupported()
|
||||
func (c *ChgPassAction) Before() {
|
||||
c.curModule = CHGPASS_MODULE
|
||||
}
|
||||
|
||||
func (a *UserAction) Del() error {
|
||||
name := a.GetString("name")
|
||||
func (c *ChgPassAction) Get() error {
|
||||
user := c.LoginUserId()
|
||||
_, err := DB.GetUser(user)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.Render("user/chgpass.html", renders.T{
|
||||
"user": user,
|
||||
"userId": c.LoginUserId(),
|
||||
"XsrfFormHtml": c.Checker.XsrfFormHtml(),
|
||||
})
|
||||
}
|
||||
|
||||
func (c *ChgPassAction) Post() error {
|
||||
var user User
|
||||
errs := c.Bind(&user)
|
||||
if errs.Len() > 0 {
|
||||
return errs[0]
|
||||
}
|
||||
err := DB.ChgPass(user.Name, user.Pass)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
c.Redirect("/user/chgpass")
|
||||
return nil
|
||||
}
|
||||
|
||||
type UserAddAction struct {
|
||||
UserBaseAction
|
||||
xsrf.Checker
|
||||
}
|
||||
|
||||
func (a *UserAddAction) Get() error {
|
||||
return a.Render("user/add.html", renders.T{
|
||||
"XsrfFormHtml": a.Checker.XsrfFormHtml(),
|
||||
})
|
||||
}
|
||||
|
||||
func (a *UserAddAction) Post() error {
|
||||
var user User
|
||||
errs := a.Bind(user)
|
||||
if errs.Len() > 0 {
|
||||
return errs[0]
|
||||
}
|
||||
err := DB.AddUser(user.Name, user.Pass)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
a.Redirect("/user")
|
||||
return nil
|
||||
}
|
||||
|
||||
type UserEditAction struct {
|
||||
UserBaseAction
|
||||
xsrf.Checker
|
||||
}
|
||||
|
||||
func (a *UserEditAction) Get() error {
|
||||
name := a.Form("name")
|
||||
pass, err := DB.GetUser(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return a.Render("user/edit.html", renders.T{
|
||||
"user": &User{name, pass},
|
||||
"XsrfFormHtml": a.Checker.XsrfFormHtml(),
|
||||
})
|
||||
}
|
||||
|
||||
func (a *UserEditAction) Post() error {
|
||||
var user User
|
||||
errs := a.Bind(&user)
|
||||
if errs.Len() > 0 {
|
||||
return errs[0]
|
||||
}
|
||||
err := DB.ChgPass(user.Name, user.Pass)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
a.Redirect("/user")
|
||||
return nil
|
||||
}
|
||||
|
||||
type UserDelAction struct {
|
||||
UserBaseAction
|
||||
}
|
||||
|
||||
func (a *UserDelAction) Get() error {
|
||||
name := a.Form("name")
|
||||
err := DB.DelUser(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return a.Go("get")
|
||||
a.Redirect("/user")
|
||||
return nil
|
||||
}
|
||||
|
||||
89
web/web.go
@@ -1,9 +1,15 @@
|
||||
package web
|
||||
|
||||
import (
|
||||
"github.com/go-xweb/xweb"
|
||||
"time"
|
||||
|
||||
"github.com/goftp/server"
|
||||
"github.com/lunny/tango"
|
||||
"github.com/syndtr/goleveldb/leveldb"
|
||||
"github.com/tango-contrib/binding"
|
||||
"github.com/tango-contrib/renders"
|
||||
"github.com/tango-contrib/session"
|
||||
"github.com/tango-contrib/xsrf"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -20,7 +26,31 @@ var (
|
||||
adminUser string
|
||||
)
|
||||
|
||||
func Web(listen, static, templates, admin, pass string, ssl bool) {
|
||||
type auther interface {
|
||||
AskLogin() bool
|
||||
IsLogin() bool
|
||||
LoginUserId() string
|
||||
}
|
||||
|
||||
func auth() tango.HandlerFunc {
|
||||
return func(ctx *tango.Context) {
|
||||
if a, ok := ctx.Action().(auther); ok {
|
||||
if a.AskLogin() {
|
||||
if !a.IsLogin() {
|
||||
ctx.Redirect("/login")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
ctx.Next()
|
||||
}
|
||||
}
|
||||
|
||||
const (
|
||||
timeout = time.Minute * 20
|
||||
)
|
||||
|
||||
func Web(listen, static, templates, admin, pass string, tls bool, certFile, keyFile string) {
|
||||
_, err := DB.GetUser(admin)
|
||||
if err != nil {
|
||||
if err == leveldb.ErrNotFound {
|
||||
@@ -32,18 +62,51 @@ func Web(listen, static, templates, admin, pass string, ssl bool) {
|
||||
}
|
||||
adminUser = admin
|
||||
|
||||
app := xweb.RootApp()
|
||||
filter := xweb.NewLoginFilter(app, "userId", "/login")
|
||||
filter.AddAnonymousUrls("/login")
|
||||
app.AddFilter(filter)
|
||||
t := tango.Classic()
|
||||
t.Use(tango.Static(tango.StaticOptions{
|
||||
RootPath: static,
|
||||
}))
|
||||
t.Use(renders.New(renders.Options{
|
||||
Reload: true, // if reload when template is changed
|
||||
Directory: templates,
|
||||
}))
|
||||
t.Use(session.New(session.Options{
|
||||
MaxAge: timeout,
|
||||
}))
|
||||
t.Use(auth())
|
||||
t.Use(binding.Bind())
|
||||
t.Use(xsrf.New(timeout))
|
||||
|
||||
xweb.SetStaticDir(static)
|
||||
xweb.SetTemplateDir(templates)
|
||||
xweb.AddAction(&MainAction{})
|
||||
xweb.AutoAction(&UserAction{}, &GroupAction{}, &PermAction{})
|
||||
t.Get("/", new(MainAction))
|
||||
t.Any("/login", new(LoginAction))
|
||||
t.Get("/logout", new(LogoutAction))
|
||||
t.Group("/user", func(g *tango.Group) {
|
||||
g.Get("/", new(UserAction))
|
||||
g.Any("/add", new(UserAddAction))
|
||||
g.Any("/edit", new(UserEditAction))
|
||||
g.Any("/del", new(UserDelAction))
|
||||
})
|
||||
|
||||
if ssl {
|
||||
//xweb.RunTLS(listen, config)
|
||||
t.Group("/group", func(g *tango.Group) {
|
||||
g.Get("/", new(GroupAction))
|
||||
g.Get("/add", new(GroupAddAction))
|
||||
g.Get("/edit", new(GroupEditAction))
|
||||
g.Get("/del", new(GroupDelAction))
|
||||
})
|
||||
t.Group("/perm", func(g *tango.Group) {
|
||||
g.Get("/", new(PermAction))
|
||||
g.Any("/add", new(PermAddAction))
|
||||
g.Any("/edit", new(PermEditAction))
|
||||
g.Any("/del", new(PermDelAction))
|
||||
g.Any("/updateOwner", new(PermUpdateOwner))
|
||||
g.Any("/updateGroup", new(PermUpdateGroup))
|
||||
g.Any("/updatePerm", new(PermUpdatePerm))
|
||||
})
|
||||
|
||||
if tls {
|
||||
t.RunTLS(certFile, keyFile, listen)
|
||||
return
|
||||
}
|
||||
xweb.Run(listen)
|
||||
|
||||
t.Run(listen)
|
||||
}
|
||||
|
||||