Skip to content

Fix org admin can not access org project unit #25691

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from 20 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions models/migrations/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -554,6 +554,8 @@ var migrations = []Migration{
NewMigration("Add combined Index to issue_user.uid and issue_id", v1_22.AddCombinedIndexToIssueUser),
// v284 -> v285
NewMigration("Add ignore stale approval column on branch table", v1_22.AddIgnoreStaleApprovalsColumnToProtectedBranchTable),
// v285 -> v286
NewMigration("Fix missing admin team unit records", v1_22.FixMissingAdminTeamUnitRecords),
}

// GetCurrentDBVersion returns the current db version
Expand Down
114 changes: 114 additions & 0 deletions models/migrations/v1_22/v285.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package v1_22 //nolint

import (
"code.gitea.io/gitea/modules/container"

"xorm.io/xorm"
)

func FixMissingAdminTeamUnitRecords(x *xorm.Engine) error {
type UnitType int
type AccessMode int

type Team struct {
ID int64 `xorm:"pk autoincr"`
OrgID int64 `xorm:"INDEX"`
AccessMode AccessMode `xorm:"'authorize'"`
}

type TeamUnit struct {
ID int64 `xorm:"pk autoincr"`
OrgID int64 `xorm:"INDEX"`
TeamID int64 `xorm:"UNIQUE(s)"`
Type UnitType `xorm:"UNIQUE(s)"`
AccessMode AccessMode
}

const (
// AccessModeRead read access
AccessModeRead = 1
// AccessModeAdmin admin access
AccessModeAdmin = 3

// Unit Type
TypeInvalid UnitType = iota // 0 invalid
TypeCode // 1 code
TypeIssues // 2 issues
TypePullRequests // 3 PRs
TypeReleases // 4 Releases
TypeWiki // 5 Wiki
TypeExternalWiki // 6 ExternalWiki
TypeExternalTracker // 7 ExternalTracker
TypeProjects // 8 Kanban board
TypePackages // 9 Packages
TypeActions // 10 Actions
)

AllRepoUnitTypes := []UnitType{
TypeCode,
TypeIssues,
TypePullRequests,
TypeReleases,
TypeWiki,
TypeExternalWiki,
TypeExternalTracker,
TypeProjects,
TypePackages,
TypeActions,
}

sess := x.NewSession()
defer sess.Close()

if err := sess.Begin(); err != nil {
return err
}

// find all admin teams
teams := make([]*Team, 0)
err := sess.Where("team.authorize = ?", AccessModeAdmin).Find(&teams)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It may consume much memory for a big instance.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

if err != nil {
return err
}

for _, team := range teams {
// find all existing records
teamunits := make([]*TeamUnit, 0, len(AllRepoUnitTypes))
err := sess.Where("`team_unit`.team_id = ?", team.ID).Find(&teamunits)
if err != nil {
return err
}
existingUnitTypes := make(container.Set[UnitType], 0)
for _, tu := range teamunits {
if tu.Type > 0 {
existingUnitTypes.Add(tu.Type)
}
}

// insert or update records
for _, u := range AllRepoUnitTypes {
newTeamUnit := &TeamUnit{
OrgID: team.OrgID,
TeamID: team.ID,
Type: u,
}
// external unit should be read
if u == TypeExternalWiki || u == TypeExternalTracker {
newTeamUnit.AccessMode = AccessModeRead
} else {
newTeamUnit.AccessMode = AccessModeAdmin
}

if existingUnitTypes.Contains(u) {
sess.Cols("access_mode").Update(newTeamUnit)
} else {
sess.Insert(newTeamUnit)
}
}
}

return sess.Commit()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to detect whether there are still records haven't been committed. Some database will fail if submit a zero change commit.

}
4 changes: 2 additions & 2 deletions models/organization/team_list.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ func (t TeamList) LoadUnits(ctx context.Context) error {
func (t TeamList) UnitMaxAccess(tp unit.Type) perm.AccessMode {
maxAccess := perm.AccessModeNone
for _, team := range t {
if team.IsOwnerTeam() {
return perm.AccessModeOwner
if team.AccessMode >= perm.AccessModeAdmin {
return team.AccessMode
}
for _, teamUnit := range team.Units {
if teamUnit.Type != tp {
Expand Down