loading up the forgejo repo on tangled to test page performance
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Respect `REQUIRE_SIGNIN_VIEW` for packages (#20873)

Fix #20863

When REQUIRE_SIGNIN_VIEW = true, even with public repositories, you can only see them after you login. The packages should not be accessed without login.

Co-authored-by: Lauris BH <lauris@nix.lv>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>

authored by

KN4CK3R
Lauris BH
wxiaoguang
and committed by
GitHub
0a9a86b9 d9bc6881

+62 -33
+49 -33
modules/context/package.go
··· 14 14 "code.gitea.io/gitea/models/perm" 15 15 "code.gitea.io/gitea/models/unit" 16 16 user_model "code.gitea.io/gitea/models/user" 17 + "code.gitea.io/gitea/modules/setting" 17 18 "code.gitea.io/gitea/modules/structs" 18 19 "code.gitea.io/gitea/modules/templates" 19 20 ) ··· 54 55 Owner: ctx.ContextUser, 55 56 } 56 57 58 + var err error 59 + ctx.Package.AccessMode, err = determineAccessMode(ctx) 60 + if err != nil { 61 + errCb(http.StatusInternalServerError, "determineAccessMode", err) 62 + return 63 + } 64 + 65 + packageType := ctx.Params("type") 66 + name := ctx.Params("name") 67 + version := ctx.Params("version") 68 + if packageType != "" && name != "" && version != "" { 69 + pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.Type(packageType), name, version) 70 + if err != nil { 71 + if err == packages_model.ErrPackageNotExist { 72 + errCb(http.StatusNotFound, "GetVersionByNameAndVersion", err) 73 + } else { 74 + errCb(http.StatusInternalServerError, "GetVersionByNameAndVersion", err) 75 + } 76 + return 77 + } 78 + 79 + ctx.Package.Descriptor, err = packages_model.GetPackageDescriptor(ctx, pv) 80 + if err != nil { 81 + errCb(http.StatusInternalServerError, "GetPackageDescriptor", err) 82 + return 83 + } 84 + } 85 + } 86 + 87 + func determineAccessMode(ctx *Context) (perm.AccessMode, error) { 88 + accessMode := perm.AccessModeNone 89 + 90 + if setting.Service.RequireSignInView && ctx.Doer == nil { 91 + return accessMode, nil 92 + } 93 + 57 94 if ctx.Package.Owner.IsOrganization() { 58 95 org := organization.OrgFromUser(ctx.Package.Owner) 59 96 60 97 // 1. Get user max authorize level for the org (may be none, if user is not member of the org) 61 98 if ctx.Doer != nil { 62 99 var err error 63 - ctx.Package.AccessMode, err = org.GetOrgUserMaxAuthorizeLevel(ctx.Doer.ID) 100 + accessMode, err = org.GetOrgUserMaxAuthorizeLevel(ctx.Doer.ID) 64 101 if err != nil { 65 - errCb(http.StatusInternalServerError, "GetOrgUserMaxAuthorizeLevel", err) 66 - return 102 + return accessMode, err 67 103 } 68 104 // If access mode is less than write check every team for more permissions 69 - if ctx.Package.AccessMode < perm.AccessModeWrite { 105 + if accessMode < perm.AccessModeWrite { 70 106 teams, err := organization.GetUserOrgTeams(ctx, org.ID, ctx.Doer.ID) 71 107 if err != nil { 72 - errCb(http.StatusInternalServerError, "GetUserOrgTeams", err) 73 - return 108 + return accessMode, err 74 109 } 75 110 for _, t := range teams { 76 111 perm := t.UnitAccessModeCtx(ctx, unit.TypePackages) 77 - if ctx.Package.AccessMode < perm { 78 - ctx.Package.AccessMode = perm 112 + if accessMode < perm { 113 + accessMode = perm 79 114 } 80 115 } 81 116 } 82 117 } 83 118 // 2. If authorize level is none, check if org is visible to user 84 - if ctx.Package.AccessMode == perm.AccessModeNone && organization.HasOrgOrUserVisible(ctx, ctx.Package.Owner, ctx.Doer) { 85 - ctx.Package.AccessMode = perm.AccessModeRead 119 + if accessMode == perm.AccessModeNone && organization.HasOrgOrUserVisible(ctx, ctx.Package.Owner, ctx.Doer) { 120 + accessMode = perm.AccessModeRead 86 121 } 87 122 } else { 88 123 if ctx.Doer != nil && !ctx.Doer.IsGhost() { 89 124 // 1. Check if user is package owner 90 125 if ctx.Doer.ID == ctx.Package.Owner.ID { 91 - ctx.Package.AccessMode = perm.AccessModeOwner 126 + accessMode = perm.AccessModeOwner 92 127 } else if ctx.Package.Owner.Visibility == structs.VisibleTypePublic || ctx.Package.Owner.Visibility == structs.VisibleTypeLimited { // 2. Check if package owner is public or limited 93 - ctx.Package.AccessMode = perm.AccessModeRead 128 + accessMode = perm.AccessModeRead 94 129 } 95 130 } else if ctx.Package.Owner.Visibility == structs.VisibleTypePublic { // 3. Check if package owner is public 96 - ctx.Package.AccessMode = perm.AccessModeRead 131 + accessMode = perm.AccessModeRead 97 132 } 98 133 } 99 134 100 - packageType := ctx.Params("type") 101 - name := ctx.Params("name") 102 - version := ctx.Params("version") 103 - if packageType != "" && name != "" && version != "" { 104 - pv, err := packages_model.GetVersionByNameAndVersion(ctx, ctx.Package.Owner.ID, packages_model.Type(packageType), name, version) 105 - if err != nil { 106 - if err == packages_model.ErrPackageNotExist { 107 - errCb(http.StatusNotFound, "GetVersionByNameAndVersion", err) 108 - } else { 109 - errCb(http.StatusInternalServerError, "GetVersionByNameAndVersion", err) 110 - } 111 - return 112 - } 113 - 114 - ctx.Package.Descriptor, err = packages_model.GetPackageDescriptor(ctx, pv) 115 - if err != nil { 116 - errCb(http.StatusInternalServerError, "GetPackageDescriptor", err) 117 - return 118 - } 119 - } 135 + return accessMode, nil 120 136 } 121 137 122 138 // PackageContexter initializes a package context for a request.
+13
tests/integration/api_packages_generic_test.go
··· 14 14 "code.gitea.io/gitea/models/packages" 15 15 "code.gitea.io/gitea/models/unittest" 16 16 user_model "code.gitea.io/gitea/models/user" 17 + "code.gitea.io/gitea/modules/setting" 17 18 "code.gitea.io/gitea/tests" 18 19 19 20 "github.com/stretchr/testify/assert" ··· 125 126 126 127 req := NewRequest(t, "GET", url+"/not.found") 127 128 MakeRequest(t, req, http.StatusNotFound) 129 + }) 130 + 131 + t.Run("RequireSignInView", func(t *testing.T) { 132 + defer tests.PrintCurrentTest(t)() 133 + 134 + setting.Service.RequireSignInView = true 135 + defer func() { 136 + setting.Service.RequireSignInView = false 137 + }() 138 + 139 + req = NewRequest(t, "GET", url+"/dummy.bin") 140 + MakeRequest(t, req, http.StatusUnauthorized) 128 141 }) 129 142 }) 130 143