code.gitea.io/gitea@v1.21.7/tests/integration/api_keys_test.go (about)

     1  // Copyright 2017 The Gogs Authors. All rights reserved.
     2  // SPDX-License-Identifier: MIT
     3  
     4  package integration
     5  
     6  import (
     7  	"fmt"
     8  	"net/http"
     9  	"net/url"
    10  	"testing"
    11  
    12  	asymkey_model "code.gitea.io/gitea/models/asymkey"
    13  	auth_model "code.gitea.io/gitea/models/auth"
    14  	"code.gitea.io/gitea/models/perm"
    15  	repo_model "code.gitea.io/gitea/models/repo"
    16  	"code.gitea.io/gitea/models/unittest"
    17  	user_model "code.gitea.io/gitea/models/user"
    18  	api "code.gitea.io/gitea/modules/structs"
    19  	"code.gitea.io/gitea/tests"
    20  
    21  	"github.com/stretchr/testify/assert"
    22  )
    23  
    24  func TestViewDeployKeysNoLogin(t *testing.T) {
    25  	defer tests.PrepareTestEnv(t)()
    26  	req := NewRequest(t, "GET", "/api/v1/repos/user2/repo1/keys")
    27  	MakeRequest(t, req, http.StatusUnauthorized)
    28  }
    29  
    30  func TestCreateDeployKeyNoLogin(t *testing.T) {
    31  	defer tests.PrepareTestEnv(t)()
    32  	req := NewRequestWithJSON(t, "POST", "/api/v1/repos/user2/repo1/keys", api.CreateKeyOption{
    33  		Title: "title",
    34  		Key:   "key",
    35  	})
    36  	MakeRequest(t, req, http.StatusUnauthorized)
    37  }
    38  
    39  func TestGetDeployKeyNoLogin(t *testing.T) {
    40  	defer tests.PrepareTestEnv(t)()
    41  	req := NewRequest(t, "GET", "/api/v1/repos/user2/repo1/keys/1")
    42  	MakeRequest(t, req, http.StatusUnauthorized)
    43  }
    44  
    45  func TestDeleteDeployKeyNoLogin(t *testing.T) {
    46  	defer tests.PrepareTestEnv(t)()
    47  	req := NewRequest(t, "DELETE", "/api/v1/repos/user2/repo1/keys/1")
    48  	MakeRequest(t, req, http.StatusUnauthorized)
    49  }
    50  
    51  func TestCreateReadOnlyDeployKey(t *testing.T) {
    52  	defer tests.PrepareTestEnv(t)()
    53  	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: "repo1"})
    54  	repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
    55  
    56  	session := loginUser(t, repoOwner.Name)
    57  	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
    58  	keysURL := fmt.Sprintf("/api/v1/repos/%s/%s/keys?token=%s", repoOwner.Name, repo.Name, token)
    59  	rawKeyBody := api.CreateKeyOption{
    60  		Title:    "read-only",
    61  		Key:      "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment\n",
    62  		ReadOnly: true,
    63  	}
    64  	req := NewRequestWithJSON(t, "POST", keysURL, rawKeyBody)
    65  	resp := MakeRequest(t, req, http.StatusCreated)
    66  
    67  	var newDeployKey api.DeployKey
    68  	DecodeJSON(t, resp, &newDeployKey)
    69  	unittest.AssertExistsAndLoadBean(t, &asymkey_model.DeployKey{
    70  		ID:      newDeployKey.ID,
    71  		Name:    rawKeyBody.Title,
    72  		Content: rawKeyBody.Key,
    73  		Mode:    perm.AccessModeRead,
    74  	})
    75  
    76  	// Using the ID of a key that does not belong to the repository must fail
    77  	{
    78  		req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/keys/%d?token=%s", repoOwner.Name, repo.Name, newDeployKey.ID, token))
    79  		MakeRequest(t, req, http.StatusOK)
    80  
    81  		session5 := loginUser(t, "user5")
    82  		token5 := getTokenForLoggedInUser(t, session5, auth_model.AccessTokenScopeWriteRepository)
    83  		req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/user5/repo4/keys/%d?token=%s", newDeployKey.ID, token5))
    84  		MakeRequest(t, req, http.StatusNotFound)
    85  	}
    86  }
    87  
    88  func TestCreateReadWriteDeployKey(t *testing.T) {
    89  	defer tests.PrepareTestEnv(t)()
    90  	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: "repo1"})
    91  	repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID})
    92  
    93  	session := loginUser(t, repoOwner.Name)
    94  	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
    95  	keysURL := fmt.Sprintf("/api/v1/repos/%s/%s/keys?token=%s", repoOwner.Name, repo.Name, token)
    96  	rawKeyBody := api.CreateKeyOption{
    97  		Title: "read-write",
    98  		Key:   "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment\n",
    99  	}
   100  	req := NewRequestWithJSON(t, "POST", keysURL, rawKeyBody)
   101  	resp := MakeRequest(t, req, http.StatusCreated)
   102  
   103  	var newDeployKey api.DeployKey
   104  	DecodeJSON(t, resp, &newDeployKey)
   105  	unittest.AssertExistsAndLoadBean(t, &asymkey_model.DeployKey{
   106  		ID:      newDeployKey.ID,
   107  		Name:    rawKeyBody.Title,
   108  		Content: rawKeyBody.Key,
   109  		Mode:    perm.AccessModeWrite,
   110  	})
   111  }
   112  
   113  func TestCreateUserKey(t *testing.T) {
   114  	defer tests.PrepareTestEnv(t)()
   115  	user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"})
   116  
   117  	session := loginUser(t, "user1")
   118  	token := url.QueryEscape(getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser))
   119  	keysURL := fmt.Sprintf("/api/v1/user/keys?token=%s", token)
   120  	keyType := "ssh-rsa"
   121  	keyContent := "AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM="
   122  	rawKeyBody := api.CreateKeyOption{
   123  		Title: "test-key",
   124  		Key:   keyType + " " + keyContent,
   125  	}
   126  	req := NewRequestWithJSON(t, "POST", keysURL, rawKeyBody)
   127  	resp := MakeRequest(t, req, http.StatusCreated)
   128  
   129  	var newPublicKey api.PublicKey
   130  	DecodeJSON(t, resp, &newPublicKey)
   131  	fingerprint, err := asymkey_model.CalcFingerprint(rawKeyBody.Key)
   132  	assert.NoError(t, err)
   133  	unittest.AssertExistsAndLoadBean(t, &asymkey_model.PublicKey{
   134  		ID:          newPublicKey.ID,
   135  		OwnerID:     user.ID,
   136  		Name:        rawKeyBody.Title,
   137  		Fingerprint: fingerprint,
   138  		Mode:        perm.AccessModeWrite,
   139  	})
   140  
   141  	// Search by fingerprint
   142  	fingerprintURL := fmt.Sprintf("/api/v1/user/keys?token=%s&fingerprint=%s", token, newPublicKey.Fingerprint)
   143  
   144  	req = NewRequest(t, "GET", fingerprintURL)
   145  	resp = MakeRequest(t, req, http.StatusOK)
   146  
   147  	var fingerprintPublicKeys []api.PublicKey
   148  	DecodeJSON(t, resp, &fingerprintPublicKeys)
   149  	assert.Equal(t, newPublicKey.Fingerprint, fingerprintPublicKeys[0].Fingerprint)
   150  	assert.Equal(t, newPublicKey.ID, fingerprintPublicKeys[0].ID)
   151  	assert.Equal(t, user.ID, fingerprintPublicKeys[0].Owner.ID)
   152  
   153  	fingerprintURL = fmt.Sprintf("/api/v1/users/%s/keys?token=%s&fingerprint=%s", user.Name, token, newPublicKey.Fingerprint)
   154  
   155  	req = NewRequest(t, "GET", fingerprintURL)
   156  	resp = MakeRequest(t, req, http.StatusOK)
   157  
   158  	DecodeJSON(t, resp, &fingerprintPublicKeys)
   159  	assert.Equal(t, newPublicKey.Fingerprint, fingerprintPublicKeys[0].Fingerprint)
   160  	assert.Equal(t, newPublicKey.ID, fingerprintPublicKeys[0].ID)
   161  	assert.Equal(t, user.ID, fingerprintPublicKeys[0].Owner.ID)
   162  
   163  	// Fail search by fingerprint
   164  	fingerprintURL = fmt.Sprintf("/api/v1/user/keys?token=%s&fingerprint=%sA", token, newPublicKey.Fingerprint)
   165  
   166  	req = NewRequest(t, "GET", fingerprintURL)
   167  	resp = MakeRequest(t, req, http.StatusOK)
   168  
   169  	DecodeJSON(t, resp, &fingerprintPublicKeys)
   170  	assert.Len(t, fingerprintPublicKeys, 0)
   171  
   172  	// Fail searching for wrong users key
   173  	fingerprintURL = fmt.Sprintf("/api/v1/users/%s/keys?token=%s&fingerprint=%s", "user2", token, newPublicKey.Fingerprint)
   174  	req = NewRequest(t, "GET", fingerprintURL)
   175  	resp = MakeRequest(t, req, http.StatusOK)
   176  
   177  	DecodeJSON(t, resp, &fingerprintPublicKeys)
   178  	assert.Len(t, fingerprintPublicKeys, 0)
   179  
   180  	// Now login as user 2
   181  	session2 := loginUser(t, "user2")
   182  	token2 := url.QueryEscape(getTokenForLoggedInUser(t, session2, auth_model.AccessTokenScopeWriteUser))
   183  
   184  	// Should find key even though not ours, but we shouldn't know whose it is
   185  	fingerprintURL = fmt.Sprintf("/api/v1/user/keys?token=%s&fingerprint=%s", token2, newPublicKey.Fingerprint)
   186  	req = NewRequest(t, "GET", fingerprintURL)
   187  	resp = MakeRequest(t, req, http.StatusOK)
   188  
   189  	DecodeJSON(t, resp, &fingerprintPublicKeys)
   190  	assert.Equal(t, newPublicKey.Fingerprint, fingerprintPublicKeys[0].Fingerprint)
   191  	assert.Equal(t, newPublicKey.ID, fingerprintPublicKeys[0].ID)
   192  	assert.Nil(t, fingerprintPublicKeys[0].Owner)
   193  
   194  	// Should find key even though not ours, but we shouldn't know whose it is
   195  	fingerprintURL = fmt.Sprintf("/api/v1/users/%s/keys?token=%s&fingerprint=%s", user.Name, token2, newPublicKey.Fingerprint)
   196  
   197  	req = NewRequest(t, "GET", fingerprintURL)
   198  	resp = MakeRequest(t, req, http.StatusOK)
   199  
   200  	DecodeJSON(t, resp, &fingerprintPublicKeys)
   201  	assert.Equal(t, newPublicKey.Fingerprint, fingerprintPublicKeys[0].Fingerprint)
   202  	assert.Equal(t, newPublicKey.ID, fingerprintPublicKeys[0].ID)
   203  	assert.Nil(t, fingerprintPublicKeys[0].Owner)
   204  
   205  	// Fail when searching for key if it is not ours
   206  	fingerprintURL = fmt.Sprintf("/api/v1/users/%s/keys?token=%s&fingerprint=%s", "user2", token2, newPublicKey.Fingerprint)
   207  	req = NewRequest(t, "GET", fingerprintURL)
   208  	resp = MakeRequest(t, req, http.StatusOK)
   209  
   210  	DecodeJSON(t, resp, &fingerprintPublicKeys)
   211  	assert.Len(t, fingerprintPublicKeys, 0)
   212  }