code.gitea.io/gitea@v1.22.3/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", repoOwner.Name, repo.Name) 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 AddTokenAuth(token) 66 resp := MakeRequest(t, req, http.StatusCreated) 67 68 var newDeployKey api.DeployKey 69 DecodeJSON(t, resp, &newDeployKey) 70 unittest.AssertExistsAndLoadBean(t, &asymkey_model.DeployKey{ 71 ID: newDeployKey.ID, 72 Name: rawKeyBody.Title, 73 Content: rawKeyBody.Key, 74 Mode: perm.AccessModeRead, 75 }) 76 77 // Using the ID of a key that does not belong to the repository must fail 78 { 79 req := NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/%s/%s/keys/%d", repoOwner.Name, repo.Name, newDeployKey.ID)). 80 AddTokenAuth(token) 81 MakeRequest(t, req, http.StatusOK) 82 83 session5 := loginUser(t, "user5") 84 token5 := getTokenForLoggedInUser(t, session5, auth_model.AccessTokenScopeWriteRepository) 85 req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/repos/user5/repo4/keys/%d", newDeployKey.ID)). 86 AddTokenAuth(token5) 87 MakeRequest(t, req, http.StatusNotFound) 88 } 89 } 90 91 func TestCreateReadWriteDeployKey(t *testing.T) { 92 defer tests.PrepareTestEnv(t)() 93 repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{Name: "repo1"}) 94 repoOwner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: repo.OwnerID}) 95 96 session := loginUser(t, repoOwner.Name) 97 token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository) 98 keysURL := fmt.Sprintf("/api/v1/repos/%s/%s/keys", repoOwner.Name, repo.Name) 99 rawKeyBody := api.CreateKeyOption{ 100 Title: "read-write", 101 Key: "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM= nocomment\n", 102 } 103 req := NewRequestWithJSON(t, "POST", keysURL, rawKeyBody). 104 AddTokenAuth(token) 105 resp := MakeRequest(t, req, http.StatusCreated) 106 107 var newDeployKey api.DeployKey 108 DecodeJSON(t, resp, &newDeployKey) 109 unittest.AssertExistsAndLoadBean(t, &asymkey_model.DeployKey{ 110 ID: newDeployKey.ID, 111 Name: rawKeyBody.Title, 112 Content: rawKeyBody.Key, 113 Mode: perm.AccessModeWrite, 114 }) 115 } 116 117 func TestCreateUserKey(t *testing.T) { 118 defer tests.PrepareTestEnv(t)() 119 user := unittest.AssertExistsAndLoadBean(t, &user_model.User{Name: "user1"}) 120 121 session := loginUser(t, "user1") 122 token := url.QueryEscape(getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteUser)) 123 keyType := "ssh-rsa" 124 keyContent := "AAAAB3NzaC1yc2EAAAADAQABAAABgQC4cn+iXnA4KvcQYSV88vGn0Yi91vG47t1P7okprVmhNTkipNRIHWr6WdCO4VDr/cvsRkuVJAsLO2enwjGWWueOO6BodiBgyAOZ/5t5nJNMCNuLGT5UIo/RI1b0WRQwxEZTRjt6mFNw6lH14wRd8ulsr9toSWBPMOGWoYs1PDeDL0JuTjL+tr1SZi/EyxCngpYszKdXllJEHyI79KQgeD0Vt3pTrkbNVTOEcCNqZePSVmUH8X8Vhugz3bnE0/iE9Pb5fkWO9c4AnM1FgI/8Bvp27Fw2ShryIXuR6kKvUqhVMTuOSDHwu6A8jLE5Owt3GAYugDpDYuwTVNGrHLXKpPzrGGPE/jPmaLCMZcsdkec95dYeU3zKODEm8UQZFhmJmDeWVJ36nGrGZHL4J5aTTaeFUJmmXDaJYiJ+K2/ioKgXqnXvltu0A9R8/LGy4nrTJRr4JMLuJFoUXvGm1gXQ70w2LSpk6yl71RNC0hCtsBe8BP8IhYCM0EP5jh7eCMQZNvM=" 125 rawKeyBody := api.CreateKeyOption{ 126 Title: "test-key", 127 Key: keyType + " " + keyContent, 128 } 129 req := NewRequestWithJSON(t, "POST", "/api/v1/user/keys", rawKeyBody). 130 AddTokenAuth(token) 131 resp := MakeRequest(t, req, http.StatusCreated) 132 133 var newPublicKey api.PublicKey 134 DecodeJSON(t, resp, &newPublicKey) 135 fingerprint, err := asymkey_model.CalcFingerprint(rawKeyBody.Key) 136 assert.NoError(t, err) 137 unittest.AssertExistsAndLoadBean(t, &asymkey_model.PublicKey{ 138 ID: newPublicKey.ID, 139 OwnerID: user.ID, 140 Name: rawKeyBody.Title, 141 Fingerprint: fingerprint, 142 Mode: perm.AccessModeWrite, 143 }) 144 145 // Search by fingerprint 146 req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/keys?fingerprint=%s", newPublicKey.Fingerprint)). 147 AddTokenAuth(token) 148 resp = MakeRequest(t, req, http.StatusOK) 149 150 var fingerprintPublicKeys []api.PublicKey 151 DecodeJSON(t, resp, &fingerprintPublicKeys) 152 assert.Equal(t, newPublicKey.Fingerprint, fingerprintPublicKeys[0].Fingerprint) 153 assert.Equal(t, newPublicKey.ID, fingerprintPublicKeys[0].ID) 154 assert.Equal(t, user.ID, fingerprintPublicKeys[0].Owner.ID) 155 156 req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/keys?fingerprint=%s", user.Name, newPublicKey.Fingerprint)). 157 AddTokenAuth(token) 158 resp = MakeRequest(t, req, http.StatusOK) 159 160 DecodeJSON(t, resp, &fingerprintPublicKeys) 161 assert.Equal(t, newPublicKey.Fingerprint, fingerprintPublicKeys[0].Fingerprint) 162 assert.Equal(t, newPublicKey.ID, fingerprintPublicKeys[0].ID) 163 assert.Equal(t, user.ID, fingerprintPublicKeys[0].Owner.ID) 164 165 // Fail search by fingerprint 166 req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/keys?fingerprint=%sA", newPublicKey.Fingerprint)). 167 AddTokenAuth(token) 168 resp = MakeRequest(t, req, http.StatusOK) 169 170 DecodeJSON(t, resp, &fingerprintPublicKeys) 171 assert.Len(t, fingerprintPublicKeys, 0) 172 173 // Fail searching for wrong users key 174 req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/keys?fingerprint=%s", "user2", newPublicKey.Fingerprint)). 175 AddTokenAuth(token) 176 resp = MakeRequest(t, req, http.StatusOK) 177 178 DecodeJSON(t, resp, &fingerprintPublicKeys) 179 assert.Len(t, fingerprintPublicKeys, 0) 180 181 // Now login as user 2 182 session2 := loginUser(t, "user2") 183 token2 := getTokenForLoggedInUser(t, session2, auth_model.AccessTokenScopeWriteUser) 184 185 // Should find key even though not ours, but we shouldn't know whose it is 186 req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/user/keys?fingerprint=%s", newPublicKey.Fingerprint)). 187 AddTokenAuth(token2) 188 resp = MakeRequest(t, req, http.StatusOK) 189 190 DecodeJSON(t, resp, &fingerprintPublicKeys) 191 assert.Equal(t, newPublicKey.Fingerprint, fingerprintPublicKeys[0].Fingerprint) 192 assert.Equal(t, newPublicKey.ID, fingerprintPublicKeys[0].ID) 193 assert.Nil(t, fingerprintPublicKeys[0].Owner) 194 195 // Should find key even though not ours, but we shouldn't know whose it is 196 req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/keys?fingerprint=%s", user.Name, newPublicKey.Fingerprint)). 197 AddTokenAuth(token2) 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 req = NewRequest(t, "GET", fmt.Sprintf("/api/v1/users/%s/keys?fingerprint=%s", "user2", newPublicKey.Fingerprint)). 207 AddTokenAuth(token2) 208 resp = MakeRequest(t, req, http.StatusOK) 209 210 DecodeJSON(t, resp, &fingerprintPublicKeys) 211 assert.Len(t, fingerprintPublicKeys, 0) 212 }