github.com/clerkinc/clerk-sdk-go@v1.49.1/clerk/saml_connections_test.go (about) 1 package clerk 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "net/http" 7 "net/url" 8 "reflect" 9 "testing" 10 11 "github.com/stretchr/testify/assert" 12 ) 13 14 func TestSAMLConnectionsService_ListAll(t *testing.T) { 15 c, mux, _, teardown := setup("token") 16 defer teardown() 17 18 dummyResponse := fmt.Sprintf(`{ 19 "data": [%s], 20 "total_count": 1 21 }`, dummySAMLConnectionJSON) 22 23 mux.HandleFunc("/saml_connections", func(w http.ResponseWriter, req *http.Request) { 24 testHttpMethod(t, req, http.MethodGet) 25 testHeader(t, req, "Authorization", "Bearer token") 26 27 expectedQuery := url.Values{ 28 "limit": {"5"}, 29 "offset": {"6"}, 30 "query": {"my-query"}, 31 "order_by": {"created_at"}, 32 } 33 assert.Equal(t, expectedQuery, req.URL.Query()) 34 35 _, _ = fmt.Fprint(w, dummyResponse) 36 }) 37 38 listParams := ListSAMLConnectionsParams{ 39 Limit: intToPtr(5), 40 Offset: intToPtr(6), 41 Query: stringToPtr("my-query"), 42 OrderBy: stringToPtr("created_at"), 43 } 44 45 got, err := c.SAMLConnections().ListAll(listParams) 46 assert.NoError(t, err) 47 48 expected := &ListSAMLConnectionsResponse{} 49 _ = json.Unmarshal([]byte(dummyResponse), expected) 50 51 if !reflect.DeepEqual(got, expected) { 52 t.Errorf("Response = %v, want %v", got, expected) 53 } 54 } 55 56 func TestSAMLConnectionsService_Read(t *testing.T) { 57 dummyResponse := dummySAMLConnectionJSON 58 59 c, mux, _, teardown := setup("token") 60 defer teardown() 61 62 url := fmt.Sprintf("/saml_connections/%s", dummySAMLConnectionID) 63 64 mux.HandleFunc(url, func(w http.ResponseWriter, req *http.Request) { 65 testHttpMethod(t, req, http.MethodGet) 66 testHeader(t, req, "Authorization", "Bearer token") 67 _, _ = fmt.Fprint(w, dummyResponse) 68 }) 69 70 got, err := c.SAMLConnections().Read(dummySAMLConnectionID) 71 assert.NoError(t, err) 72 73 expected := SAMLConnection{} 74 _ = json.Unmarshal([]byte(dummyResponse), &expected) 75 76 if !reflect.DeepEqual(*got, expected) { 77 t.Errorf("Response = %v, want %v", got, expected) 78 } 79 } 80 81 func TestSAMLConnectionsService_Create(t *testing.T) { 82 dummyResponse := dummySAMLConnectionJSON 83 84 c, mux, _, teardown := setup("token") 85 defer teardown() 86 87 mux.HandleFunc("/saml_connections", func(w http.ResponseWriter, req *http.Request) { 88 testHttpMethod(t, req, http.MethodPost) 89 testHeader(t, req, "Authorization", "Bearer token") 90 _, _ = fmt.Fprint(w, dummyResponse) 91 }) 92 93 createParams := &CreateSAMLConnectionParams{ 94 Name: "Testing SAML", 95 Domain: "example.com", 96 Provider: "saml_custom", 97 IdpEntityID: stringToPtr("test-idp-entity-id"), 98 IdpSsoURL: stringToPtr("https://example.com/saml/sso"), 99 IdpCertificate: stringToPtr(dummySAMLConnectionCertificate), 100 } 101 102 got, err := c.SAMLConnections().Create(createParams) 103 assert.NoError(t, err) 104 105 expected := SAMLConnection{} 106 _ = json.Unmarshal([]byte(dummyResponse), &expected) 107 108 if !reflect.DeepEqual(*got, expected) { 109 t.Errorf("Response = %v, want %v", got, expected) 110 } 111 } 112 113 func TestSAMLConnectionsService_Update(t *testing.T) { 114 expectedName := "New name for Testing SAML" 115 expectedActive := true 116 expectedSyncUserAttributes := false 117 expectedAllowSubdomains := true 118 expectedAllowIdpInitiated := true 119 dummyResponse := dummySAMLConnectionUpdatedJSON 120 121 c, mux, _, teardown := setup("token") 122 defer teardown() 123 124 url := fmt.Sprintf("/saml_connections/%s", dummySAMLConnectionID) 125 126 mux.HandleFunc(url, func(w http.ResponseWriter, req *http.Request) { 127 testHttpMethod(t, req, http.MethodPatch) 128 testHeader(t, req, "Authorization", "Bearer token") 129 _, _ = fmt.Fprint(w, dummyResponse) 130 }) 131 132 updateParams := &UpdateSAMLConnectionParams{ 133 Name: &expectedName, 134 Active: &expectedActive, 135 SyncUserAttributes: &expectedSyncUserAttributes, 136 IdpMetadataURL: stringToPtr("https://example.com/saml/metadata"), 137 IdpMetadata: stringToPtr(dummyIdpMetadata), 138 AttributeMapping: &SAMLConnectionAttributeMapping{ 139 UserID: "custom_user_id", 140 EmailAddress: "custom_email", 141 FirstName: "custom_first", 142 LastName: "custom_last", 143 }, 144 AllowSubdomains: &expectedAllowSubdomains, 145 AllowIdpInitiated: &expectedAllowIdpInitiated, 146 } 147 148 got, err := c.SAMLConnections().Update(dummySAMLConnectionID, updateParams) 149 assert.NoError(t, err) 150 151 expected := SAMLConnection{} 152 _ = json.Unmarshal([]byte(dummyResponse), &expected) 153 154 if !reflect.DeepEqual(*got, expected) { 155 t.Errorf("Response = %v, want %v", got, expected) 156 } 157 } 158 159 func TestSAMLConnectionsService_Delete(t *testing.T) { 160 c, mux, _, teardown := setup("token") 161 defer teardown() 162 163 url := fmt.Sprintf("/saml_connections/%s", dummySAMLConnectionID) 164 165 mux.HandleFunc(url, func(w http.ResponseWriter, req *http.Request) { 166 testHttpMethod(t, req, http.MethodDelete) 167 testHeader(t, req, "Authorization", "Bearer token") 168 response := fmt.Sprintf(`{ "deleted": true, "id": "%s", "object": "saml_connection" }`, dummySAMLConnectionID) 169 _, _ = fmt.Fprint(w, response) 170 }) 171 172 expected := DeleteResponse{ 173 ID: dummySAMLConnectionID, 174 Object: "saml_connection", 175 Deleted: true, 176 } 177 178 got, err := c.SAMLConnections().Delete(dummySAMLConnectionID) 179 assert.NoError(t, err) 180 181 if !reflect.DeepEqual(*got, expected) { 182 t.Errorf("Response = %v, want %v", *got, expected) 183 } 184 } 185 186 const ( 187 dummySAMLConnectionID = "samlc_2P17P4pXsx8MmunM1pkeYeimDDd" 188 189 dummySAMLConnectionJSON = ` 190 { 191 "object": "saml_connection", 192 "id": "` + dummySAMLConnectionID + `", 193 "name": "Testing SAML", 194 "domain": "example.com", 195 "idp_entity_id": "test-idp-entity-id", 196 "idp_sso_url": "https://example.com/saml/sso", 197 "idp_certificate": "` + dummySAMLConnectionCertificate + `", 198 "idp_metadata_url": "https://example.com/saml/metadata", 199 "acs_url": "` + "https://clerk.example.com/v1/saml/acs/" + dummySAMLConnectionID + `", 200 "sp_entity_id": "` + "https://clerk.example.com/saml/" + dummySAMLConnectionID + `", 201 "sp_metadata_url": "` + "https://clerk.example.com/v1/saml/metadata/" + dummySAMLConnectionID + `", 202 "attribute_mapping": { 203 "user_id": "id", 204 "email_address": "mail", 205 "first_name": "firstName", 206 "last_name": "lastName" 207 }, 208 "active": false, 209 "provider": "saml_custom", 210 "user_count": 3, 211 "sync_user_attributes": true, 212 "allow_subdomains": false, 213 "allow_idp_initiated": false 214 }` 215 216 dummySAMLConnectionUpdatedJSON = ` 217 { 218 "object": "saml_connection", 219 "id": "` + dummySAMLConnectionID + `", 220 "name": "New name for Testing SAML", 221 "domain": "example.com", 222 "idp_entity_id": "test-idp-entity-id", 223 "idp_sso_url": "https://example.com/saml/sso", 224 "idp_certificate": "` + dummySAMLConnectionCertificate + `", 225 "idp_metadata_url": "https://example.com/saml/metadata", 226 "idp_metadata": "` + dummyIdpMetadata + `", 227 "acs_url": "` + "https://clerk.example.com/v1/saml/acs/" + dummySAMLConnectionID + `", 228 "sp_entity_id": "` + "https://clerk.example.com/saml/" + dummySAMLConnectionID + `", 229 "sp_metadata_url": "` + "https://clerk.example.com/v1/saml/metadata/" + dummySAMLConnectionID + `", 230 "attribute_mapping": { 231 "user_id": "custom_id", 232 "email_address": "custom_email", 233 "first_name": "custom_first", 234 "last_name": "custom_last" 235 }, 236 "active": true, 237 "provider": "saml_custom", 238 "user_count": 3, 239 "sync_user_attributes": false, 240 "allow_subdomains": true, 241 "allow_idp_initiated": true 242 }` 243 244 dummySAMLConnectionCertificate = `MIIDBzCCAe+gAwIBAgIJAPr/Mrlc8EGhMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTAeFw0xNTEyMjgxOTE5NDVaFw0yNTEyMjUxOTE5NDVaMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANDoWzLos4LWxTn8Gyu2lEbl4WcelUbgLN5zYm4ron8Ahs+rvcsu2zkdD/s6jdGJI8WqJKhYK2u61ygnXgAZqC6ggtFPnBpizcDzjgND2g+aucSoUODHt67f0fQuAmupN/zp5MZysJ6IHLJnYLNpfJYk96lRz9ODnO1Mpqtr9PWxm+pz7nzq5F0vRepkgpcRxv6ufQBjlrFytccyEVdXrvFtkjXcnhVVNSR4kHuOOMS6D7pebSJ1mrCmshbD5SX1jXPBKFPAjozYX6PxqLxUx1Y4faFEf4MBBVcInyB4oURNB2s59hEEi2jq9izNE7EbEK6BY5sEhoCPl9m32zE6ljkCAwEAAaNQME4wHQYDVR0OBBYEFB9ZklC1Ork2zl56zg08ei7ss/+iMB8GA1UdIwQYMBaAFB9ZklC1Ork2zl56zg08ei7ss/+iMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAVoTSQ5pAirw8OR9FZ1bRSuTDhY9uxzl/OL7lUmsv2cMNeCB3BRZqm3mFt+cwN8GsH6f3uvNONIhgFpTGN5LEcXQz89zJEzB+qaHqmbFpHQl/sx2B8ezNgT/882H2IH00dXESEfy/+1gHg2pxjGnhRBN6el/gSaDiySIMKbilDrffuvxiCfbpPN0NRRiPJhd2ay9KuL/RxQRl1gl9cHaWiouWWba1bSBb2ZPhv2rPMUsFo98ntkGCObDX6Y1SpkqmoTbrsbGFsTG2DLxnvr4GdN1BSr0Uu/KV3adj47WkXVPeMYQti/bQmxQB8tRFhrw80qakTLUzreO96WzlBBMtY=` 245 246 dummyIdpMetadata = `<?xml version=\"1.0\" encoding=\"UTF-8\"?><md:EntityDescriptor entityID=\"test-idp-entity-id\" xmlns:md=\"urn:oasis:names:tc:SAML:2.0:metadata\"><md:IDPSSODescriptor WantAuthnRequestsSigned=\"false\" protocolSupportEnumeration=\"urn:oasis:names:tc:SAML:2.0:protocol\"><md:KeyDescriptor use=\"signing\"><ds:KeyInfo xmlns:ds=\"http://www.w3.org/2000/09/xmldsig#\"><ds:X509Data><ds:X509Certificate>MIIDBzCCAe+gAwIBAgIJAPr/Mrlc8EGhMA0GCSqGSIb3DQEBBQUAMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTAeFw0xNTEyMjgxOTE5NDVaFw0yNTEyMjUxOTE5NDVaMBoxGDAWBgNVBAMMD3d3dy5leGFtcGxlLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANDoWzLos4LWxTn8Gyu2lEbl4WcelUbgLN5zYm4ron8Ahs+rvcsu2zkdD/s6jdGJI8WqJKhYK2u61ygnXgAZqC6ggtFPnBpizcDzjgND2g+aucSoUODHt67f0fQuAmupN/zp5MZysJ6IHLJnYLNpfJYk96lRz9ODnO1Mpqtr9PWxm+pz7nzq5F0vRepkgpcRxv6ufQBjlrFytccyEVdXrvFtkjXcnhVVNSR4kHuOOMS6D7pebSJ1mrCmshbD5SX1jXPBKFPAjozYX6PxqLxUx1Y4faFEf4MBBVcInyB4oURNB2s59hEEi2jq9izNE7EbEK6BY5sEhoCPl9m32zE6ljkCAwEAAaNQME4wHQYDVR0OBBYEFB9ZklC1Ork2zl56zg08ei7ss/+iMB8GA1UdIwQYMBaAFB9ZklC1Ork2zl56zg08ei7ss/+iMAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEFBQADggEBAAVoTSQ5pAirw8OR9FZ1bRSuTDhY9uxzl/OL7lUmsv2cMNeCB3BRZqm3mFt+cwN8GsH6f3uvNONIhgFpTGN5LEcXQz89zJEzB+qaHqmbFpHQl/sx2B8ezNgT/882H2IH00dXESEfy/+1gHg2pxjGnhRBN6el/gSaDiySIMKbilDrffuvxiCfbpPN0NRRiPJhd2ay9KuL/RxQRl1gl9cHaWiouWWba1bSBb2ZPhv2rPMUsFo98ntkGCObDX6Y1SpkqmoTbrsbGFsTG2DLxnvr4GdN1BSr0Uu/KV3adj47WkXVPeMYQti/bQmxQB8tRFhrw80qakTLUzreO96WzlBBMtY=</ds:X509Certificate></ds:X509Data></ds:KeyInfo></md:KeyDescriptor><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:unspecified</md:NameIDFormat><md:NameIDFormat>urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress</md:NameIDFormat><md:SingleSignOnService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\" Location=\"https://example.com/saml/sso\"/></md:IDPSSODescriptor></md:EntityDescriptor>` 247 )