github.com/snowflakedb/gosnowflake@v1.9.0/authexternalbrowser_test.go (about) 1 // Copyright (c) 2022 Snowflake Computing Inc. All rights reserved. 2 3 package gosnowflake 4 5 import ( 6 "context" 7 "errors" 8 "net/url" 9 "strings" 10 "testing" 11 "time" 12 ) 13 14 func TestGetTokenFromResponseFail(t *testing.T) { 15 response := "GET /?fakeToken=fakeEncodedSamlToken HTTP/1.1\r\n" + 16 "Host: localhost:54001\r\n" + 17 "Connection: keep-alive\r\n" + 18 "Upgrade-Insecure-Requests: 1\r\n" + 19 "User-Agent: userAgentStr\r\n" + 20 "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\n" + 21 "Referer: https://myaccount.snowflakecomputing.com/fed/login\r\n" + 22 "Accept-Encoding: gzip, deflate, br\r\n" + 23 "Accept-Language: en-US,en;q=0.9\r\n\r\n" 24 25 _, err := getTokenFromResponse(response) 26 if err == nil { 27 t.Errorf("Should have failed parsing the malformed response.") 28 } 29 } 30 31 func TestGetTokenFromResponse(t *testing.T) { 32 response := "GET /?token=GETtokenFromResponse HTTP/1.1\r\n" + 33 "Host: localhost:54001\r\n" + 34 "Connection: keep-alive\r\n" + 35 "Upgrade-Insecure-Requests: 1\r\n" + 36 "User-Agent: userAgentStr\r\n" + 37 "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8\r\n" + 38 "Referer: https://myaccount.snowflakecomputing.com/fed/login\r\n" + 39 "Accept-Encoding: gzip, deflate, br\r\n" + 40 "Accept-Language: en-US,en;q=0.9\r\n\r\n" 41 42 expected := "GETtokenFromResponse" 43 44 token, err := getTokenFromResponse(response) 45 if err != nil { 46 t.Errorf("Failed to get the token. Err: %#v", err) 47 } 48 if token != expected { 49 t.Errorf("Expected: %s, found: %s", expected, token) 50 } 51 } 52 53 func TestBuildResponse(t *testing.T) { 54 resp := buildResponse("Go") 55 bytes := resp.Bytes() 56 respStr := string(bytes[:]) 57 if !strings.Contains(respStr, "Your identity was confirmed and propagated to Snowflake Go.\nYou can close this window now and go back where you started from.") { 58 t.Fatalf("failed to build response") 59 } 60 } 61 62 func postAuthExternalBrowserError(_ context.Context, _ *snowflakeRestful, _ map[string]string, _ []byte, _ time.Duration) (*authResponse, error) { 63 return &authResponse{}, errors.New("failed to get SAML response") 64 } 65 66 func postAuthExternalBrowserFail(_ context.Context, _ *snowflakeRestful, _ map[string]string, _ []byte, _ time.Duration) (*authResponse, error) { 67 return &authResponse{ 68 Success: false, 69 Message: "external browser auth failed", 70 }, nil 71 } 72 73 func postAuthExternalBrowserFailWithCode(_ context.Context, _ *snowflakeRestful, _ map[string]string, _ []byte, _ time.Duration) (*authResponse, error) { 74 return &authResponse{ 75 Success: false, 76 Message: "failed to connect to db", 77 Code: "260008", 78 }, nil 79 } 80 81 func TestUnitAuthenticateByExternalBrowser(t *testing.T) { 82 authenticator := "externalbrowser" 83 application := "testapp" 84 account := "testaccount" 85 user := "u" 86 password := "p" 87 timeout := defaultExternalBrowserTimeout 88 sr := &snowflakeRestful{ 89 Protocol: "https", 90 Host: "abc.com", 91 Port: 443, 92 FuncPostAuthSAML: postAuthExternalBrowserError, 93 TokenAccessor: getSimpleTokenAccessor(), 94 } 95 _, _, err := authenticateByExternalBrowser(context.Background(), sr, authenticator, application, account, user, password, timeout, ConfigBoolTrue) 96 if err == nil { 97 t.Fatal("should have failed.") 98 } 99 sr.FuncPostAuthSAML = postAuthExternalBrowserFail 100 _, _, err = authenticateByExternalBrowser(context.Background(), sr, authenticator, application, account, user, password, timeout, ConfigBoolTrue) 101 if err == nil { 102 t.Fatal("should have failed.") 103 } 104 sr.FuncPostAuthSAML = postAuthExternalBrowserFailWithCode 105 _, _, err = authenticateByExternalBrowser(context.Background(), sr, authenticator, application, account, user, password, timeout, ConfigBoolTrue) 106 if err == nil { 107 t.Fatal("should have failed.") 108 } 109 driverErr, ok := err.(*SnowflakeError) 110 if !ok { 111 t.Fatalf("should be snowflake error. err: %v", err) 112 } 113 if driverErr.Number != ErrCodeFailedToConnect { 114 t.Fatalf("unexpected error code. expected: %v, got: %v", ErrCodeFailedToConnect, driverErr.Number) 115 } 116 } 117 118 func TestAuthenticationTimeout(t *testing.T) { 119 authenticator := "externalbrowser" 120 application := "testapp" 121 account := "testaccount" 122 user := "u" 123 password := "p" 124 timeout := 0 * time.Second 125 sr := &snowflakeRestful{ 126 Protocol: "https", 127 Host: "abc.com", 128 Port: 443, 129 FuncPostAuthSAML: postAuthExternalBrowserError, 130 TokenAccessor: getSimpleTokenAccessor(), 131 } 132 _, _, err := authenticateByExternalBrowser(context.Background(), sr, authenticator, application, account, user, password, timeout, ConfigBoolTrue) 133 if err.Error() != "authentication timed out" { 134 t.Fatal("should have timed out") 135 } 136 } 137 138 func Test_createLocalTCPListener(t *testing.T) { 139 listener, err := createLocalTCPListener() 140 if err != nil { 141 t.Fatalf("createLocalTCPListener() failed: %v", err) 142 } 143 if listener == nil { 144 t.Fatal("createLocalTCPListener() returned nil listener") 145 } 146 147 // Close the listener after the test. 148 defer listener.Close() 149 } 150 151 func TestUnitGetLoginURL(t *testing.T) { 152 expectedScheme := "https" 153 expectedHost := "abc.com:443" 154 user := "u" 155 callbackPort := 123 156 sr := &snowflakeRestful{ 157 Protocol: "https", 158 Host: "abc.com", 159 Port: 443, 160 TokenAccessor: getSimpleTokenAccessor(), 161 } 162 163 loginURL, proofKey, err := getLoginURL(sr, user, callbackPort) 164 assertNilF(t, err, "failed to get login URL") 165 assertNotNilF(t, len(proofKey), "proofKey should be non-empty string") 166 167 urlPtr, err := url.Parse(loginURL) 168 assertNilF(t, err, "failed to parse the login URL") 169 assertEqualF(t, urlPtr.Scheme, expectedScheme) 170 assertEqualF(t, urlPtr.Host, expectedHost) 171 assertEqualF(t, urlPtr.Path, consoleLoginRequestPath) 172 assertStringContainsF(t, urlPtr.RawQuery, "login_name") 173 assertStringContainsF(t, urlPtr.RawQuery, "browser_mode_redirect_port") 174 assertStringContainsF(t, urlPtr.RawQuery, "proof_key") 175 }