diff --git a/services/markup/processorhelper.go b/services/markup/processorhelper.go index 2b1cac2a5..5042884e5 100644 --- a/services/markup/processorhelper.go +++ b/services/markup/processorhelper.go @@ -8,22 +8,26 @@ import ( "context" "code.gitea.io/gitea/models/user" - "code.gitea.io/gitea/modules/log" + gitea_context "code.gitea.io/gitea/modules/context" "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) + mentionedUser, err := user.GetUserByName(ctx, username) if err != nil { - log.Error("Failed to validate user in mention %q exists, assuming it does", username) - userExists = true + return false } - return userExists + + giteaCtx, ok := ctx.(*gitea_context.Context) + if !ok { + // when using general context, use user's visibility to check + return mentionedUser.Visibility.IsPublic() + } + + // when using gitea context (web context), use user's visibility and user's permission to check + return user.IsUserVisibleToViewer(giteaCtx, mentionedUser, giteaCtx.Doer) }, } } diff --git a/services/markup/processorhelper_test.go b/services/markup/processorhelper_test.go index 386465bc9..f7eab3d95 100644 --- a/services/markup/processorhelper_test.go +++ b/services/markup/processorhelper_test.go @@ -6,15 +6,48 @@ package markup import ( "context" + "net/http" "testing" + "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" + "code.gitea.io/gitea/models/user" + gitea_context "code.gitea.io/gitea/modules/context" "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")) + + userPublic := "user1" + userPrivate := "user31" + userLimited := "user33" + userNoSuch := "no-such-user" + + unittest.AssertCount(t, &user.User{Name: userPublic}, 1) + unittest.AssertCount(t, &user.User{Name: userPrivate}, 1) + unittest.AssertCount(t, &user.User{Name: userLimited}, 1) + unittest.AssertCount(t, &user.User{Name: userNoSuch}, 0) + + // when using general context, use user's visibility to check + assert.True(t, ProcessorHelper().IsUsernameMentionable(context.Background(), userPublic)) + assert.False(t, ProcessorHelper().IsUsernameMentionable(context.Background(), userLimited)) + assert.False(t, ProcessorHelper().IsUsernameMentionable(context.Background(), userPrivate)) + assert.False(t, ProcessorHelper().IsUsernameMentionable(context.Background(), userNoSuch)) + + // when using web context, use user.IsUserVisibleToViewer to check + var err error + giteaCtx := &gitea_context.Context{} + giteaCtx.Req, err = http.NewRequest("GET", "/", nil) + assert.NoError(t, err) + + giteaCtx.Doer = nil + assert.True(t, ProcessorHelper().IsUsernameMentionable(giteaCtx, userPublic)) + assert.False(t, ProcessorHelper().IsUsernameMentionable(giteaCtx, userPrivate)) + + giteaCtx.Doer, err = user.GetUserByName(db.DefaultContext, userPrivate) + assert.NoError(t, err) + assert.True(t, ProcessorHelper().IsUsernameMentionable(giteaCtx, userPublic)) + assert.True(t, ProcessorHelper().IsUsernameMentionable(giteaCtx, userPrivate)) }