From 7827899d13ebd83b59bef4441d85c6d8bd05cf49 Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Sat, 20 Aug 2022 11:22:14 +0000 Subject: [PATCH 1/2] Respect RequireSignInView. --- modules/context/package.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modules/context/package.go b/modules/context/package.go index 92a97831ddc0..7bc78a1960ad 100644 --- a/modules/context/package.go +++ b/modules/context/package.go @@ -13,6 +13,7 @@ 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/setting" "code.gitea.io/gitea/modules/structs" ) @@ -79,7 +80,7 @@ func packageAssignment(ctx *Context, errCb func(int, string, interface{})) { } } // 2. If authorize level is none, check if org is visible to user - if ctx.Package.AccessMode == perm.AccessModeNone && organization.HasOrgOrUserVisible(ctx, ctx.Package.Owner, ctx.Doer) { + if ctx.Package.AccessMode == perm.AccessModeNone && organization.HasOrgOrUserVisible(ctx, ctx.Package.Owner, ctx.Doer) && !setting.Service.RequireSignInView { ctx.Package.AccessMode = perm.AccessModeRead } } else { @@ -90,7 +91,7 @@ func packageAssignment(ctx *Context, errCb func(int, string, interface{})) { } else if ctx.Package.Owner.Visibility == structs.VisibleTypePublic || ctx.Package.Owner.Visibility == structs.VisibleTypeLimited { // 2. Check if package owner is public or limited ctx.Package.AccessMode = perm.AccessModeRead } - } else if ctx.Package.Owner.Visibility == structs.VisibleTypePublic { // 3. Check if package owner is public + } else if ctx.Package.Owner.Visibility == structs.VisibleTypePublic && !setting.Service.RequireSignInView { // 3. Check if package owner is public ctx.Package.AccessMode = perm.AccessModeRead } } From d36d4deac862abf296b546fe59f289318bc941f8 Mon Sep 17 00:00:00 2001 From: KN4CK3R Date: Sat, 10 Sep 2022 19:49:27 +0000 Subject: [PATCH 2/2] Move code into function and add test. --- integrations/api_packages_generic_test.go | 13 ++++ modules/context/package.go | 83 +++++++++++++---------- 2 files changed, 62 insertions(+), 34 deletions(-) diff --git a/integrations/api_packages_generic_test.go b/integrations/api_packages_generic_test.go index c60a387f533b..ff8ea6e47435 100644 --- a/integrations/api_packages_generic_test.go +++ b/integrations/api_packages_generic_test.go @@ -14,6 +14,7 @@ import ( "code.gitea.io/gitea/models/packages" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/setting" "github.com/stretchr/testify/assert" ) @@ -125,6 +126,18 @@ func TestPackageGeneric(t *testing.T) { req := NewRequest(t, "GET", url+"/not.found") MakeRequest(t, req, http.StatusNotFound) }) + + t.Run("RequireSignInView", func(t *testing.T) { + defer PrintCurrentTest(t)() + + setting.Service.RequireSignInView = true + defer func() { + setting.Service.RequireSignInView = false + }() + + req = NewRequest(t, "GET", url+"/dummy.bin") + MakeRequest(t, req, http.StatusUnauthorized) + }) }) t.Run("Delete", func(t *testing.T) { diff --git a/modules/context/package.go b/modules/context/package.go index 7bc78a1960ad..89a8c4466c15 100644 --- a/modules/context/package.go +++ b/modules/context/package.go @@ -53,69 +53,84 @@ func packageAssignment(ctx *Context, errCb func(int, string, interface{})) { Owner: ctx.ContextUser, } + var err error + ctx.Package.AccessMode, err = determineAccessMode(ctx) + if err != nil { + errCb(http.StatusInternalServerError, "determineAccessMode", err) + return + } + + packageType := ctx.Params("type") + name := ctx.Params("name") + version := ctx.Params("version") + if packageType != "" && name != "" && version != "" { + pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.Type(packageType), name, version) + if err != nil { + if err == packages_model.ErrPackageNotExist { + errCb(http.StatusNotFound, "GetVersionByNameAndVersion", err) + } else { + errCb(http.StatusInternalServerError, "GetVersionByNameAndVersion", err) + } + return + } + + ctx.Package.Descriptor, err = packages_model.GetPackageDescriptor(ctx, pv) + if err != nil { + errCb(http.StatusInternalServerError, "GetPackageDescriptor", err) + return + } + } +} + +func determineAccessMode(ctx *Context) (perm.AccessMode, error) { + accessMode := perm.AccessModeNone + + if setting.Service.RequireSignInView && ctx.Doer == nil { + return accessMode, nil + } + if ctx.Package.Owner.IsOrganization() { org := organization.OrgFromUser(ctx.Package.Owner) // 1. Get user max authorize level for the org (may be none, if user is not member of the org) if ctx.Doer != nil { var err error - ctx.Package.AccessMode, err = org.GetOrgUserMaxAuthorizeLevel(ctx.Doer.ID) + accessMode, err = org.GetOrgUserMaxAuthorizeLevel(ctx.Doer.ID) if err != nil { - errCb(http.StatusInternalServerError, "GetOrgUserMaxAuthorizeLevel", err) - return + return accessMode, err } // If access mode is less than write check every team for more permissions - if ctx.Package.AccessMode < perm.AccessModeWrite { + if accessMode < perm.AccessModeWrite { teams, err := organization.GetUserOrgTeams(ctx, org.ID, ctx.Doer.ID) if err != nil { - errCb(http.StatusInternalServerError, "GetUserOrgTeams", err) - return + return accessMode, err } for _, t := range teams { perm := t.UnitAccessModeCtx(ctx, unit.TypePackages) - if ctx.Package.AccessMode < perm { - ctx.Package.AccessMode = perm + if accessMode < perm { + accessMode = perm } } } } // 2. If authorize level is none, check if org is visible to user - if ctx.Package.AccessMode == perm.AccessModeNone && organization.HasOrgOrUserVisible(ctx, ctx.Package.Owner, ctx.Doer) && !setting.Service.RequireSignInView { - ctx.Package.AccessMode = perm.AccessModeRead + if accessMode == perm.AccessModeNone && organization.HasOrgOrUserVisible(ctx, ctx.Package.Owner, ctx.Doer) { + accessMode = perm.AccessModeRead } } else { if ctx.Doer != nil && !ctx.Doer.IsGhost() { // 1. Check if user is package owner if ctx.Doer.ID == ctx.Package.Owner.ID { - ctx.Package.AccessMode = perm.AccessModeOwner + accessMode = perm.AccessModeOwner } else if ctx.Package.Owner.Visibility == structs.VisibleTypePublic || ctx.Package.Owner.Visibility == structs.VisibleTypeLimited { // 2. Check if package owner is public or limited - ctx.Package.AccessMode = perm.AccessModeRead + accessMode = perm.AccessModeRead } - } else if ctx.Package.Owner.Visibility == structs.VisibleTypePublic && !setting.Service.RequireSignInView { // 3. Check if package owner is public - ctx.Package.AccessMode = perm.AccessModeRead + } else if ctx.Package.Owner.Visibility == structs.VisibleTypePublic { // 3. Check if package owner is public + accessMode = perm.AccessModeRead } } - packageType := ctx.Params("type") - name := ctx.Params("name") - version := ctx.Params("version") - if packageType != "" && name != "" && version != "" { - pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.Type(packageType), name, version) - if err != nil { - if err == packages_model.ErrPackageNotExist { - errCb(http.StatusNotFound, "GetVersionByNameAndVersion", err) - } else { - errCb(http.StatusInternalServerError, "GetVersionByNameAndVersion", err) - } - return - } - - ctx.Package.Descriptor, err = packages_model.GetPackageDescriptor(ctx, pv) - if err != nil { - errCb(http.StatusInternalServerError, "GetPackageDescriptor", err) - return - } - } + return accessMode, nil } // PackageContexter initializes a package context for a request.