Skip to content
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

Fix invalid issues in project boards #22865

Draft
wants to merge 95 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 13 commits
Commits
Show all changes
95 commits
Select commit Hold shift + click to select a range
16836c2
fix edit/close/delete projects in org
yp05327 Feb 11, 2023
91cbfce
fix
yp05327 Feb 11, 2023
3f76a8f
fix lint
zeripath Feb 11, 2023
192a6d4
improve edit/close/delete permission
yp05327 Feb 12, 2023
26564fb
fix write projects permission of users in teams
yp05327 Feb 12, 2023
a266778
fix no access team permission of projects/packages
yp05327 Feb 12, 2023
99a3351
fix code tab permission in org team unit
yp05327 Feb 12, 2023
810de4e
fix
yp05327 Feb 12, 2023
39f8366
remove noused canAccessProjects
yp05327 Feb 12, 2023
33c57bc
test add issue
yp05327 Feb 14, 2023
5242c79
test add porject.TypeUser
yp05327 Feb 14, 2023
f92c5e0
remove TypeUser
yp05327 Feb 15, 2023
feb43e0
fix TODO: repoID is 0 in user/org projects
yp05327 Feb 15, 2023
3e6ae97
remove break in addUpdateIssueProject
yp05327 Feb 15, 2023
49a9595
fix
yp05327 Feb 15, 2023
a608963
Merge branch 'main' into fix-edit-close-delete-projects-of-org
yp05327 Feb 16, 2023
a3396b9
fix redundant break statement
yp05327 Feb 16, 2023
005568f
change ProjectList to project.List
yp05327 Feb 16, 2023
adb83e6
imporve variable name
yp05327 Feb 16, 2023
6ebb80d
revert the change of issue-action project data-url
yp05327 Feb 16, 2023
87d98fc
add TODO
yp05327 Feb 16, 2023
ebb6e83
fix retrieve projects in an issue
yp05327 Feb 17, 2023
762cfa6
fix 'new project' button in repo projects page
yp05327 Feb 17, 2023
2579105
Merge branch 'go-gitea:main' into fix-edit-close-delete-projects-of-org
yp05327 Feb 17, 2023
ec104a2
improve project type
yp05327 Feb 17, 2023
c0677c3
fix wrong project link
yp05327 Feb 17, 2023
f9c3351
fix permission check in projectboard
yp05327 Feb 18, 2023
6e668ef
remove used code
yp05327 Feb 18, 2023
a4a75a3
fix var-naming
yp05327 Feb 18, 2023
6235923
fix misspelling
yp05327 Feb 18, 2023
a75dedb
add db migration
yp05327 Feb 18, 2023
0d2869d
fix permission check in issue.CanRetrievedByDoer
yp05327 Feb 18, 2023
2d11075
Merge branch 'go-gitea:main' into fix-edit-close-delete-projects-of-org
yp05327 Feb 18, 2023
e022704
rename GetOwner to LoadOwner
yp05327 Feb 18, 2023
5850d85
rename GetOwner to LoadOwner
yp05327 Feb 18, 2023
2b398fd
fix incorrect issue num
yp05327 Feb 19, 2023
87668f7
fix incorrect permission check in repo project
yp05327 Feb 19, 2023
4c1c419
fix incorrect open/closed issuenum in project list
yp05327 Feb 19, 2023
72d059d
binding a issue to a project needs Write perm
yp05327 Feb 19, 2023
7be7b02
fix incorrect open/close issue num in project list
yp05327 Feb 19, 2023
43336a2
Merge branch 'main' into fix-edit-close-delete-projects-of-org
yp05327 Mar 7, 2023
0a22729
remove projects.Name
yp05327 Mar 7, 2023
951c4f1
Merge branch 'main' into fix-edit-close-delete-projects-of-org
yp05327 Mar 9, 2023
05f6415
remove migration
yp05327 Mar 9, 2023
e0475b7
revert project type
yp05327 Mar 9, 2023
eac2724
Merge branch 'main' into fix-edit-close-delete-projects-of-org
yp05327 Mar 10, 2023
d1d5f30
move canWriteProjects
yp05327 Mar 10, 2023
17b2eb2
update new design
yp05327 Mar 10, 2023
8868100
Merge branch 'main' into fix-edit-close-delete-projects-of-org
yp05327 Mar 10, 2023
a824862
Merge branch 'main' into fix-edit-close-delete-projects-of-org
yp05327 Mar 13, 2023
aaf9ef8
remove
yp05327 Mar 13, 2023
5adbb7d
remove unnecessary code
yp05327 Mar 13, 2023
894f960
add permission check for collaborations
yp05327 Mar 13, 2023
cd10524
improve performance
yp05327 Mar 13, 2023
3fba5cc
fix incorrect issue num in project list page
yp05327 Mar 13, 2023
f16fc72
update
yp05327 Mar 13, 2023
f0cd211
add err check
yp05327 Mar 13, 2023
396f11e
fix conflicts
yp05327 Mar 15, 2023
cf84ed7
Merge branch 'main' into fix-edit-close-delete-projects-of-org
yp05327 Mar 15, 2023
cad44d9
update
yp05327 Mar 17, 2023
b9227fa
Merge branch 'main' into fix-edit-close-delete-projects-of-org
yp05327 Mar 17, 2023
77a2c67
add nolint
yp05327 Mar 17, 2023
c92cb2e
improve search logic and performance
yp05327 Mar 17, 2023
42af698
Merge branch 'main' into fix-edit-close-delete-projects-of-org
yp05327 Mar 17, 2023
5e42b0e
Merge branch 'main' into fix-edit-close-delete-projects-of-org
yp05327 Apr 14, 2023
1a6da57
fix
yp05327 Apr 14, 2023
265e7d3
Merge branch 'main' into fix-edit-close-delete-projects-of-org
yp05327 Apr 20, 2023
32dd6a0
Merge branch 'main' into fix-edit-close-delete-projects-of-org
yp05327 Apr 24, 2023
5dc2aa0
fix typo
yp05327 Apr 26, 2023
d761487
rename
yp05327 Apr 26, 2023
62efaae
Merge branch 'main' into fix-edit-close-delete-projects-of-org
yp05327 May 1, 2023
0d6757d
remove archived repo check
yp05327 May 15, 2023
b78d62e
Merge branch 'main' into fix-edit-close-delete-projects-of-org
yp05327 May 17, 2023
a5cf0a4
Merge branch 'main' into fix-edit-close-delete-projects-of-org
yp05327 May 18, 2023
8f3d51d
move UnitGlobalDisabled
yp05327 May 18, 2023
752ae93
Merge branch 'main' into fix-edit-close-delete-projects-of-org
yp05327 May 25, 2023
77ac2bc
fix
yp05327 May 25, 2023
4a70ec2
Merge branch 'main' into fix-edit-close-delete-projects-of-org
yp05327 Jun 5, 2023
c90b29e
Merge branch 'main' into fix-edit-close-delete-projects-of-org
GiteaBot Jun 5, 2023
598cddf
Merge branch 'main' into fix-edit-close-delete-projects-of-org
GiteaBot Jun 6, 2023
14122ea
Merge branch 'main' into fix-edit-close-delete-projects-of-org
GiteaBot Jun 6, 2023
cdb454a
only check repo unit permission
yp05327 Jun 6, 2023
79a6d4e
improve FilterWritableByDoer
yp05327 Jun 7, 2023
821fce2
improve UnitGlobalDisabled check
yp05327 Jun 7, 2023
e22dcfa
fix
yp05327 Jun 7, 2023
f924720
Merge branch 'main' into fix-edit-close-delete-projects-of-org
yp05327 Jul 10, 2023
cedeb38
fix
yp05327 Jul 10, 2023
4313a8c
Merge branch 'main' into fix-edit-close-delete-projects-of-org
yp05327 Jul 25, 2023
e0c91cb
Merge branch 'main' into fix-edit-close-delete-projects-of-org
yp05327 Aug 3, 2023
d2fad57
Merge branch 'main' into fix-edit-close-delete-projects-of-org
yp05327 Mar 6, 2024
0621ed5
fix
yp05327 Mar 6, 2024
a48cdba
fix lint
yp05327 Mar 6, 2024
b229467
remove issueList.FilterValidByDoer
yp05327 Mar 6, 2024
004f4d2
improve(bug public individual project cannot display the issues in pu…
yp05327 Mar 7, 2024
80922b1
fix issue search bug
yp05327 Mar 7, 2024
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
22 changes: 20 additions & 2 deletions models/issues/issue_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,26 @@ func addUpdateIssueProject(ctx context.Context, issue *Issue, doer *user_model.U
if err != nil {
return err
}
if newProject.RepoID != issue.RepoID && newProject.OwnerID != issue.Repo.OwnerID {
return fmt.Errorf("issue's repository is not the same as project's repository")

switch newProject.Type {
case project_model.TypeRepository:
if newProject.RepoID != issue.RepoID && newProject.OwnerID != issue.Repo.OwnerID {
return fmt.Errorf("issue's repository is not the same as project's repository")
}
break
yp05327 marked this conversation as resolved.
Show resolved Hide resolved
case project_model.TypeOrganization:
// TODO: org team permission check
if newProject.OwnerID != issue.Repo.OwnerID {
return fmt.Errorf("issue's repository's owner is not the same as project's repository's owner")
}
break
case project_model.TypeIndividual:
if newProject.OwnerID != doer.ID {
return fmt.Errorf("user does not have the project [id: %d]", newProjectID)
}
break
default:
return fmt.Errorf("unknown project type: %d", newProject.Type)
}
}

Expand Down
94 changes: 87 additions & 7 deletions models/project/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@ type (

// Type is used to identify the type of project in question and ownership
Type uint8

// ProjectList is used to identify a list of projects
ProjectList []*Project
)

const (
Expand Down Expand Up @@ -85,6 +88,25 @@ func (err ErrProjectBoardNotExist) Unwrap() error {
return util.ErrNotExist
}

// ErrUserType represents a "ErrUserType" kind of error.
type ErrUserType struct {
UserType user_model.UserType
}

// IsErrUserType checks if an error is a ErrUserType
func IsErrUserType(err error) bool {
_, ok := err.(ErrUserType)
return ok
}

func (err ErrUserType) Error() string {
return fmt.Sprintf("projects does not support user type: %d", err.UserType)
}

func (err ErrUserType) Unwrap() error {
return util.ErrNotExist
}

// Project represents a project board
type Project struct {
ID int64 `xorm:"pk autoincr"`
Expand Down Expand Up @@ -115,6 +137,18 @@ func (p *Project) LoadOwner(ctx context.Context) (err error) {
return err
}

func (pl ProjectList) LoadOwners(ctx context.Context) (err error) {
for _, p := range pl {
if p.Owner != nil {
continue
}
if p.Owner, err = user_model.GetUserByID(ctx, p.OwnerID); err != nil {
return err
}
}
return nil
}

func (p *Project) LoadRepo(ctx context.Context) (err error) {
if p.RepoID == 0 || p.Repo != nil {
return nil
Expand All @@ -123,19 +157,29 @@ func (p *Project) LoadRepo(ctx context.Context) (err error) {
return err
}

func (pl ProjectList) LoadRepos(ctx context.Context) (err error) {
for _, p := range pl {
if p.RepoID == 0 || p.Repo != nil {
continue
}
if p.Repo, err = repo_model.GetRepositoryByID(ctx, p.RepoID); err != nil {
return err
}
}
return nil
}

// Link returns the project's relative URL.
func (p *Project) Link() string {
if p.OwnerID > 0 {
err := p.LoadOwner(db.DefaultContext)
if err != nil {
if err := p.LoadOwner(db.DefaultContext); err != nil {
log.Error("LoadOwner: %v", err)
return ""
}
return fmt.Sprintf("%s/-/projects/%d", p.Owner.HomeLink(), p.ID)
}
if p.RepoID > 0 {
err := p.LoadRepo(db.DefaultContext)
if err != nil {
if err := p.LoadRepo(db.DefaultContext); err != nil {
log.Error("LoadRepo: %v", err)
return ""
}
Expand All @@ -144,10 +188,46 @@ func (p *Project) Link() string {
return ""
}

// Name return the project's name which is combined with owner/repo/project's name
func (p *Project) Name() string {
if p.OwnerID > 0 {
if err := p.LoadOwner(db.DefaultContext); err != nil {
log.Error("LoadOwner: %v", err)
return ""
}
return fmt.Sprintf("%s/-/%s", p.Owner.Name, p.Title)
}
if p.RepoID > 0 {
if err := p.LoadRepo(db.DefaultContext); err != nil {
log.Error("LoadRepo: %v", err)
return ""
}

return fmt.Sprintf("%s/%s/%s", p.Repo.OwnerName, p.Repo.Name, p.Title)
}
return ""
}

func (p *Project) IsOrganizationProject() bool {
return p.Type == TypeOrganization
}

func (p *Project) IsIndividualProject() bool {
return p.Type == TypeIndividual
}

// GetProjectTypeByUser retrieves the type of a project by user's type
func GetProjectTypeByUser(user *user_model.User) (Type, error) {
switch user.Type {
case user_model.UserTypeIndividual:
return TypeIndividual, nil
case user_model.UserTypeOrganization:
return TypeOrganization, nil
default:
return 0, ErrUserType{UserType: user.Type}
}
}

func init() {
db.RegisterModel(new(Project))
}
Expand All @@ -172,7 +252,7 @@ func GetCardConfig() []CardConfig {
// IsTypeValid checks if a project type is valid
func IsTypeValid(p Type) bool {
switch p {
case TypeRepository, TypeOrganization:
case TypeIndividual, TypeRepository, TypeOrganization:
return true
default:
return false
Expand Down Expand Up @@ -216,9 +296,9 @@ func CountProjects(ctx context.Context, opts SearchOptions) (int64, error) {
}

// FindProjects returns a list of all projects that have been created in the repository
func FindProjects(ctx context.Context, opts SearchOptions) ([]*Project, int64, error) {
func FindProjects(ctx context.Context, opts SearchOptions) (ProjectList, int64, error) {
e := db.GetEngine(ctx)
projects := make([]*Project, 0, setting.UI.IssuePagingNum)
projects := make(ProjectList, 0, setting.UI.IssuePagingNum)
cond := opts.toConds()

count, err := e.Where(cond).Count(new(Project))
Expand Down
5 changes: 5 additions & 0 deletions models/user/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,11 @@ func (u *User) IsOrganization() bool {
return u.Type == UserTypeOrganization
}

// IsIndividual returns true if user is actually a individual user.
func (u *User) IsIndividual() bool {
return u.Type == UserTypeIndividual
}

// DisplayName returns full name if it's not empty,
// returns username otherwise.
func (u *User) DisplayName() string {
Expand Down
64 changes: 48 additions & 16 deletions modules/context/org.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,26 @@ func (org *Organization) CanWriteUnit(ctx *Context, unitType unit.Type) bool {
return org.UnitPermission(ctx, ctx.Doer.ID, unitType) >= perm.AccessModeWrite
}

func (org *Organization) CanAccessUnit(ctx *Context, unitType unit.Type) bool {
if ctx.Doer == nil {
return false
}
return org.UnitPermission(ctx, ctx.Doer.ID, unitType) >= perm.AccessModeRead
}

func (org *Organization) UnitPermission(ctx *Context, doerID int64, unitType unit.Type) perm.AccessMode {
if doerID > 0 {
teams, err := organization.GetUserOrgTeams(ctx, org.Organization.ID, doerID)
if err != nil {
log.Error("GetUserOrgTeams: %v", err)
return perm.AccessModeNone
}

if err := teams.LoadUnits(ctx); err != nil {
log.Error("LoadUnits: %v", err)
return perm.AccessModeNone
}

if len(teams) > 0 {
return teams.UnitMaxAccess(unitType)
}
Expand All @@ -56,6 +69,29 @@ func (org *Organization) UnitPermission(ctx *Context, doerID int64, unitType uni
return perm.AccessModeNone
}

func GetOrganizationByParams(ctx *Context) {
orgName := ctx.Params(":org")

var err error

ctx.Org.Organization, err = organization.GetOrgByName(ctx, orgName)
if err != nil {
if organization.IsErrOrgNotExist(err) {
redirectUserID, err := user_model.LookupUserRedirect(orgName)
if err == nil {
RedirectToUser(ctx, orgName, redirectUserID)
} else if user_model.IsErrUserRedirectNotExist(err) {
ctx.NotFound("GetUserByName", err)
} else {
ctx.ServerError("LookupUserRedirect", err)
}
} else {
ctx.ServerError("GetUserByName", err)
}
return
}
}

// HandleOrgAssignment handles organization assignment
func HandleOrgAssignment(ctx *Context, args ...bool) {
var (
Expand All @@ -77,25 +113,17 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
requireTeamAdmin = args[3]
}

orgName := ctx.Params(":org")

var err error
ctx.Org.Organization, err = organization.GetOrgByName(ctx, orgName)
if err != nil {
if organization.IsErrOrgNotExist(err) {
redirectUserID, err := user_model.LookupUserRedirect(orgName)
if err == nil {
RedirectToUser(ctx, orgName, redirectUserID)
} else if user_model.IsErrUserRedirectNotExist(err) {
ctx.NotFound("GetUserByName", err)
} else {
ctx.ServerError("LookupUserRedirect", err)
}
} else {
ctx.ServerError("GetUserByName", err)

// if Organization is not defined, get it from params
if ctx.Org.Organization == nil {
GetOrganizationByParams(ctx)

if ctx.Written() {
return
}
return
}

org := ctx.Org.Organization

// Handle Visibility
Expand Down Expand Up @@ -231,6 +259,10 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
return
}
}

ctx.Data["CanAccessProjects"] = ctx.Org.CanAccessUnit(ctx, unit.TypeProjects)
ctx.Data["CanAccessPackages"] = ctx.Org.CanAccessUnit(ctx, unit.TypePackages)
ctx.Data["CanAccessCode"] = ctx.Org.CanAccessUnit(ctx, unit.TypeCode)
}

// OrgAssignment returns a middleware to handle organization assignment
Expand Down
Loading