code.gitea.io/gitea@v1.22.3/tests/integration/api_gpg_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  	"net/http"
     8  	"net/http/httptest"
     9  	"strconv"
    10  	"testing"
    11  
    12  	auth_model "code.gitea.io/gitea/models/auth"
    13  	api "code.gitea.io/gitea/modules/structs"
    14  	"code.gitea.io/gitea/tests"
    15  
    16  	"github.com/stretchr/testify/assert"
    17  )
    18  
    19  type makeRequestFunc func(testing.TB, *RequestWrapper, int) *httptest.ResponseRecorder
    20  
    21  func TestGPGKeys(t *testing.T) {
    22  	defer tests.PrepareTestEnv(t)()
    23  	session := loginUser(t, "user2")
    24  	token := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository)
    25  	tokenWithGPGKeyScope := getTokenForLoggedInUser(t, session, auth_model.AccessTokenScopeWriteRepository, auth_model.AccessTokenScopeWriteUser)
    26  
    27  	tt := []struct {
    28  		name        string
    29  		makeRequest makeRequestFunc
    30  		token       string
    31  		results     []int
    32  	}{
    33  		{
    34  			name: "NoLogin", makeRequest: MakeRequest, token: "",
    35  			results: []int{http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized, http.StatusUnauthorized},
    36  		},
    37  		{
    38  			name: "LoggedAsUser2", makeRequest: session.MakeRequest, token: token,
    39  			results: []int{http.StatusForbidden, http.StatusForbidden, http.StatusForbidden, http.StatusForbidden, http.StatusForbidden, http.StatusForbidden, http.StatusForbidden, http.StatusForbidden, http.StatusForbidden},
    40  		},
    41  		{
    42  			name: "LoggedAsUser2WithScope", makeRequest: session.MakeRequest, token: tokenWithGPGKeyScope,
    43  			results: []int{http.StatusOK, http.StatusOK, http.StatusNotFound, http.StatusNoContent, http.StatusUnprocessableEntity, http.StatusNotFound, http.StatusCreated, http.StatusNotFound, http.StatusCreated},
    44  		},
    45  	}
    46  
    47  	for _, tc := range tt {
    48  		// Basic test on result code
    49  		t.Run(tc.name, func(t *testing.T) {
    50  			t.Run("ViewOwnGPGKeys", func(t *testing.T) {
    51  				testViewOwnGPGKeys(t, tc.makeRequest, tc.token, tc.results[0])
    52  			})
    53  			t.Run("ViewGPGKeys", func(t *testing.T) {
    54  				testViewGPGKeys(t, tc.makeRequest, tc.token, tc.results[1])
    55  			})
    56  			t.Run("GetGPGKey", func(t *testing.T) {
    57  				testGetGPGKey(t, tc.makeRequest, tc.token, tc.results[2])
    58  			})
    59  			t.Run("DeleteGPGKey", func(t *testing.T) {
    60  				testDeleteGPGKey(t, tc.makeRequest, tc.token, tc.results[3])
    61  			})
    62  
    63  			t.Run("CreateInvalidGPGKey", func(t *testing.T) {
    64  				testCreateInvalidGPGKey(t, tc.makeRequest, tc.token, tc.results[4])
    65  			})
    66  			t.Run("CreateNoneRegistredEmailGPGKey", func(t *testing.T) {
    67  				testCreateNoneRegistredEmailGPGKey(t, tc.makeRequest, tc.token, tc.results[5])
    68  			})
    69  			t.Run("CreateValidGPGKey", func(t *testing.T) {
    70  				testCreateValidGPGKey(t, tc.makeRequest, tc.token, tc.results[6])
    71  			})
    72  			t.Run("CreateValidSecondaryEmailGPGKeyNotActivated", func(t *testing.T) {
    73  				testCreateValidSecondaryEmailGPGKey(t, tc.makeRequest, tc.token, tc.results[7])
    74  			})
    75  		})
    76  	}
    77  
    78  	// Check state after basic add
    79  	t.Run("CheckState", func(t *testing.T) {
    80  		var keys []*api.GPGKey
    81  
    82  		req := NewRequest(t, "GET", "/api/v1/user/gpg_keys"). // GET all keys
    83  									AddTokenAuth(tokenWithGPGKeyScope)
    84  		resp := MakeRequest(t, req, http.StatusOK)
    85  		DecodeJSON(t, resp, &keys)
    86  		assert.Len(t, keys, 1)
    87  
    88  		primaryKey1 := keys[0] // Primary key 1
    89  		assert.EqualValues(t, "38EA3BCED732982C", primaryKey1.KeyID)
    90  		assert.Len(t, primaryKey1.Emails, 1)
    91  		assert.EqualValues(t, "user2@example.com", primaryKey1.Emails[0].Email)
    92  		assert.True(t, primaryKey1.Emails[0].Verified)
    93  
    94  		subKey := primaryKey1.SubsKey[0] // Subkey of 38EA3BCED732982C
    95  		assert.EqualValues(t, "70D7C694D17D03AD", subKey.KeyID)
    96  		assert.Empty(t, subKey.Emails)
    97  
    98  		var key api.GPGKey
    99  		req = NewRequest(t, "GET", "/api/v1/user/gpg_keys/"+strconv.FormatInt(primaryKey1.ID, 10)). // Primary key 1
   100  														AddTokenAuth(tokenWithGPGKeyScope)
   101  		resp = MakeRequest(t, req, http.StatusOK)
   102  		DecodeJSON(t, resp, &key)
   103  		assert.EqualValues(t, "38EA3BCED732982C", key.KeyID)
   104  		assert.Len(t, key.Emails, 1)
   105  		assert.EqualValues(t, "user2@example.com", key.Emails[0].Email)
   106  		assert.True(t, key.Emails[0].Verified)
   107  
   108  		req = NewRequest(t, "GET", "/api/v1/user/gpg_keys/"+strconv.FormatInt(subKey.ID, 10)). // Subkey of 38EA3BCED732982C
   109  													AddTokenAuth(tokenWithGPGKeyScope)
   110  		resp = MakeRequest(t, req, http.StatusOK)
   111  		DecodeJSON(t, resp, &key)
   112  		assert.EqualValues(t, "70D7C694D17D03AD", key.KeyID)
   113  		assert.Empty(t, key.Emails)
   114  	})
   115  
   116  	// Check state after basic add
   117  	t.Run("CheckCommits", func(t *testing.T) {
   118  		t.Run("NotSigned", func(t *testing.T) {
   119  			var branch api.Branch
   120  			req := NewRequest(t, "GET", "/api/v1/repos/user2/repo16/branches/not-signed").
   121  				AddTokenAuth(token)
   122  			resp := MakeRequest(t, req, http.StatusOK)
   123  			DecodeJSON(t, resp, &branch)
   124  			assert.False(t, branch.Commit.Verification.Verified)
   125  		})
   126  
   127  		t.Run("SignedWithNotValidatedEmail", func(t *testing.T) {
   128  			var branch api.Branch
   129  			req := NewRequest(t, "GET", "/api/v1/repos/user2/repo16/branches/good-sign-not-yet-validated").
   130  				AddTokenAuth(token)
   131  			resp := MakeRequest(t, req, http.StatusOK)
   132  			DecodeJSON(t, resp, &branch)
   133  			assert.False(t, branch.Commit.Verification.Verified)
   134  		})
   135  
   136  		t.Run("SignedWithValidEmail", func(t *testing.T) {
   137  			var branch api.Branch
   138  			req := NewRequest(t, "GET", "/api/v1/repos/user2/repo16/branches/good-sign").
   139  				AddTokenAuth(token)
   140  			resp := MakeRequest(t, req, http.StatusOK)
   141  			DecodeJSON(t, resp, &branch)
   142  			assert.True(t, branch.Commit.Verification.Verified)
   143  		})
   144  	})
   145  }
   146  
   147  func testViewOwnGPGKeys(t *testing.T, makeRequest makeRequestFunc, token string, expected int) {
   148  	req := NewRequest(t, "GET", "/api/v1/user/gpg_keys").
   149  		AddTokenAuth(token)
   150  	makeRequest(t, req, expected)
   151  }
   152  
   153  func testViewGPGKeys(t *testing.T, makeRequest makeRequestFunc, token string, expected int) {
   154  	req := NewRequest(t, "GET", "/api/v1/users/user2/gpg_keys").
   155  		AddTokenAuth(token)
   156  	makeRequest(t, req, expected)
   157  }
   158  
   159  func testGetGPGKey(t *testing.T, makeRequest makeRequestFunc, token string, expected int) {
   160  	req := NewRequest(t, "GET", "/api/v1/user/gpg_keys/1").
   161  		AddTokenAuth(token)
   162  	makeRequest(t, req, expected)
   163  }
   164  
   165  func testDeleteGPGKey(t *testing.T, makeRequest makeRequestFunc, token string, expected int) {
   166  	req := NewRequest(t, "DELETE", "/api/v1/user/gpg_keys/1").
   167  		AddTokenAuth(token)
   168  	makeRequest(t, req, expected)
   169  }
   170  
   171  func testCreateGPGKey(t *testing.T, makeRequest makeRequestFunc, token string, expected int, publicKey string) {
   172  	req := NewRequestWithJSON(t, "POST", "/api/v1/user/gpg_keys", api.CreateGPGKeyOption{
   173  		ArmoredKey: publicKey,
   174  	}).AddTokenAuth(token)
   175  	makeRequest(t, req, expected)
   176  }
   177  
   178  func testCreateInvalidGPGKey(t *testing.T, makeRequest makeRequestFunc, token string, expected int) {
   179  	testCreateGPGKey(t, makeRequest, token, expected, "invalid_key")
   180  }
   181  
   182  func testCreateNoneRegistredEmailGPGKey(t *testing.T, makeRequest makeRequestFunc, token string, expected int) {
   183  	testCreateGPGKey(t, makeRequest, token, expected, `-----BEGIN PGP PUBLIC KEY BLOCK-----
   184  
   185  mQENBFmGUygBCACjCNbKvMGgp0fd5vyFW9olE1CLCSyyF9gQN2hSuzmZLuAZF2Kh
   186  dCMCG2T1UwzUB/yWUFWJ2BtCwSjuaRv+cGohqEy6bhEBV90peGA33lHfjx7wP25O
   187  7moAphDOTZtDj1AZfCh/PTcJut8Lc0eRDMhNyp/bYtO7SHNT1Hr6rrCV/xEtSAvR
   188  3b148/tmIBiSadaLwc558KU3ucjnW5RVGins3AjBZ+TuT4XXVH/oeLSeXPSJ5rt1
   189  rHwaseslMqZ4AbvwFLx5qn1OC9rEQv/F548QsA8m0IntLjoPon+6wcubA9Gra21c
   190  Fp6aRYl9x7fiqXDLg8i3s2nKdV7+e6as6Tp9ABEBAAG0FG5vdGtub3duQGV4YW1w
   191  bGUuY29tiQEcBBABAgAGBQJZhlMoAAoJEC8+pvYULDtte/wH/2JNrhmHwDY+hMj0
   192  batIK4HICnkKxjIgbha80P2Ao08NkzSge58fsxiKDFYAQjHui+ZAw4dq79Ax9AOO
   193  Iv2GS9+DUfWhrb6RF+vNuJldFzcI0rTW/z2q+XGKrUCwN3khJY5XngHfQQrdBtMK
   194  qsoUXz/5B8g422RTbo/SdPsyYAV6HeLLeV3rdgjI1fpaW0seZKHeTXQb/HvNeuPg
   195  qz+XV1g6Gdqa1RjDOaX7A8elVKxrYq3LBtc93FW+grBde8n7JL0zPM3DY+vJ0IJZ
   196  INx/MmBfmtCq05FqNclvU+sj2R3N1JJOtBOjZrJHQbJhzoILou8AkxeX1A+q9OAz
   197  1geiY5E=
   198  =TkP3
   199  -----END PGP PUBLIC KEY BLOCK-----`)
   200  }
   201  
   202  func testCreateValidGPGKey(t *testing.T, makeRequest makeRequestFunc, token string, expected int) {
   203  	// User2 <user2@example.com> //primary & activated
   204  	testCreateGPGKey(t, makeRequest, token, expected, `-----BEGIN PGP PUBLIC KEY BLOCK-----
   205  
   206  mQENBFmGVsMBCACuxgZ7W7rI9xN08Y4M7B8yx/6/I4Slm94+wXf8YNRvAyqj30dW
   207  VJhyBcnfNRDLKSQp5o/hhfDkCgdqBjLa1PnHlGS3PXJc0hP/FyYPD2BFvNMPpCYS
   208  eu3T1qKSNXm6X0XOWD2LIrdiDC8HaI9FqZVMI/srMK2CF8XCL2m67W1FuoPlWzod
   209  5ORy0IZB7spoF0xihmcgnEGElRmdo5w/vkGH8U7Zyn9Eb57UVFeafgeskf4wqB23
   210  BjbMdW2YaB+yzMRwYgOnD5lnBD4uqSmvjaV9C0kxn7x+oJkkiRV8/z1cNcO+BaeQ
   211  Akh/yTTeTzYGSc/ZOqCX1O+NOPgSeixVlqenABEBAAG0GVVzZXIyIDx1c2VyMkBl
   212  eGFtcGxlLmNvbT6JAVQEEwEIAD4WIQRXgbSh0TtGbgRd7XI46jvO1zKYLAUCWYZW
   213  wwIbAwUJA8JnAAULCQgHAgYVCAkKCwIEFgIDAQIeAQIXgAAKCRA46jvO1zKYLF/e
   214  B/91wm2KLMIQBZBA9WA2/+9rQWTo9EqgYrXN60rEzX3cYJWXZiE4DrKR1oWDGNLi
   215  KXOCW62snvJldolBqq0ZqaKvPKzl0Y5TRqbYEc9AjUSqgRin1b+G2DevLGT4ibq+
   216  7ocQvz0XkASEUAgHahp0Ubiiib1521WwT/duL+AG8Gg0+DK09RfV3eX5/EOkQCKv
   217  8cutqgsd2Smz40A8wXuJkRcipZBtrB/GkUaZ/eJdwEeSYZjEA9GWF61LJT2stvRN
   218  HCk7C3z3pVEek1PluiFs/4VN8BG8yDzW4c0tLty4Fj3VwPqwIbB5AJbquVfhQCb4
   219  Eep2lm3Lc9b1OwO5N3coPJkouQENBFmGVsMBCADAGba2L6NCOE1i3WIP6CPzbdOo
   220  N3gdTfTgccAx9fNeon9jor+3tgEjlo9/6cXiRoksOV6W4wFab/ZwWgwN6JO4CGvZ
   221  Wi7EQwMMMp1E36YTojKQJrcA9UvMnTHulqQQ88F5E845DhzFQM3erv42QZZMBAX3
   222  kXCgy1GNFocl6tLUvJdEqs+VcJGGANMpmzE4WLa8KhSYnxipwuQ62JBy9R+cHyKT
   223  OARk8znRqSu5bT3LtlrZ/HXu+6Oy4+2uCdNzZIh5J5tPS7CPA6ptl88iGVBte/CJ
   224  7cjgJWSQqeYp2Y5QvsWAivkQ4Ww9plHbbwV0A2eaHsjjWzlUl3HoJ/snMOhBABEB
   225  AAGJATwEGAEIACYWIQRXgbSh0TtGbgRd7XI46jvO1zKYLAUCWYZWwwIbDAUJA8Jn
   226  AAAKCRA46jvO1zKYLBwLCACQOpeRVrwIKVaWcPMYjVHHJsGscaLKpgpARAUgbiG6
   227  Cbc2WI8Sm3fRwrY0VAfN+u9QwrtvxANcyB3vTgTzw7FimfhOimxiTSO8HQCfjDZF
   228  Xly8rq+Fua7+ClWUpy21IekW41VvZYjH2sL6EVP+UcEOaGAyN53XfhaRVZPhNtZN
   229  NKAE9N5EG3rbsZ33LzJj40rEKlzFSseAAPft8qA3IXjzFBx+PQXHMpNCagL79he6
   230  lqockTJ+oPmta4CF/J0U5LUr1tOZXheL3TP6m8d08gDrtn0YuGOPk87i9sJz+jR9
   231  uy6MA3VSB99SK9ducGmE1Jv8mcziREroz2TEGr0zPs6h
   232  =J59D
   233  -----END PGP PUBLIC KEY BLOCK-----`)
   234  }
   235  
   236  func testCreateValidSecondaryEmailGPGKey(t *testing.T, makeRequest makeRequestFunc, token string, expected int) {
   237  	// User2 <user2-2@example.com> //secondary and not activated
   238  	testCreateGPGKey(t, makeRequest, token, expected, `-----BEGIN PGP PUBLIC KEY BLOCK-----
   239  
   240  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
   276  6qgtsUdi5eviONRkBgeZtN3oxA==
   277  =MgDv
   278  -----END PGP PUBLIC KEY BLOCK-----`)
   279  }