コード例 #1
0
 public override bool Equals(object obj)
 {
     if (obj == null)
     {
         return(false);
     }
     try
     {
         SFSessionProperties prop = (SFSessionProperties)obj;
         foreach (SFSessionProperty sessionProperty in Enum.GetValues(typeof(SFSessionProperty)))
         {
             if (this.ContainsKey(sessionProperty) ^ prop.ContainsKey(sessionProperty))
             {
                 return(false);
             }
             if (!this.ContainsKey(sessionProperty))
             {
                 continue;
             }
             if (!this[sessionProperty].Equals(prop[sessionProperty]))
             {
                 return(false);
             }
         }
         return(true);
     }
     catch (InvalidCastException)
     {
         logger.Warn("Invalid casting to SFSessionProperties");
         return(false);
     }
 }
        /// <see cref="IAuthenticator"/>
        async Task IAuthenticator.AuthenticateAsync(CancellationToken cancellationToken)
        {
            logger.Info("External Browser Authentication");

            int    localPort = GetRandomUnusedPort();
            string proofKey;
            string samlResponseToken;

            using (var httpListener = GetHttpListener(localPort))
            {
                httpListener.Start();

                logger.Debug("Get IdpUrl and ProofKey");
                var authenticatorRestRequest  = BuildAuthenticatorRestRequest(localPort);
                var authenticatorRestResponse =
                    await session.restRequester.PostAsync <AuthenticatorResponse>(
                        authenticatorRestRequest,
                        cancellationToken
                        ).ConfigureAwait(false);

                authenticatorRestResponse.FilterFailedResponse();

                var idpUrl = authenticatorRestResponse.data.ssoUrl;
                proofKey = authenticatorRestResponse.data.proofKey;

                logger.Debug("Open browser");
                StartBrowser(idpUrl);

                logger.Debug("Get the redirect SAML request");
                var context = await httpListener.GetContextAsync().ConfigureAwait(false);

                var request = context.Request;
                samlResponseToken = ValidateAndExtractToken(request);
                HttpListenerResponse response = context.Response;
                try
                {
                    using (var output = response.OutputStream)
                    {
                        await output.WriteAsync(SUCCESS_RESPONSE, 0, SUCCESS_RESPONSE.Length).ConfigureAwait(false);
                    }
                }
                catch (Exception e)
                {
                    // Ignore the exception as it does not affect the overall authentication flow
                    logger.Warn("External browser response not sent out");
                }

                httpListener.Stop();
            }

            logger.Debug("Send login request");
            var loginResponse = await session.restRequester.PostAsync <LoginResponse>(
                BuildExternalBrowserLoginRequest(samlResponseToken, proofKey),
                cancellationToken
                ).ConfigureAwait(false);

            session.ProcessLoginResponse(loginResponse);
        }
コード例 #3
0
        internal static SFSessionProperties parseConnectionString(String connectionString, SecureString password)
        {
            logger.Info("Start parsing connection string.");
            SFSessionProperties properties = new SFSessionProperties();

            string[] propertyEntry = connectionString.Split(';');

            foreach (string keyVal in propertyEntry)
            {
                if (keyVal.Length > 0)
                {
                    string[] token = keyVal.Split(new string[] { "=" }, StringSplitOptions.None);
                    if (token.Length == 2)
                    {
                        try
                        {
                            SFSessionProperty p = (SFSessionProperty)Enum.Parse(
                                typeof(SFSessionProperty), token[0].ToUpper());
                            properties.Add(p, token[1]);
                            logger.Info($"Connection property: {p}, value: {(p == SFSessionProperty.PASSWORD ? "XXXXXXXX" : token[1])}");
                        }
                        catch (ArgumentException e)
                        {
                            logger.Warn($"Property {token[0]} not found ignored.");
                        }
                    }
                    else
                    {
                        string invalidStringDetail = String.Format("Invalid kay value pair {0}", keyVal);
                        SnowflakeDbException e     = new SnowflakeDbException(SFError.INVALID_CONNECTION_STRING,
                                                                              new object[] { invalidStringDetail });
                        logger.Error("Invalid string.", e);
                        throw e;
                    }
                }
            }

            if (password != null)
            {
                properties[SFSessionProperty.PASSWORD] = new NetworkCredential(string.Empty, password).Password;
            }
            checkSessionProperties(properties);

            // compose host value if not specified
            if (!properties.ContainsKey(SFSessionProperty.HOST))
            {
                string hostName = String.Format("%s.snowflakecomputing.com", properties[SFSessionProperty.ACCOUNT]);
                properties.Add(SFSessionProperty.HOST, hostName);
                logger.Info($"Compose host name: {hostName}");
            }

            return(properties);
        }
コード例 #4
0
        internal SFSession(String connectionString, SecureString password, IRestRequester restRequester)
        {
            this.restRequester = restRequester;
            properties         = SFSessionProperties.parseConnectionString(connectionString, password);

            ParameterMap = new Dictionary <SFSessionParameter, object>();
            int recommendedMinTimeoutSec = BaseRestRequest.DEFAULT_REST_RETRY_SECONDS_TIMEOUT;
            int timeoutInSec             = recommendedMinTimeoutSec;

            try
            {
                ParameterMap[SFSessionParameter.CLIENT_VALIDATE_DEFAULT_PARAMETERS] =
                    Boolean.Parse(properties[SFSessionProperty.VALIDATE_DEFAULT_PARAMETERS]);

                timeoutInSec = int.Parse(properties[SFSessionProperty.CONNECTION_TIMEOUT]);

                InsecureMode = Boolean.Parse(properties[SFSessionProperty.INSECUREMODE]);
            }
            catch (Exception e)
            {
                logger.Error(e.Message);
                throw new SnowflakeDbException(e.InnerException,
                                               SFError.INVALID_CONNECTION_STRING,
                                               "Unable to connect");
            }

            if (timeoutInSec < recommendedMinTimeoutSec)
            {
                logger.Warn($"Connection timeout provided is less than recommended minimum value of" +
                            $" {recommendedMinTimeoutSec}");
            }
            if (timeoutInSec < 0)
            {
                logger.Warn($"Connection timeout provided is negative. Timeout will be infinite.");
            }

            connectionTimeout = timeoutInSec > 0 ? TimeSpan.FromSeconds(timeoutInSec) : Timeout.InfiniteTimeSpan;
        }
コード例 #5
0
        internal void close()
        {
            var queryParams = new Dictionary <string, string>();

            queryParams[SF_QUERY_SESSION_DELETE] = "true";
            queryParams[SF_QUERY_REQUEST_ID]     = Guid.NewGuid().ToString();

            SFRestRequest closeSessionRequest = new SFRestRequest
            {
                uri = BuildUri(SF_SESSION_PATH, queryParams),
                authorizationToken = string.Format(SF_AUTHORIZATION_SNOWFLAKE_FMT, sessionToken)
            };

            var response = restRequest.Post <NullDataResponse>(closeSessionRequest);

            if (!response.success)
            {
                logger.Warn($"Failed to delete session, error ignored. Code: {response.code} Message: {response.message}");
            }
        }
コード例 #6
0
        internal void Cancel()
        {
            SFRestRequest request = BuildCancelQueryRequest();

            if (request == null)
            {
                return;
            }

            var response = _restRequester.Post <NullDataResponse>(request);

            if (response.success)
            {
                logger.Info("Query cancellation succeed");
            }
            else
            {
                logger.Warn("Query cancellation failed.");
            }
        }
コード例 #7
0
            protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage requestMessage,
                                                                          CancellationToken cancellationToken)
            {
                HttpResponseMessage response = null;
                int backOffInSec             = 1;

                TimeSpan httpTimeout = (TimeSpan)requestMessage.Properties["TIMEOUT_PER_HTTP_REQUEST"];

                CancellationTokenSource childCts = null;

                while (true)
                {
                    try
                    {
                        childCts = null;

                        if (!httpTimeout.Equals(Timeout.InfiniteTimeSpan))
                        {
                            childCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
                            childCts.CancelAfter(httpTimeout);
                        }

                        response = await base.SendAsync(requestMessage, childCts == null?
                                                        cancellationToken : childCts.Token);
                    }
                    catch (Exception e)
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            logger.Debug("SF rest request timeout.");
                            cancellationToken.ThrowIfCancellationRequested();
                        }
                        else if (childCts != null && childCts.Token.IsCancellationRequested)
                        {
                            logger.Warn("Http request timeout. Retry the request");
                        }
                        else
                        {
                            //TODO: Should probably check to see if the error is recoverable or transient.
                            logger.Warn("Error occurred during request, retrying...", e);
                        }
                    }

                    if (response != null)
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            logger.Debug($"Success Response: {response.ToString()}");
                            return(response);
                        }
                        logger.Debug($"Failed Response: {response.ToString()}");
                    }
                    else
                    {
                        logger.Info("Response returned was null.");
                    }

                    logger.Debug($"Sleep {backOffInSec} seconds and then retry the request");
                    Thread.Sleep(backOffInSec * 1000);
                    backOffInSec = backOffInSec >= 16 ? 16 : backOffInSec * 2;
                }
            }
コード例 #8
0
            protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage requestMessage,
                                                                          CancellationToken cancellationToken)
            {
                HttpResponseMessage response = null;
                int backOffInSec             = 1;
                int totalRetryTime           = 0;
                int maxDefaultBackoff        = 16;

                ServicePoint p = ServicePointManager.FindServicePoint(requestMessage.RequestUri);

                p.Expect100Continue = false; // Saves about 100 ms per request
                p.UseNagleAlgorithm = false; // Saves about 200 ms per request
                p.ConnectionLimit   = 20;    // Default value is 2, we need more connections for performing multiple parallel queries

                TimeSpan httpTimeout = (TimeSpan)requestMessage.Properties[SFRestRequest.HTTP_REQUEST_TIMEOUT_KEY];
                TimeSpan restTimeout = (TimeSpan)requestMessage.Properties[SFRestRequest.REST_REQUEST_TIMEOUT_KEY];

                if (logger.IsDebugEnabled())
                {
                    logger.Debug("Http request timeout : " + httpTimeout);
                    logger.Debug("Rest request timeout : " + restTimeout);
                }

                CancellationTokenSource childCts = null;

                UriUpdater updater = new UriUpdater(requestMessage.RequestUri);

                while (true)
                {
                    try
                    {
                        childCts = null;

                        if (!httpTimeout.Equals(Timeout.InfiniteTimeSpan))
                        {
                            childCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
                            childCts.CancelAfter(httpTimeout);
                        }

                        response = await base.SendAsync(requestMessage, childCts == null?
                                                        cancellationToken : childCts.Token).ConfigureAwait(false);
                    }
                    catch (Exception e)
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            logger.Debug("SF rest request timeout or explicit cancel called.");
                            cancellationToken.ThrowIfCancellationRequested();
                        }
                        else if (childCts != null && childCts.Token.IsCancellationRequested)
                        {
                            logger.Warn("Http request timeout. Retry the request");
                            totalRetryTime += (int)httpTimeout.TotalSeconds;
                        }
                        else
                        {
                            //TODO: Should probably check to see if the error is recoverable or transient.
                            logger.Warn("Error occurred during request, retrying...", e);
                        }
                    }

                    if (response != null)
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            return(response);
                        }
                        else
                        {
                            logger.Debug($"Failed Response: {response.ToString()}");
                            bool isRetryable = isRetryableHTTPCode((int)response.StatusCode);
                            if (!isRetryable)
                            {
                                // No need to keep retrying, stop here
                                return(response);
                            }
                        }
                    }
                    else
                    {
                        logger.Info("Response returned was null.");
                    }

                    requestMessage.RequestUri = updater.Update();

                    logger.Debug($"Sleep {backOffInSec} seconds and then retry the request");
                    Thread.Sleep(backOffInSec * 1000);
                    totalRetryTime += backOffInSec;
                    backOffInSec    = backOffInSec >= maxDefaultBackoff ?
                                      maxDefaultBackoff : backOffInSec * 2;

                    if (totalRetryTime + backOffInSec > restTimeout.TotalSeconds)
                    {
                        // No need to wait more than necessary if it can be avoided.
                        // If the rest timeout will be reached before the next back-off,
                        // use a smaller one to give the Rest request a chance to timeout early
                        backOffInSec = Math.Max(1, (int)restTimeout.TotalSeconds - totalRetryTime - 1);
                    }
                }
            }
コード例 #9
0
            protected override async Task <HttpResponseMessage> SendAsync(HttpRequestMessage requestMessage,
                                                                          CancellationToken cancellationToken)
            {
                HttpResponseMessage response = null;
                int backOffInSec             = 1;

                ServicePoint p = ServicePointManager.FindServicePoint(requestMessage.RequestUri);

                p.Expect100Continue = false; // Saves about 100 ms per request
                p.UseNagleAlgorithm = false; // Saves about 200 ms per request
                p.ConnectionLimit   = 20;    // Default value is 2, we need more connections for performing multiple parallel queries

                TimeSpan httpTimeout = (TimeSpan)requestMessage.Properties["TIMEOUT_PER_HTTP_REQUEST"];

                CancellationTokenSource childCts = null;

                UriUpdater updater = new UriUpdater(requestMessage.RequestUri);

                while (true)
                {
                    try
                    {
                        childCts = null;

                        if (!httpTimeout.Equals(Timeout.InfiniteTimeSpan))
                        {
                            childCts = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken);
                            childCts.CancelAfter(httpTimeout);
                        }

                        response = await base.SendAsync(requestMessage, childCts == null?
                                                        cancellationToken : childCts.Token).ConfigureAwait(false);
                    }
                    catch (Exception e)
                    {
                        if (cancellationToken.IsCancellationRequested)
                        {
                            logger.Debug("SF rest request timeout.");
                            cancellationToken.ThrowIfCancellationRequested();
                        }
                        else if (childCts != null && childCts.Token.IsCancellationRequested)
                        {
                            logger.Warn("Http request timeout. Retry the request");
                        }
                        else
                        {
                            //TODO: Should probably check to see if the error is recoverable or transient.
                            logger.Warn("Error occurred during request, retrying...", e);
                        }
                    }

                    if (response != null)
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            return(response);
                        }
                        logger.Debug($"Failed Response: {response.ToString()}");
                    }
                    else
                    {
                        logger.Info("Response returned was null.");
                    }

                    requestMessage.RequestUri = updater.Update();

                    logger.Debug($"Sleep {backOffInSec} seconds and then retry the request");
                    Thread.Sleep(backOffInSec * 1000);
                    backOffInSec = backOffInSec >= 16 ? 16 : backOffInSec * 2;
                }
            }