From a1fc0ab2d0d777db54939dbeb8397dcf54f41d23 Mon Sep 17 00:00:00 2001 From: Jahziel Villasana-Espinoza Date: Fri, 24 May 2024 12:25:59 -0400 Subject: [PATCH] feat: update integration test for new endpoint --- server/mock/datastore_mock.go | 12 ++++++ server/service/integration_mdm_test.go | 53 ++++++++++++++++++++++++-- server/service/testdata/apns.pem | 30 +++++++++++++++ 3 files changed, 91 insertions(+), 4 deletions(-) create mode 100644 server/service/testdata/apns.pem diff --git a/server/mock/datastore_mock.go b/server/mock/datastore_mock.go index ca887a1472..cd3b06697b 100644 --- a/server/mock/datastore_mock.go +++ b/server/mock/datastore_mock.go @@ -825,6 +825,8 @@ type InsertMDMConfigAssetsFunc func(ctx context.Context, assets []fleet.MDMConfi type GetMDMConfigAssetsByNameFunc func(ctx context.Context, assetNames []fleet.MDMAssetName) ([]fleet.MDMConfigAsset, error) +type DeleteMDMConfigAssetsByNameFunc func(ctx context.Context, assetNames []fleet.MDMAssetName) error + type WSTEPStoreCertificateFunc func(ctx context.Context, name string, crt *x509.Certificate) error type WSTEPNewSerialFunc func(ctx context.Context) (*big.Int, error) @@ -2167,6 +2169,9 @@ type DataStore struct { GetMDMConfigAssetsByNameFunc GetMDMConfigAssetsByNameFunc GetMDMConfigAssetsByNameFuncInvoked bool + DeleteMDMConfigAssetsByNameFunc DeleteMDMConfigAssetsByNameFunc + DeleteMDMConfigAssetsByNameFuncInvoked bool + WSTEPStoreCertificateFunc WSTEPStoreCertificateFunc WSTEPStoreCertificateFuncInvoked bool @@ -5189,6 +5194,13 @@ func (s *DataStore) GetMDMConfigAssetsByName(ctx context.Context, assetNames []f return s.GetMDMConfigAssetsByNameFunc(ctx, assetNames) } +func (s *DataStore) DeleteMDMConfigAssetsByName(ctx context.Context, assetNames []fleet.MDMAssetName) error { + s.mu.Lock() + s.DeleteMDMConfigAssetsByNameFuncInvoked = true + s.mu.Unlock() + return s.DeleteMDMConfigAssetsByNameFunc(ctx, assetNames) +} + func (s *DataStore) WSTEPStoreCertificate(ctx context.Context, name string, crt *x509.Certificate) error { s.mu.Lock() s.WSTEPStoreCertificateFuncInvoked = true diff --git a/server/service/integration_mdm_test.go b/server/service/integration_mdm_test.go index c06c42d4c3..cbd466c4f9 100644 --- a/server/service/integration_mdm_test.go +++ b/server/service/integration_mdm_test.go @@ -920,9 +920,10 @@ foobar -----END CERTIFICATE REQUEST-----`) // Check that we created the right assets - assetsFromCall1, err := s.ds.GetMDMConfigAssetsByName(ctx, []fleet.MDMAssetName{fleet.MDMAssetCACert, fleet.MDMAssetCAKey, fleet.MDMAssetAPNSKey}) + var originalAssets []fleet.MDMConfigAsset + originalAssets, err := s.ds.GetMDMConfigAssetsByName(ctx, []fleet.MDMAssetName{fleet.MDMAssetCACert, fleet.MDMAssetCAKey, fleet.MDMAssetAPNSKey}) require.NoError(t, err) - require.Len(t, assetsFromCall1, 3) + require.Len(t, originalAssets, 3) resp = getMDMAppleCSRResponse{} s.SucceedNextCSRRequest() @@ -933,9 +934,53 @@ foobar -----END CERTIFICATE REQUEST-----`) // Check that the assets stayed the same in the subsequent call - assetsFromCall2, err := s.ds.GetMDMConfigAssetsByName(ctx, []fleet.MDMAssetName{fleet.MDMAssetCACert, fleet.MDMAssetCAKey, fleet.MDMAssetAPNSKey}) + assets, err := s.ds.GetMDMConfigAssetsByName(ctx, []fleet.MDMAssetName{fleet.MDMAssetCACert, fleet.MDMAssetCAKey, fleet.MDMAssetAPNSKey}) require.NoError(t, err) - require.Equal(t, assetsFromCall1, assetsFromCall2) + require.Equal(t, originalAssets, assets) + + // Upload an APNS cert + s.uploadAPNSCert("apns.pem", http.StatusAccepted) + + assets, err = s.ds.GetMDMConfigAssetsByName(ctx, []fleet.MDMAssetName{fleet.MDMAssetCACert, fleet.MDMAssetCAKey, fleet.MDMAssetAPNSKey, fleet.MDMAssetAPNSCert}) + require.NoError(t, err) + require.Len(t, assets, 4) + + // Delete APNS cert, should soft delete all certs and keys created in this test + s.Do("DELETE", "/api/latest/fleet/mdm/apple/apns_certificate", nil, http.StatusOK) + + assets, err = s.ds.GetMDMConfigAssetsByName(ctx, []fleet.MDMAssetName{fleet.MDMAssetCACert, fleet.MDMAssetCAKey, fleet.MDMAssetAPNSKey, fleet.MDMAssetAPNSCert}) + require.NoError(t, err) + require.Len(t, assets, 0) +} + +func (s *integrationMDMTestSuite) uploadAPNSCert(pemFileName string, expectedStatus int) { + t := s.T() + read := func(name string) []byte { + b, err := os.ReadFile(filepath.Join("testdata", name)) + require.NoError(t, err) + return b + } + + pemBytes := read(pemFileName) + + var b bytes.Buffer + w := multipart.NewWriter(&b) + + // add the package field + fw, err := w.CreateFormFile("certificate", pemFileName) + require.NoError(t, err) + _, err = io.Copy(fw, bytes.NewBuffer(pemBytes)) + require.NoError(t, err) + + w.Close() + + headers := map[string]string{ + "Content-Type": w.FormDataContentType(), + "Accept": "application/json", + "Authorization": fmt.Sprintf("Bearer %s", s.token), + } + + s.DoRawWithHeaders("POST", "/api/latest/fleet/mdm/apple/apns_certificate", b.Bytes(), expectedStatus, headers) } func (s *integrationMDMTestSuite) TestMDMAppleUnenroll() { diff --git a/server/service/testdata/apns.pem b/server/service/testdata/apns.pem new file mode 100644 index 0000000000..585e9622e0 --- /dev/null +++ b/server/service/testdata/apns.pem @@ -0,0 +1,30 @@ +-----BEGIN CERTIFICATE----- +MIIFHDCCAwSgAwIBAgIBATANBgkqhkiG9w0BAQsFADBSMREwDwYDVQQDEwhncm9v +Yi1jYTELMAkGA1UEBhMCVVMxETAPBgNVBAcTCE5ldyBZb3JrMRAwDgYDVQQKEwdF +eGFtcGxlMQswCQYDVQQIEwJOWTAeFw0xNjEwMjQxMzExNDRaFw0xNzEwMjQxMzEx +NDRaMFgxFzAVBgNVBAMTDnNlcnZxLmdyb29iLmlvMQswCQYDVQQGEwJVUzERMA8G +A1UEBxMITmV3IFlvcmsxEDAOBgNVBAoTB0V4YW1wbGUxCzAJBgNVBAgTAk5ZMIIB +IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3Vdpw+hV4Y/4pLkJMwSUtmFq +g6hntniWfEZOz+uvlnbgNZRFRdD4lgfP8qEjWvcfoDpXpNakel9VkO2asxsJEBQM +ykDp1NLUpPBvPIGTvlwRy028LSqRM8yNPo5dXg9+hhf4W1I8PVnXBJQsuTIg23oa +F6/wXahoAz9zFfBg/v4e+PjdwH1naVJaFRr3FUqFAyoROh2Kr78blk7Vbc6MlBvF +OpV5PbcedSKkCnUHycP2FLCVqU7MHp9s2TCjFsc7dlFKEnq6CUdV4sxccSSjYbgD +4S5/wkjKcEptxsIinY9FMoIt0QV1pBOS+A8EOYk3PcEGILhqzx+hebMBDAxXAQID +AQABo4H2MIHzMHoGA1UdIwRzMHGAFCSIxl7pVfQrIzKc46qvMFXUT8ijoVakVDBS +MQswCQYDVQQGEwJVUzELMAkGA1UECBMCTlkxETAPBgNVBAcTCE5ldyBZb3JrMRAw +DgYDVQQKEwdFeGFtcGxlMREwDwYDVQQDEwhncm9vYi1jYYIBATAMBgNVHRMBAf8E +AjAAMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDATAOBgNVHQ8BAf8EBAMC +BaAwGQYDVR0RBBIwEIIOc2VydnEuZ3Jvb2IuaW8wHQYDVR0OBBYEFDxic9wp8N4s +6OE2NjWIOyTBSZyBMA0GCSqGSIb3DQEBCwUAA4ICAQCUPTPSPK1/aFPtqD2m3jQD +PFBEVSL4EbIGw1fKWxd3+pbydJFRlJIetwJvZu05JpK0VXy8pzMx3DW4ZKLrK6Jv +zJNB03B2hDLTbhoqyf3uE3gYdXyFA4R/AdfuBv8DfXRcgDmX3VG+ov3JQ3Wx4TNE +QF99nDtL6LfDVteAbxSnSrUneCivgguUQWbaw3dlVjV16JfM1gjjcNrKiOBzc6Gr +vYZrUUj64Ql1P2jOdcYaTPPtaC41zicrhQOqowkoz6V4fCeMvSbgz46Az5wVLPPb +2fhGE4FJDONs1L9sl9i4H0yanYgeEElVs20tI6ncyxJFiZoI+TNDTO4hE6o16H+h +ofs3wL+zGikBWRw3Q/uMTsddnom39kjG4RAXhShQ8IYGjEcHCfolsi7C6cxNAzQH +BHRKoTE+sHaGftaxvkaqOm3NcJMGZxwUiuZxkRz3g2QG5jE4eUZj/dCm10jCSE5m +hUTJyFp+VHL9P033vlLg+nBifbv1+Hv7cR+aM1prOOI+R60edhEZAfct0yXlRmz5 +gpolYkraRCxwQMV3AOp7DGbcbqwkH+Mknl7QcvKPZbEdWBcgU1h1Avd1hbm1lOsd +sYT32Bn408ADGdofR8MHseytX8tXNUnN3MotrraiHpsxL2LmELXD6P1pa22s7zXC +RV3Xwd/agUXlC+WVnlXCaQ== +-----END CERTIFICATE----- \ No newline at end of file