Skip to content

Commit 6770177

Browse files
KN4CK3Rdelvhwxiaoguanglafriks
authored
Add support for NuGet API keys (#20721) (#20734)
Co-authored-by: delvh <[email protected]> Co-authored-by: wxiaoguang <[email protected]> Co-authored-by: Lauris BH <[email protected]>
1 parent 113d13a commit 6770177

File tree

4 files changed

+59
-0
lines changed

4 files changed

+59
-0
lines changed

docs/content/doc/packages/nuget.en-us.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,8 @@ For example:
4747
dotnet nuget add source --name gitea --username testuser --password password123 https://gitea.example.com/api/packages/testuser/nuget/index.json
4848
```
4949

50+
You can add the source without credentials and use the [`--api-key`](https://docs.microsoft.com/en-us/dotnet/core/tools/dotnet-nuget-push) parameter when publishing packages. In this case you need to provide a [personal access token]({{< relref "doc/developers/api-usage.en-us.md#authentication" >}}).
51+
5052
## Publish a package
5153

5254
Publish a package by running the following command:

integrations/api_packages_nuget_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,16 @@ import (
2424
"github.com/stretchr/testify/assert"
2525
)
2626

27+
func addNuGetAPIKeyHeader(request *http.Request, token string) *http.Request {
28+
request.Header.Set("X-NuGet-ApiKey", token)
29+
return request
30+
}
31+
2732
func TestPackageNuGet(t *testing.T) {
2833
defer prepareTestEnv(t)()
34+
2935
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
36+
token := getUserToken(t, user.Name)
3037

3138
packageName := "test.package"
3239
packageVersion := "1.0.3"
@@ -60,6 +67,10 @@ func TestPackageNuGet(t *testing.T) {
6067

6168
req := NewRequest(t, "GET", fmt.Sprintf("%s/index.json", url))
6269
req = AddBasicAuthHeader(req, user.Name)
70+
MakeRequest(t, req, http.StatusOK)
71+
72+
req = NewRequest(t, "GET", fmt.Sprintf("%s/index.json", url))
73+
req = addNuGetAPIKeyHeader(req, token)
6374
resp := MakeRequest(t, req, http.StatusOK)
6475

6576
var result nuget.ServiceIndexResponse

routers/api/packages/api.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ func Routes() *web.Route {
4545
authMethods := []auth.Method{
4646
&auth.OAuth2{},
4747
&auth.Basic{},
48+
&nuget.Auth{},
4849
&conan.Auth{},
4950
}
5051
if setting.Service.EnableReverseProxyAuth {

routers/api/packages/nuget/auth.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// Copyright 2022 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package nuget
6+
7+
import (
8+
"net/http"
9+
10+
"code.gitea.io/gitea/models"
11+
user_model "code.gitea.io/gitea/models/user"
12+
"code.gitea.io/gitea/modules/log"
13+
"code.gitea.io/gitea/modules/timeutil"
14+
"code.gitea.io/gitea/services/auth"
15+
)
16+
17+
type Auth struct{}
18+
19+
func (a *Auth) Name() string {
20+
return "nuget"
21+
}
22+
23+
// https://docs.microsoft.com/en-us/nuget/api/package-publish-resource#request-parameters
24+
func (a *Auth) Verify(req *http.Request, w http.ResponseWriter, store auth.DataStore, sess auth.SessionStore) *user_model.User {
25+
token, err := models.GetAccessTokenBySHA(req.Header.Get("X-NuGet-ApiKey"))
26+
if err != nil {
27+
if !(models.IsErrAccessTokenNotExist(err) || models.IsErrAccessTokenEmpty(err)) {
28+
log.Error("GetAccessTokenBySHA: %v", err)
29+
}
30+
return nil
31+
}
32+
33+
u, err := user_model.GetUserByID(token.UID)
34+
if err != nil {
35+
log.Error("GetUserByID: %v", err)
36+
return nil
37+
}
38+
39+
token.UpdatedUnix = timeutil.TimeStampNow()
40+
if err := models.UpdateAccessToken(token); err != nil {
41+
log.Error("UpdateAccessToken: %v", err)
42+
}
43+
44+
return u
45+
}

0 commit comments

Comments
 (0)