mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-09-15 18:56:59 +00:00
Merge pull request '[gitea] week 2024-48 cherry pick (gitea/main -> forgejo)' (#6062) from earl-warren/wcp/2024-48 into forgejo
Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/6062 Reviewed-by: Gusted <gusted@noreply.codeberg.org>
This commit is contained in:
commit
e5417fdede
18 changed files with 287 additions and 146 deletions
|
@ -83,7 +83,12 @@ func ParseAuthorizationToken(req *http.Request) (int64, error) {
|
|||
return 0, fmt.Errorf("split token failed")
|
||||
}
|
||||
|
||||
token, err := jwt.ParseWithClaims(parts[1], &actionsClaims{}, func(t *jwt.Token) (any, error) {
|
||||
return TokenToTaskID(parts[1])
|
||||
}
|
||||
|
||||
// TokenToTaskID returns the TaskID associated with the provided JWT token
|
||||
func TokenToTaskID(token string) (int64, error) {
|
||||
parsedToken, err := jwt.ParseWithClaims(token, &actionsClaims{}, func(t *jwt.Token) (any, error) {
|
||||
if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"])
|
||||
}
|
||||
|
@ -93,8 +98,8 @@ func ParseAuthorizationToken(req *http.Request) (int64, error) {
|
|||
return 0, err
|
||||
}
|
||||
|
||||
c, ok := token.Claims.(*actionsClaims)
|
||||
if !token.Valid || !ok {
|
||||
c, ok := parsedToken.Claims.(*actionsClaims)
|
||||
if !parsedToken.Valid || !ok {
|
||||
return 0, fmt.Errorf("invalid token claim")
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import (
|
|||
"code.gitea.io/gitea/modules/setting"
|
||||
"code.gitea.io/gitea/modules/timeutil"
|
||||
"code.gitea.io/gitea/modules/web/middleware"
|
||||
"code.gitea.io/gitea/services/actions"
|
||||
"code.gitea.io/gitea/services/auth/source/oauth2"
|
||||
)
|
||||
|
||||
|
@ -94,6 +95,18 @@ func CheckOAuthAccessToken(ctx context.Context, accessToken string) (int64, stri
|
|||
return grant.UserID, grantScopes
|
||||
}
|
||||
|
||||
// CheckTaskIsRunning verifies that the TaskID corresponds to a running task
|
||||
func CheckTaskIsRunning(ctx context.Context, taskID int64) bool {
|
||||
// Verify the task exists
|
||||
task, err := actions_model.GetTaskByID(ctx, taskID)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
// Verify that it's running
|
||||
return task.Status == actions_model.StatusRunning
|
||||
}
|
||||
|
||||
// OAuth2 implements the Auth interface and authenticates requests
|
||||
// (API requests only) by looking for an OAuth token in query parameters or the
|
||||
// "Authorization" header.
|
||||
|
@ -137,8 +150,17 @@ func parseToken(req *http.Request) (string, bool) {
|
|||
func (o *OAuth2) userIDFromToken(ctx context.Context, tokenSHA string, store DataStore) int64 {
|
||||
// Let's see if token is valid.
|
||||
if strings.Contains(tokenSHA, ".") {
|
||||
uid, grantScopes := CheckOAuthAccessToken(ctx, tokenSHA)
|
||||
// First attempt to decode an actions JWT, returning the actions user
|
||||
if taskID, err := actions.TokenToTaskID(tokenSHA); err == nil {
|
||||
if CheckTaskIsRunning(ctx, taskID) {
|
||||
store.GetData()["IsActionsToken"] = true
|
||||
store.GetData()["ActionsTaskID"] = taskID
|
||||
return user_model.ActionsUserID
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, check if this is an OAuth access token
|
||||
uid, grantScopes := CheckOAuthAccessToken(ctx, tokenSHA)
|
||||
if uid != 0 {
|
||||
store.GetData()["IsApiToken"] = true
|
||||
if grantScopes != "" {
|
||||
|
|
55
services/auth/oauth2_test.go
Normal file
55
services/auth/oauth2_test.go
Normal file
|
@ -0,0 +1,55 @@
|
|||
// Copyright 2024 The Gitea Authors. All rights reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/web/middleware"
|
||||
"code.gitea.io/gitea/services/actions"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestUserIDFromToken(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
t.Run("Actions JWT", func(t *testing.T) {
|
||||
const RunningTaskID = 47
|
||||
token, err := actions.CreateAuthorizationToken(RunningTaskID, 1, 2)
|
||||
require.NoError(t, err)
|
||||
|
||||
ds := make(middleware.ContextData)
|
||||
|
||||
o := OAuth2{}
|
||||
uid := o.userIDFromToken(context.Background(), token, ds)
|
||||
assert.Equal(t, int64(user_model.ActionsUserID), uid)
|
||||
assert.Equal(t, true, ds["IsActionsToken"])
|
||||
assert.Equal(t, ds["ActionsTaskID"], int64(RunningTaskID))
|
||||
})
|
||||
}
|
||||
|
||||
func TestCheckTaskIsRunning(t *testing.T) {
|
||||
require.NoError(t, unittest.PrepareTestDatabase())
|
||||
cases := map[string]struct {
|
||||
TaskID int64
|
||||
Expected bool
|
||||
}{
|
||||
"Running": {TaskID: 47, Expected: true},
|
||||
"Missing": {TaskID: 1, Expected: false},
|
||||
"Cancelled": {TaskID: 46, Expected: false},
|
||||
}
|
||||
|
||||
for name := range cases {
|
||||
c := cases[name]
|
||||
t.Run(name, func(t *testing.T) {
|
||||
actual := CheckTaskIsRunning(context.Background(), c.TaskID)
|
||||
assert.Equal(t, c.Expected, actual)
|
||||
})
|
||||
}
|
||||
}
|
|
@ -413,14 +413,7 @@ func repoAssignment(ctx *Context, repo *repo_model.Repository) {
|
|||
}
|
||||
}
|
||||
|
||||
pushMirrors, _, err := repo_model.GetPushMirrorsByRepoID(ctx, repo.ID, db.ListOptions{})
|
||||
if err != nil {
|
||||
ctx.ServerError("GetPushMirrorsByRepoID", err)
|
||||
return
|
||||
}
|
||||
|
||||
ctx.Repo.Repository = repo
|
||||
ctx.Data["PushMirrors"] = pushMirrors
|
||||
ctx.Data["RepoName"] = ctx.Repo.Repository.Name
|
||||
ctx.Data["IsEmptyRepo"] = ctx.Repo.Repository.IsEmpty
|
||||
ctx.Data["DefaultWikiBranchName"] = setting.Repository.DefaultBranch
|
||||
|
|
|
@ -43,7 +43,7 @@ func TestRepository_ContributorsGraph(t *testing.T) {
|
|||
dataString, isData := mockCache.Get("key2").(string)
|
||||
assert.True(t, isData)
|
||||
// Verify that JSON is actually stored in the cache.
|
||||
assert.JSONEq(t, `{"ethantkoenig@gmail.com":{"name":"Ethan Koenig","login":"","avatar_link":"https://secure.gravatar.com/avatar/b42fb195faa8c61b8d88abfefe30e9e3?d=identicon","home_link":"","total_commits":1,"weeks":{"1511654400000":{"week":1511654400000,"additions":3,"deletions":0,"commits":1}}},"jimmy.praet@telenet.be":{"name":"Jimmy Praet","login":"","avatar_link":"https://secure.gravatar.com/avatar/93c49b7c89eb156971d11161c9b52795?d=identicon","home_link":"","total_commits":1,"weeks":{"1624752000000":{"week":1624752000000,"additions":2,"deletions":0,"commits":1}}},"jon@allspice.io":{"name":"Jon","login":"","avatar_link":"https://secure.gravatar.com/avatar/00388ce725e6886f3e07c3733007289b?d=identicon","home_link":"","total_commits":1,"weeks":{"1607817600000":{"week":1607817600000,"additions":10,"deletions":0,"commits":1}}},"total":{"name":"Total","login":"","avatar_link":"","home_link":"","total_commits":3,"weeks":{"1511654400000":{"week":1511654400000,"additions":3,"deletions":0,"commits":1},"1607817600000":{"week":1607817600000,"additions":10,"deletions":0,"commits":1},"1624752000000":{"week":1624752000000,"additions":2,"deletions":0,"commits":1}}}}`, dataString)
|
||||
assert.JSONEq(t, `{"ethantkoenig@gmail.com":{"name":"Ethan Koenig","login":"","avatar_link":"/assets/img/avatar_default.png","home_link":"","total_commits":1,"weeks":{"1511654400000":{"week":1511654400000,"additions":3,"deletions":0,"commits":1}}},"jimmy.praet@telenet.be":{"name":"Jimmy Praet","login":"","avatar_link":"/assets/img/avatar_default.png","home_link":"","total_commits":1,"weeks":{"1624752000000":{"week":1624752000000,"additions":2,"deletions":0,"commits":1}}},"jon@allspice.io":{"name":"Jon","login":"","avatar_link":"/assets/img/avatar_default.png","home_link":"","total_commits":1,"weeks":{"1607817600000":{"week":1607817600000,"additions":10,"deletions":0,"commits":1}}},"total":{"name":"Total","login":"","avatar_link":"","home_link":"","total_commits":3,"weeks":{"1511654400000":{"week":1511654400000,"additions":3,"deletions":0,"commits":1},"1607817600000":{"week":1607817600000,"additions":10,"deletions":0,"commits":1},"1624752000000":{"week":1624752000000,"additions":2,"deletions":0,"commits":1}}}}`, dataString)
|
||||
|
||||
var data map[string]*ContributorData
|
||||
require.NoError(t, json.Unmarshal([]byte(dataString), &data))
|
||||
|
@ -62,7 +62,7 @@ func TestRepository_ContributorsGraph(t *testing.T) {
|
|||
|
||||
assert.EqualValues(t, &ContributorData{
|
||||
Name: "Ethan Koenig",
|
||||
AvatarLink: "https://secure.gravatar.com/avatar/b42fb195faa8c61b8d88abfefe30e9e3?d=identicon",
|
||||
AvatarLink: "/assets/img/avatar_default.png",
|
||||
TotalCommits: 1,
|
||||
Weeks: map[int64]*WeekData{
|
||||
1511654400000: {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue