summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYarden Shoham <hrsi88@gmail.com>2022-10-22 20:15:52 +0300
committerGitHub <noreply@github.com>2022-10-23 01:15:52 +0800
commit63ebb53fd526021666bd9fab1f9d092380f7a2f4 (patch)
tree138c35a4bbe7dae7110399cd1a145598db248f43
parent82ecd3b19eb1382521b7999bd0e2dd977c3b994d (diff)
downloadgitea-63ebb53fd526021666bd9fab1f9d092380f7a2f4.tar.gz
gitea-63ebb53fd526021666bd9fab1f9d092380f7a2f4.zip
Add link to user profile in markdown mention only if user exists (#21533)
Previously mentioning a user would link to its profile, regardless of whether the user existed. This change tests if the user exists and only if it does - a link to its profile is added. * Fixes #3444 Signed-off-by: Yarden Shoham <hrsi88@gmail.com> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com> Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
-rw-r--r--contrib/pr/checkout.go3
-rw-r--r--modules/markup/html.go10
-rw-r--r--modules/markup/markdown/markdown_test.go5
-rw-r--r--modules/markup/renderer.go12
-rw-r--r--routers/api/v1/misc/markdown_test.go7
-rw-r--r--routers/init.go3
-rw-r--r--services/markup/main_test.go19
-rw-r--r--services/markup/processorhelper.go29
-rw-r--r--services/markup/processorhelper_test.go20
9 files changed, 103 insertions, 5 deletions
diff --git a/contrib/pr/checkout.go b/contrib/pr/checkout.go
index 09510ac2c5..686a3ddffa 100644
--- a/contrib/pr/checkout.go
+++ b/contrib/pr/checkout.go
@@ -33,6 +33,7 @@ import (
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/routers"
+ markup_service "code.gitea.io/gitea/services/markup"
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/config"
@@ -112,7 +113,7 @@ func runPR() {
log.Printf("[PR] Setting up router\n")
// routers.GlobalInit()
external.RegisterRenderers()
- markup.Init()
+ markup.Init(markup_service.ProcessorHelper())
c := routers.NormalRoutes(graceful.GetManager().HammerContext())
log.Printf("[PR] Ready for testing !\n")
diff --git a/modules/markup/html.go b/modules/markup/html.go
index a5606dbb51..ae00c3905f 100644
--- a/modules/markup/html.go
+++ b/modules/markup/html.go
@@ -603,8 +603,14 @@ func mentionProcessor(ctx *RenderContext, node *html.Node) {
start = loc.End
continue
}
- replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(setting.AppURL, mention[1:]), mention, "mention"))
- node = node.NextSibling.NextSibling
+ mentionedUsername := mention[1:]
+
+ if processorHelper.IsUsernameMentionable != nil && processorHelper.IsUsernameMentionable(ctx.Ctx, mentionedUsername) {
+ replaceContent(node, loc.Start, loc.End, createLink(util.URLJoin(setting.AppURL, mentionedUsername), mention, "mention"))
+ node = node.NextSibling.NextSibling
+ } else {
+ node = node.NextSibling
+ }
start = 0
}
}
diff --git a/modules/markup/markdown/markdown_test.go b/modules/markup/markdown/markdown_test.go
index 12c6288c24..fbb741d1cd 100644
--- a/modules/markup/markdown/markdown_test.go
+++ b/modules/markup/markdown/markdown_test.go
@@ -38,6 +38,11 @@ func TestMain(m *testing.M) {
if err := git.InitSimple(context.Background()); err != nil {
log.Fatal("git init failed, err: %v", err)
}
+ markup.Init(&markup.ProcessorHelper{
+ IsUsernameMentionable: func(ctx context.Context, username string) bool {
+ return username == "r-lyeh"
+ },
+ })
os.Exit(m.Run())
}
diff --git a/modules/markup/renderer.go b/modules/markup/renderer.go
index 5f69dc7235..b3289cb3c3 100644
--- a/modules/markup/renderer.go
+++ b/modules/markup/renderer.go
@@ -19,8 +19,18 @@ import (
"code.gitea.io/gitea/modules/setting"
)
+type ProcessorHelper struct {
+ IsUsernameMentionable func(ctx context.Context, username string) bool
+}
+
+var processorHelper ProcessorHelper
+
// Init initialize regexps for markdown parsing
-func Init() {
+func Init(ph *ProcessorHelper) {
+ if ph != nil {
+ processorHelper = *ph
+ }
+
NewSanitizer()
if len(setting.Markdown.CustomURLSchemes) > 0 {
CustomLinkURLSchemes(setting.Markdown.CustomURLSchemes)
diff --git a/routers/api/v1/misc/markdown_test.go b/routers/api/v1/misc/markdown_test.go
index 7809fa5cc7..65ce060278 100644
--- a/routers/api/v1/misc/markdown_test.go
+++ b/routers/api/v1/misc/markdown_test.go
@@ -5,6 +5,7 @@
package misc
import (
+ go_context "context"
"io"
"net/http"
"net/http/httptest"
@@ -13,6 +14,7 @@ import (
"testing"
"code.gitea.io/gitea/modules/context"
+ "code.gitea.io/gitea/modules/markup"
"code.gitea.io/gitea/modules/setting"
api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/templates"
@@ -50,6 +52,11 @@ func wrap(ctx *context.Context) *context.APIContext {
func TestAPI_RenderGFM(t *testing.T) {
setting.AppURL = AppURL
+ markup.Init(&markup.ProcessorHelper{
+ IsUsernameMentionable: func(ctx go_context.Context, username string) bool {
+ return username == "r-lyeh"
+ },
+ })
options := api.MarkdownOption{
Mode: "gfm",
diff --git a/routers/init.go b/routers/init.go
index 0f2e993413..9045437f87 100644
--- a/routers/init.go
+++ b/routers/init.go
@@ -41,6 +41,7 @@ import (
"code.gitea.io/gitea/services/automerge"
"code.gitea.io/gitea/services/cron"
"code.gitea.io/gitea/services/mailer"
+ markup_service "code.gitea.io/gitea/services/markup"
repo_migrations "code.gitea.io/gitea/services/migrations"
mirror_service "code.gitea.io/gitea/services/mirror"
pull_service "code.gitea.io/gitea/services/pull"
@@ -123,7 +124,7 @@ func GlobalInitInstalled(ctx context.Context) {
highlight.NewContext()
external.RegisterRenderers()
- markup.Init()
+ markup.Init(markup_service.ProcessorHelper())
if setting.EnableSQLite3 {
log.Info("SQLite3 support is enabled")
diff --git a/services/markup/main_test.go b/services/markup/main_test.go
new file mode 100644
index 0000000000..8efd08e69d
--- /dev/null
+++ b/services/markup/main_test.go
@@ -0,0 +1,19 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package markup
+
+import (
+ "path/filepath"
+ "testing"
+
+ "code.gitea.io/gitea/models/unittest"
+)
+
+func TestMain(m *testing.M) {
+ unittest.MainTest(m, &unittest.TestOptions{
+ GiteaRootPath: filepath.Join("..", ".."),
+ FixtureFiles: []string{"user.yml"},
+ })
+}
diff --git a/services/markup/processorhelper.go b/services/markup/processorhelper.go
new file mode 100644
index 0000000000..2b1cac2a5b
--- /dev/null
+++ b/services/markup/processorhelper.go
@@ -0,0 +1,29 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package markup
+
+import (
+ "context"
+
+ "code.gitea.io/gitea/models/user"
+ "code.gitea.io/gitea/modules/log"
+ "code.gitea.io/gitea/modules/markup"
+)
+
+func ProcessorHelper() *markup.ProcessorHelper {
+ return &markup.ProcessorHelper{
+ IsUsernameMentionable: func(ctx context.Context, username string) bool {
+ // TODO: cast ctx to modules/context.Context and use IsUserVisibleToViewer
+
+ // Only link if the user actually exists
+ userExists, err := user.IsUserExist(ctx, 0, username)
+ if err != nil {
+ log.Error("Failed to validate user in mention %q exists, assuming it does", username)
+ userExists = true
+ }
+ return userExists
+ },
+ }
+}
diff --git a/services/markup/processorhelper_test.go b/services/markup/processorhelper_test.go
new file mode 100644
index 0000000000..386465bc91
--- /dev/null
+++ b/services/markup/processorhelper_test.go
@@ -0,0 +1,20 @@
+// Copyright 2022 The Gitea Authors. All rights reserved.
+// Use of this source code is governed by a MIT-style
+// license that can be found in the LICENSE file.
+
+package markup
+
+import (
+ "context"
+ "testing"
+
+ "code.gitea.io/gitea/models/unittest"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestProcessorHelper(t *testing.T) {
+ assert.NoError(t, unittest.PrepareTestDatabase())
+ assert.True(t, ProcessorHelper().IsUsernameMentionable(context.Background(), "user10"))
+ assert.False(t, ProcessorHelper().IsUsernameMentionable(context.Background(), "no-such-user"))
+}