Skip to content

Commit 6e876cc

Browse files
committed
incorporate logic into userIDFromToken instead of a standalone function
1 parent 91b01ea commit 6e876cc

File tree

2 files changed

+31
-49
lines changed

2 files changed

+31
-49
lines changed

services/actions/auth.go

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,12 @@ func ParseAuthorizationToken(req *http.Request) (int64, error) {
8383
return 0, fmt.Errorf("split token failed")
8484
}
8585

86-
token, err := jwt.ParseWithClaims(parts[1], &actionsClaims{}, func(t *jwt.Token) (any, error) {
86+
return TokenToTaskID(parts[1])
87+
}
88+
89+
// TokenToTaskID returns the TaskID associated with the provided JWT token
90+
func TokenToTaskID(token string) (int64, error) {
91+
parsedToken, err := jwt.ParseWithClaims(token, &actionsClaims{}, func(t *jwt.Token) (any, error) {
8792
if _, ok := t.Method.(*jwt.SigningMethodHMAC); !ok {
8893
return nil, fmt.Errorf("unexpected signing method: %v", t.Header["alg"])
8994
}
@@ -93,8 +98,8 @@ func ParseAuthorizationToken(req *http.Request) (int64, error) {
9398
return 0, err
9499
}
95100

96-
c, ok := token.Claims.(*actionsClaims)
97-
if !token.Valid || !ok {
101+
c, ok := parsedToken.Claims.(*actionsClaims)
102+
if !parsedToken.Valid || !ok {
98103
return 0, fmt.Errorf("invalid token claim")
99104
}
100105

services/auth/oauth2.go

Lines changed: 23 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ package auth
66

77
import (
88
"context"
9-
"errors"
109
"net/http"
1110
"strings"
1211
"time"
@@ -17,7 +16,6 @@ import (
1716
"code.gitea.io/gitea/modules/log"
1817
"code.gitea.io/gitea/modules/setting"
1918
"code.gitea.io/gitea/modules/timeutil"
20-
"code.gitea.io/gitea/modules/util"
2119
"code.gitea.io/gitea/modules/web/middleware"
2220
"code.gitea.io/gitea/services/actions"
2321
"code.gitea.io/gitea/services/oauth2_provider"
@@ -57,6 +55,18 @@ func CheckOAuthAccessToken(ctx context.Context, accessToken string) int64 {
5755
return grant.UserID
5856
}
5957

58+
// CheckTaskID verifies that the TaskID corresponds to a running task
59+
func CheckTaskID(ctx context.Context, taskID int64) bool {
60+
// Verify the task exists
61+
task, err := actions_model.GetTaskByID(ctx, taskID)
62+
if err != nil {
63+
return false
64+
}
65+
66+
// Verify that it's running
67+
return task.Status == actions_model.StatusRunning
68+
}
69+
6070
// OAuth2 implements the Auth interface and authenticates requests
6171
// (API requests only) by looking for an OAuth token in query parameters or the
6272
// "Authorization" header.
@@ -100,6 +110,16 @@ func parseToken(req *http.Request) (string, bool) {
100110
func (o *OAuth2) userIDFromToken(ctx context.Context, tokenSHA string, store DataStore) int64 {
101111
// Let's see if token is valid.
102112
if strings.Contains(tokenSHA, ".") {
113+
// First attempt to decode an actions JWT, returning the actions user
114+
if taskID, err := actions.TokenToTaskID(tokenSHA); err == nil {
115+
if CheckTaskID(ctx, taskID) {
116+
store.GetData()["IsActionsToken"] = true
117+
store.GetData()["ActionsTaskID"] = taskID
118+
return user_model.ActionsUserID
119+
}
120+
}
121+
122+
// Otherwise, check if this is an OAuth access token
103123
uid := CheckOAuthAccessToken(ctx, tokenSHA)
104124
if uid != 0 {
105125
store.GetData()["IsApiToken"] = true
@@ -134,40 +154,6 @@ func (o *OAuth2) userIDFromToken(ctx context.Context, tokenSHA string, store Dat
134154
return t.UID
135155
}
136156

137-
// parseActionJWT identifies actions runner JWTs that look like an
138-
// OAuth token, but needs to be parsed by its code
139-
func parseActionsJWT(req *http.Request, store DataStore) (*user_model.User, error) {
140-
taskID, err := actions.ParseAuthorizationToken(req)
141-
if err != nil || taskID == 0 {
142-
return nil, nil
143-
}
144-
145-
// Verify the task exists
146-
task, err := actions_model.GetTaskByID(req.Context(), taskID)
147-
if err != nil {
148-
if errors.Is(err, util.ErrNotExist) {
149-
return nil, nil
150-
}
151-
152-
return nil, err
153-
}
154-
155-
// Verify that it's running
156-
if task.Status != actions_model.StatusRunning {
157-
return nil, nil
158-
}
159-
160-
store.GetData()["IsActionsToken"] = true
161-
store.GetData()["ActionsTaskID"] = taskID
162-
163-
user, err := user_model.GetPossibleUserByID(req.Context(), user_model.ActionsUserID)
164-
if err != nil {
165-
return nil, err
166-
}
167-
168-
return user, nil
169-
}
170-
171157
// Verify extracts the user ID from the OAuth token in the query parameters
172158
// or the "Authorization" header and returns the corresponding user object for that ID.
173159
// If verification is successful returns an existing user object.
@@ -179,15 +165,6 @@ func (o *OAuth2) Verify(req *http.Request, w http.ResponseWriter, store DataStor
179165
return nil, nil
180166
}
181167

182-
user, err := parseActionsJWT(req, store)
183-
if err != nil {
184-
return nil, err
185-
}
186-
187-
if user != nil {
188-
return user, nil
189-
}
190-
191168
token, ok := parseToken(req)
192169
if !ok {
193170
return nil, nil
@@ -200,7 +177,7 @@ func (o *OAuth2) Verify(req *http.Request, w http.ResponseWriter, store DataStor
200177
}
201178
log.Trace("OAuth2 Authorization: Found token for user[%d]", id)
202179

203-
user, err = user_model.GetPossibleUserByID(req.Context(), id)
180+
user, err := user_model.GetPossibleUserByID(req.Context(), id)
204181
if err != nil {
205182
if !user_model.IsErrUserNotExist(err) {
206183
log.Error("GetUserByName: %v", err)

0 commit comments

Comments
 (0)