summaryrefslogtreecommitdiffstats
path: root/routers
diff options
context:
space:
mode:
authorSergey Dryabzhinsky <sergey@rusoft.ru>2021-06-26 22:53:14 +0300
committerGitHub <noreply@github.com>2021-06-26 20:53:14 +0100
commit22a0636544237bcffb46b36b593a501e77ae02cc (patch)
tree009c2bcf2b478f45356b8aae59f29091ffc5809f /routers
parent19ac575d572af655ab691f829d0b4de38a1f10be (diff)
downloadgitea-22a0636544237bcffb46b36b593a501e77ae02cc.tar.gz
gitea-22a0636544237bcffb46b36b593a501e77ae02cc.zip
Add Visible modes function from Organisation to Users too (#16069)
You can limit or hide organisations. This pull make it also posible for users - new strings to translte - add checkbox to user profile form - add checkbox to admin user.edit form - filter explore page user search - filter api admin and public user searches - allow admins view "hidden" users - add app option DEFAULT_USER_VISIBILITY - rewrite many files to use Visibility field - check for teams intersection - fix context output - right fake 404 if not visible Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: Andrew Thornton <art27@cantab.net>
Diffstat (limited to 'routers')
-rw-r--r--routers/api/v1/admin/user.go15
-rw-r--r--routers/api/v1/org/org.go4
-rw-r--r--routers/api/v1/repo/repo.go4
-rw-r--r--routers/api/v1/user/helper.go2
-rw-r--r--routers/api/v1/user/user.go7
-rw-r--r--routers/web/admin/orgs.go3
-rw-r--r--routers/web/admin/users.go10
-rw-r--r--routers/web/admin/users_test.go81
-rw-r--r--routers/web/org/home.go4
-rw-r--r--routers/web/user/profile.go16
-rw-r--r--routers/web/user/setting/profile.go1
11 files changed, 131 insertions, 16 deletions
diff --git a/routers/api/v1/admin/user.go b/routers/api/v1/admin/user.go
index 4bbe7f77ba..6bc9b849b1 100644
--- a/routers/api/v1/admin/user.go
+++ b/routers/api/v1/admin/user.go
@@ -66,6 +66,7 @@ func CreateUser(ctx *context.APIContext) {
// "422":
// "$ref": "#/responses/validationError"
form := web.GetForm(ctx).(*api.CreateUserOption)
+
u := &models.User{
Name: form.Username,
FullName: form.FullName,
@@ -97,7 +98,15 @@ func CreateUser(ctx *context.APIContext) {
ctx.Error(http.StatusBadRequest, "PasswordPwned", errors.New("PasswordPwned"))
return
}
- if err := models.CreateUser(u); err != nil {
+
+ var overwriteDefault *models.CreateUserOverwriteOptions
+ if form.Visibility != "" {
+ overwriteDefault = &models.CreateUserOverwriteOptions{
+ Visibility: api.VisibilityModes[form.Visibility],
+ }
+ }
+
+ if err := models.CreateUser(u, overwriteDefault); err != nil {
if models.IsErrUserAlreadyExist(err) ||
models.IsErrEmailAlreadyUsed(err) ||
models.IsErrNameReserved(err) ||
@@ -209,6 +218,9 @@ func EditUser(ctx *context.APIContext) {
if form.Active != nil {
u.IsActive = *form.Active
}
+ if len(form.Visibility) != 0 {
+ u.Visibility = api.VisibilityModes[form.Visibility]
+ }
if form.Admin != nil {
u.IsAdmin = *form.Admin
}
@@ -395,6 +407,7 @@ func GetAllUsers(ctx *context.APIContext) {
listOptions := utils.GetListOptions(ctx)
users, maxResults, err := models.SearchUsers(&models.SearchUserOptions{
+ Actor: ctx.User,
Type: models.UserTypeIndividual,
OrderBy: models.SearchOrderByAlphabetically,
ListOptions: listOptions,
diff --git a/routers/api/v1/org/org.go b/routers/api/v1/org/org.go
index f4a634f4d5..5c16594f89 100644
--- a/routers/api/v1/org/org.go
+++ b/routers/api/v1/org/org.go
@@ -225,8 +225,8 @@ func Get(ctx *context.APIContext) {
// "200":
// "$ref": "#/responses/Organization"
- if !models.HasOrgVisible(ctx.Org.Organization, ctx.User) {
- ctx.NotFound("HasOrgVisible", nil)
+ if !models.HasOrgOrUserVisible(ctx.Org.Organization, ctx.User) {
+ ctx.NotFound("HasOrgOrUserVisible", nil)
return
}
ctx.JSON(http.StatusOK, convert.ToOrganization(ctx.Org.Organization))
diff --git a/routers/api/v1/repo/repo.go b/routers/api/v1/repo/repo.go
index 7a3160fa99..35d3490510 100644
--- a/routers/api/v1/repo/repo.go
+++ b/routers/api/v1/repo/repo.go
@@ -375,8 +375,8 @@ func CreateOrgRepo(ctx *context.APIContext) {
return
}
- if !models.HasOrgVisible(org, ctx.User) {
- ctx.NotFound("HasOrgVisible", nil)
+ if !models.HasOrgOrUserVisible(org, ctx.User) {
+ ctx.NotFound("HasOrgOrUserVisible", nil)
return
}
diff --git a/routers/api/v1/user/helper.go b/routers/api/v1/user/helper.go
index fcdac257ed..a3500e0ee6 100644
--- a/routers/api/v1/user/helper.go
+++ b/routers/api/v1/user/helper.go
@@ -17,7 +17,7 @@ func GetUserByParamsName(ctx *context.APIContext, name string) *models.User {
user, err := models.GetUserByName(username)
if err != nil {
if models.IsErrUserNotExist(err) {
- if redirectUserID, err := models.LookupUserRedirect(username); err == nil {
+ if redirectUserID, err2 := models.LookupUserRedirect(username); err2 == nil {
context.RedirectToUser(ctx.Context, username, redirectUserID)
} else {
ctx.NotFound("GetUserByName", err)
diff --git a/routers/api/v1/user/user.go b/routers/api/v1/user/user.go
index 4adae532fd..ac543d597d 100644
--- a/routers/api/v1/user/user.go
+++ b/routers/api/v1/user/user.go
@@ -57,6 +57,7 @@ func Search(ctx *context.APIContext) {
listOptions := utils.GetListOptions(ctx)
opts := &models.SearchUserOptions{
+ Actor: ctx.User,
Keyword: strings.Trim(ctx.Query("q"), " "),
UID: ctx.QueryInt64("uid"),
Type: models.UserTypeIndividual,
@@ -102,10 +103,16 @@ func GetInfo(ctx *context.APIContext) {
// "$ref": "#/responses/notFound"
u := GetUserByParams(ctx)
+
if ctx.Written() {
return
}
+ if !u.IsVisibleToUser(ctx.User) {
+ // fake ErrUserNotExist error message to not leak information about existence
+ ctx.NotFound("GetUserByName", models.ErrUserNotExist{Name: ctx.Params(":username")})
+ return
+ }
ctx.JSON(http.StatusOK, convert.ToUser(u, ctx.User))
}
diff --git a/routers/web/admin/orgs.go b/routers/web/admin/orgs.go
index 618f945704..a2b3ed1bcc 100644
--- a/routers/web/admin/orgs.go
+++ b/routers/web/admin/orgs.go
@@ -25,7 +25,8 @@ func Organizations(ctx *context.Context) {
ctx.Data["PageIsAdminOrganizations"] = true
explore.RenderUserSearch(ctx, &models.SearchUserOptions{
- Type: models.UserTypeOrganization,
+ Actor: ctx.User,
+ Type: models.UserTypeOrganization,
ListOptions: models.ListOptions{
PageSize: setting.UI.Admin.OrgPagingNum,
},
diff --git a/routers/web/admin/users.go b/routers/web/admin/users.go
index 1b65795865..dc2a97e526 100644
--- a/routers/web/admin/users.go
+++ b/routers/web/admin/users.go
@@ -37,7 +37,8 @@ func Users(ctx *context.Context) {
ctx.Data["PageIsAdminUsers"] = true
explore.RenderUserSearch(ctx, &models.SearchUserOptions{
- Type: models.UserTypeIndividual,
+ Actor: ctx.User,
+ Type: models.UserTypeIndividual,
ListOptions: models.ListOptions{
PageSize: setting.UI.Admin.UserPagingNum,
},
@@ -50,6 +51,7 @@ func NewUser(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("admin.users.new_account")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminUsers"] = true
+ ctx.Data["DefaultUserVisibilityMode"] = setting.Service.DefaultUserVisibilityMode
ctx.Data["login_type"] = "0-0"
@@ -70,6 +72,7 @@ func NewUserPost(ctx *context.Context) {
ctx.Data["Title"] = ctx.Tr("admin.users.new_account")
ctx.Data["PageIsAdmin"] = true
ctx.Data["PageIsAdminUsers"] = true
+ ctx.Data["DefaultUserVisibilityMode"] = setting.Service.DefaultUserVisibilityMode
sources, err := models.LoginSources()
if err != nil {
@@ -126,7 +129,8 @@ func NewUserPost(ctx *context.Context) {
}
u.MustChangePassword = form.MustChangePassword
}
- if err := models.CreateUser(u); err != nil {
+
+ if err := models.CreateUser(u, &models.CreateUserOverwriteOptions{Visibility: form.Visibility}); err != nil {
switch {
case models.IsErrUserAlreadyExist(err):
ctx.Data["Err_UserName"] = true
@@ -312,6 +316,8 @@ func EditUserPost(ctx *context.Context) {
u.AllowImportLocal = form.AllowImportLocal
u.AllowCreateOrganization = form.AllowCreateOrganization
+ u.Visibility = form.Visibility
+
// skip self Prohibit Login
if ctx.User.ID == u.ID {
u.ProhibitLogin = false
diff --git a/routers/web/admin/users_test.go b/routers/web/admin/users_test.go
index b19dcb886b..17c5a309b4 100644
--- a/routers/web/admin/users_test.go
+++ b/routers/web/admin/users_test.go
@@ -8,6 +8,8 @@ import (
"testing"
"code.gitea.io/gitea/models"
+ "code.gitea.io/gitea/modules/setting"
+ api "code.gitea.io/gitea/modules/structs"
"code.gitea.io/gitea/modules/test"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/services/forms"
@@ -121,3 +123,82 @@ func TestNewUserPost_InvalidEmail(t *testing.T) {
assert.NotEmpty(t, ctx.Flash.ErrorMsg)
}
+
+func TestNewUserPost_VisiblityDefaultPublic(t *testing.T) {
+
+ models.PrepareTestEnv(t)
+ ctx := test.MockContext(t, "admin/users/new")
+
+ u := models.AssertExistsAndLoadBean(t, &models.User{
+ IsAdmin: true,
+ ID: 2,
+ }).(*models.User)
+
+ ctx.User = u
+
+ username := "gitea"
+ email := "gitea@gitea.io"
+
+ form := forms.AdminCreateUserForm{
+ LoginType: "local",
+ LoginName: "local",
+ UserName: username,
+ Email: email,
+ Password: "abc123ABC!=$",
+ SendNotify: false,
+ MustChangePassword: false,
+ }
+
+ web.SetForm(ctx, &form)
+ NewUserPost(ctx)
+
+ assert.NotEmpty(t, ctx.Flash.SuccessMsg)
+
+ u, err := models.GetUserByName(username)
+
+ assert.NoError(t, err)
+ assert.Equal(t, username, u.Name)
+ assert.Equal(t, email, u.Email)
+ // As default user visibility
+ assert.Equal(t, setting.Service.DefaultUserVisibilityMode, u.Visibility)
+}
+
+func TestNewUserPost_VisibilityPrivate(t *testing.T) {
+
+ models.PrepareTestEnv(t)
+ ctx := test.MockContext(t, "admin/users/new")
+
+ u := models.AssertExistsAndLoadBean(t, &models.User{
+ IsAdmin: true,
+ ID: 2,
+ }).(*models.User)
+
+ ctx.User = u
+
+ username := "gitea"
+ email := "gitea@gitea.io"
+
+ form := forms.AdminCreateUserForm{
+ LoginType: "local",
+ LoginName: "local",
+ UserName: username,
+ Email: email,
+ Password: "abc123ABC!=$",
+ SendNotify: false,
+ MustChangePassword: false,
+ Visibility: api.VisibleTypePrivate,
+ }
+
+ web.SetForm(ctx, &form)
+ NewUserPost(ctx)
+
+ assert.NotEmpty(t, ctx.Flash.SuccessMsg)
+
+ u, err := models.GetUserByName(username)
+
+ assert.NoError(t, err)
+ assert.Equal(t, username, u.Name)
+ assert.Equal(t, email, u.Email)
+ // As default user visibility
+ assert.True(t, u.Visibility.IsPrivate())
+}
diff --git a/routers/web/org/home.go b/routers/web/org/home.go
index ad14f18454..aad0a2a90b 100644
--- a/routers/web/org/home.go
+++ b/routers/web/org/home.go
@@ -30,8 +30,8 @@ func Home(ctx *context.Context) {
org := ctx.Org.Organization
- if !models.HasOrgVisible(org, ctx.User) {
- ctx.NotFound("HasOrgVisible", nil)
+ if !models.HasOrgOrUserVisible(org, ctx.User) {
+ ctx.NotFound("HasOrgOrUserVisible", nil)
return
}
diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go
index 72d0066645..631ca21135 100644
--- a/routers/web/user/profile.go
+++ b/routers/web/user/profile.go
@@ -75,6 +75,17 @@ func Profile(ctx *context.Context) {
return
}
+ if ctxUser.IsOrganization() {
+ org.Home(ctx)
+ return
+ }
+
+ // check view permissions
+ if !ctxUser.IsVisibleToUser(ctx.User) {
+ ctx.NotFound("user", fmt.Errorf(uname))
+ return
+ }
+
// Show SSH keys.
if isShowKeys {
ShowSSHKeys(ctx, ctxUser.ID)
@@ -87,11 +98,6 @@ func Profile(ctx *context.Context) {
return
}
- if ctxUser.IsOrganization() {
- org.Home(ctx)
- return
- }
-
// Show OpenID URIs
openIDs, err := models.GetUserOpenIDs(ctxUser.ID)
if err != nil {
diff --git a/routers/web/user/setting/profile.go b/routers/web/user/setting/profile.go
index 20042caca4..463c4ec203 100644
--- a/routers/web/user/setting/profile.go
+++ b/routers/web/user/setting/profile.go
@@ -114,6 +114,7 @@ func ProfilePost(ctx *context.Context) {
}
ctx.User.Description = form.Description
ctx.User.KeepActivityPrivate = form.KeepActivityPrivate
+ ctx.User.Visibility = form.Visibility
if err := models.UpdateUserSetting(ctx.User); err != nil {
if _, ok := err.(models.ErrEmailAlreadyUsed); ok {
ctx.Flash.Error(ctx.Tr("form.email_been_used"))