public void TestInitialize()
        {
            // Arrange
            Ioc.Container = new DependencyInjectionContainer();

            IServiceLocator serviceLocator = Substitute.For <IServiceLocator>();

            serviceLocator.GetInstance <WebHealthVaultConfiguration>().Returns(new WebHealthVaultConfiguration
            {
                DefaultHealthVaultUrl      = new Uri("http://www.bing.com"),
                DefaultHealthVaultShellUrl = new Uri("http://www.bing.com")
            });

            HealthServiceInstance healthServiceInstance = Substitute.For <HealthServiceInstance>();
            SessionCredential     sessionCredential     = new SessionCredential
            {
                ExpirationUtc = DateTimeOffset.UtcNow.AddHours(4),
                SharedSecret  = SessionSharedSecret,
                Token         = SessionToken
            };

            _userAuthToken = "someToken";

            _webHealthVaultConnection = new WebHealthVaultConnection(serviceLocator)
            {
                UserAuthToken     = _userAuthToken,
                ServiceInstance   = healthServiceInstance,
                SessionCredential = sessionCredential
            };
        }
예제 #2
0
        private void PrepareAuthSessionHeader(Request request, SessionCredential credentials)
        {
            if (credentials == null)
            {
                return;
            }

            var session = new AuthSession();

            session.Token = credentials.Token;

            if (UseOnlineAuthModel)
            {
                if (request.ShouldEnsureOnlineToken && m_state.HasOnlineToken)
                {
                    session.OnlineToken = m_state.OnlineToken;
                }
            }
            else if (request.Record != null)
            {
                session.Person = new OfflinePersonInfo(request.Record.PersonId);
            }

            request.Header.Session = session;
        }
예제 #3
0
        public async Task RefreshSessionTokenAsync(CancellationToken cancelToken)
        {
            SessionCredential credential = await m_serviceMethods.GetSessionTokenAsync(cancelToken);

            lock (m_state)
            {
                m_state.Credentials = credential;
                SaveState();
            }
        }
 public override async Task AuthenticateAsync()
 {
     using (await _authenticateLock.LockAsync().ConfigureAwait(false))
     {
         if (SessionCredential == null || SessionCredential.IsExpired())
         {
             await RefreshSessionCredentialAsync(CancellationToken.None).ConfigureAwait(false);
         }
     }
 }
예제 #5
0
        private void PrepareHeader(Request request, SessionCredential credentials)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            PrepareStandardHeaders(request);
            PrepareBodyHash(request);
            PrepareAuthSessionHeader(request, credentials);
        }
예제 #6
0
        private void PrepareRequestAsync(Request request, SessionCredential credentials)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            PrepareHeader(request, credentials);
            PrepareAuth(request, credentials);

            request.Validate();
        }
        protected override async Task RefreshSessionCredentialAsync(CancellationToken token)
        {
            IClientSessionCredentialClient sessionCredentialClient = ServiceLocator.GetInstance <IClientSessionCredentialClient>();

            sessionCredentialClient.Connection      = this;
            sessionCredentialClient.AppSharedSecret = ApplicationCreationInfo.SharedSecret;
            SessionCredential newCredential = await sessionCredentialClient.GetSessionCredentialAsync(CancellationToken.None).ConfigureAwait(false);

            await _localObjectStore.WriteAsync(SessionCredentialKey, newCredential).ConfigureAwait(false);

            SessionCredential = newCredential;
        }
예제 #8
0
        /// <summary>
        /// Creates the offline connection.
        /// </summary>
        /// <param name="offlinePersonId">The offline person identifier.</param>
        /// <param name="instanceId">The instance identifier.</param>
        /// <param name="sessionCredential">The session credential.</param>
        /// <returns></returns>
        public static async Task <IOfflineHealthVaultConnection> CreateOfflineConnectionAsync(
            string offlinePersonId,
            string instanceId = null,
            SessionCredential sessionCredential = null)
        {
            WebHealthVaultFactory         factory = new WebHealthVaultFactory();
            IOfflineHealthVaultConnection webHealthVaultConnection = await factory.CreateOfflineConnectionInternalAsync(
                offlinePersonId,
                instanceId,
                sessionCredential);

            return(webHealthVaultConnection);
        }
        private void SetupLocalStore()
        {
            var serviceInstance = new HealthServiceInstance
            {
                Id               = "1",
                Name             = "US",
                Description      = "US instance",
                HealthServiceUrl = new Uri("https://platform.healthvault-ppe.com/platform/wildcat.ashx"),
                ShellUrl         = new Uri("https://account.healthvault-ppe.com/")
            };

            var applicationCreationInfo = new ApplicationCreationInfo
            {
                AppInstanceId    = new Guid(ApplicationInstanceId),
                SharedSecret     = ApplicationSharedSecret,
                AppCreationToken = ApplicationCreationToken
            };

            var sessionCredential = new SessionCredential
            {
                Token         = SessionToken,
                SharedSecret  = SessionSharedSecret,
                ExpirationUtc = DateTimeOffset.UtcNow.AddHours(4)
            };

            var personInfo = new PersonInfo
            {
                PersonId = PersonId
            };

            _subLocalObjectStore
            .ReadAsync <HealthServiceInstance>(HealthVaultSodaConnection.ServiceInstanceKey)
            .Returns(serviceInstance);

            _subLocalObjectStore
            .ReadAsync <ApplicationCreationInfo>(HealthVaultSodaConnection.ApplicationCreationInfoKey)
            .Returns(applicationCreationInfo);

            _subLocalObjectStore
            .ReadAsync <SessionCredential>(HealthVaultSodaConnection.SessionCredentialKey)
            .Returns(sessionCredential);

            _subLocalObjectStore
            .ReadAsync <PersonInfo>(HealthVaultSodaConnection.PersonInfoKey)
            .Returns(personInfo);
        }
예제 #10
0
        private void PrepareAuth(Request request, SessionCredential credentials)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }
            if (request.IsAnonymous)
            {
                return;
            }
            if (credentials == null)
            {
                throw new ArgumentNullException("credentials");
            }

            VerifyCredentials();

            string headerXml = request.Header.ToXml();
            Hmac   hmac      = m_cryptographer.Hmac(credentials.SharedSecret, headerXml);

            request.Auth = new RequestAuth(hmac);
        }
예제 #11
0
        // Enables unit test
        internal async Task <IOfflineHealthVaultConnection> CreateOfflineConnectionInternalAsync(
            string offlinePersonId,
            string instanceId = null,
            SessionCredential sessionCredential = null)
        {
            Guid parsedOfflinePersonId;

            if (!Guid.TryParse(offlinePersonId, out parsedOfflinePersonId))
            {
                throw new ArgumentException("Unable to parse offline person id to Guid", nameof(offlinePersonId));
            }

            IServiceLocator serviceLocator = new ServiceLocator();

            HealthServiceInstance serviceInstance = null;

            if (!string.IsNullOrEmpty(instanceId))
            {
                // Get ServiceInstance
                IServiceInstanceProvider serviceInstanceProvider = serviceLocator.GetInstance <IServiceInstanceProvider>();
                serviceInstance = await serviceInstanceProvider.GetHealthServiceInstanceAsync(instanceId);
            }

            IOfflineHealthVaultConnection offlineHealthVaultConnection = Ioc.Container.Locate <IOfflineHealthVaultConnection>(
                extraData: new { serviceLocator = serviceLocator });

            OfflineHealthVaultConnection connection = offlineHealthVaultConnection as OfflineHealthVaultConnection;

            connection.SessionCredential = sessionCredential;
            connection.OfflinePersonId   = parsedOfflinePersonId;

            // By default, service instance is "US", so do not override in case the instance id is not set
            if (serviceInstance != null)
            {
                connection.ServiceInstance = serviceInstance;
            }

            return(offlineHealthVaultConnection);
        }
예제 #12
0
        // Enables unit test
        internal async Task <IWebHealthVaultConnection> CreateWebConnectionInternalAsync()
        {
            IHealthVaultIdentityProvider healthVaultIdentityProvider = Ioc.Container.Locate <IHealthVaultIdentityProvider>();
            HealthVaultIdentity          identity = healthVaultIdentityProvider.TryGetIdentity();

            IServiceLocator serviceLocator = new ServiceLocator();

            if (identity == null)
            {
                IWebHealthVaultConnection anonymousWebConnection = serviceLocator.GetInstance <IWebHealthVaultConnection>();
                return(anonymousWebConnection);
            }

            var webConnectionInfo = identity.WebConnectionInfo;

            if (webConnectionInfo == null)
            {
                throw new NotSupportedException("WebConnectionInfo is expected for authenticated connections");
            }

            // Get ServiceInstance
            IServiceInstanceProvider serviceInstanceProvider = Ioc.Container.Locate <IServiceInstanceProvider>();
            HealthServiceInstance    serviceInstance         = await serviceInstanceProvider.GetHealthServiceInstanceAsync(webConnectionInfo.ServiceInstanceId);

            // Get AuthInformation
            SessionCredential sessionCredentialToken = webConnectionInfo.SessionCredential;
            string            token = webConnectionInfo.UserAuthToken;

            IWebHealthVaultConnection webConnection = Ioc.Container.Locate <IWebHealthVaultConnection>(extraData: new { serviceLocator = serviceLocator });

            WebHealthVaultConnection connection = webConnection as WebHealthVaultConnection;

            connection.UserAuthToken     = token;
            connection.ServiceInstance   = serviceInstance;
            connection.SessionCredential = sessionCredentialToken;

            return(webConnection);
        }
예제 #13
0
 /// <summary> Method finishListenerAuthentication
 /// 
 /// see SASLProfile's version of this.
 /// </summary>
 protected internal override void finishListenerAuthentication(SessionCredential c, Session s)
 {
     base.finishListenerAuthentication(c, s);
 }
예제 #14
0
 /// <summary> Method finishListenerAuthentication basically says 'some peer has
 /// authenticated successfully' and calls the tuningprofile
 /// method (exposed by SASLProfile's extension of the core
 /// class TuningProfile) which sets the peer credential.  The
 /// session has two credentials, one in each direction, so it's
 /// necessary to differentiate between local credentials and 
 /// credentials associated with the peer in a given session.
 /// </summary>
 protected internal virtual void finishListenerAuthentication(SessionCredential cred, Session s)
 {
     if (cred != null)
     {
         setPeerCredential(s, cred);
         sessionTable.addEntry(s);
     }
 }
예제 #15
0
 /// <summary> Method finishInitiatorAuthentication basically says 'we've
 /// authenticated successfully' and calls the tuningprofile
 /// method (exposed by SASLProfile's extension of the core
 /// class TuningProfile) which sets the local credential.  The
 /// session has two credentials, one in each direction, so it's
 /// necessary to differentiate between local credentials and 
 /// credentials associated with the peer in a given session.
 /// </summary>
 protected internal virtual void finishInitiatorAuthentication(SessionCredential cred, Session s)
 {
     // @todo incredibly lame -you'retired, go to bed
     setLocalCredential(s, cred);
 }
예제 #16
0
 protected internal override void finishInitiatorAuthentication(SessionCredential cred, Session s)
 {
     base.finishInitiatorAuthentication(cred, s);
 }
예제 #17
0
        private void EnsureSession(Request request, SessionCredential credentials)
        {
            if (credentials == null)
            {
                return;
            }

            var session = new AuthSession();
            session.Token = credentials.Token;
            if (request.Record != null)
            {
                session.Person = new OfflinePersonInfo(request.Record.PersonId);
            }

            request.Header.Session = session;
        }
예제 #18
0
        private void PrepareAuth(Request request, SessionCredential credentials)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }
            if (request.IsAnonymous)
            {
                return;
            }
            if (credentials == null)
            {
                throw new ArgumentNullException("credentials");
            }

            VerifyCredentials();

            string headerXml = request.Header.ToXml();
            Hmac hmac = m_cryptographer.Hmac(credentials.SharedSecret, headerXml);
            request.Auth = new RequestAuth(hmac);
        }
예제 #19
0
        private void PrepareHeader(Request request, SessionCredential credentials)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            EnsureStandardHeaders(request);
            EnsureBodyHash(request);
            EnsureSession(request, credentials);
        }
예제 #20
0
        private void PrepareRequestAsync(Request request, SessionCredential credentials)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            PrepareHeader(request, credentials);
            PrepareAuth(request, credentials);

            request.Validate();
        }
예제 #21
0
 /// <summary>
 /// Determines whether the access token is expired.
 /// </summary>
 public static bool IsExpired(this SessionCredential credential)
 {
     return(credential.ExpirationUtc < DateTimeOffset.UtcNow);
 }
예제 #22
0
 protected internal override void finishListenerAuthentication(SessionCredential cred, Session s)
 {
     base.finishListenerAuthentication(cred, s);
     SupportClass.HashtableRemove(authenticators, cred.Authenticator);
 }
        public async Task WhenAuthenticateCalledWithNoStoredInfo_ThenInfoIsFetchedAndStored()
        {
            SetupEmptyLocalStore();

            _healthVaultConfiguration.MasterApplicationId = s_masterApplicationId;

            var responseMessage1 = GenerateResponseMessage("NewApplicationCreationInfoResult.xml");
            var responseMessage2 = GenerateResponseMessage("GetServiceDefinitionResult.xml");

            // #3 is CAST call - but goes through IClientSessionCredentialClient and not HealthWebRequestClient
            var responseMessage4 = GenerateResponseMessage("GetAuthorizedPeopleResult.xml");

            // The first few calls use the default endpoint
            _subHealthWebRequestClient
            .SendAsync(
                new Uri("https://platform2.healthvault.com/platform/wildcat.ashx"),
                Arg.Any <byte[]>(),
                Arg.Any <int>(),
                Arg.Any <IDictionary <string, string> >(),
                Arg.Any <CancellationToken>())
            .Returns(responseMessage1, responseMessage2);

            // After GetServiceDefinition called, we are calling new endpoint
            _subHealthWebRequestClient
            .SendAsync(
                new Uri("https://platform.healthvault-ppe.com/platform/wildcat.ashx"),
                Arg.Any <byte[]>(),
                Arg.Any <int>(),
                Arg.Any <IDictionary <string, string> >(),
                Arg.Any <CancellationToken>())
            .Returns(responseMessage4);

            var sessionCredential = new SessionCredential
            {
                Token        = SessionToken,
                SharedSecret = SessionSharedSecret
            };

            _subClientSessionCredentialClient
            .GetSessionCredentialAsync(Arg.Any <CancellationToken>())
            .Returns(sessionCredential);

            _subServiceLocator
            .GetInstance <IClientSessionCredentialClient>()
            .Returns(_subClientSessionCredentialClient);

            // These values match the values in NewApplicationCreationInfoResult.xml
            _subShellAuthService
            .ProvisionApplicationAsync(
                new Uri("https://account.healthvault.com"),
                s_masterApplicationId,
                ApplicationCreationToken,
                ApplicationInstanceId)
            .Returns("1");

            HealthVaultSodaConnection healthVaultSodaConnection = CreateHealthVaultSodaConnection();
            await healthVaultSodaConnection.AuthenticateAsync();

            _subClientSessionCredentialClient.Received().AppSharedSecret = ApplicationSharedSecret;
            _subClientSessionCredentialClient.Received().Connection      = healthVaultSodaConnection;

            await _subLocalObjectStore.Received()
            .WriteAsync(
                HealthVaultSodaConnection.ServiceInstanceKey,
                Arg.Is <object>(o => ((HealthServiceInstance)o).HealthServiceUrl == new Uri("https://platform.healthvault-ppe.com/platform/wildcat.ashx")));

            await _subLocalObjectStore.Received()
            .WriteAsync(
                HealthVaultSodaConnection.ApplicationCreationInfoKey,
                Arg.Is <object>(o => ((ApplicationCreationInfo)o).AppInstanceId == new Guid("b5c5593b-afb4-466d-88f2-31707fb8634b")));

            await _subLocalObjectStore.Received()
            .WriteAsync(
                HealthVaultSodaConnection.SessionCredentialKey,
                Arg.Is <object>(o => ((SessionCredential)o).SharedSecret == SessionSharedSecret));

            await _subLocalObjectStore.Received()
            .WriteAsync(
                HealthVaultSodaConnection.PersonInfoKey,
                Arg.Is <object>(o => ((PersonInfo)o).Name == "David Rickard"));
        }
예제 #24
0
        public async Task <Response> ExecuteRequestAsync(
            Request request, Type responseBodyType,
            CancellationToken cancelToken)
        {
            if (request == null)
            {
                throw new ArgumentNullException("request");
            }

            Response  response    = null;
            int       attempt     = 1;
            const int maxAttempts = 3;

            while (attempt <= maxAttempts)
            {
                //
                // Ensure we've got a session set up
                //
                SessionCredential credentials = null;
                if (!request.IsAnonymous)
                {
                    credentials = await EnsureCredentialsAsync(cancelToken);

                    if (UseOnlineAuthModel && request.ShouldEnsureOnlineToken)
                    {
                        await EnsureOnlineTokenAsync(cancelToken);
                    }
                }
                //
                // Prepare request - adding headers, session & auth information
                //
                PrepareRequestAsync(request, credentials);
                //
                // Notify any subscribers
                //
                NotifySending(request);
                //
                // Call HealthVault
                //
                response = await GetResponseAsync(request, responseBodyType, cancelToken);

                if (
                    response.IsSuccess ||
                    !(response.Status.IsStatusCredentialsExpired ||
                      response.Status.IsStatusInvalidOnlineToken ||
                      response.Status.IsStatusServerFailure) ||
                    attempt == maxAttempts)
                {
                    break;
                }

                if (response.Status.IsStatusCredentialsExpired)
                {
                    await RefreshSessionTokenAsync(cancelToken);
                }

                if (response.Status.IsStatusInvalidOnlineToken &&
                    UseOnlineAuthModel &&
                    request.ShouldEnsureOnlineToken)
                {
                    await RefreshOnlineTokenAsync(cancelToken);
                }

                ++attempt;
            }

            return(response);
        }