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.

Set repository link based on the url in package.json for npm packages (#20379)

automatically set repository link for package based on the repository
url present inside package.json

closes #20146

authored by

Mai-Lapyst and committed by
GitHub
5cd1d6c9 3cab9c6b

+135
+43
models/repo/repo.go
··· 658 658 return repo, err 659 659 } 660 660 661 + // getRepositoryURLPathSegments returns segments (owner, reponame) extracted from a url 662 + func getRepositoryURLPathSegments(repoURL string) []string { 663 + if strings.HasPrefix(repoURL, setting.AppURL) { 664 + return strings.Split(strings.TrimPrefix(repoURL, setting.AppURL), "/") 665 + } 666 + 667 + sshURLVariants := [4]string{ 668 + setting.SSH.Domain + ":", 669 + setting.SSH.User + "@" + setting.SSH.Domain + ":", 670 + "git+ssh://" + setting.SSH.Domain + "/", 671 + "git+ssh://" + setting.SSH.User + "@" + setting.SSH.Domain + "/", 672 + } 673 + 674 + for _, sshURL := range sshURLVariants { 675 + if strings.HasPrefix(repoURL, sshURL) { 676 + return strings.Split(strings.TrimPrefix(repoURL, sshURL), "/") 677 + } 678 + } 679 + 680 + return nil 681 + } 682 + 683 + // GetRepositoryByURL returns the repository by given url 684 + func GetRepositoryByURL(ctx context.Context, repoURL string) (*Repository, error) { 685 + // possible urls for git: 686 + // https://my.domain/sub-path/<owner>/<repo>.git 687 + // https://my.domain/sub-path/<owner>/<repo> 688 + // git+ssh://user@my.domain/<owner>/<repo>.git 689 + // git+ssh://user@my.domain/<owner>/<repo> 690 + // user@my.domain:<owner>/<repo>.git 691 + // user@my.domain:<owner>/<repo> 692 + 693 + pathSegments := getRepositoryURLPathSegments(repoURL) 694 + 695 + if len(pathSegments) != 2 { 696 + return nil, fmt.Errorf("unknown or malformed repository URL") 697 + } 698 + 699 + ownerName := pathSegments[0] 700 + repoName := strings.TrimSuffix(pathSegments[1], ".git") 701 + return GetRepositoryByOwnerAndName(ctx, ownerName, repoName) 702 + } 703 + 661 704 // GetRepositoryByID returns the repository by given id if exists. 662 705 func GetRepositoryByID(ctx context.Context, id int64) (*Repository, error) { 663 706 repo := new(Repository)
+62
models/repo/repo_test.go
··· 124 124 assert.Equal(t, "user3", metas["org"]) 125 125 assert.Equal(t, ",owners,team1,", metas["teams"]) 126 126 } 127 + 128 + func TestGetRepositoryByURL(t *testing.T) { 129 + assert.NoError(t, unittest.PrepareTestDatabase()) 130 + 131 + t.Run("InvalidPath", func(t *testing.T) { 132 + repo, err := repo_model.GetRepositoryByURL(db.DefaultContext, "something") 133 + 134 + assert.Nil(t, repo) 135 + assert.Error(t, err) 136 + }) 137 + 138 + t.Run("ValidHttpURL", func(t *testing.T) { 139 + test := func(t *testing.T, url string) { 140 + repo, err := repo_model.GetRepositoryByURL(db.DefaultContext, url) 141 + 142 + assert.NotNil(t, repo) 143 + assert.NoError(t, err) 144 + 145 + assert.Equal(t, repo.ID, int64(2)) 146 + assert.Equal(t, repo.OwnerID, int64(2)) 147 + } 148 + 149 + test(t, "https://try.gitea.io/user2/repo2") 150 + test(t, "https://try.gitea.io/user2/repo2.git") 151 + }) 152 + 153 + t.Run("ValidGitSshURL", func(t *testing.T) { 154 + test := func(t *testing.T, url string) { 155 + repo, err := repo_model.GetRepositoryByURL(db.DefaultContext, url) 156 + 157 + assert.NotNil(t, repo) 158 + assert.NoError(t, err) 159 + 160 + assert.Equal(t, repo.ID, int64(2)) 161 + assert.Equal(t, repo.OwnerID, int64(2)) 162 + } 163 + 164 + test(t, "git+ssh://sshuser@try.gitea.io/user2/repo2") 165 + test(t, "git+ssh://sshuser@try.gitea.io/user2/repo2.git") 166 + 167 + test(t, "git+ssh://try.gitea.io/user2/repo2") 168 + test(t, "git+ssh://try.gitea.io/user2/repo2.git") 169 + }) 170 + 171 + t.Run("ValidImplicitSshURL", func(t *testing.T) { 172 + test := func(t *testing.T, url string) { 173 + repo, err := repo_model.GetRepositoryByURL(db.DefaultContext, url) 174 + 175 + assert.NotNil(t, repo) 176 + assert.NoError(t, err) 177 + 178 + assert.Equal(t, repo.ID, int64(2)) 179 + assert.Equal(t, repo.OwnerID, int64(2)) 180 + } 181 + 182 + test(t, "sshuser@try.gitea.io:user2/repo2") 183 + test(t, "sshuser@try.gitea.io:user2/repo2.git") 184 + 185 + test(t, "try.gitea.io:user2/repo2") 186 + test(t, "try.gitea.io:user2/repo2.git") 187 + }) 188 + }
+30
routers/api/packages/npm/npm.go
··· 13 13 14 14 "code.gitea.io/gitea/models/db" 15 15 packages_model "code.gitea.io/gitea/models/packages" 16 + access_model "code.gitea.io/gitea/models/perm/access" 17 + repo_model "code.gitea.io/gitea/models/repo" 18 + "code.gitea.io/gitea/models/unit" 16 19 "code.gitea.io/gitea/modules/context" 17 20 packages_module "code.gitea.io/gitea/modules/packages" 18 21 npm_module "code.gitea.io/gitea/modules/packages/npm" ··· 166 169 return 167 170 } 168 171 172 + repo, err := repo_model.GetRepositoryByURL(ctx, npmPackage.Metadata.Repository.URL) 173 + if err == nil { 174 + canWrite := repo.OwnerID == ctx.Doer.ID 175 + 176 + if !canWrite { 177 + perms, err := access_model.GetUserRepoPermission(ctx, repo, ctx.Doer) 178 + if err != nil { 179 + apiError(ctx, http.StatusInternalServerError, err) 180 + return 181 + } 182 + 183 + canWrite = perms.CanWrite(unit.TypePackages) 184 + } 185 + 186 + if !canWrite { 187 + apiError(ctx, http.StatusForbidden, "no permission to upload this package") 188 + return 189 + } 190 + } 191 + 169 192 buf, err := packages_module.CreateHashedBufferFromReader(bytes.NewReader(npmPackage.Data), 32*1024*1024) 170 193 if err != nil { 171 194 apiError(ctx, http.StatusInternalServerError, err) ··· 212 235 apiError(ctx, http.StatusBadRequest, err) 213 236 return 214 237 } 238 + apiError(ctx, http.StatusInternalServerError, err) 239 + return 240 + } 241 + } 242 + 243 + if repo != nil { 244 + if err := packages_model.SetRepositoryLink(ctx, pv.PackageID, repo.ID); err != nil { 215 245 apiError(ctx, http.StatusInternalServerError, err) 216 246 return 217 247 }