code.gitea.io/gitea@v1.21.7/routers/private/actions.go (about)

     1  // Copyright 2023 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package private
     5  
     6  import (
     7  	"errors"
     8  	"fmt"
     9  	"net/http"
    10  	"strings"
    11  
    12  	actions_model "code.gitea.io/gitea/models/actions"
    13  	repo_model "code.gitea.io/gitea/models/repo"
    14  	user_model "code.gitea.io/gitea/models/user"
    15  	"code.gitea.io/gitea/modules/context"
    16  	"code.gitea.io/gitea/modules/json"
    17  	"code.gitea.io/gitea/modules/log"
    18  	"code.gitea.io/gitea/modules/private"
    19  	"code.gitea.io/gitea/modules/util"
    20  )
    21  
    22  // GenerateActionsRunnerToken generates a new runner token for a given scope
    23  func GenerateActionsRunnerToken(ctx *context.PrivateContext) {
    24  	var genRequest private.GenerateTokenRequest
    25  	rd := ctx.Req.Body
    26  	defer rd.Close()
    27  
    28  	if err := json.NewDecoder(rd).Decode(&genRequest); err != nil {
    29  		log.Error("%v", err)
    30  		ctx.JSON(http.StatusInternalServerError, private.Response{
    31  			Err: err.Error(),
    32  		})
    33  		return
    34  	}
    35  
    36  	owner, repo, err := parseScope(ctx, genRequest.Scope)
    37  	if err != nil {
    38  		log.Error("%v", err)
    39  		ctx.JSON(http.StatusInternalServerError, private.Response{
    40  			Err: err.Error(),
    41  		})
    42  	}
    43  
    44  	token, err := actions_model.GetLastestRunnerToken(ctx, owner, repo)
    45  	if errors.Is(err, util.ErrNotExist) || (token != nil && !token.IsActive) {
    46  		token, err = actions_model.NewRunnerToken(ctx, owner, repo)
    47  		if err != nil {
    48  			err := fmt.Sprintf("error while creating runner token: %v", err)
    49  			log.Error("%v", err)
    50  			ctx.JSON(http.StatusInternalServerError, private.Response{
    51  				Err: err,
    52  			})
    53  			return
    54  		}
    55  	} else if err != nil {
    56  		err := fmt.Sprintf("could not get unactivated runner token: %v", err)
    57  		log.Error("%v", err)
    58  		ctx.JSON(http.StatusInternalServerError, private.Response{
    59  			Err: err,
    60  		})
    61  		return
    62  	}
    63  
    64  	ctx.PlainText(http.StatusOK, token.Token)
    65  }
    66  
    67  func parseScope(ctx *context.PrivateContext, scope string) (ownerID, repoID int64, err error) {
    68  	ownerID = 0
    69  	repoID = 0
    70  	if scope == "" {
    71  		return ownerID, repoID, nil
    72  	}
    73  
    74  	ownerName, repoName, found := strings.Cut(scope, "/")
    75  
    76  	u, err := user_model.GetUserByName(ctx, ownerName)
    77  	if err != nil {
    78  		return ownerID, repoID, err
    79  	}
    80  	ownerID = u.ID
    81  
    82  	if !found {
    83  		return ownerID, repoID, nil
    84  	}
    85  
    86  	r, err := repo_model.GetRepositoryByName(u.ID, repoName)
    87  	if err != nil {
    88  		return ownerID, repoID, err
    89  	}
    90  	repoID = r.ID
    91  	return ownerID, repoID, nil
    92  }