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 }