mirror of https://github.com/mindoc-org/mindoc.git
bugfix: 1. 修复私有问题访问bug;2. 重构私有文档访问逻辑代码;3. shell生成zip包中,删除go文件。 resolves mindoc-org/mindoc#751, resolves mindoc-org/mindoc#801
parent
b4b7528e3f
commit
0b83a53b56
|
@ -14,7 +14,7 @@ go build -v -o mindoc_linux_amd64 -ldflags="-linkmode external -extldflags '-sta
|
|||
mkdir ../mindoc_linux_amd64
|
||||
cp -r * ../mindoc_linux_amd64
|
||||
cd ../mindoc_linux_amd64
|
||||
rm -rf cache commands controllers converter .git .github graphics mail models routers utils runtime
|
||||
rm -rf cache commands controllers converter .git .github graphics mail models routers utils runtime conf/*.go
|
||||
rm appveyor.yml docker-compose.yml Dockerfile .travis.yml .gitattributes .gitignore go.mod go.sum main.go README.md simsun.ttc start.sh sync_host.sh build_amd64.sh build_musl_amd64.sh
|
||||
zip -r mindoc_linux_amd64.zip conf static uploads views lib mindoc_linux_amd64 favicon.ico LICENSE.md
|
||||
mv ./mindoc_linux_amd64.zip ../
|
||||
|
|
|
@ -14,7 +14,7 @@ go build -v -o mindoc_linux_musl_amd64 -ldflags="-linkmode external -extldflags
|
|||
mkdir ../mindoc_linux_musl_amd64
|
||||
cp -r * ../mindoc_linux_musl_amd64
|
||||
cd ../mindoc_linux_musl_amd64
|
||||
rm -rf cache commands controllers converter .git .github graphics mail models routers utils runtime
|
||||
rm -rf cache commands controllers converter .git .github graphics mail models routers utils runtime conf/*.go
|
||||
rm appveyor.yml docker-compose.yml Dockerfile .travis.yml .gitattributes .gitignore go.mod go.sum main.go README.md simsun.ttc start.sh sync_host.sh build_amd64.sh build_musl_amd64.sh
|
||||
zip -r mindoc_linux_musl_amd64.zip conf static uploads views lib mindoc_linux_musl_amd64 favicon.ico LICENSE.md
|
||||
mv ./mindoc_linux_musl_amd64.zip ../
|
||||
|
|
|
@ -190,8 +190,9 @@ func (c *BaseController) ShowErrorPage(errCode int, errMsg string) {
|
|||
c.Data["ErrorCode"] = errCode
|
||||
|
||||
var buf bytes.Buffer
|
||||
exeData := map[string]interface{}{"ErrorMessage": errMsg, "ErrorCode": errCode, "BaseUrl": conf.BaseUrl, "Lang": c.Lang}
|
||||
|
||||
if err := web.ExecuteViewPathTemplate(&buf, "errors/error.tpl", web.BConfig.WebConfig.ViewsPath, map[string]interface{}{"ErrorMessage": errMsg, "ErrorCode": errCode, "BaseUrl": conf.BaseUrl}); err != nil {
|
||||
if err := web.ExecuteViewPathTemplate(&buf, "errors/error.tpl", web.BConfig.WebConfig.ViewsPath, exeData); err != nil {
|
||||
c.Abort("500")
|
||||
}
|
||||
if errCode >= 200 && errCode <= 510 {
|
||||
|
|
|
@ -96,6 +96,41 @@ func (c *DocumentController) Index() {
|
|||
|
||||
}
|
||||
|
||||
// CheckPassword : Handles password verification for private documents,
|
||||
// and front-end requests are made through Ajax.
|
||||
func (c *DocumentController) CheckPassword() {
|
||||
c.Prepare()
|
||||
|
||||
identify := c.Ctx.Input.Param(":key")
|
||||
password := c.GetString("bPassword")
|
||||
|
||||
if identify == "" || password == "" {
|
||||
c.JsonResult(http.StatusBadRequest, i18n.Tr(c.Lang, "message.param_error"))
|
||||
}
|
||||
|
||||
// You have not logged in and need to log in again.
|
||||
if !c.EnableAnonymous && !c.isUserLoggedIn() {
|
||||
logs.Info("You have not logged in and need to log in again(SessionId: %s).",
|
||||
c.CruSession.SessionID(context.TODO()))
|
||||
c.JsonResult(6000, i18n.Tr(c.Lang, "message.need_relogin"))
|
||||
return
|
||||
}
|
||||
|
||||
book, err := models.NewBook().FindByFieldFirst("identify", identify)
|
||||
|
||||
if err != nil {
|
||||
logs.Error(err)
|
||||
c.JsonResult(500, i18n.Tr(c.Lang, "message.item_not_exist"))
|
||||
}
|
||||
|
||||
if book.BookPassword != password {
|
||||
c.JsonResult(5001, i18n.Tr(c.Lang, "message.wrong_password"))
|
||||
} else {
|
||||
c.SetSession(identify, password)
|
||||
c.JsonResult(0, "OK")
|
||||
}
|
||||
}
|
||||
|
||||
// 阅读文档
|
||||
func (c *DocumentController) Read() {
|
||||
c.Prepare()
|
||||
|
@ -1258,47 +1293,57 @@ func (c *DocumentController) isReadable(identify, token string) *models.BookResu
|
|||
bookResult.RoleId = roleId
|
||||
}
|
||||
}
|
||||
// 如果文档是私有的
|
||||
if book.PrivatelyOwned == 1 && (!c.isUserLoggedIn() || !c.Member.IsAdministrator()) {
|
||||
if s, ok := c.GetSession(identify).(string); !ok || (!strings.EqualFold(s, book.PrivateToken) && !strings.EqualFold(s, book.BookPassword)) {
|
||||
|
||||
if book.PrivateToken != "" && !isOk && token != "" {
|
||||
// 如果有访问的 Token,并且该项目设置了访问 Token,并且和用户提供的相匹配,则记录到 Session 中。
|
||||
// 如果用户未提供 Token 且用户登录了,则判断用户是否参与了该项目。
|
||||
// 如果用户未登录,则从 Session 中读取 Token。
|
||||
if token != "" && strings.EqualFold(token, book.PrivateToken) {
|
||||
c.SetSession(identify, token)
|
||||
} else if token, ok := c.GetSession(identify).(string); !ok || !strings.EqualFold(token, book.PrivateToken) {
|
||||
logs.Info("尝试访问文档但权限不足 ->", identify, token)
|
||||
c.ShowErrorPage(403, i18n.Tr(c.Lang, "message.no_permission"))
|
||||
}
|
||||
} else if password := c.GetString("bPassword", ""); !isOk && book.BookPassword != "" && password != "" {
|
||||
/* 私有项目:
|
||||
* 管理员可以直接访问
|
||||
* 参与者可以直接访问
|
||||
* 其他用户(支持匿名访问)
|
||||
* token设置情况
|
||||
* 已设置:可以通过token访问
|
||||
* 未设置:不可以通过token访问
|
||||
* password设置情况
|
||||
* 已设置:可以通过password访问
|
||||
* 未设置:不可以通过password访问
|
||||
* 注意:
|
||||
* 1. 第一次访问需要存session
|
||||
* 2. 有session优先使用session中的token或者password,再使用携带的token或者password
|
||||
* 3. 私有项目如果token和password都没有设置,则除管理员和参与者的其他用户不可以访问
|
||||
* 4. 使用token访问如果不通过,则提示输入密码
|
||||
*/
|
||||
if book.PrivatelyOwned == 1 {
|
||||
if c.isUserLoggedIn() && c.Member.IsAdministrator() {
|
||||
return bookResult
|
||||
}
|
||||
if isOk { // Project participant.
|
||||
return bookResult
|
||||
}
|
||||
|
||||
//如果设置了密码,则判断密码是否正确
|
||||
if book.BookPassword != password {
|
||||
c.JsonResult(5001, i18n.Tr(c.Lang, "message.wrong_password"))
|
||||
} else {
|
||||
c.SetSession(identify, password)
|
||||
c.JsonResult(0, "OK")
|
||||
}
|
||||
|
||||
} else if !isOk {
|
||||
//如果设置了密码,则显示密码输入页面
|
||||
if book.BookPassword != "" {
|
||||
//判断已存在的密码是否正确
|
||||
if password, ok := c.GetSession(identify).(string); !ok || !strings.EqualFold(password, book.BookPassword) {
|
||||
body, err := c.ExecuteViewPathTemplate("document/document_password.tpl", map[string]string{"Identify": book.Identify})
|
||||
if err != nil {
|
||||
logs.Error("显示密码页面失败 ->", err)
|
||||
}
|
||||
c.CustomAbort(200, body)
|
||||
}
|
||||
} else {
|
||||
logs.Info("尝试访问文档但权限不足 ->", identify, token)
|
||||
c.ShowErrorPage(403, i18n.Tr(c.Lang, "message.no_permission"))
|
||||
}
|
||||
// Use session in preference.
|
||||
if tokenOrPassword, ok := c.GetSession(identify).(string); ok {
|
||||
if strings.EqualFold(book.PrivateToken, tokenOrPassword) || strings.EqualFold(book.BookPassword, tokenOrPassword) {
|
||||
return bookResult
|
||||
}
|
||||
}
|
||||
|
||||
// Next: Session not exist or not correct.
|
||||
if book.PrivateToken != "" && book.PrivateToken == token {
|
||||
c.SetSession(identify, token)
|
||||
return bookResult
|
||||
} else if book.BookPassword != "" {
|
||||
// Send a page for inputting password.
|
||||
// For verification, see function DocumentController.CheckPassword
|
||||
body, err := c.ExecuteViewPathTemplate("document/document_password.tpl",
|
||||
map[string]string{"Identify": book.Identify, "Lang": c.Lang})
|
||||
if err != nil {
|
||||
logs.Error("显示密码页面失败 ->", err)
|
||||
c.ShowErrorPage(500, i18n.Tr(c.Lang, "message.system_error"))
|
||||
}
|
||||
c.CustomAbort(200, body)
|
||||
} else {
|
||||
// No permission to access this book.
|
||||
logs.Info("尝试访问文档但权限不足 ->", identify, token)
|
||||
c.ShowErrorPage(403, i18n.Tr(c.Lang, "message.no_permission"))
|
||||
}
|
||||
}
|
||||
|
||||
return bookResult
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/beego/beego/v2/core/logs"
|
||||
"github.com/beego/beego/v2/server/web"
|
||||
"github.com/beego/beego/v2/server/web/context"
|
||||
|
||||
// "github.com/mindoc-org/mindoc/conf"
|
||||
"github.com/mindoc-org/mindoc/controllers"
|
||||
)
|
||||
|
@ -243,6 +244,7 @@ func init() {
|
|||
web.Router("/history/restore", &controllers.DocumentController{}, "*:RestoreHistory")
|
||||
|
||||
web.Router("/docs/:key", &controllers.DocumentController{}, "*:Index")
|
||||
web.Router("/docs/:key/check-password", &controllers.DocumentController{}, "post:CheckPassword")
|
||||
web.Router("/docs/:key/:id", &controllers.DocumentController{}, "*:Read")
|
||||
web.Router("/docs/:key/search", &controllers.DocumentController{}, "post:Search")
|
||||
web.Router("/export/:key", &controllers.DocumentController{}, "*:Export")
|
||||
|
|
|
@ -100,7 +100,7 @@
|
|||
<body>
|
||||
<div class="auth_form">
|
||||
<div class="shell">
|
||||
<form action="{{urlfor "DocumentController.Index" ":key" .Identify}}" method="post" id="auth_form">
|
||||
<form action="{{urlfor "DocumentController.CheckPassword" ":key" .Identify}}" method="post" id="auth_form">
|
||||
<div class="tit">{{i18n .Lang "doc.input_pwd"}}</div>
|
||||
<div style="margin-top: 10px;">
|
||||
<input type="password" name="bPassword" placeholder="{{i18n .Lang "doc.read_pwd"}}" class="inp"/>
|
||||
|
|
Loading…
Reference in New Issue