code.gitea.io/gitea@v1.19.3/modules/private/serv.go (about)

     1  // Copyright 2019 The Gitea Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package private
     5  
     6  import (
     7  	"context"
     8  	"fmt"
     9  	"net/http"
    10  	"net/url"
    11  
    12  	asymkey_model "code.gitea.io/gitea/models/asymkey"
    13  	"code.gitea.io/gitea/models/perm"
    14  	user_model "code.gitea.io/gitea/models/user"
    15  	"code.gitea.io/gitea/modules/json"
    16  	"code.gitea.io/gitea/modules/setting"
    17  )
    18  
    19  // KeyAndOwner is the response from ServNoCommand
    20  type KeyAndOwner struct {
    21  	Key   *asymkey_model.PublicKey `json:"key"`
    22  	Owner *user_model.User         `json:"user"`
    23  }
    24  
    25  // ServNoCommand returns information about the provided key
    26  func ServNoCommand(ctx context.Context, keyID int64) (*asymkey_model.PublicKey, *user_model.User, error) {
    27  	reqURL := setting.LocalURL + fmt.Sprintf("api/internal/serv/none/%d",
    28  		keyID)
    29  	resp, err := newInternalRequest(ctx, reqURL, "GET").Response()
    30  	if err != nil {
    31  		return nil, nil, err
    32  	}
    33  	defer resp.Body.Close()
    34  	if resp.StatusCode != http.StatusOK {
    35  		return nil, nil, fmt.Errorf("%s", decodeJSONError(resp).Err)
    36  	}
    37  
    38  	var keyAndOwner KeyAndOwner
    39  	if err := json.NewDecoder(resp.Body).Decode(&keyAndOwner); err != nil {
    40  		return nil, nil, err
    41  	}
    42  	return keyAndOwner.Key, keyAndOwner.Owner, nil
    43  }
    44  
    45  // ServCommandResults are the results of a call to the private route serv
    46  type ServCommandResults struct {
    47  	IsWiki      bool
    48  	DeployKeyID int64
    49  	KeyID       int64  // public key
    50  	KeyName     string // this field is ambiguous, it can be the name of DeployKey, or the name of the PublicKey
    51  	UserName    string
    52  	UserEmail   string
    53  	UserID      int64
    54  	OwnerName   string
    55  	RepoName    string
    56  	RepoID      int64
    57  }
    58  
    59  // ErrServCommand is an error returned from ServCommmand.
    60  type ErrServCommand struct {
    61  	Results    ServCommandResults
    62  	Err        string
    63  	StatusCode int
    64  }
    65  
    66  func (err ErrServCommand) Error() string {
    67  	return err.Err
    68  }
    69  
    70  // IsErrServCommand checks if an error is a ErrServCommand.
    71  func IsErrServCommand(err error) bool {
    72  	_, ok := err.(ErrServCommand)
    73  	return ok
    74  }
    75  
    76  // ServCommand preps for a serv call
    77  func ServCommand(ctx context.Context, keyID int64, ownerName, repoName string, mode perm.AccessMode, verbs ...string) (*ServCommandResults, error) {
    78  	reqURL := setting.LocalURL + fmt.Sprintf("api/internal/serv/command/%d/%s/%s?mode=%d",
    79  		keyID,
    80  		url.PathEscape(ownerName),
    81  		url.PathEscape(repoName),
    82  		mode)
    83  	for _, verb := range verbs {
    84  		if verb != "" {
    85  			reqURL += fmt.Sprintf("&verb=%s", url.QueryEscape(verb))
    86  		}
    87  	}
    88  
    89  	resp, err := newInternalRequest(ctx, reqURL, "GET").Response()
    90  	if err != nil {
    91  		return nil, err
    92  	}
    93  	defer resp.Body.Close()
    94  
    95  	if resp.StatusCode != http.StatusOK {
    96  		var errServCommand ErrServCommand
    97  		if err := json.NewDecoder(resp.Body).Decode(&errServCommand); err != nil {
    98  			return nil, err
    99  		}
   100  		errServCommand.StatusCode = resp.StatusCode
   101  		return nil, errServCommand
   102  	}
   103  	var results ServCommandResults
   104  	if err := json.NewDecoder(resp.Body).Decode(&results); err != nil {
   105  		return nil, err
   106  	}
   107  	return &results, nil
   108  }