Repository: snowflakedb/gosnowflake
Pull request #386 (2021-02-26 05:40:38)

SNOW-209081 Allow bypass authentication by re-using token from accessor
SNOW-209081

### Description
Description
Introduce a no-op authentication type that bypasses the actual authentication
by grabbing the auth token and session from the existing token accessor.

Testing
add new unit test case to verify that post auth http call is not made when auth type is token accessor

### Checklist
- [x] Code compiles correctly
- [x] Run ``make fmt`` to fix inconsistent formats
- [x] Run ``make lint`` to get lint errors and fix all of them
- [x] Created tests which fail without the change (if possible)
- [x] All tests passing
- [ ] Extended the README / documentation, if necessary



Patch:
diff --git a/auth.go b/auth.go
index 33fc060..f6d080a 100644
--- a/auth.go
+++ b/auth.go
@@ -39,6 +39,8 @@ const (
 	AuthTypeOkta
 	// AuthTypeJwt is to use Jwt to perform authentication
 	AuthTypeJwt
+	// AuthTypeTokenAccessor is to use the provided token accessor and bypass authentication
+	AuthTypeTokenAccessor
 )
 
 func determineAuthenticatorType(cfg *Config, value string) error {
@@ -101,6 +103,8 @@ func (authType AuthType) String() string {
 		return "OKTA"
 	case AuthTypeJwt:
 		return "SNOWFLAKE_JWT"
+	case AuthTypeTokenAccessor:
+		return "TOKENACCESSOR"
 	default:
 		return "UNKNOWN"
 	}
@@ -318,6 +322,21 @@ func authenticate(
 			requestMain.Passcode = sc.cfg.Passcode
 			requestMain.ExtAuthnDuoMethod = "passcode"
 		}
+	case AuthTypeTokenAccessor:
+		logger.Info("Bypass authentication using existing token from token accessor")
+		sessionInfo := authResponseSessionInfo{
+			DatabaseName:  sc.cfg.Database,
+			SchemaName:    sc.cfg.Schema,
+			WarehouseName: sc.cfg.Warehouse,
+			RoleName:      sc.cfg.Role,
+		}
+		token, masterToken, sessionID := sc.cfg.TokenAccessor.GetTokens()
+		return &authResponseMain{
+			Token:       token,
+			MasterToken: masterToken,
+			SessionID:   sessionID,
+			SessionInfo: sessionInfo,
+		}, nil
 	}
 
 	authRequest := authRequest{


Test patch:
diff --git a/auth_test.go b/auth_test.go
index 9e74507..c827a9c 100644
--- a/auth_test.go
+++ b/auth_test.go
@@ -251,6 +251,51 @@ func getDefaultSnowflakeConn() *snowflakeConn {
 	return sc
 }
 
+func TestUnitAuthenticateWithTokenAccessor(t *testing.T) {
+	expectedSessionID := 123
+	expectedMasterToken := "master_token"
+	expectedToken := "auth_token"
+
+	ta := getSimpleTokenAccessor()
+	ta.SetTokens(expectedToken, expectedMasterToken, expectedSessionID)
+	sc := getDefaultSnowflakeConn()
+	sc.cfg.Authenticator = AuthTypeTokenAccessor
+	sc.cfg.TokenAccessor = ta
+	sr := &snowflakeRestful{
+		FuncPostAuth:  postAuthFailServiceIssue,
+		TokenAccessor: ta,
+	}
+	sc.rest = sr
+
+	// FuncPostAuth is set to fail, but AuthTypeTokenAccessor should not even make a call to FuncPostAuth
+	resp, err := authenticate(context.TODO(), sc, []byte{}, []byte{})
+	if err != nil {
+		t.Fatalf("should not have failed, err %v", err)
+	}
+
+	if resp.SessionID != expectedSessionID {
+		t.Fatalf("Expected session id %v but got %v", expectedSessionID, resp.SessionID)
+	}
+	if resp.Token != expectedToken {
+		t.Fatalf("Expected token %v but got %v", expectedToken, resp.Token)
+	}
+	if resp.MasterToken != expectedMasterToken {
+		t.Fatalf("Expected master token %v but got %v", expectedMasterToken, resp.MasterToken)
+	}
+	if resp.SessionInfo.DatabaseName != sc.cfg.Database {
+		t.Fatalf("Expected database %v but got %v", sc.cfg.Database, resp.SessionInfo.DatabaseName)
+	}
+	if resp.SessionInfo.WarehouseName != sc.cfg.Warehouse {
+		t.Fatalf("Expected warehouse %v but got %v", sc.cfg.Warehouse, resp.SessionInfo.WarehouseName)
+	}
+	if resp.SessionInfo.RoleName != sc.cfg.Role {
+		t.Fatalf("Expected role %v but got %v", sc.cfg.Role, resp.SessionInfo.RoleName)
+	}
+	if resp.SessionInfo.SchemaName != sc.cfg.Schema {
+		t.Fatalf("Expected schema %v but got %v", sc.cfg.Schema, resp.SessionInfo.SchemaName)
+	}
+}
+
 func TestUnitAuthenticate(t *testing.T) {
 	var err error
 	var driverErr *SnowflakeError