1package cloudflare 2 3import ( 4 "context" 5 "fmt" 6 "io/ioutil" 7 "net/http" 8 "testing" 9 "time" 10 11 "github.com/stretchr/testify/assert" 12) 13 14func TestCreateSSL(t *testing.T) { 15 setup() 16 defer teardown() 17 18 handler := func(w http.ResponseWriter, r *http.Request) { 19 assert.Equal(t, http.MethodPost, r.Method, "Expected method 'POST', got %s", r.Method) 20 b, err := ioutil.ReadAll(r.Body) 21 defer r.Body.Close() 22 23 if assert.NoError(t, err) { 24 assert.JSONEq(t, `{"certificate":"-----BEGIN CERTIFICATE----- MIIDtTCCAp2gAwIBAgIJAM15n7fdxhRtMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMTQwMzExMTkyMTU5WhcNMTQwNDEwMTkyMTU5WjBF MQswCQYDVQQGEwJVUzETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAvq3sKsHpeduJHimOK+fvQdKsI8z8A05MZyyLp2/R/GE8FjNv+hkVY1WQ LIyTNNQH7CJecE1nbTfo8Y56S7x/rhxC6/DJ8MIulapFPnorq46KU6yRxiM0MQ3N nTJHlHA2ozZta6YBBfVfhHWl1F0IfNbXCLKvGwWWMbCx43OfW6KTkbRnE6gFWKuO fSO5h2u5TaWVuSIzBvYs7Vza6m+gtYAvKAJV2nSZ+eSEFPDo29corOy8+huEOUL8 5FAw4BFPsr1TlrlGPFitduQUHGrSL7skk1ESGza0to3bOtrodKei2s9bk5MXm7lZ qI+WZJX4Zu9+mzZhc9pCVi8r/qlXuQIDAQABo4GnMIGkMB0GA1UdDgQWBBRvavf+ sWM4IwKiH9X9w1vl6nUVRDB1BgNVHSMEbjBsgBRvavf+sWM4IwKiH9X9w1vl6nUV RKFJpEcwRTELMAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAM15n7fdxhRtMAwGA1UdEwQF MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBABY2ZzBaW0dMsAAT7tPJzrVWVzQx6KU4 UEBLudIlWPlkAwTnINCWR/8eNjCCmGA4heUdHmazdpPa8RzwOmc0NT1NQqzSyktt vTqb4iHD7+8f9MqJ9/FssCfTtqr/Qst/hGH4Wmdf1EJ/6FqYAAb5iRlPgshFZxU8 uXtA8hWn6fK6eISD9HBdcAFToUvKNZ1BIDPvh9f95Ine8ar6yGd56TUNrHR8eHBs ESxz5ddVR/oWRysNJ+aGAyYqHS8S/ttmC7r4XCAHqXptkHPCGRqkAhsterYhd4I8 /cBzejUobNCjjHFbtkAL/SjxZOLW+pNkZwfeYdM8iPkD54Uua1v2tdw= -----END CERTIFICATE-----","geo_restrictions":{"label":"us"},"private_key":"-----BEGIN RSA PRIVATE KEY-----MIIEowIBAAKCAQEAl 1cSc0vfcJLI4ZdWjiZZqy86Eof4czCwilyjXdvHqbdgDjz9H6K/0FX78EzVdfyExESptPCDl5YYjvcZyAWlgNfYEpFpGeoh/pTFW3hlyKImh4EgBXbDrR251J Ew2Nf56X3duibI6X20gKZA6cvdmWeKh MOOXuh1bSPU3dkb4YOF/fng5iGrx0q3txdMQXTPMZ1uXHFcBH7idgViYesXUBhdll3GP1N Y8laq0yrqh 8HMsZK m27MebqonbNmjOqE218lVEvjCdRO6xvNXrO6vNJBoGn2eGwZ8BVd0mTA3Tj43/2cmxQFY9FLq56cCXqYI1fbRRib ZLrjSNkwIDAQABAoIBABfAjjsjjxc0NxcYvKOMUb9Rpj8Sx6U/o/tDC5u XmsGX37aaJmC5yw9BQiAxgvXtQryEl5uoNoqOdsxzKV6yM0vPcwKEJVBd4G6yx6AjVJZnc2qf72erR7BbA2CQh scMDRBKE041HhgTBRNP6roim0SOgYP5JZIrGAQXNIkyE0fZc5gZNUt388ne/mjWM6Xi08BDGurLC68nsdt7Nd UYqeBVxo2EqChp5vKYZYEcG8h9XBj4u4NIwg1Mty2JqX30uBjoHvF5w/pMs8lG uvj6JR9I 19wtCuccbAJl 4cUq03UQoIDmwejea oC8A8WJr3vVpODDWrvAsjllGPBECgYEAyQRa6edYO6bsSvgbM13qXW9OQTn9YmgzfN24Ux1D66TQU6sBSLdfSHshDhTCi Ax 698aJNRWujAakA2DDgspSx98aRnHbF zvY7i7iWGesN6uN0zL 6/MK5uWoieGZRjgk230fLk00l4/FK1mJIp0apr0Lis9xmDjP5AaUPTUUCgYEAwXuhTHZWPT6v8YwOksjbuK UDkIIvyMux53kb73vrkgMboS4DB1zMLNyG 9EghS414CFROUwGl4ZUKboH1Jo5G34y8VgDuHjirTqL2H6 zNpML iMrWCXjpFKkxwPbeQnEAZ 5Rud4d PTyXAt71blZHE9tZ4KHy8cU1iKc9APcCgYAIqKZd4vg7AZK2G//X85iv06aUSrIudfyZyVcyRVVyphPPNtOEVVnGXn9rAtvqeIrOo52BR68 cj4vlXp hkDuEH QVBuY/NdQhOzFtPrKPQTJdGjIlQ2x65Vidj7r3sRukNkLPyV2v D885zcpTkp83JFuWTYiIrg275DIuAI3QKBgAglM0IrzS g3vlVQxvM1ussgRgkkYeybHq82 wUW 3DXLqeXb0s1DedplUkuoabZriz0Wh4GZFSmtA5ZpZC uV697lkYsndmp2xRhaekllW7bu pY5q88URwO2p8CO5AZ6CWFWuBwSDML5VOapGRqDRgwaD oGpb7fb7IgHOls7AoGBAJnL6Q8t35uYJ8J8hY7wso88IE04z6VaT8WganxcndesWER9eFQDHDDy//ZYeyt6M41uIY CL Vkm9Kwl/bHLJKdnOE1a9NdE6mtfah0Bk2u/YOuzyu5mmcgZiX X/OZuEbGmmbZOR1FCuIyrNYfwYohhcZP7/r0Ia/1GpkHc3Bi-----END RSA PRIVATE KEY-----","bundle_method":"ubiquitous"}`, string(b)) 25 } 26 27 w.Header().Set("content-type", "application/json") 28 fmt.Fprint(w, `{ 29 "success": true, 30 "errors": [], 31 "messages": [], 32 "result": { 33 "id": "7e7b8deba8538af625850b7b2530034c", 34 "hosts": [ 35 "example.com" 36 ], 37 "issuer": "GlobalSign", 38 "signature": "SHA256WithRSA", 39 "status": "active", 40 "bundle_method": "ubiquitous", 41 "geo_restrictions": { 42 "label": "us" 43 }, 44 "zone_id": "023e105f4ecef8ad9ca31a8372d0c353", 45 "uploaded_on": "2014-01-01T05:20:00Z", 46 "modified_on": "2014-01-01T05:20:00Z", 47 "expires_on": "2016-01-01T05:20:00Z", 48 "priority": 1 49 } 50 }`) 51 } 52 53 mux.HandleFunc("/zones/023e105f4ecef8ad9ca31a8372d0c353/custom_certificates", handler) 54 55 hosts := make([]string, 1, 4) 56 hosts[0] = "example.com" 57 uploadedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z") 58 modifiedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z") 59 expiresOn, _ := time.Parse(time.RFC3339, "2016-01-01T05:20:00Z") 60 want := ZoneCustomSSL{ 61 ID: "7e7b8deba8538af625850b7b2530034c", 62 Hosts: hosts, 63 Issuer: "GlobalSign", 64 Signature: "SHA256WithRSA", 65 Status: "active", 66 BundleMethod: "ubiquitous", 67 GeoRestrictions: ZoneCustomSSLGeoRestrictions{Label: "us"}, 68 ZoneID: "023e105f4ecef8ad9ca31a8372d0c353", 69 UploadedOn: uploadedOn, 70 ModifiedOn: modifiedOn, 71 ExpiresOn: expiresOn, 72 Priority: 1, 73 } 74 75 actual, err := client.CreateSSL(context.Background(), "023e105f4ecef8ad9ca31a8372d0c353", ZoneCustomSSLOptions{ 76 Certificate: "-----BEGIN CERTIFICATE----- MIIDtTCCAp2gAwIBAgIJAM15n7fdxhRtMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMTQwMzExMTkyMTU5WhcNMTQwNDEwMTkyMTU5WjBF MQswCQYDVQQGEwJVUzETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAvq3sKsHpeduJHimOK+fvQdKsI8z8A05MZyyLp2/R/GE8FjNv+hkVY1WQ LIyTNNQH7CJecE1nbTfo8Y56S7x/rhxC6/DJ8MIulapFPnorq46KU6yRxiM0MQ3N nTJHlHA2ozZta6YBBfVfhHWl1F0IfNbXCLKvGwWWMbCx43OfW6KTkbRnE6gFWKuO fSO5h2u5TaWVuSIzBvYs7Vza6m+gtYAvKAJV2nSZ+eSEFPDo29corOy8+huEOUL8 5FAw4BFPsr1TlrlGPFitduQUHGrSL7skk1ESGza0to3bOtrodKei2s9bk5MXm7lZ qI+WZJX4Zu9+mzZhc9pCVi8r/qlXuQIDAQABo4GnMIGkMB0GA1UdDgQWBBRvavf+ sWM4IwKiH9X9w1vl6nUVRDB1BgNVHSMEbjBsgBRvavf+sWM4IwKiH9X9w1vl6nUV RKFJpEcwRTELMAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAM15n7fdxhRtMAwGA1UdEwQF MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBABY2ZzBaW0dMsAAT7tPJzrVWVzQx6KU4 UEBLudIlWPlkAwTnINCWR/8eNjCCmGA4heUdHmazdpPa8RzwOmc0NT1NQqzSyktt vTqb4iHD7+8f9MqJ9/FssCfTtqr/Qst/hGH4Wmdf1EJ/6FqYAAb5iRlPgshFZxU8 uXtA8hWn6fK6eISD9HBdcAFToUvKNZ1BIDPvh9f95Ine8ar6yGd56TUNrHR8eHBs ESxz5ddVR/oWRysNJ+aGAyYqHS8S/ttmC7r4XCAHqXptkHPCGRqkAhsterYhd4I8 /cBzejUobNCjjHFbtkAL/SjxZOLW+pNkZwfeYdM8iPkD54Uua1v2tdw= -----END CERTIFICATE-----", 77 PrivateKey: "-----BEGIN RSA PRIVATE KEY-----MIIEowIBAAKCAQEAl 1cSc0vfcJLI4ZdWjiZZqy86Eof4czCwilyjXdvHqbdgDjz9H6K/0FX78EzVdfyExESptPCDl5YYjvcZyAWlgNfYEpFpGeoh/pTFW3hlyKImh4EgBXbDrR251J Ew2Nf56X3duibI6X20gKZA6cvdmWeKh MOOXuh1bSPU3dkb4YOF/fng5iGrx0q3txdMQXTPMZ1uXHFcBH7idgViYesXUBhdll3GP1N Y8laq0yrqh 8HMsZK m27MebqonbNmjOqE218lVEvjCdRO6xvNXrO6vNJBoGn2eGwZ8BVd0mTA3Tj43/2cmxQFY9FLq56cCXqYI1fbRRib ZLrjSNkwIDAQABAoIBABfAjjsjjxc0NxcYvKOMUb9Rpj8Sx6U/o/tDC5u XmsGX37aaJmC5yw9BQiAxgvXtQryEl5uoNoqOdsxzKV6yM0vPcwKEJVBd4G6yx6AjVJZnc2qf72erR7BbA2CQh scMDRBKE041HhgTBRNP6roim0SOgYP5JZIrGAQXNIkyE0fZc5gZNUt388ne/mjWM6Xi08BDGurLC68nsdt7Nd UYqeBVxo2EqChp5vKYZYEcG8h9XBj4u4NIwg1Mty2JqX30uBjoHvF5w/pMs8lG uvj6JR9I 19wtCuccbAJl 4cUq03UQoIDmwejea oC8A8WJr3vVpODDWrvAsjllGPBECgYEAyQRa6edYO6bsSvgbM13qXW9OQTn9YmgzfN24Ux1D66TQU6sBSLdfSHshDhTCi Ax 698aJNRWujAakA2DDgspSx98aRnHbF zvY7i7iWGesN6uN0zL 6/MK5uWoieGZRjgk230fLk00l4/FK1mJIp0apr0Lis9xmDjP5AaUPTUUCgYEAwXuhTHZWPT6v8YwOksjbuK UDkIIvyMux53kb73vrkgMboS4DB1zMLNyG 9EghS414CFROUwGl4ZUKboH1Jo5G34y8VgDuHjirTqL2H6 zNpML iMrWCXjpFKkxwPbeQnEAZ 5Rud4d PTyXAt71blZHE9tZ4KHy8cU1iKc9APcCgYAIqKZd4vg7AZK2G//X85iv06aUSrIudfyZyVcyRVVyphPPNtOEVVnGXn9rAtvqeIrOo52BR68 cj4vlXp hkDuEH QVBuY/NdQhOzFtPrKPQTJdGjIlQ2x65Vidj7r3sRukNkLPyV2v D885zcpTkp83JFuWTYiIrg275DIuAI3QKBgAglM0IrzS g3vlVQxvM1ussgRgkkYeybHq82 wUW 3DXLqeXb0s1DedplUkuoabZriz0Wh4GZFSmtA5ZpZC uV697lkYsndmp2xRhaekllW7bu pY5q88URwO2p8CO5AZ6CWFWuBwSDML5VOapGRqDRgwaD oGpb7fb7IgHOls7AoGBAJnL6Q8t35uYJ8J8hY7wso88IE04z6VaT8WganxcndesWER9eFQDHDDy//ZYeyt6M41uIY CL Vkm9Kwl/bHLJKdnOE1a9NdE6mtfah0Bk2u/YOuzyu5mmcgZiX X/OZuEbGmmbZOR1FCuIyrNYfwYohhcZP7/r0Ia/1GpkHc3Bi-----END RSA PRIVATE KEY-----", 78 BundleMethod: "ubiquitous", 79 GeoRestrictions: &ZoneCustomSSLGeoRestrictions{Label: "us"}, 80 }) 81 82 if assert.NoError(t, err) { 83 assert.Equal(t, want, actual) 84 } 85 86 _, err = client.CreateSSL(context.Background(), "bar", ZoneCustomSSLOptions{}) 87 assert.Error(t, err) 88} 89 90func TestListSSL(t *testing.T) { 91 setup() 92 defer teardown() 93 94 handler := func(w http.ResponseWriter, r *http.Request) { 95 assert.Equal(t, http.MethodGet, r.Method, "Expected method 'GET', got %s", r.Method) 96 w.Header().Set("content-type", "application/json") 97 fmt.Fprint(w, `{ 98 "success": true, 99 "errors": [], 100 "messages": [], 101 "result": [ 102 { 103 "id": "7e7b8deba8538af625850b7b2530034c", 104 "hosts": [ 105 "example.com" 106 ], 107 "issuer": "GlobalSign", 108 "signature": "SHA256WithRSA", 109 "status": "active", 110 "bundle_method": "ubiquitous", 111 "zone_id": "023e105f4ecef8ad9ca31a8372d0c353", 112 "uploaded_on": "2014-01-01T05:20:00Z", 113 "modified_on": "2014-01-01T05:20:00Z", 114 "expires_on": "2016-01-01T05:20:00Z", 115 "priority": 1 116 } 117 ], 118 "result_info": { 119 "page": 1, 120 "per_page": 20, 121 "count": 1, 122 "total_count": 2000 123 } 124 }`) 125 } 126 127 mux.HandleFunc("/zones/023e105f4ecef8ad9ca31a8372d0c353/custom_certificates", handler) 128 129 hosts := make([]string, 1, 4) 130 hosts[0] = "example.com" 131 uploadedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z") 132 modifiedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z") 133 expiresOn, _ := time.Parse(time.RFC3339, "2016-01-01T05:20:00Z") 134 135 want := make([]ZoneCustomSSL, 1, 4) 136 want[0] = ZoneCustomSSL{ 137 ID: "7e7b8deba8538af625850b7b2530034c", 138 Hosts: hosts, 139 Issuer: "GlobalSign", 140 Signature: "SHA256WithRSA", 141 Status: "active", 142 BundleMethod: "ubiquitous", 143 ZoneID: "023e105f4ecef8ad9ca31a8372d0c353", 144 UploadedOn: uploadedOn, 145 ModifiedOn: modifiedOn, 146 ExpiresOn: expiresOn, 147 Priority: 1, 148 } 149 150 actual, err := client.ListSSL(context.Background(), "023e105f4ecef8ad9ca31a8372d0c353") 151 if assert.NoError(t, err) { 152 assert.Equal(t, want, actual) 153 } 154 155 _, err = client.ListSSL(context.Background(), "bar") 156 assert.Error(t, err) 157} 158 159func TestSSLDetails(t *testing.T) { 160 setup() 161 defer teardown() 162 163 handler := func(w http.ResponseWriter, r *http.Request) { 164 w.Header().Set("content-type", "application/json") 165 fmt.Fprint(w, `{ 166 "success": true, 167 "errors": [], 168 "messages": [], 169 "result": { 170 "id": "7e7b8deba8538af625850b7b2530034c", 171 "hosts": [ 172 "example.com" 173 ], 174 "issuer": "GlobalSign", 175 "signature": "SHA256WithRSA", 176 "status": "active", 177 "bundle_method": "ubiquitous", 178 "zone_id": "023e105f4ecef8ad9ca31a8372d0c353", 179 "uploaded_on": "2014-01-01T05:20:00Z", 180 "modified_on": "2014-01-01T05:20:00Z", 181 "expires_on": "2016-01-01T05:20:00Z", 182 "priority": 1 183 } 184 }`) 185 } 186 187 mux.HandleFunc("/zones/023e105f4ecef8ad9ca31a8372d0c353/custom_certificates/7e7b8deba8538af625850b7b2530034c", handler) 188 189 hosts := make([]string, 1, 4) 190 hosts[0] = "example.com" 191 uploadedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z") 192 modifiedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z") 193 expiresOn, _ := time.Parse(time.RFC3339, "2016-01-01T05:20:00Z") 194 want := ZoneCustomSSL{ 195 ID: "7e7b8deba8538af625850b7b2530034c", 196 Hosts: hosts, 197 Issuer: "GlobalSign", 198 Signature: "SHA256WithRSA", 199 Status: "active", 200 BundleMethod: "ubiquitous", 201 ZoneID: "023e105f4ecef8ad9ca31a8372d0c353", 202 UploadedOn: uploadedOn, 203 ModifiedOn: modifiedOn, 204 ExpiresOn: expiresOn, 205 Priority: 1, 206 } 207 208 actual, err := client.SSLDetails(context.Background(), "023e105f4ecef8ad9ca31a8372d0c353", "7e7b8deba8538af625850b7b2530034c") 209 if assert.NoError(t, err) { 210 assert.Equal(t, want, actual) 211 } 212 213 _, err = client.SSLDetails(context.Background(), "023e105f4ecef8ad9ca31a8372d0c353", "bar") 214 assert.Error(t, err) 215} 216 217func TestUpdateSSL(t *testing.T) { 218 setup() 219 defer teardown() 220 221 handler := func(w http.ResponseWriter, r *http.Request) { 222 assert.Equal(t, http.MethodPatch, r.Method, "Expected method 'PATCH', got %s", r.Method) 223 b, err := ioutil.ReadAll(r.Body) 224 defer r.Body.Close() 225 if assert.NoError(t, err) { 226 assert.JSONEq(t, `{"certificate":"-----BEGIN CERTIFICATE----- MIIDtTCCAp2gAwIBAgIJAM15n7fdxhRtMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMTQwMzExMTkyMTU5WhcNMTQwNDEwMTkyMTU5WjBF MQswCQYDVQQGEwJVUzETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAvq3sKsHpeduJHimOK+fvQdKsI8z8A05MZyyLp2/R/GE8FjNv+hkVY1WQ LIyTNNQH7CJecE1nbTfo8Y56S7x/rhxC6/DJ8MIulapFPnorq46KU6yRxiM0MQ3N nTJHlHA2ozZta6YBBfVfhHWl1F0IfNbXCLKvGwWWMbCx43OfW6KTkbRnE6gFWKuO fSO5h2u5TaWVuSIzBvYs7Vza6m+gtYAvKAJV2nSZ+eSEFPDo29corOy8+huEOUL8 5FAw4BFPsr1TlrlGPFitduQUHGrSL7skk1ESGza0to3bOtrodKei2s9bk5MXm7lZ qI+WZJX4Zu9+mzZhc9pCVi8r/qlXuQIDAQABo4GnMIGkMB0GA1UdDgQWBBRvavf+ sWM4IwKiH9X9w1vl6nUVRDB1BgNVHSMEbjBsgBRvavf+sWM4IwKiH9X9w1vl6nUV RKFJpEcwRTELMAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAM15n7fdxhRtMAwGA1UdEwQF MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBABY2ZzBaW0dMsAAT7tPJzrVWVzQx6KU4 UEBLudIlWPlkAwTnINCWR/8eNjCCmGA4heUdHmazdpPa8RzwOmc0NT1NQqzSyktt vTqb4iHD7+8f9MqJ9/FssCfTtqr/Qst/hGH4Wmdf1EJ/6FqYAAb5iRlPgshFZxU8 uXtA8hWn6fK6eISD9HBdcAFToUvKNZ1BIDPvh9f95Ine8ar6yGd56TUNrHR8eHBs ESxz5ddVR/oWRysNJ+aGAyYqHS8S/ttmC7r4XCAHqXptkHPCGRqkAhsterYhd4I8 /cBzejUobNCjjHFbtkAL/SjxZOLW+pNkZwfeYdM8iPkD54Uua1v2tdw= -----END CERTIFICATE-----","geo_restrictions":{"label":"us"},"private_key":"-----BEGIN RSA PRIVATE KEY-----MIIEowIBAAKCAQEAl 1cSc0vfcJLI4ZdWjiZZqy86Eof4czCwilyjXdvHqbdgDjz9H6K/0FX78EzVdfyExESptPCDl5YYjvcZyAWlgNfYEpFpGeoh/pTFW3hlyKImh4EgBXbDrR251J Ew2Nf56X3duibI6X20gKZA6cvdmWeKh MOOXuh1bSPU3dkb4YOF/fng5iGrx0q3txdMQXTPMZ1uXHFcBH7idgViYesXUBhdll3GP1N Y8laq0yrqh 8HMsZK m27MebqonbNmjOqE218lVEvjCdRO6xvNXrO6vNJBoGn2eGwZ8BVd0mTA3Tj43/2cmxQFY9FLq56cCXqYI1fbRRib ZLrjSNkwIDAQABAoIBABfAjjsjjxc0NxcYvKOMUb9Rpj8Sx6U/o/tDC5u XmsGX37aaJmC5yw9BQiAxgvXtQryEl5uoNoqOdsxzKV6yM0vPcwKEJVBd4G6yx6AjVJZnc2qf72erR7BbA2CQh scMDRBKE041HhgTBRNP6roim0SOgYP5JZIrGAQXNIkyE0fZc5gZNUt388ne/mjWM6Xi08BDGurLC68nsdt7Nd UYqeBVxo2EqChp5vKYZYEcG8h9XBj4u4NIwg1Mty2JqX30uBjoHvF5w/pMs8lG uvj6JR9I 19wtCuccbAJl 4cUq03UQoIDmwejea oC8A8WJr3vVpODDWrvAsjllGPBECgYEAyQRa6edYO6bsSvgbM13qXW9OQTn9YmgzfN24Ux1D66TQU6sBSLdfSHshDhTCi Ax 698aJNRWujAakA2DDgspSx98aRnHbF zvY7i7iWGesN6uN0zL 6/MK5uWoieGZRjgk230fLk00l4/FK1mJIp0apr0Lis9xmDjP5AaUPTUUCgYEAwXuhTHZWPT6v8YwOksjbuK UDkIIvyMux53kb73vrkgMboS4DB1zMLNyG 9EghS414CFROUwGl4ZUKboH1Jo5G34y8VgDuHjirTqL2H6 zNpML iMrWCXjpFKkxwPbeQnEAZ 5Rud4d PTyXAt71blZHE9tZ4KHy8cU1iKc9APcCgYAIqKZd4vg7AZK2G//X85iv06aUSrIudfyZyVcyRVVyphPPNtOEVVnGXn9rAtvqeIrOo52BR68 cj4vlXp hkDuEH QVBuY/NdQhOzFtPrKPQTJdGjIlQ2x65Vidj7r3sRukNkLPyV2v D885zcpTkp83JFuWTYiIrg275DIuAI3QKBgAglM0IrzS g3vlVQxvM1ussgRgkkYeybHq82 wUW 3DXLqeXb0s1DedplUkuoabZriz0Wh4GZFSmtA5ZpZC uV697lkYsndmp2xRhaekllW7bu pY5q88URwO2p8CO5AZ6CWFWuBwSDML5VOapGRqDRgwaD oGpb7fb7IgHOls7AoGBAJnL6Q8t35uYJ8J8hY7wso88IE04z6VaT8WganxcndesWER9eFQDHDDy//ZYeyt6M41uIY CL Vkm9Kwl/bHLJKdnOE1a9NdE6mtfah0Bk2u/YOuzyu5mmcgZiX X/OZuEbGmmbZOR1FCuIyrNYfwYohhcZP7/r0Ia/1GpkHc3Bi-----END RSA PRIVATE KEY-----","bundle_method":"ubiquitous"}`, string(b)) 227 } 228 229 w.Header().Set("content-type", "application/json") 230 fmt.Fprint(w, `{ 231 "success": true, 232 "errors": [], 233 "messages": [], 234 "result": { 235 "id": "7e7b8deba8538af625850b7b2530034c", 236 "hosts": [ 237 "example.com" 238 ], 239 "issuer": "GlobalSign", 240 "signature": "SHA256WithRSA", 241 "status": "active", 242 "bundle_method": "ubiquitous", 243 "geo_restrictions": { 244 "label": "us" 245 }, 246 "zone_id": "023e105f4ecef8ad9ca31a8372d0c353", 247 "uploaded_on": "2014-01-01T05:20:00Z", 248 "modified_on": "2014-01-01T05:20:00Z", 249 "expires_on": "2016-01-01T05:20:00Z", 250 "priority": 1 251 } 252 }`) 253 } 254 255 mux.HandleFunc("/zones/023e105f4ecef8ad9ca31a8372d0c353/custom_certificates/7e7b8deba8538af625850b7b2530034c", handler) 256 257 hosts := make([]string, 1, 4) 258 hosts[0] = "example.com" 259 uploadedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z") 260 modifiedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z") 261 expiresOn, _ := time.Parse(time.RFC3339, "2016-01-01T05:20:00Z") 262 want := ZoneCustomSSL{ 263 ID: "7e7b8deba8538af625850b7b2530034c", 264 Hosts: hosts, 265 Issuer: "GlobalSign", 266 Signature: "SHA256WithRSA", 267 Status: "active", 268 BundleMethod: "ubiquitous", 269 GeoRestrictions: ZoneCustomSSLGeoRestrictions{Label: "us"}, 270 ZoneID: "023e105f4ecef8ad9ca31a8372d0c353", 271 UploadedOn: uploadedOn, 272 ModifiedOn: modifiedOn, 273 ExpiresOn: expiresOn, 274 Priority: 1, 275 } 276 277 actual, err := client.UpdateSSL(context.Background(), "023e105f4ecef8ad9ca31a8372d0c353", "7e7b8deba8538af625850b7b2530034c", ZoneCustomSSLOptions{ 278 Certificate: "-----BEGIN CERTIFICATE----- MIIDtTCCAp2gAwIBAgIJAM15n7fdxhRtMA0GCSqGSIb3DQEBBQUAMEUxCzAJBgNV BAYTAlVTMRMwEQYDVQQIEwpTb21lLVN0YXRlMSEwHwYDVQQKExhJbnRlcm5ldCBX aWRnaXRzIFB0eSBMdGQwHhcNMTQwMzExMTkyMTU5WhcNMTQwNDEwMTkyMTU5WjBF MQswCQYDVQQGEwJVUzETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50 ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB CgKCAQEAvq3sKsHpeduJHimOK+fvQdKsI8z8A05MZyyLp2/R/GE8FjNv+hkVY1WQ LIyTNNQH7CJecE1nbTfo8Y56S7x/rhxC6/DJ8MIulapFPnorq46KU6yRxiM0MQ3N nTJHlHA2ozZta6YBBfVfhHWl1F0IfNbXCLKvGwWWMbCx43OfW6KTkbRnE6gFWKuO fSO5h2u5TaWVuSIzBvYs7Vza6m+gtYAvKAJV2nSZ+eSEFPDo29corOy8+huEOUL8 5FAw4BFPsr1TlrlGPFitduQUHGrSL7skk1ESGza0to3bOtrodKei2s9bk5MXm7lZ qI+WZJX4Zu9+mzZhc9pCVi8r/qlXuQIDAQABo4GnMIGkMB0GA1UdDgQWBBRvavf+ sWM4IwKiH9X9w1vl6nUVRDB1BgNVHSMEbjBsgBRvavf+sWM4IwKiH9X9w1vl6nUV RKFJpEcwRTELMAkGA1UEBhMCVVMxEzARBgNVBAgTClNvbWUtU3RhdGUxITAfBgNV BAoTGEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZIIJAM15n7fdxhRtMAwGA1UdEwQF MAMBAf8wDQYJKoZIhvcNAQEFBQADggEBABY2ZzBaW0dMsAAT7tPJzrVWVzQx6KU4 UEBLudIlWPlkAwTnINCWR/8eNjCCmGA4heUdHmazdpPa8RzwOmc0NT1NQqzSyktt vTqb4iHD7+8f9MqJ9/FssCfTtqr/Qst/hGH4Wmdf1EJ/6FqYAAb5iRlPgshFZxU8 uXtA8hWn6fK6eISD9HBdcAFToUvKNZ1BIDPvh9f95Ine8ar6yGd56TUNrHR8eHBs ESxz5ddVR/oWRysNJ+aGAyYqHS8S/ttmC7r4XCAHqXptkHPCGRqkAhsterYhd4I8 /cBzejUobNCjjHFbtkAL/SjxZOLW+pNkZwfeYdM8iPkD54Uua1v2tdw= -----END CERTIFICATE-----", 279 PrivateKey: "-----BEGIN RSA PRIVATE KEY-----MIIEowIBAAKCAQEAl 1cSc0vfcJLI4ZdWjiZZqy86Eof4czCwilyjXdvHqbdgDjz9H6K/0FX78EzVdfyExESptPCDl5YYjvcZyAWlgNfYEpFpGeoh/pTFW3hlyKImh4EgBXbDrR251J Ew2Nf56X3duibI6X20gKZA6cvdmWeKh MOOXuh1bSPU3dkb4YOF/fng5iGrx0q3txdMQXTPMZ1uXHFcBH7idgViYesXUBhdll3GP1N Y8laq0yrqh 8HMsZK m27MebqonbNmjOqE218lVEvjCdRO6xvNXrO6vNJBoGn2eGwZ8BVd0mTA3Tj43/2cmxQFY9FLq56cCXqYI1fbRRib ZLrjSNkwIDAQABAoIBABfAjjsjjxc0NxcYvKOMUb9Rpj8Sx6U/o/tDC5u XmsGX37aaJmC5yw9BQiAxgvXtQryEl5uoNoqOdsxzKV6yM0vPcwKEJVBd4G6yx6AjVJZnc2qf72erR7BbA2CQh scMDRBKE041HhgTBRNP6roim0SOgYP5JZIrGAQXNIkyE0fZc5gZNUt388ne/mjWM6Xi08BDGurLC68nsdt7Nd UYqeBVxo2EqChp5vKYZYEcG8h9XBj4u4NIwg1Mty2JqX30uBjoHvF5w/pMs8lG uvj6JR9I 19wtCuccbAJl 4cUq03UQoIDmwejea oC8A8WJr3vVpODDWrvAsjllGPBECgYEAyQRa6edYO6bsSvgbM13qXW9OQTn9YmgzfN24Ux1D66TQU6sBSLdfSHshDhTCi Ax 698aJNRWujAakA2DDgspSx98aRnHbF zvY7i7iWGesN6uN0zL 6/MK5uWoieGZRjgk230fLk00l4/FK1mJIp0apr0Lis9xmDjP5AaUPTUUCgYEAwXuhTHZWPT6v8YwOksjbuK UDkIIvyMux53kb73vrkgMboS4DB1zMLNyG 9EghS414CFROUwGl4ZUKboH1Jo5G34y8VgDuHjirTqL2H6 zNpML iMrWCXjpFKkxwPbeQnEAZ 5Rud4d PTyXAt71blZHE9tZ4KHy8cU1iKc9APcCgYAIqKZd4vg7AZK2G//X85iv06aUSrIudfyZyVcyRVVyphPPNtOEVVnGXn9rAtvqeIrOo52BR68 cj4vlXp hkDuEH QVBuY/NdQhOzFtPrKPQTJdGjIlQ2x65Vidj7r3sRukNkLPyV2v D885zcpTkp83JFuWTYiIrg275DIuAI3QKBgAglM0IrzS g3vlVQxvM1ussgRgkkYeybHq82 wUW 3DXLqeXb0s1DedplUkuoabZriz0Wh4GZFSmtA5ZpZC uV697lkYsndmp2xRhaekllW7bu pY5q88URwO2p8CO5AZ6CWFWuBwSDML5VOapGRqDRgwaD oGpb7fb7IgHOls7AoGBAJnL6Q8t35uYJ8J8hY7wso88IE04z6VaT8WganxcndesWER9eFQDHDDy//ZYeyt6M41uIY CL Vkm9Kwl/bHLJKdnOE1a9NdE6mtfah0Bk2u/YOuzyu5mmcgZiX X/OZuEbGmmbZOR1FCuIyrNYfwYohhcZP7/r0Ia/1GpkHc3Bi-----END RSA PRIVATE KEY-----", 280 BundleMethod: "ubiquitous", 281 GeoRestrictions: &ZoneCustomSSLGeoRestrictions{Label: "us"}, 282 }) 283 if assert.NoError(t, err) { 284 assert.Equal(t, want, actual) 285 } 286 287 _, err = client.UpdateSSL(context.Background(), "023e105f4ecef8ad9ca31a8372d0c353", "bar", ZoneCustomSSLOptions{}) 288 assert.Error(t, err) 289} 290 291func TestReprioritizeSSL(t *testing.T) { 292 setup() 293 defer teardown() 294 295 handler := func(w http.ResponseWriter, r *http.Request) { 296 assert.Equal(t, http.MethodPut, r.Method, "Expected method 'PUT', got %s", r.Method) 297 b, err := ioutil.ReadAll(r.Body) 298 defer r.Body.Close() 299 if assert.NoError(t, err) { 300 assert.JSONEq(t, `{"certificates":[{"ID":"5a7805061c76ada191ed06f989cc3dac","priority":2},{"ID":"9a7806061c88ada191ed06f989cc3dac","priority":1}]}`, string(b)) 301 } 302 303 w.Header().Set("content-type", "application/json") 304 // XXX: Test response flow properly. 305 // Current response assertion uses generic example from the documentation, 306 // rather than responding to the actual PUT request. 307 // https://api.cloudflare.com/#custom-ssl-for-a-zone-re-prioritize-ssl-certificates 308 fmt.Fprint(w, `{ 309 "success": true, 310 "errors": [], 311 "messages": [], 312 "result": [ 313 { 314 "id": "7e7b8deba8538af625850b7b2530034c", 315 "hosts": [ 316 "example.com" 317 ], 318 "issuer": "GlobalSign", 319 "signature": "SHA256WithRSA", 320 "status": "active", 321 "bundle_method": "ubiquitous", 322 "zone_id": "023e105f4ecef8ad9ca31a8372d0c353", 323 "uploaded_on": "2014-01-01T05:20:00Z", 324 "modified_on": "2014-01-01T05:20:00Z", 325 "expires_on": "2016-01-01T05:20:00Z", 326 "priority": 1 327 } 328 ], 329 "result_info": { 330 "page": 1, 331 "per_page": 20, 332 "count": 1, 333 "total_count": 2000 334 } 335 }`) 336 } 337 338 mux.HandleFunc("/zones/023e105f4ecef8ad9ca31a8372d0c353/custom_certificates/prioritize", handler) 339 340 hosts := make([]string, 1, 4) 341 hosts[0] = "example.com" 342 uploadedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z") 343 modifiedOn, _ := time.Parse(time.RFC3339, "2014-01-01T05:20:00Z") 344 expiresOn, _ := time.Parse(time.RFC3339, "2016-01-01T05:20:00Z") 345 346 want := make([]ZoneCustomSSL, 1, 4) 347 want[0] = ZoneCustomSSL{ 348 ID: "7e7b8deba8538af625850b7b2530034c", 349 Hosts: hosts, 350 Issuer: "GlobalSign", 351 Signature: "SHA256WithRSA", 352 Status: "active", 353 BundleMethod: "ubiquitous", 354 ZoneID: "023e105f4ecef8ad9ca31a8372d0c353", 355 UploadedOn: uploadedOn, 356 ModifiedOn: modifiedOn, 357 ExpiresOn: expiresOn, 358 Priority: 1, 359 } 360 361 actual, err := client.ReprioritizeSSL(context.Background(), "023e105f4ecef8ad9ca31a8372d0c353", []ZoneCustomSSLPriority{ 362 {ID: "5a7805061c76ada191ed06f989cc3dac", Priority: 2}, 363 {ID: "9a7806061c88ada191ed06f989cc3dac", Priority: 1}, 364 }) 365 366 if assert.NoError(t, err) { 367 assert.Equal(t, want, actual) 368 } 369} 370 371func TestDeleteSSL(t *testing.T) { 372 setup() 373 defer teardown() 374 375 handler := func(w http.ResponseWriter, r *http.Request) { 376 assert.Equal(t, http.MethodDelete, r.Method, "Expected method 'DELETE', got %s", r.Method) 377 w.Header().Set("content-type", "application/json") 378 fmt.Fprint(w, `{ 379 "id": "7e7b8deba8538af625850b7b2530034c" 380 }`) 381 } 382 383 mux.HandleFunc("/zones/023e105f4ecef8ad9ca31a8372d0c353/custom_certificates/7e7b8deba8538af625850b7b2530034c", handler) 384 385 err := client.DeleteSSL(context.Background(), "023e105f4ecef8ad9ca31a8372d0c353", "7e7b8deba8538af625850b7b2530034c") 386 assert.NoError(t, err, "Expected to successfully delete certificate ID '7e7b8deba8538af625850b7b2530034c', received error instead") 387 388 err = client.DeleteSSL(context.Background(), "023e105f4ecef8ad9ca31a8372d0c353", "bar") 389 assert.Error(t, err, "Expected to error when attempting to delete certificate ID 'bar', did not receive error instead") 390} 391