Fix bug preventing transfer to private organization (#12497)
* Fix bug preventing transfer to private organization The code assessing whether a private organization was visible to a user before allowing transfer was incorrect due to testing membership the wrong way round This PR fixes this issue and renames the function performing the test to be clearer. Further looking at the API for transfer repository - no testing was performed to ensure that the acting user could actually see the new owning organization. Signed-off-by: Andrew Thornton <art27@cantab.net> * change IsUserPartOfOrg everywhererelease/v1.15
parent
f50364a5b0
commit
d1e67d7ade
|
@ -148,7 +148,7 @@ func addBranchProtectionCanPushAndEnableWhitelist(x *xorm.Engine) error {
|
||||||
if user == nil {
|
if user == nil {
|
||||||
hasOrgVisible = repoOwner.Visibility == VisibleTypePublic
|
hasOrgVisible = repoOwner.Visibility == VisibleTypePublic
|
||||||
} else if !user.IsAdmin {
|
} else if !user.IsAdmin {
|
||||||
isUserPartOfOrg, err := sess.
|
hasMemberWithUserID, err := sess.
|
||||||
Where("uid=?", user.ID).
|
Where("uid=?", user.ID).
|
||||||
And("org_id=?", repoOwner.ID).
|
And("org_id=?", repoOwner.ID).
|
||||||
Table("org_user").
|
Table("org_user").
|
||||||
|
@ -156,7 +156,7 @@ func addBranchProtectionCanPushAndEnableWhitelist(x *xorm.Engine) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
hasOrgVisible = false
|
hasOrgVisible = false
|
||||||
}
|
}
|
||||||
if (repoOwner.Visibility == VisibleTypePrivate || user.IsRestricted) && !isUserPartOfOrg {
|
if (repoOwner.Visibility == VisibleTypePrivate || user.IsRestricted) && !hasMemberWithUserID {
|
||||||
hasOrgVisible = false
|
hasOrgVisible = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -435,7 +435,7 @@ func hasOrgVisible(e Engine, org *User, user *User) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (org.Visibility == structs.VisibleTypePrivate || user.IsRestricted) && !org.isUserPartOfOrg(e, user.ID) {
|
if (org.Visibility == structs.VisibleTypePrivate || user.IsRestricted) && !org.hasMemberWithUserID(e, user.ID) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -610,12 +610,12 @@ func (u *User) IsUserOrgOwner(orgID int64) bool {
|
||||||
return isOwner
|
return isOwner
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsUserPartOfOrg returns true if user with userID is part of the u organisation.
|
// HasMemberWithUserID returns true if user with userID is part of the u organisation.
|
||||||
func (u *User) IsUserPartOfOrg(userID int64) bool {
|
func (u *User) HasMemberWithUserID(userID int64) bool {
|
||||||
return u.isUserPartOfOrg(x, userID)
|
return u.hasMemberWithUserID(x, userID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (u *User) isUserPartOfOrg(e Engine, userID int64) bool {
|
func (u *User) hasMemberWithUserID(e Engine, userID int64) bool {
|
||||||
isMember, err := isOrganizationMember(e, u.ID, userID)
|
isMember, err := isOrganizationMember(e, u.ID, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("IsOrganizationMember: %v", err)
|
log.Error("IsOrganizationMember: %v", err)
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"code.gitea.io/gitea/modules/context"
|
"code.gitea.io/gitea/modules/context"
|
||||||
"code.gitea.io/gitea/modules/convert"
|
"code.gitea.io/gitea/modules/convert"
|
||||||
"code.gitea.io/gitea/modules/log"
|
"code.gitea.io/gitea/modules/log"
|
||||||
|
"code.gitea.io/gitea/modules/structs"
|
||||||
api "code.gitea.io/gitea/modules/structs"
|
api "code.gitea.io/gitea/modules/structs"
|
||||||
repo_service "code.gitea.io/gitea/services/repository"
|
repo_service "code.gitea.io/gitea/services/repository"
|
||||||
)
|
)
|
||||||
|
@ -53,13 +54,21 @@ func Transfer(ctx *context.APIContext, opts api.TransferRepoOption) {
|
||||||
newOwner, err := models.GetUserByName(opts.NewOwner)
|
newOwner, err := models.GetUserByName(opts.NewOwner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if models.IsErrUserNotExist(err) {
|
if models.IsErrUserNotExist(err) {
|
||||||
ctx.Error(http.StatusNotFound, "GetUserByName", err)
|
ctx.Error(http.StatusNotFound, "", "The new owner does not exist or cannot be found")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.InternalServerError(err)
|
ctx.InternalServerError(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if newOwner.Type == models.UserTypeOrganization {
|
||||||
|
if !ctx.User.IsAdmin && newOwner.Visibility == structs.VisibleTypePrivate && !newOwner.HasMemberWithUserID(ctx.User.ID) {
|
||||||
|
// The user shouldn't know about this organization
|
||||||
|
ctx.Error(http.StatusNotFound, "", "The new owner does not exist or cannot be found")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var teams []*models.Team
|
var teams []*models.Team
|
||||||
if opts.TeamIDs != nil {
|
if opts.TeamIDs != nil {
|
||||||
if !newOwner.IsOrganization() {
|
if !newOwner.IsOrganization() {
|
||||||
|
|
|
@ -418,7 +418,7 @@ func SettingsPost(ctx *context.Context, form auth.RepoSettingForm) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if newOwner.Type == models.UserTypeOrganization {
|
if newOwner.Type == models.UserTypeOrganization {
|
||||||
if !ctx.User.IsAdmin && newOwner.Visibility == structs.VisibleTypePrivate && !ctx.User.IsUserPartOfOrg(newOwner.ID) {
|
if !ctx.User.IsAdmin && newOwner.Visibility == structs.VisibleTypePrivate && !newOwner.HasMemberWithUserID(ctx.User.ID) {
|
||||||
// The user shouldn't know about this organization
|
// The user shouldn't know about this organization
|
||||||
ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_owner_name"), tplSettingsOptions, nil)
|
ctx.RenderWithErr(ctx.Tr("form.enterred_invalid_owner_name"), tplSettingsOptions, nil)
|
||||||
return
|
return
|
||||||
|
|
|
@ -52,7 +52,7 @@
|
||||||
<li>
|
<li>
|
||||||
<ul class="user-orgs">
|
<ul class="user-orgs">
|
||||||
{{range .Orgs}}
|
{{range .Orgs}}
|
||||||
{{if (or .Visibility.IsPublic (and ($.SignedUser) (or .Visibility.IsLimited (and (.IsUserPartOfOrg $.SignedUserID) .Visibility.IsPrivate) ($.IsAdmin))))}}
|
{{if (or .Visibility.IsPublic (and ($.SignedUser) (or .Visibility.IsLimited (and (.HasMemberWithUserID $.SignedUserID) .Visibility.IsPrivate) ($.IsAdmin))))}}
|
||||||
<li>
|
<li>
|
||||||
<a href="{{.HomeLink}}"><img class="ui image poping up" src="{{.RelAvatarLink}}" data-content="{{.Name}}" data-position="top center" data-variation="tiny inverted"></a>
|
<a href="{{.HomeLink}}"><img class="ui image poping up" src="{{.RelAvatarLink}}" data-content="{{.Name}}" data-position="top center" data-variation="tiny inverted"></a>
|
||||||
</li>
|
</li>
|
||||||
|
|
Loading…
Reference in New Issue