From 0b83a53b56a0f2ad93ee71abb9c955f9a91ba285 Mon Sep 17 00:00:00 2001 From: Go-Go-Farther Date: Tue, 5 Jul 2022 11:59:23 +0800 Subject: [PATCH] =?UTF-8?q?bugfix=EF=BC=9A=201.=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E7=A7=81=E6=9C=89=E9=97=AE=E9=A2=98=E8=AE=BF=E9=97=AEbug?= =?UTF-8?q?=EF=BC=9B2.=20=E9=87=8D=E6=9E=84=E7=A7=81=E6=9C=89=E6=96=87?= =?UTF-8?q?=E6=A1=A3=E8=AE=BF=E9=97=AE=E9=80=BB=E8=BE=91=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=EF=BC=9B3.=20shell=E7=94=9F=E6=88=90zip=E5=8C=85=E4=B8=AD?= =?UTF-8?q?=EF=BC=8C=E5=88=A0=E9=99=A4go=E6=96=87=E4=BB=B6=E3=80=82=20reso?= =?UTF-8?q?lves=20mindoc-org/mindoc#751,=20resolves=20mindoc-org/mindoc#80?= =?UTF-8?q?1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build_amd64.sh | 2 +- build_musl_amd64.sh | 2 +- controllers/BaseController.go | 3 +- controllers/DocumentController.go | 119 ++++++++++++++++++--------- routers/router.go | 2 + views/document/document_password.tpl | 2 +- 6 files changed, 89 insertions(+), 41 deletions(-) diff --git a/build_amd64.sh b/build_amd64.sh index 6d2f6239..eaf64a5b 100644 --- a/build_amd64.sh +++ b/build_amd64.sh @@ -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 ../ diff --git a/build_musl_amd64.sh b/build_musl_amd64.sh index c7f9441e..51c8ca93 100644 --- a/build_musl_amd64.sh +++ b/build_musl_amd64.sh @@ -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 ../ diff --git a/controllers/BaseController.go b/controllers/BaseController.go index 7e2a5571..4d7d27dc 100644 --- a/controllers/BaseController.go +++ b/controllers/BaseController.go @@ -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 { diff --git a/controllers/DocumentController.go b/controllers/DocumentController.go index c9e341a0..7a99a833 100644 --- a/controllers/DocumentController.go +++ b/controllers/DocumentController.go @@ -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 diff --git a/routers/router.go b/routers/router.go index c0e9d5a4..f30c8593 100644 --- a/routers/router.go +++ b/routers/router.go @@ -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") diff --git a/views/document/document_password.tpl b/views/document/document_password.tpl index efa698dd..e46d4af4 100644 --- a/views/document/document_password.tpl +++ b/views/document/document_password.tpl @@ -100,7 +100,7 @@
-
+
{{i18n .Lang "doc.input_pwd"}}