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  )