public static HealthRecordItemCollection GetHVItemsOffline(Guid personId, Guid recordGuid, DateTime? lastSync) { // Do the offline connection OfflineWebApplicationConnection offlineConn = new OfflineWebApplicationConnection(personId); offlineConn.RequestTimeoutSeconds = 180; //extending time to prevent time outs for accounts with large number of items offlineConn.Authenticate(); HealthRecordAccessor accessor = new HealthRecordAccessor(offlineConn, recordGuid); HealthRecordSearcher searcher = accessor.CreateSearcher(); HealthRecordFilter filter = new HealthRecordFilter(Exercise.TypeId, AerobicSession.TypeId); if (lastSync.HasValue) filter.UpdatedDateMin = (DateTime)lastSync; searcher.Filters.Add(filter); HealthRecordItemCollection items = null; try { items = searcher.GetMatchingItems()[0]; } catch (Exception err) { WlkMiTracer.Instance.Log("HVSync.cs:GetHVItemsOffline", WlkMiEvent.AppSync, WlkMiCat.Error, string.Format("Error for user {0} : {1} ", recordGuid.ToString(), err.ToString())); } return items; }
/// <summary> /// Creates Offline Web Application Connection /// </summary> /// <param name="personId">Person Id who granted permission to perform operation</param> /// <returns>Returns authentication connection</returns> public static OfflineWebApplicationConnection CreateConnection(Guid personId) { OfflineWebApplicationConnection offlineConn = new OfflineWebApplicationConnection(ApplicationID, WebApplicationConfiguration.HealthServiceUrl, personId); offlineConn.Authenticate(); return offlineConn; }
public static void CreateApplication() { // Create an offline connection, we use an empty Guid as personId // There is a bug to create a constructor without requiring a guid //// Use this only if you master application wants to do this in Offline mode OfflineWebApplicationConnection offlineConnection = new OfflineWebApplicationConnection(Guid.Empty); offlineConnection.Authenticate(); // Setting up the application we want to create ApplicationInfo appInfo = new ApplicationInfo(); appInfo.Name = "Android application"; appInfo.AuthorizationReason = "Android aplication"; appInfo.Description = "Just an android application"; // get a base64 encoded logo appInfo.LargeLogo = new ApplicationBinaryConfiguration( "C:\\blah.png", "image/gif"); // base64 encoded public key for this application appInfo.PublicKeys.Add( GetPublicKeyFromPfxOrP12("C:\\JourneyCompass.cer")); // You need to have PrivacyStatement + TermsOfUse or ActionUrl appInfo.PrivacyStatement = new ApplicationBinaryConfiguration( "C:\\privacy.txt", "text/plain"); appInfo.TermsOfUse = new ApplicationBinaryConfiguration ("C:\\terms.txt", "text/plain"); //actionUrl //appInfo.ActionUrl = new Uri("http://localhost/redirect.aspx"); // Create and add the rules individually List<AuthorizationSetDefinition> rules = new List<AuthorizationSetDefinition>(); rules.Add((AuthorizationSetDefinition)(new TypeIdSetDefinition(Height.TypeId))); rules.Add((AuthorizationSetDefinition)(new TypeIdSetDefinition(new Guid("a5033c9d-08cf-4204-9bd3-cb412ce39fc0")))); AuthorizationRule rule1 = new AuthorizationRule( HealthRecordItemPermissions.All, rules, null); // Here we are setting up the child as an offline application appInfo.OfflineBaseAuthorizations.Add(rule1); // Add more rules, if needed // Lets make the child app! Provisioner.AddApplication(offlineConnection, appInfo); }
public void CreateConnectRequest( string friendlyName, string secretQuestion, string secretAnswer, string patientId) { try { // Create an offline connection string healthServiceUrl = "https://platform.healthvault-ppe.com/platform/"; OfflineWebApplicationConnection connection = new OfflineWebApplicationConnection(ApplicationId, healthServiceUrl, Guid.Empty /* offlinePersonId */); PatientConnection.DeletePending(connection, patientId); // Create the connect request string code = PatientConnection.Create( connection, friendlyName, secretQuestion, secretAnswer, null /* callbackUrl -- not implemented */, patientId); //Send mail with the unique code to enter in the healthvault System.Web.Mail.MailMessage message = new System.Web.Mail.MailMessage(); message.Fields.Add("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate", 1); message.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendusername", "*****@*****.**"); message.Fields.Add("http://schemas.microsoft.com/cdo/configuration/sendpassword", "001"); message.From = "*****@*****.**"; message.Subject = "Healthvault shell"; message.To = "*****@*****.**"; message.Body = code; System.Web.Mail.SmtpMail.SmtpServer = "hisp.i3l.gatech.edu"; System.Web.Mail.SmtpMail.Send(message); this.RedirectToShellUrl("CONNECT", "appid=" + this.ApplicationId.ToString() + "&ismra=true"); } catch { } }
public ActionResult GetAuthorizedAccounts() { var ret = new { status = "ok" }; var appId = HealthApplicationConfiguration.Current.ApplicationId; var offline = new OfflineWebApplicationConnection(appId, WebApplicationConfiguration.HealthServiceUrl.ToString(), Guid.Empty); offline.Authenticate(); var coll = PatientConnection.GetValidatedConnections(offline); var res = from t in coll select new { personId = t.PersonId, recordId = t.RecordId }; return Json(new { status = ret.status, results = res } , JsonRequestBehavior.AllowGet); }
/// <summary> /// Gets the configuration information for the specified child application ID. /// </summary> /// /// <param name="connection"> /// The connection to use to get the application information. /// </param> /// /// <param name="childApplicationId"> /// The unique application identifier for the child application to get the configuration /// information for. /// </param> /// /// <returns> /// Configuration information for the specified child application. /// </returns> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="connection"/> is <b>null</b>. /// </exception> /// /// <exception cref="ArgumentException"> /// If <paramref name="childApplicationId"/> is <see cref="Guid.Empty"/>. /// </exception> /// /// <exception cref="HealthServiceAccessDeniedException"> /// If the application specified in the <paramref name="connection"/> is not a master /// application, or if <paramref name="childApplicationId"/> does not identify a child /// application of the calling application. /// </exception> /// /// <exception cref="HealthServiceException"> /// If there is an error when the HealthVault service is called. /// </exception> /// public static ApplicationInfo GetChildApplication( OfflineWebApplicationConnection connection, Guid childApplicationId) { return HealthVaultPlatformProvisioning.Current.GetChildApplication(connection, childApplicationId); }
/// <summary> /// Asks HealthVault to create a pending package for the application specified /// by the connection with the specified user specific parameters. /// </summary> /// /// <remarks> /// The password protected package supports 2 encryption algorithms, AES256 (recommended) /// and TripleDES. /// <br/><br/> /// For AES256, the supported key size is 256 bits, the blocksize is 256 bits, the IV /// length is 32 bytes. /// <br/><br/> /// For TripleDES, the supported key size is 192 bits, the blocksize is 64 bits, the IV /// length is 8 bytes. /// <br/><br/> /// The encryption key should be derived using the answer, the salt, and the number of hash /// iterations. The decryption will generate this key via the /// <see cref="Rfc2898DeriveBytes"/> class, hence, encryption should use a similar or /// identical process. To ensure case-insensitivity, the answer should be converted to its /// lower cased form using <see cref="String.ToLowerInvariant()"/> (culturally-agnostic) /// prior to generating the derived key. /// <br/><br/> /// The algorithm used has the following parameters: /// <ul> /// <li>Mode = CipherMode.CBC</li> /// <li>Padding = PaddingMode.ISO10126</li> /// </ul> /// <br/><br/> /// The salt supplied is used as the salt to the derived key as well as the key to the /// supplied HMAC. The salt should be at least 8 bytes long. /// <br/><br/> /// It is recommended that the number of hash iterations be at least 10000. /// </remarks> /// /// <param name="connection"> /// The application connection to HealthVault. The application ID in the connection is used /// when making the patient connection. /// </param> /// /// <param name="friendlyName"> /// A friendly name for the patient connection which will be shown to the user when they /// go to HealthVault Shell to validate the connection. /// </param> /// /// <param name="securityQuestion"> /// A question (usually provided by the patient) to which the patient must provide the /// answer when they go to validate the connection in the /// HealthVault Shell. /// </param> /// /// <param name="applicationPatientId"> /// The application specific identifier for the user. This identifier is used to uniquely /// identify the user in the application data storage whereas the HealthVault person ID is /// used to identify the person in HealthVault. /// </param> /// /// <param name="connectPackage"> /// The pending connect package that the user will add to his/her record. This package's /// <see cref="Blob"/> must be an encrypted and Base64 /// encoded blob of xml that represents a list of HealthRecordItems. This xml blob /// must be a sequence of <thing/> elements, each wrapping the XML representation of a /// single HealthRecordItem. Each <thing/> element may be generated by calling /// <see cref="HealthRecordItem.GetItemXml()"/>. /// </param> /// /// <returns> /// A token that the application must give to the patient to use when validating the /// connection request. /// </returns> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="connection"/> is <b>null</b>. /// </exception> /// /// <exception cref="ArgumentException"> /// If <paramref name="friendlyName"/>, <paramref name="securityQuestion"/>, /// <paramref name="applicationPatientId"/>, or <paramref name="connectPackage"/> is /// <b>null</b> or empty. /// </exception> /// /// <exception cref="HealthServiceException"> /// If an error occurs when contacting HealthVault. /// </exception> /// public static string Create( OfflineWebApplicationConnection connection, string friendlyName, string securityQuestion, string applicationPatientId, PasswordProtectedPackage connectPackage) { ConnectPackageCreationParameters creationParameters = new ConnectPackageCreationParameters( connection, null, friendlyName, securityQuestion, null, applicationPatientId, false, false); return HealthVaultPlatform.CreateConnectPackage( creationParameters, connectPackage); }
/// <summary> /// Deletes a request for a connection that has been made by the calling application but /// has not been validated by the user. /// </summary> /// /// <param name="connection"> /// The connection to HealthVault to use for this operation. /// </param> /// /// <param name="applicationPatientId"> /// The application's identifier for the user which was used to create the connection /// request. /// </param> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="connection"/> is <b>null</b>. /// </exception> /// /// <exception cref="ArgumentException"> /// If <paramref name="applicationPatientId"/> is <b>null</b> or empty. /// </exception> /// /// <exception cref="HealthServiceException"> /// If an error occurs when contacting HealthVault. /// </exception> /// public static void DeletePendingPatientConnection( OfflineWebApplicationConnection connection, string applicationPatientId) { HealthVaultPlatformPatientConnect.Current.DeletePendingPatientConnection(connection, applicationPatientId); }
/// <summary> /// Adds a HealthVault application instance for a "child" application of the calling /// application. /// </summary> /// /// <param name="connection"> /// The connection to use to add the application. /// </param> /// /// <param name="applicationConfigurationInformation"> /// Configuration information about the application being provisioned. /// </param> /// /// <returns> /// The new application identifier for the new application provided by HealthVault. /// </returns> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="connection"/> or <paramref name="applicationConfigurationInformation"/> /// is <b>null</b>. /// </exception> /// /// <exception cref="ArgumentException"> /// If <see cref="ApplicationInfo.Name"/>, <see cref="ApplicationInfo.PublicKeys"/>, /// <see cref="ApplicationInfo.OfflineBaseAuthorizations"/>, <see cref="ApplicationInfo.Description"/>, /// <see cref="ApplicationInfo.AuthorizationReason"/>, or <see cref="ApplicationInfo.LargeLogo"/> /// is not specified. /// </exception> /// /// <exception cref="HealthServiceException"> /// If there is an error when the HealthVault service is called. /// </exception> /// public static Guid AddChildApplication( OfflineWebApplicationConnection connection, ApplicationInfo applicationConfigurationInformation) { return HealthVaultPlatformProvisioning.Current.AddChildApplication(connection, applicationConfigurationInformation); }
/// <summary> /// Deletes all packages that have been created by the calling application /// for the applicationPatientId and have not been accepted by the user. /// </summary> /// /// <param name="connection"> /// The connection to HealthVault to use for this operation. /// </param> /// /// <param name="applicationPatientId"> /// The application specific user ID that was used to create the connection /// request. /// </param> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="connection"/> is <b>null</b>. /// </exception> /// /// <exception cref="ArgumentException"> /// If <paramref name="applicationPatientId"/> is <b>null</b> or empty. /// </exception> /// /// <exception cref="HealthServiceException"> /// If an error occurs when contacting HealthVault. /// </exception> /// public static void DeletePending( OfflineWebApplicationConnection connection, string applicationPatientId) { HealthVaultPlatform.DeletePendingConnectPackages( connection, applicationPatientId); }
/// <summary> /// Asks HealthVault to create a pending package for the application specified /// by the connection with the specified user specific parameters and the pre-allocated /// identity code. /// </summary> /// /// <remarks> /// The password protected package supports 2 encryption algorithms, AES256 (recommended) /// and TripleDES. /// <br/><br/> /// For AES256, the supported key size is 256 bits, the blocksize is 256 bits, the IV /// length is 32 bytes. /// <br/><br/> /// For TripleDES, the supported key size is 192 bits, the blocksize is 64 bits, the IV /// length is 8 bytes. /// <br/><br/> /// The encryption key should be derived using the answer, the salt, and the number of hash /// iterations. The decryption will generate this key via the /// <see cref="Rfc2898DeriveBytes"/> class, hence, encryption should use a similar or /// identical process. To ensure case-insensitivity, the answer should be converted to its /// lower cased form using <see cref="String.ToLowerInvariant()"/> (culturally-agnostic) /// prior to generating the derived key. /// <br/><br/> /// The algorithm used has the following parameters: /// <ul> /// <li>Mode = CipherMode.CBC</li> /// <li>Padding = PaddingMode.ISO10126</li> /// </ul> /// <br/><br/> /// The salt supplied is used as the salt to the derived key as well as the key to the /// supplied HMAC. The salt should be at least 8 bytes long. /// <br/><br/> /// It is recommended that the number of hash iterations be at least 10000. /// </remarks> /// /// <param name="connection"> /// The application connection to HealthVault. The application ID in the connection is used /// when making the patient connection. /// </param> /// /// <param name="identityCode"> /// A package identity token previously obtained from <see cref="ConnectPackage.AllocatePackageId"/>. /// </param> /// /// <param name="friendlyName"> /// A friendly name for the patient connection which will be shown to the user when they /// go to HealthVault Shell to validate the connection. /// </param> /// /// <param name="securityQuestion"> /// A question (usually provided by the patient) to which the patient must provide the /// answer when they go to validate the connection in the /// HealthVault Shell. /// </param> /// /// <param name="applicationPatientId"> /// The application specific identifier for the user. This identifier is used to uniquely /// identify the user in the application data storage whereas the HealthVault person ID is /// used to identify the person in HealthVault. /// </param> /// /// <param name="connectPackage"> /// The pending connect package that the user will add to his/her record. /// This package's /// <see cref="HealthRecordItem"/>'s <see cref="BlobStore"/> must be an encrypted /// blob of xml that represents a list of HealthRecordItems. This xml blob /// must be a sequence of <thing/> elements, each wrapping the XML representation of a /// single HealthRecordItem. Each <thing/> element may be generated by calling /// <see cref="HealthRecordItem.GetItemXml()"/>. /// </param> /// /// <returns> /// A token that the application must give to the patient to use when validating the /// connection request. /// </returns> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="connection"/> is <b>null</b>. /// </exception> /// /// <exception cref="ArgumentException"> /// If <paramref name="identityCode"/>, <paramref name="friendlyName"/>, /// <paramref name="securityQuestion"/>, /// <paramref name="applicationPatientId"/>, or <paramref name="connectPackage"/> is /// <b>null</b> or empty. /// </exception> /// /// <exception cref="HealthServiceException"> /// If an error occurs when contacting HealthVault. /// </exception> /// public static string Create( OfflineWebApplicationConnection connection, string identityCode, string friendlyName, string securityQuestion, string applicationPatientId, PasswordProtectedPackage connectPackage) { Validator.ThrowIfStringNullOrEmpty(identityCode, "identityCode"); ConnectPackageCreationParameters creationParameters = new ConnectPackageCreationParameters( connection, identityCode, friendlyName, securityQuestion, null, applicationPatientId, false, true); return HealthVaultPlatform.CreateConnectPackage( creationParameters, connectPackage); }
/// <summary> /// Allocates a package ID within HealthVault and returns it. /// </summary> /// /// <remarks> /// <para>The package ID is allocated as a place holder for information that /// is identifiable but not yet available through the HealthVault service. /// The returned package ID token should be stored or given to a patient, /// then used in a call to CreateConnectPackage() /// to send the package data to the HealthVault service.</para> /// <para>The package ID is not a GUID. It uses a shorter format that is more /// convenient for offline delivery and manual data entry. The HealthVault /// service guarantees that each package ID is unique for the lifetime of the /// package. Once the package has been accepted by the patient using the /// HealthVault Shell, or explicitly deleted using the API, the package ID is /// deallocated and may be reused.</para> /// </remarks> /// /// <param name="connection"> /// The HealthVault connection to use for the operation. /// </param> /// /// <returns> /// A token that the application must give to the patient to use when validating the /// connection request. /// </returns> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="connection"/> is <b>null</b>. /// </exception> /// /// <exception cref="HealthServiceException"> /// If an error occurs when contacting HealthVault. /// </exception> public virtual String AllocateConnectPackageId( OfflineWebApplicationConnection connection) { Validator.ThrowIfArgumentNull(connection, "connection", "ConnectPackageConnectionNull"); HealthServiceRequest request = new HealthServiceRequest(connection, "AllocatePackageId", 1); request.Execute(); XPathExpression infoPath = SDKHelper.GetInfoXPathExpressionForMethod( request.Response.InfoNavigator, "AllocatePackageId"); XPathNavigator infoNav = request.Response.InfoNavigator.SelectSingleNode(infoPath); return infoNav.SelectSingleNode("identity-code").Value; }
/// <summary> /// Fetch the <see cref="HealthRecordItem" /> instances that are specified /// in the ChangedItems collection. /// </summary> /// <remarks> /// After the operation has completed, see <see cref="HealthRecordItemChangedItem.Item" /> /// to use the fetched <see cref="HealthRecordItem" /> /// /// Items that have been removed from a record or are otherwise inaccessible will /// have a <see cref="HealthRecordItemChangedItem.Item" /> value of null. /// </remarks> /// /// <param name="applicationId">The application id to use.</param> /// <param name="healthServiceUrl">The health service URL to use.</param> /// /// <exception cref="ArgumentNullException"> /// The <paramref name="healthServiceUrl"/> parameter is <b>null</b>. /// </exception> public void GetItems(Guid applicationId, string healthServiceUrl) { Validator.ThrowIfArgumentNull(healthServiceUrl, "healthServiceUrl", "HealthServiceUrlNull"); if (ChangedItems.Count == 0) { return; } OfflineWebApplicationConnection offlineConn = new OfflineWebApplicationConnection( applicationId, healthServiceUrl, _personId); offlineConn.Authenticate(); HealthRecordAccessor accessor = new HealthRecordAccessor(offlineConn, _recordId); HealthRecordSearcher searcher = accessor.CreateSearcher(); HealthRecordFilter filter = new HealthRecordFilter(); searcher.Filters.Add(filter); Dictionary<Guid, HealthRecordItemChangedItem> changedLookup = new Dictionary<Guid, HealthRecordItemChangedItem>(ChangedItems.Count); foreach (HealthRecordItemChangedItem item in ChangedItems) { filter.ItemIds.Add(item.Id); changedLookup.Add(item.Id, item); } HealthRecordItemCollection things = searcher.GetMatchingItems()[0]; // Take the resultant items and put them back in the ChangedItems collection foreach (HealthRecordItem fetchedItem in things) { HealthRecordItemChangedItem item = changedLookup[fetchedItem.Key.Id]; item.Item = fetchedItem; } }
/// <summary> /// Allocates a package ID within HealthVault and returns it. /// </summary> /// /// <remarks> /// <para>The package ID is allocated as a place holder for information that /// is identifiable but not yet available through the HealthVault service. /// The returned package ID token should be stored or given to a patient, /// then used in a call to CreateConnectPackage() /// to send the package data to the HealthVault service.</para> /// <para>The package ID is not a GUID. It uses a shorter format that is more /// convenient for offline delivery and manual data entry. The HealthVault /// service guarantees that each package ID is unique for the lifetime of the /// package. Once the package has been accepted by the patient using the /// HealthVault Shell, or explicitly deleted using the API, the package ID is /// deallocated and may be reused.</para> /// </remarks> /// /// <param name="connection"> /// The HealthVault connection to use for the operation. /// </param> /// /// <returns> /// A token that the application must give to the patient to use when validating the /// connection request. /// </returns> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="connection"/> is <b>null</b>. /// </exception> /// /// <exception cref="HealthServiceException"> /// If an error occurs when contacting HealthVault. /// </exception> public static String AllocateConnectPackageId( OfflineWebApplicationConnection connection) { return HealthVaultPlatformPatientConnect.Current.AllocateConnectPackageId(connection); }
/// <summary> /// Gets the connections for the application that people have accepted since the specified /// date. /// </summary> /// /// <param name="connection"> /// The application's connection to HealthVault. /// </param> /// /// <param name="validatedSince"> /// Connections that have been validated since this date will be returned. The date passed /// should be in UTC time. /// </param> /// /// <returns> /// A collection of the connections that people have accepted. /// </returns> /// /// <remarks> /// Validated connect requests are removed by HealthVault after 90 days. It is advised /// that applications call <see cref="GetValidatedPatientConnections(Microsoft.Health.Web.OfflineWebApplicationConnection, DateTime)"/> /// daily or weekly to ensure that all validated connect requests are retrieved. /// </remarks> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="connection"/> is <b>null</b>. /// </exception> /// public static Collection<ValidatedPatientConnection> GetValidatedPatientConnections( OfflineWebApplicationConnection connection, DateTime validatedSince) { return HealthVaultPlatformPatientConnect.Current.GetValidatedPatientConnections( connection, validatedSince); }
/// <summary> /// Constructs an <see cref="ConnectPackageCreationParameters"/> instance /// with supplied values. /// </summary> /// /// <param name="connection"> /// The application connection to HealthVault. The application ID in the connection is used /// when making the patient connection. /// </param> /// /// <param name="friendlyName"> /// A friendly name for the patient connection which will be shown to the user when they /// go to HealthVault Shell to validate the connection. /// </param> /// /// <param name="securityQuestion"> /// A question (usually provided by the patient) to which the patient must provide the /// <paramref name="securityAnswer"/> when they go to validate the connection in the /// HealthVault Shell. /// </param> /// /// <param name="securityAnswer"> /// The answer to the <paramref name="securityQuestion"/> which the patient must use /// when adding the package to their record via HealthVault Shell. The answer is /// case-insensitive but otherwise must match exactly. Additionally, it must be at least /// 6 characters long. /// </param> /// /// <param name="applicationPatientId"> /// The application specific identifier for the user. This identifier is used to uniquely /// identify the user in the application data storage whereas the HealthVault person ID is /// used to identify the person in HealthVault. /// </param> /// /// <exception cref="ArgumentException"> /// If <paramref name="friendlyName"/>, /// <paramref name="securityQuestion"/>, or /// <paramref name="applicationPatientId"/> is /// <b>null</b> or empty. /// </exception> /// /// <exception cref="ArgumentOutOfRangeException"> /// If <paramref name="securityAnswer"/> is less than 6 characters. /// </exception> /// public ConnectPackageCreationParameters( OfflineWebApplicationConnection connection, String friendlyName, String securityQuestion, String securityAnswer, String applicationPatientId) : this(connection, null, friendlyName, securityQuestion, securityAnswer, applicationPatientId, true, false) { }
internal ConnectPackageCreationParameters( OfflineWebApplicationConnection connection, String identityCode, String friendlyName, String securityQuestion, String securityAnswer, String applicationPatientId, Boolean isSecurityAnswerAvailable, Boolean isIdentityCodeRequired) { Validator.ThrowIfArgumentNull(connection, "connection", "ConnectPackageConnectionNull"); Validator.ThrowArgumentExceptionIf( isIdentityCodeRequired && String.IsNullOrEmpty(identityCode), "identityCode", "PackageCreateHRIMissingMandatory"); Validator.ThrowIfStringNullOrEmpty(friendlyName, "friendlyName"); Validator.ThrowIfStringNullOrEmpty(securityQuestion, "friendlyName"); if (isSecurityAnswerAvailable) { Validator.ThrowIfStringNullOrEmpty(securityAnswer, "securityAnswer"); Validator.ThrowArgumentOutOfRangeIf( securityAnswer.Length < 6, "securityAnswer", "PackageCreateHRIAnswerLength"); } Validator.ThrowIfStringNullOrEmpty(applicationPatientId, "applicationPatientId"); _connection = connection; _identityCode = identityCode; _friendlyName = friendlyName; _securityQuestion = securityQuestion; _securityAnswer = securityAnswer; _applicationPatientId = applicationPatientId; _salt = Guid.NewGuid().ToString(); _passwordProtectAlgorithm = PasswordProtectAlgorithm.HmacSha256Aes256; _connectPackageEncryptionAlgorithmName = "AES256"; _blobChunkEncryptionAlgorithmName = "AES256"; _encryptionParameterGenerationIterationCount = 20000; if (isSecurityAnswerAvailable) { SetupEncryptionParameters(); } _id = Guid.NewGuid(); }
/// <summary> /// Updates existing pending packages with a new application patient identifier. /// </summary> /// /// <param name="connection"> /// The HealthVault connection to use for the operation. /// </param> /// /// <param name="oldApplicationPatientId"> /// The application patient identifier that was used to create the initial package. /// </param> /// /// <param name="newApplicationPatientId"> /// The new application patient identifier. /// </param> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="connection"/> is <b>null</b>. /// </exception> /// /// <exception cref="ArgumentException"> /// If <paramref name="oldApplicationPatientId"/> or <paramref name="newApplicationPatientId"/> /// is <b>null</b> or empty. /// </exception> /// /// <exception cref="HealthServiceException"> /// If an error occurs when contacting HealthVault. /// </exception> /// public static void UpdateApplicationPatientId( OfflineWebApplicationConnection connection, string oldApplicationPatientId, string newApplicationPatientId) { HealthVaultPlatform.UpdateConnectPackageApplicationPatientId( connection, oldApplicationPatientId, newApplicationPatientId); }
public static void SyncWlkMiWithHealthVault( DateTime? lastUpdatedDate) { WlkMiTracer.Instance.Log("HVSync.cs", WlkMiEvent.AppSync, WlkMiCat.Info, "Getting updated records from HealthVault"); // Do the offline connection OfflineWebApplicationConnection offlineConn = new OfflineWebApplicationConnection(); offlineConn.Authenticate(); IList<Guid> updatedUserIds = offlineConn.GetUpdatedRecordsForApplication(lastUpdatedDate); WlkMiTracer.Instance.Log("HVSync.cs", WlkMiEvent.AppSync, WlkMiCat.Info, string.Format("Got {0} updated records from HealthVault", updatedUserIds.Count)); foreach (Guid recordid in updatedUserIds) { ProfileModel syncUser = ProfileModel.Fetch(recordid); if (syncUser == null) { WlkMiTracer.Instance.Log("HVSync.cs", WlkMiEvent.AppSync, WlkMiCat.Error, string.Format("No WlkMi user found for recordif {0} ", recordid)); continue; } // Decide to update this guy? if (syncUser.UserCtx.hv_last_sync_time > DateTime.Now.AddSeconds( -Constants.UserSyncIntervalInSeconds)) { WlkMiTracer.Instance.Log("HVSync.cs", WlkMiEvent.AppSync, WlkMiCat.Info, string.Format("Skipping sync for user {0} ", syncUser.UserCtx.user_id)); } else { HVSync.OfflineSyncUser(syncUser); } } }
/// <summary> /// Deletes a request for a connection that has been made by the calling application but /// has not been validated by the user. /// </summary> /// /// <param name="connection"> /// The connection to HealthVault to use for this operation. /// </param> /// /// <param name="applicationPatientId"> /// The application's identifier for the user which was used to create the connection /// request. /// </param> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="connection"/> is <b>null</b>. /// </exception> /// /// <exception cref="ArgumentException"> /// If <paramref name="applicationPatientId"/> is <b>null</b> or empty. /// </exception> /// /// <exception cref="HealthServiceException"> /// If an error occurs when contacting HealthVault. /// </exception> /// public virtual void DeletePendingPatientConnection( OfflineWebApplicationConnection connection, string applicationPatientId) { Validator.ThrowIfArgumentNull(connection, "connection", "ConnectPackageConnectionNull"); Validator.ThrowIfStringNullOrEmpty(applicationPatientId, "applicationPatientId"); HealthServiceRequest request = new HealthServiceRequest(connection, "DeletePendingConnectRequest", 1); request.Parameters = "<external-id>" + applicationPatientId + "</external-id>"; request.Execute(); }
/// <summary> /// Creates a new open query using the specified /// <see cref="OfflineWebApplicationConnection"/>, definition, /// expiration time, personal identification number (PIN), description, /// and XSL. /// </summary> /// /// <param name="connection"> /// An <see cref="OfflineWebApplicationConnection"/> instance that /// creates the new open query. /// </param> /// /// <param name="searcher"> /// A <see cref="HealthRecordSearcher"/> instance that defines the open query. /// </param> /// /// <param name="expires"> /// The number of minutes the query will expire from the creation time. /// A value of Int32.MaxValue denotes that the query does not expire. /// </param> /// /// <param name="pinCode"> /// The PIN that protects the query. /// </param> /// /// <param name="note"> /// The note describing the query. /// </param> /// /// <param name="finalXsl"> /// The XSL that transforms the results of the query when the /// <see cref="OpenQuery"/> is invoked. /// </param> /// /// <returns> /// An <see cref="OpenQuery"/> instance that represents the newly created query. /// </returns> /// /// <remarks> /// The creation of an open query makes public the data returned by that /// query. However, the query URL must be known to retrieve the data. /// </remarks> /// /// <exception cref="ArgumentNullException"> /// The <paramref name="connection"/> or <paramref name="searcher"/> /// parameter is <b>null</b>. /// </exception> /// /// <exception cref="ArgumentException"> /// The <paramref name="searcher"/> parameter contains no valid search /// filters or the <paramref name="pinCode"/> parameter is <b>null</b> /// or empty. /// </exception> /// /// <exception cref="HealthServiceException"> /// An error occurred when HealthVault processed the request. /// </exception> /// public static OpenQuery NewQuery( OfflineWebApplicationConnection connection, HealthRecordSearcher searcher, int expires, string pinCode, string note, string finalXsl) { return HealthVaultPlatform.NewOpenQuery( connection, searcher, expires, pinCode, note, finalXsl); }
/// <summary> /// Updates an existing pending package with a new application patient identifier. /// </summary> /// /// <param name="connection"> /// The HealthVault connection to use for the operation. /// </param> /// /// <param name="identityCode"> /// The unique token that identifies the package. /// </param> /// /// <param name="newApplicationPatientId"> /// The new application patient identifier. /// </param> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="connection"/> is <b>null</b>. /// </exception> /// /// <exception cref="ArgumentException"> /// If <paramref name="newApplicationPatientId"/> /// is <b>null</b> or empty. /// </exception> /// /// <exception cref="HealthServiceException"> /// If an error occurs when contacting HealthVault. /// </exception> /// public virtual void UpdateConnectPackageApplicationPatientIdForIdentityCode( OfflineWebApplicationConnection connection, string identityCode, string newApplicationPatientId) { Validator.ThrowIfArgumentNull(connection, "connection", "ConnectPackageConnectionNull"); Validator.ThrowIfStringNullOrEmpty(identityCode, "identityCode"); Validator.ThrowIfStringNullOrEmpty(newApplicationPatientId, "newApplicationPatientId"); StringBuilder requestBuilder = new StringBuilder(256); XmlWriterSettings writerSettings = new XmlWriterSettings(); writerSettings.ConformanceLevel = ConformanceLevel.Fragment; using (XmlWriter writer = XmlWriter.Create(requestBuilder, writerSettings)) { writer.WriteElementString("identity-code", identityCode); writer.WriteElementString("new-external-id", newApplicationPatientId); } HealthServiceRequest request = new HealthServiceRequest(connection, "UpdateExternalId", 1); request.Parameters = requestBuilder.ToString(); request.Execute(); }
/// <summary> /// Updates an existing pending package with a new application patient identifier. /// </summary> /// /// <param name="connection"> /// The HealthVault connection to use for the operation. /// </param> /// /// <param name="identityCode"> /// The unique token that identifies the package. /// </param> /// /// <param name="newApplicationPatientId"> /// The new application patient identifier. /// </param> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="connection"/> is <b>null</b>. /// </exception> /// /// <exception cref="ArgumentException"> /// If <paramref name="newApplicationPatientId"/> /// is <b>null</b> or empty. /// </exception> /// /// <exception cref="HealthServiceException"> /// If an error occurs when contacting HealthVault. /// </exception> /// public static void UpdateConnectPackageApplicationPatientIdForIdentityCode( OfflineWebApplicationConnection connection, string identityCode, string newApplicationPatientId) { HealthVaultPlatformPatientConnect.Current.UpdateConnectPackageApplicationPatientIdForIdentityCode( connection, identityCode, newApplicationPatientId); }
/// <summary> /// Asks HealthVault to create a pending package for the application specified /// by the connection with the specified user specific parameters. /// </summary> /// /// <remarks> /// The encryption is delegated to the .NET Crypto classes. The encryption algorithm /// supported by default is AES256. If TripleDES is required, the caller should create /// the custom Password Protected Package and call <see cref="Create(Microsoft.Health.Web.OfflineWebApplicationConnection, string, string, string, Microsoft.Health.ItemTypes.PasswordProtectedPackage)"/>. /// <br/><br/> /// The answer key provided is not the actual key to the decryption. A key is derived using /// the answer, the salt, and the number of hash iterations (via the /// <see cref="Rfc2898DeriveBytes"/> class). To ensure case-insensitivity, the answer /// is lower cased using <see cref="String.ToLowerInvariant()"/> (culturally-agnostic) /// prior to generating the derived key. /// <br/><br/> /// The algorithm used has the following parameters: /// <ul> /// <li>Mode = CipherMode.CBC</li> /// <li>Padding = PaddingMode.ISO10126</li> /// </ul> /// <br/><br/> /// The salt supplied is used as the salt to the derived key as well as the key to the /// supplied HMAC. The data must be appended to the hash, then encrypted and then Base64 /// encoded. /// </remarks> /// /// <param name="connection"> /// The application connection to HealthVault. The application ID in the connection is used /// when making the patient connection. /// </param> /// /// <param name="identityCode"> /// The application unique identifier of the package. /// </param> /// /// <param name="friendlyName"> /// A friendly name for the patient connection which will be shown to the user when they /// go to HealthVault Shell to validate the connection. /// </param> /// /// <param name="securityQuestion"> /// A question (usually provided by the patient) to which the patient must provide the /// <paramref name="securityAnswer"/> when they go to validate the connection in /// the HealthVault Shell. /// </param> /// /// <param name="securityAnswer"> /// The answer to the <paramref name="securityQuestion"/> which the patient must use /// when adding the package to their record via HealthVault Shell. The answer is /// case-insensitive but otherwise must match exactly. Additionally, it must be at least /// 6 characters long. /// </param> /// /// <param name="applicationPatientId"> /// The application specific identifier for the user. This identifier is used to uniquely /// identify the user in the application data storage, whereas the HealthVault person ID is /// used to identify the person in HealthVault. /// </param> /// /// <param name="packageContents"> /// The list of HealthRecordItems that will be encrypted and added to the package that the /// user will claim via HealthVault Shell. /// </param> /// /// <returns> /// A token that the application must give to the patient to use when validating the /// connection request. /// </returns> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="connection"/> is <b>null</b>. /// </exception> /// /// <exception cref="ArgumentException"> /// If <paramref name="identityCode"/>, <paramref name="friendlyName"/>, <paramref name="securityQuestion"/>, /// <paramref name="securityAnswer"/>, <paramref name="applicationPatientId"/> or /// any element in <paramref name="packageContents"/> are /// <b>null</b> or empty. /// </exception> /// /// <exception cref="ArgumentOutOfRangeException"> /// If <paramref name="securityAnswer"/> is less than 6 characters. /// </exception> /// /// <exception cref="NotSupportedException"> /// One of the items in <paramref name="packageContents"/> is signed and contains /// streamed blobs. This is not supported. /// </exception> /// /// <exception cref="HealthServiceException"> /// If an error occurs when contacting HealthVault. /// </exception> /// public static string CreatePackage( OfflineWebApplicationConnection connection, string identityCode, string friendlyName, string securityQuestion, string securityAnswer, string applicationPatientId, IList<HealthRecordItem> packageContents) { ConnectPackageCreationParameters creationParameters = new ConnectPackageCreationParameters( connection, identityCode, friendlyName, securityQuestion, securityAnswer, applicationPatientId); return CreatePackageWithContentsAllParameters( creationParameters, packageContents); }
/// <summary> /// Asks HealthVault to create a pending patient connection for the application specified /// by the connection with the specified user specific parameters. /// </summary> /// /// <param name="connection"> /// The connection to HealthVault. The application ID in the connection is used /// when making the patient connection. /// </param> /// /// <param name="friendlyName"> /// A friendly name for the patient connection which will be shown to the user when they /// go to HealthVault Shell to validate the connection. /// </param> /// /// <param name="securityQuestion"> /// A question (usually provided by the patient) to which the patient must provide the /// answer when they go to validate the connection in the HealthVault Shell. /// </param> /// /// <param name="securityAnswer"> /// The answer to the <paramref name="securityQuestion"/> which the patient must use /// when validating the connection in HealthVault Shell. The answer is case-insensitive but /// otherwise must match exactly. In most cases it is recommended that this is a single /// word to prevent entry problems when validating the connection. /// </param> /// /// <param name="callbackUrl"> /// Not yet implemented. May be null. /// </param> /// /// <param name="applicationPatientId"> /// The application specific identifier for the user. This identifier is used to uniquely /// identify the user in the application data storage whereas the HealthVault person ID is /// used to identify the person in HealthVault. /// </param> /// /// <returns> /// A token that the application must give to the patient to use when validating the /// connection request. /// </returns> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="connection"/> is <b>null</b>. /// </exception> /// /// <exception cref="ArgumentException"> /// If <paramref name="friendlyName"/>, <paramref name="securityQuestion"/>, /// <paramref name="securityAnswer"/>, or <paramref name="applicationPatientId"/> is /// <b>null</b> or empty. /// </exception> /// /// <exception cref="HealthServiceException"> /// If an error occurs when contacting HealthVault. /// </exception> /// public virtual string CreatePatientConnection( OfflineWebApplicationConnection connection, string friendlyName, string securityQuestion, string securityAnswer, Uri callbackUrl, string applicationPatientId) { Validator.ThrowIfArgumentNull(connection, "connection", "ConnectPackageConnectionNull"); Validator.ThrowIfStringNullOrEmpty(friendlyName, "friendlyName"); Validator.ThrowIfStringNullOrEmpty(securityQuestion, "securityQuestion"); Validator.ThrowIfStringNullOrEmpty(securityAnswer, "securityAnswer"); Validator.ThrowIfStringNullOrEmpty(applicationPatientId, "applicationPatientId"); HealthServiceRequest request = new HealthServiceRequest(connection, "CreateConnectRequest", 1); request.Parameters = GetCreateConnectRequestParameters( friendlyName, securityQuestion, securityAnswer, callbackUrl, applicationPatientId); request.Execute(); XPathExpression infoPath = SDKHelper.GetInfoXPathExpressionForMethod( request.Response.InfoNavigator, "CreateConnectRequest"); XPathNavigator infoNav = request.Response.InfoNavigator.SelectSingleNode(infoPath); return infoNav.SelectSingleNode("identity-code").Value; }
/// <summary> /// Updates an existing pending patient connection with a new application patient identifier. /// </summary> /// /// <param name="connection"> /// The HealthVault connection to use for the operation. /// </param> /// /// <param name="oldApplicationPatientId"> /// The application patient identifier that was used to make the initial connection request. /// </param> /// /// <param name="newApplicationPatientId"> /// The new application patient identifier. /// </param> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="connection"/> is <b>null</b>. /// </exception> /// /// <exception cref="ArgumentException"> /// If <paramref name="oldApplicationPatientId"/> or <paramref name="newApplicationPatientId"/> /// is <b>null</b> or empty. /// </exception> /// /// <exception cref="HealthServiceException"> /// If an error occurs when contacting HealthVault. /// </exception> /// public static void UpdatePatientConnectionApplicationPatientId( OfflineWebApplicationConnection connection, string oldApplicationPatientId, string newApplicationPatientId) { HealthVaultPlatformPatientConnect.Current.UpdatePatientConnectionApplicationPatientId( connection, oldApplicationPatientId, newApplicationPatientId); }
/// <summary> /// Gets the connections for the application that people have accepted since the specified /// date. /// </summary> /// /// <param name="connection"> /// The application's connection to HealthVault. /// </param> /// /// <param name="validatedSince"> /// Connections that have been validated since this date will be returned. The date passed /// should be in UTC time. /// </param> /// /// <returns> /// A collection of the connections that people have accepted. /// </returns> /// /// <remarks> /// Validated connect requests are removed by HealthVault after 90 days. It is advised /// that applications call <see cref="GetValidatedPatientConnections(Microsoft.Health.Web.OfflineWebApplicationConnection, DateTime)"/> /// daily or weekly to ensure that all validated connect requests are retrieved. /// </remarks> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="connection"/> is <b>null</b>. /// </exception> /// public virtual Collection<ValidatedPatientConnection> GetValidatedPatientConnections( OfflineWebApplicationConnection connection, DateTime validatedSince) { Validator.ThrowIfArgumentNull(connection, "connection", "ConnectPackageConnectionNull"); HealthServiceRequest request = new HealthServiceRequest(connection, "GetAuthorizedConnectRequests", 1); if (validatedSince != DateTime.MinValue) { request.Parameters = "<authorized-connect-requests-since>" + SDKHelper.XmlFromDateTime(validatedSince) + "</authorized-connect-requests-since>"; } request.Execute(); XPathExpression infoPath = SDKHelper.GetInfoXPathExpressionForMethod( request.Response.InfoNavigator, "GetAuthorizedConnectRequests"); XPathNavigator infoNav = request.Response.InfoNavigator.SelectSingleNode(infoPath); Collection<ValidatedPatientConnection> result = new Collection<ValidatedPatientConnection>(); XPathNodeIterator validatedConnectionsIterator = infoNav.Select("connect-request"); foreach (XPathNavigator nav in validatedConnectionsIterator) { ValidatedPatientConnection validatedConnection = new ValidatedPatientConnection(); validatedConnection.ParseXml(nav); result.Add(validatedConnection); } return result; }
/// <summary> /// Asks HealthVault to create a pending patient connection for the application specified /// by the connection with the specified user specific parameters. /// </summary> /// /// <param name="connection"> /// The connection to HealthVault. The application ID in the connection is used /// when making the patient connection. /// </param> /// /// <param name="friendlyName"> /// A friendly name for the patient connection which will be shown to the user when they /// go to HealthVault Shell to validate the connection. /// </param> /// /// <param name="securityQuestion"> /// A question (usually provided by the patient) to which the patient must provide the /// answer when they go to validate the connection in the HealthVault Shell. /// </param> /// /// <param name="securityAnswer"> /// The answer to the <paramref name="securityQuestion"/> which the patient must use /// when validating the connection in HealthVault Shell. The answer is case-insensitive but /// otherwise must match exactly. In most cases it is recommended that this is a single /// word to prevent entry problems when validating the connection. /// </param> /// /// <param name="callbackUrl"> /// Not yet implemented. May be null. /// </param> /// /// <param name="applicationPatientId"> /// The application specific identifier for the user. This identifier is used to uniquely /// identify the user in the application data storage whereas the HealthVault person ID is /// used to identify the person in HealthVault. /// </param> /// /// <returns> /// A token that the application must give to the patient to use when validating the /// connection request. /// </returns> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="connection"/> is <b>null</b>. /// </exception> /// /// <exception cref="ArgumentException"> /// If <paramref name="friendlyName"/>, <paramref name="securityQuestion"/>, /// <paramref name="securityAnswer"/>, or <paramref name="applicationPatientId"/> is /// <b>null</b> or empty. /// </exception> /// /// <exception cref="HealthServiceException"> /// If an error occurs when contacting HealthVault. /// </exception> /// public static string CreatePatientConnection( OfflineWebApplicationConnection connection, string friendlyName, string securityQuestion, string securityAnswer, Uri callbackUrl, string applicationPatientId) { return HealthVaultPlatformPatientConnect.Current.CreatePatientConnection( connection, friendlyName, securityQuestion, securityAnswer, callbackUrl, applicationPatientId); }
/// <summary> /// Updates an existing pending patient connection with a new application patient identifier. /// </summary> /// /// <param name="connection"> /// The HealthVault connection to use for the operation. /// </param> /// /// <param name="oldApplicationPatientId"> /// The application patient identifier that was used to make the initial connection request. /// </param> /// /// <param name="newApplicationPatientId"> /// The new application patient identifier. /// </param> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="connection"/> is <b>null</b>. /// </exception> /// /// <exception cref="ArgumentException"> /// If <paramref name="oldApplicationPatientId"/> or <paramref name="newApplicationPatientId"/> /// is <b>null</b> or empty. /// </exception> /// /// <exception cref="HealthServiceException"> /// If an error occurs when contacting HealthVault. /// </exception> /// public virtual void UpdatePatientConnectionApplicationPatientId( OfflineWebApplicationConnection connection, string oldApplicationPatientId, string newApplicationPatientId) { Validator.ThrowIfArgumentNull(connection, "connection", "ConnectPackageConnectionNull"); Validator.ThrowIfStringNullOrEmpty(oldApplicationPatientId, "oldApplicationPatientId"); Validator.ThrowIfStringNullOrEmpty(newApplicationPatientId, "newApplicationPatientId"); HealthServiceRequest request = new HealthServiceRequest(connection, "UpdateExternalId", 1); request.Parameters = String.Join( String.Empty, new string[] { "<old-external-id>", oldApplicationPatientId, "</old-external-id>", "<new-external-id>", newApplicationPatientId, "</new-external-id>" }); request.Execute(); }
/// <summary> /// Deletes a single package that has been created by the calling application but has not been /// accepted by the user. /// </summary> /// /// <param name="connection"> /// The connection to HealthVault to use for this operation. /// </param> /// /// <param name="identityCode"> /// The unique token that identifies the package. /// </param> /// /// <exception cref="ArgumentNullException"> /// If <paramref name="connection"/> is <b>null</b>. /// </exception> /// /// <exception cref="ArgumentException"> /// If <paramref name="identityCode"/> is <b>null</b> or empty. /// </exception> /// /// <exception cref="HealthServiceException"> /// If an error occurs when contacting HealthVault. /// </exception> /// public static void DeletePendingConnectionPackageForIdentityCode( OfflineWebApplicationConnection connection, string identityCode) { HealthVaultPlatformPatientConnect.Current.DeletePendingConnectionPackageForIdentityCode( connection, identityCode); }