From f9f1eabb9b10ca02eae972e74e97306a8acdaa7b Mon Sep 17 00:00:00 2001
From: yp05327 <576951401@qq.com>
Date: Wed, 1 Feb 2023 14:23:15 +0900
Subject: [PATCH 01/10] fix org projects page incorrect tab

---
 modules/context/org.go      | 44 +++++++++++++++++++++++--------------
 routers/web/org/projects.go |  1 +
 services/context/user.go    |  3 ++-
 3 files changed, 30 insertions(+), 18 deletions(-)

diff --git a/modules/context/org.go b/modules/context/org.go
index ff3a5ae7ec3f2..65a9c64df71aa 100644
--- a/modules/context/org.go
+++ b/modules/context/org.go
@@ -56,6 +56,28 @@ 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(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 (
@@ -77,25 +99,13 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
 		requireTeamAdmin = args[3]
 	}
 
-	orgName := ctx.Params(":org")
-
 	var err error
-	ctx.Org.Organization, err = organization.GetOrgByName(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
+
+	// if Organization is not defined, get it from params
+	if ctx.Org.Organization == nil {
+		GetOrganizationByParams(ctx)
 	}
+
 	org := ctx.Org.Organization
 
 	// Handle Visibility
diff --git a/routers/web/org/projects.go b/routers/web/org/projects.go
index 1ce44d4866d8e..7887b4f47506e 100644
--- a/routers/web/org/projects.go
+++ b/routers/web/org/projects.go
@@ -123,6 +123,7 @@ func NewProject(ctx *context.Context) {
 	ctx.Data["Title"] = ctx.Tr("repo.projects.new")
 	ctx.Data["ProjectTypes"] = project_model.GetProjectsConfig()
 	ctx.Data["CanWriteProjects"] = canWriteUnit(ctx)
+	ctx.Data["PageIsViewProjects"] = true
 	ctx.Data["HomeLink"] = ctx.ContextUser.HomeLink()
 	shared_user.RenderUserHeader(ctx)
 	ctx.HTML(http.StatusOK, tplProjectsNew)
diff --git a/services/context/user.go b/services/context/user.go
index 7642cba4e1f03..29a02a4aa563e 100644
--- a/services/context/user.go
+++ b/services/context/user.go
@@ -63,7 +63,8 @@ func userAssignment(ctx *context.Context, errCb func(int, string, interface{}))
 					ctx.Org = &context.Organization{}
 				}
 				ctx.Org.Organization = (*org_model.Organization)(ctx.ContextUser)
-				ctx.Data["Org"] = ctx.Org.Organization
+
+				context.HandleOrgAssignment(ctx)
 			}
 		}
 	}

From 89324e6511441e34cf94cbd9a7c4b70f65060afb Mon Sep 17 00:00:00 2001
From: yp05327 <576951401@qq.com>
Date: Wed, 1 Feb 2023 15:29:06 +0900
Subject: [PATCH 02/10] enable GetOrganizationByParams error handling

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
---
 modules/context/org.go | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/modules/context/org.go b/modules/context/org.go
index 65a9c64df71aa..c2a7f1087bf69 100644
--- a/modules/context/org.go
+++ b/modules/context/org.go
@@ -104,6 +104,9 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
 	// if Organization is not defined, get it from params
 	if ctx.Org.Organization == nil {
 		GetOrganizationByParams(ctx)
+		if ctx.Written() {
+		    return
+		}
 	}
 
 	org := ctx.Org.Organization

From 000c193a2c47bec27860f92cf5ce9b003f8d9f29 Mon Sep 17 00:00:00 2001
From: yp05327 <576951401@qq.com>
Date: Wed, 1 Feb 2023 15:55:05 +0900
Subject: [PATCH 03/10] fix fmt

---
 modules/context/org.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/modules/context/org.go b/modules/context/org.go
index c2a7f1087bf69..a1d732f19173e 100644
--- a/modules/context/org.go
+++ b/modules/context/org.go
@@ -105,7 +105,7 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
 	if ctx.Org.Organization == nil {
 		GetOrganizationByParams(ctx)
 		if ctx.Written() {
-		    return
+			return
 		}
 	}
 

From ae2024483c2ff028864ae2c711ed7fd818b4b045 Mon Sep 17 00:00:00 2001
From: yp05327 <576951401@qq.com>
Date: Wed, 8 Feb 2023 17:37:30 +0900
Subject: [PATCH 04/10] fix wrong package enable check variable

---
 templates/user/overview/header.tmpl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/templates/user/overview/header.tmpl b/templates/user/overview/header.tmpl
index 18fbd3070b987..0a1a835934bcc 100644
--- a/templates/user/overview/header.tmpl
+++ b/templates/user/overview/header.tmpl
@@ -25,7 +25,7 @@
 			<a href="{{.ContextUser.HomeLink}}/-/projects" class="{{if .PageIsViewProjects}}active {{end}}item">
 				{{svg "octicon-project"}} {{.locale.Tr "user.projects"}}
 			</a>
-			{{if (not .UnitPackagesGlobalDisabled)}}
+			{{if .IsPackageEnabled}}
 				<a href="{{.ContextUser.HomeLink}}/-/packages" class="{{if .IsPackagesPage}}active {{end}}item">
 					{{svg "octicon-package"}} {{.locale.Tr "packages.title"}}
 				</a>

From 9e3ed4c7d2ef3885a67c0c82734e7d09085f26b2 Mon Sep 17 00:00:00 2001
From: yp05327 <576951401@qq.com>
Date: Thu, 9 Feb 2023 10:42:21 +0900
Subject: [PATCH 05/10] remove unnecessary PageIsOrgCode

---
 templates/org/menu.tmpl | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/templates/org/menu.tmpl b/templates/org/menu.tmpl
index 5f543424fce32..fac052e23381b 100644
--- a/templates/org/menu.tmpl
+++ b/templates/org/menu.tmpl
@@ -12,7 +12,7 @@
 		</a>
 		{{end}}
 		{{if .IsRepoIndexerEnabled}}
-		<a class="{{if $.PageIsOrgCode}}active {{end}}item" href="{{$.Org.HomeLink}}/-/code">
+		<a class="item" href="{{$.Org.HomeLink}}/-/code">
 			{{svg "octicon-code"}}&nbsp;{{$.locale.Tr "org.code"}}
 		</a>
 		{{end}}

From 667f68ebc87b23d5b46c4c41666153f285bf5b49 Mon Sep 17 00:00:00 2001
From: yp05327 <576951401@qq.com>
Date: Tue, 21 Feb 2023 15:44:49 +0900
Subject: [PATCH 06/10] add org team permission check

---
 models/organization/org.go          | 26 +++++++++++++++++++++++
 models/user/user.go                 |  5 +++++
 modules/context/org.go              | 30 ++++++++-------------------
 routers/web/org/home.go             |  3 ++-
 routers/web/shared/user/header.go   |  2 ++
 routers/web/user/code.go            |  1 +
 routers/web/user/profile.go         |  1 +
 routers/web/web.go                  | 32 ++++++++++++++++++++++++++---
 templates/org/menu.tmpl             |  6 ++++--
 templates/user/overview/header.tmpl |  6 ++++--
 10 files changed, 82 insertions(+), 30 deletions(-)

diff --git a/models/organization/org.go b/models/organization/org.go
index f05027be729d4..269b3e83288dc 100644
--- a/models/organization/org.go
+++ b/models/organization/org.go
@@ -239,6 +239,32 @@ func (org *Organization) CustomAvatarRelativePath() string {
 	return org.Avatar
 }
 
+// UnitPermission returns unit permission
+func (org *Organization) UnitPermission(ctx context.Context, doer *user_model.User, unitType unit.Type) perm.AccessMode {
+	if doer != nil {
+		teams, err := GetUserOrgTeams(ctx, org.ID, doer.ID)
+		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)
+		}
+	}
+
+	if org.Visibility.IsPublic() {
+		return perm.AccessModeRead
+	}
+
+	return perm.AccessModeNone
+}
+
 // CreateOrganization creates record of a new organization.
 func CreateOrganization(org *Organization, owner *user_model.User) (err error) {
 	if !owner.CanCreateOrganization() {
diff --git a/models/user/user.go b/models/user/user.go
index f6fafe64f3915..454779b9ea361 100644
--- a/models/user/user.go
+++ b/models/user/user.go
@@ -393,6 +393,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 {
diff --git a/modules/context/org.go b/modules/context/org.go
index 50c9f6f757760..61491eedf2334 100644
--- a/modules/context/org.go
+++ b/modules/context/org.go
@@ -11,7 +11,6 @@ import (
 	"code.gitea.io/gitea/models/perm"
 	"code.gitea.io/gitea/models/unit"
 	user_model "code.gitea.io/gitea/models/user"
-	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
 	"code.gitea.io/gitea/modules/structs"
 )
@@ -31,29 +30,11 @@ type Organization struct {
 }
 
 func (org *Organization) CanWriteUnit(ctx *Context, unitType unit.Type) bool {
-	if ctx.Doer == nil {
-		return false
-	}
-	return org.UnitPermission(ctx, ctx.Doer.ID, unitType) >= perm.AccessModeWrite
+	return org.Organization.UnitPermission(ctx, ctx.Doer, unitType) >= perm.AccessModeWrite
 }
 
-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 len(teams) > 0 {
-			return teams.UnitMaxAccess(unitType)
-		}
-	}
-
-	if org.Organization.Visibility == structs.VisibleTypePublic {
-		return perm.AccessModeRead
-	}
-
-	return perm.AccessModeNone
+func (org *Organization) CanReadUnit(ctx *Context, unitType unit.Type) bool {
+	return org.Organization.UnitPermission(ctx, ctx.Doer, unitType) >= perm.AccessModeRead
 }
 
 func GetOrganizationByParams(ctx *Context) {
@@ -170,6 +151,7 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
 	}
 	ctx.Data["IsOrganizationOwner"] = ctx.Org.IsOwner
 	ctx.Data["IsOrganizationMember"] = ctx.Org.IsMember
+	ctx.Data["IsProjectEnabled"] = true
 	ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
 	ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
 	ctx.Data["IsPublicMember"] = func(uid int64) bool {
@@ -245,6 +227,10 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
 			return
 		}
 	}
+
+	ctx.Data["CanReadProjects"] = ctx.Org.CanReadUnit(ctx, unit.TypeProjects)
+	ctx.Data["CanReadPackages"] = ctx.Org.CanReadUnit(ctx, unit.TypePackages)
+	ctx.Data["CanReadCode"] = ctx.Org.CanReadUnit(ctx, unit.TypeCode)
 }
 
 // OrgAssignment returns a middleware to handle organization assignment
diff --git a/routers/web/org/home.go b/routers/web/org/home.go
index 4cc364acd3a01..61eaa1bb933bf 100644
--- a/routers/web/org/home.go
+++ b/routers/web/org/home.go
@@ -156,6 +156,7 @@ func Home(ctx *context.Context) {
 	pager.SetDefaultParams(ctx)
 	pager.AddParam(ctx, "language", "Language")
 	ctx.Data["Page"] = pager
-
+	ctx.Data["ContextUser"] = ctx.ContextUser
+	
 	ctx.HTML(http.StatusOK, tplOrgHome)
 }
diff --git a/routers/web/shared/user/header.go b/routers/web/shared/user/header.go
index 94e59e2a490fd..05e45f999eed9 100644
--- a/routers/web/shared/user/header.go
+++ b/routers/web/shared/user/header.go
@@ -9,6 +9,8 @@ import (
 )
 
 func RenderUserHeader(ctx *context.Context) {
+	ctx.Data["IsProjectEnabled"] = true
+	ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
 	ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
 	ctx.Data["ContextUser"] = ctx.ContextUser
 }
diff --git a/routers/web/user/code.go b/routers/web/user/code.go
index 81e3e65b4b67a..b3adbcb8d3a8f 100644
--- a/routers/web/user/code.go
+++ b/routers/web/user/code.go
@@ -24,6 +24,7 @@ func CodeSearch(ctx *context.Context) {
 		return
 	}
 
+	ctx.Data["IsProjectEnabled"] = true
 	ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
 	ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
 	ctx.Data["Title"] = ctx.Tr("explore.code")
diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go
index 4f0a816569bb9..0a215e920344e 100644
--- a/routers/web/user/profile.go
+++ b/routers/web/user/profile.go
@@ -288,6 +288,7 @@ func Profile(ctx *context.Context) {
 		pager.AddParam(ctx, "language", "Language")
 	}
 	ctx.Data["Page"] = pager
+	ctx.Data["IsProjectEnabled"] = true
 	ctx.Data["IsPackageEnabled"] = setting.Packages.Enabled
 	ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
 
diff --git a/routers/web/web.go b/routers/web/web.go
index 88e27ad678992..36986cff63793 100644
--- a/routers/web/web.go
+++ b/routers/web/web.go
@@ -869,8 +869,21 @@ func RegisterRoutes(m *web.Route) {
 		}
 
 		m.Group("/projects", func() {
-			m.Get("", org.Projects)
-			m.Get("/{id}", org.ViewProject)
+			m.Group("", func() {
+				m.Get("", org.Projects)
+				m.Get("/{id}", org.ViewProject)
+			}, func(ctx *context.Context) {
+				if ctx.ContextUser == nil {
+					ctx.NotFound("Project", nil)
+					return
+				}
+				if ctx.ContextUser.IsOrganization() {
+					if !ctx.Org.CanReadUnit(ctx, unit.TypeProjects) {
+						ctx.NotFound("Project", nil)
+						return
+					}
+				}
+			})
 			m.Group("", func() { //nolint:dupl
 				m.Get("/new", org.NewProject)
 				m.Post("/new", web.Bind(forms.CreateProjectForm{}), org.NewProjectPost)
@@ -907,7 +920,20 @@ func RegisterRoutes(m *web.Route) {
 			})
 		}, repo.MustEnableProjects)
 
-		m.Get("/code", user.CodeSearch)
+		m.Group("", func() {
+			m.Get("/code", user.CodeSearch)
+		}, func(ctx *context.Context) {
+			if ctx.ContextUser == nil {
+				ctx.NotFound("Code", nil)
+				return
+			}
+			if ctx.ContextUser.IsOrganization() {
+				if !ctx.Org.CanReadUnit(ctx, unit.TypeCode) {
+					ctx.NotFound("Code", nil)
+					return
+				}
+			}
+		})
 	}, context_service.UserAssignmentWeb())
 
 	// ***** Release Attachment Download without Signin
diff --git a/templates/org/menu.tmpl b/templates/org/menu.tmpl
index 4c6000603f268..d4bea05f9d6c7 100644
--- a/templates/org/menu.tmpl
+++ b/templates/org/menu.tmpl
@@ -3,15 +3,17 @@
 		<a class="{{if .PageIsViewRepositories}}active {{end}}item" href="{{$.Org.HomeLink}}">
 			{{svg "octicon-repo"}} {{.locale.Tr "user.repositories"}}
 		</a>
+		{{if and .IsProjectEnabled (and .ContextUser.IsOrganization .CanReadProjects)}}
 		<a class="{{if .PageIsViewProjects}}active {{end}}item" href="{{$.Org.HomeLink}}/-/projects">
 			{{svg "octicon-project"}} {{.locale.Tr "user.projects"}}
 		</a>
-		{{if .IsPackageEnabled}}
+		{{end}}
+		{{if and .IsPackageEnabled (and .ContextUser.IsOrganization .CanReadPackages)}}
 		<a class="item" href="{{$.Org.HomeLink}}/-/packages">
 			{{svg "octicon-package"}} {{.locale.Tr "packages.title"}}
 		</a>
 		{{end}}
-		{{if .IsRepoIndexerEnabled}}
+		{{if and .IsRepoIndexerEnabled (and .ContextUser.IsOrganization .CanReadCode)}}
 		<a class="item" href="{{$.Org.HomeLink}}/-/code">
 			{{svg "octicon-code"}}&nbsp;{{$.locale.Tr "org.code"}}
 		</a>
diff --git a/templates/user/overview/header.tmpl b/templates/user/overview/header.tmpl
index 9b32886891dfe..f0537f3d1a453 100644
--- a/templates/user/overview/header.tmpl
+++ b/templates/user/overview/header.tmpl
@@ -22,15 +22,17 @@
 			<a class="item" href="{{.ContextUser.HomeLink}}">
 				{{svg "octicon-repo"}} {{.locale.Tr "user.repositories"}}
 			</a>
+			{{if and .IsProjectEnabled (or .ContextUser.IsIndividual (and .ContextUser.IsOrganization .CanReadProjects))}}
 			<a href="{{.ContextUser.HomeLink}}/-/projects" class="{{if .PageIsViewProjects}}active {{end}}item">
 				{{svg "octicon-project"}} {{.locale.Tr "user.projects"}}
 			</a>
-			{{if .IsPackageEnabled}}
+			{{end}}
+			{{if and .IsPackageEnabled (or .ContextUser.IsIndividual (and .ContextUser.IsOrganization .CanReadPackages))}}
 				<a href="{{.ContextUser.HomeLink}}/-/packages" class="{{if .IsPackagesPage}}active {{end}}item">
 					{{svg "octicon-package"}} {{.locale.Tr "packages.title"}}
 				</a>
 			{{end}}
-			{{if .IsRepoIndexerEnabled}}
+			{{if and .IsRepoIndexerEnabled (or .ContextUser.IsIndividual (and .ContextUser.IsOrganization .CanReadCode))}}
 				<a href="{{.ContextUser.HomeLink}}/-/code" class="{{if .IsCodePage}}active {{end}}item">
 					{{svg "octicon-code"}} {{.locale.Tr "user.code"}}
 				</a>

From 8a9026f477431ac16980483494ca5d1428d14c77 Mon Sep 17 00:00:00 2001
From: yp05327 <576951401@qq.com>
Date: Wed, 22 Feb 2023 21:56:42 +0900
Subject: [PATCH 07/10] fix fmt

---
 routers/web/org/home.go | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/routers/web/org/home.go b/routers/web/org/home.go
index 61eaa1bb933bf..8c9cc8a9d86be 100644
--- a/routers/web/org/home.go
+++ b/routers/web/org/home.go
@@ -157,6 +157,6 @@ func Home(ctx *context.Context) {
 	pager.AddParam(ctx, "language", "Language")
 	ctx.Data["Page"] = pager
 	ctx.Data["ContextUser"] = ctx.ContextUser
-	
+
 	ctx.HTML(http.StatusOK, tplOrgHome)
 }

From 8450b099a6a34aea022616c8687bd5f3695bfca8 Mon Sep 17 00:00:00 2001
From: yp05327 <576951401@qq.com>
Date: Fri, 3 Mar 2023 07:02:09 +0000
Subject: [PATCH 08/10] improve code

---
 routers/web/web.go | 54 ++++++++++++++++------------------------------
 1 file changed, 19 insertions(+), 35 deletions(-)

diff --git a/routers/web/web.go b/routers/web/web.go
index 36986cff63793..1a79528414c26 100644
--- a/routers/web/web.go
+++ b/routers/web/web.go
@@ -690,6 +690,21 @@ func RegisterRoutes(m *web.Route) {
 		}
 	}
 
+	reqUnitAccess := func(unitType unit.Type, accessMode perm.AccessMode) func(ctx *context.Context) {
+		return func(ctx *context.Context) {
+			if ctx.ContextUser == nil {
+				ctx.NotFound(unitType.String(), nil)
+				return
+			}
+			if ctx.ContextUser.IsOrganization() {
+				if ctx.Org.Organization.UnitPermission(ctx, ctx.Doer, unitType) < accessMode {
+					ctx.NotFound(unitType.String(), nil)
+					return
+				}
+			}
+		}
+	}
+
 	// ***** START: Organization *****
 	m.Group("/org", func() {
 		m.Group("/{org}", func() {
@@ -872,18 +887,7 @@ func RegisterRoutes(m *web.Route) {
 			m.Group("", func() {
 				m.Get("", org.Projects)
 				m.Get("/{id}", org.ViewProject)
-			}, func(ctx *context.Context) {
-				if ctx.ContextUser == nil {
-					ctx.NotFound("Project", nil)
-					return
-				}
-				if ctx.ContextUser.IsOrganization() {
-					if !ctx.Org.CanReadUnit(ctx, unit.TypeProjects) {
-						ctx.NotFound("Project", nil)
-						return
-					}
-				}
-			})
+			}, reqUnitAccess(unit.TypeProjects, perm.AccessModeRead))
 			m.Group("", func() { //nolint:dupl
 				m.Get("/new", org.NewProject)
 				m.Post("/new", web.Bind(forms.CreateProjectForm{}), org.NewProjectPost)
@@ -903,17 +907,8 @@ func RegisterRoutes(m *web.Route) {
 						m.Post("/move", org.MoveIssues)
 					})
 				})
-			}, reqSignIn, func(ctx *context.Context) {
-				if ctx.ContextUser == nil {
-					ctx.NotFound("NewProject", nil)
-					return
-				}
-				if ctx.ContextUser.IsOrganization() {
-					if !ctx.Org.CanWriteUnit(ctx, unit.TypeProjects) {
-						ctx.NotFound("NewProject", nil)
-						return
-					}
-				} else if ctx.ContextUser.ID != ctx.Doer.ID {
+			}, reqSignIn, reqUnitAccess(unit.TypeProjects, perm.AccessModeWrite), func(ctx *context.Context) {
+				if ctx.ContextUser.IsIndividual() && ctx.ContextUser.ID != ctx.Doer.ID {
 					ctx.NotFound("NewProject", nil)
 					return
 				}
@@ -922,18 +917,7 @@ func RegisterRoutes(m *web.Route) {
 
 		m.Group("", func() {
 			m.Get("/code", user.CodeSearch)
-		}, func(ctx *context.Context) {
-			if ctx.ContextUser == nil {
-				ctx.NotFound("Code", nil)
-				return
-			}
-			if ctx.ContextUser.IsOrganization() {
-				if !ctx.Org.CanReadUnit(ctx, unit.TypeCode) {
-					ctx.NotFound("Code", nil)
-					return
-				}
-			}
-		})
+		}, reqUnitAccess(unit.TypeCode, perm.AccessModeRead))
 	}, context_service.UserAssignmentWeb())
 
 	// ***** Release Attachment Download without Signin

From b2d5d95dc59a84435970c69b3d496b71f0ea0dc8 Mon Sep 17 00:00:00 2001
From: yp05327 <576951401@qq.com>
Date: Wed, 8 Mar 2023 04:37:18 +0000
Subject: [PATCH 09/10] disuse migration of userassgnment and orgassgnment

---
 modules/context/org.go   | 20 +++++++++++++++-----
 routers/web/web.go       |  2 +-
 services/context/user.go | 10 ----------
 3 files changed, 16 insertions(+), 16 deletions(-)

diff --git a/modules/context/org.go b/modules/context/org.go
index 61491eedf2334..39a3038f910cb 100644
--- a/modules/context/org.go
+++ b/modules/context/org.go
@@ -83,12 +83,22 @@ func HandleOrgAssignment(ctx *Context, args ...bool) {
 
 	var err error
 
-	// if Organization is not defined, get it from params
-	if ctx.Org.Organization == nil {
-		GetOrganizationByParams(ctx)
-		if ctx.Written() {
-			return
+	if ctx.ContextUser == nil {
+		// if Organization is not defined, get it from params
+		if ctx.Org.Organization == nil {
+			GetOrganizationByParams(ctx)
+			if ctx.Written() {
+				return
+			}
 		}
+	} else if ctx.ContextUser.IsOrganization() {
+		if ctx.Org == nil {
+			ctx.Org = &Organization{}
+		}
+		ctx.Org.Organization = (*organization.Organization)(ctx.ContextUser)
+	} else {
+		// ContextUser is an individual User
+		return
 	}
 
 	org := ctx.Org.Organization
diff --git a/routers/web/web.go b/routers/web/web.go
index b3f95c9ba3c05..3bb96d930ad2a 100644
--- a/routers/web/web.go
+++ b/routers/web/web.go
@@ -918,7 +918,7 @@ func RegisterRoutes(m *web.Route) {
 		m.Group("", func() {
 			m.Get("/code", user.CodeSearch)
 		}, reqUnitAccess(unit.TypeCode, perm.AccessModeRead))
-	}, context_service.UserAssignmentWeb())
+	}, context_service.UserAssignmentWeb(), context.OrgAssignment())
 
 	// ***** Release Attachment Download without Signin
 	m.Get("/{username}/{reponame}/releases/download/{vTag}/{fileName}", ignSignIn, context.RepoAssignment, repo.MustBeNotEmpty, repo.RedirectDownload)
diff --git a/services/context/user.go b/services/context/user.go
index 29a02a4aa563e..9dc84c3ac15e1 100644
--- a/services/context/user.go
+++ b/services/context/user.go
@@ -8,7 +8,6 @@ import (
 	"net/http"
 	"strings"
 
-	org_model "code.gitea.io/gitea/models/organization"
 	user_model "code.gitea.io/gitea/models/user"
 	"code.gitea.io/gitea/modules/context"
 )
@@ -57,15 +56,6 @@ func userAssignment(ctx *context.Context, errCb func(int, string, interface{}))
 			} else {
 				errCb(http.StatusInternalServerError, "GetUserByName", err)
 			}
-		} else {
-			if ctx.ContextUser.IsOrganization() {
-				if ctx.Org == nil {
-					ctx.Org = &context.Organization{}
-				}
-				ctx.Org.Organization = (*org_model.Organization)(ctx.ContextUser)
-
-				context.HandleOrgAssignment(ctx)
-			}
 		}
 	}
 }

From adec7929447564daec4656003c2448f67d7c3eff Mon Sep 17 00:00:00 2001
From: yp05327 <576951401@qq.com>
Date: Wed, 8 Mar 2023 04:48:48 +0000
Subject: [PATCH 10/10] fix org menu

---
 templates/org/menu.tmpl | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/templates/org/menu.tmpl b/templates/org/menu.tmpl
index d4bea05f9d6c7..a3dcd382a7b3b 100644
--- a/templates/org/menu.tmpl
+++ b/templates/org/menu.tmpl
@@ -3,17 +3,17 @@
 		<a class="{{if .PageIsViewRepositories}}active {{end}}item" href="{{$.Org.HomeLink}}">
 			{{svg "octicon-repo"}} {{.locale.Tr "user.repositories"}}
 		</a>
-		{{if and .IsProjectEnabled (and .ContextUser.IsOrganization .CanReadProjects)}}
+		{{if and .IsProjectEnabled .CanReadProjects}}
 		<a class="{{if .PageIsViewProjects}}active {{end}}item" href="{{$.Org.HomeLink}}/-/projects">
 			{{svg "octicon-project"}} {{.locale.Tr "user.projects"}}
 		</a>
 		{{end}}
-		{{if and .IsPackageEnabled (and .ContextUser.IsOrganization .CanReadPackages)}}
+		{{if and .IsPackageEnabled .CanReadPackages}}
 		<a class="item" href="{{$.Org.HomeLink}}/-/packages">
 			{{svg "octicon-package"}} {{.locale.Tr "packages.title"}}
 		</a>
 		{{end}}
-		{{if and .IsRepoIndexerEnabled (and .ContextUser.IsOrganization .CanReadCode)}}
+		{{if and .IsRepoIndexerEnabled .CanReadCode}}
 		<a class="item" href="{{$.Org.HomeLink}}/-/code">
 			{{svg "octicon-code"}}&nbsp;{{$.locale.Tr "org.code"}}
 		</a>