GetPersonInfo access is denied

Aug 18, 2013 at 5:30 AM
Edited Aug 18, 2013 at 5:40 AM
Hi

I m using the latest library and trying to get the "GetPersonInfo" working to retrieve the id of the owner of a healthvault account. However i keep getting the following error:

com.microsoft.hsg.HVAccessDeniedException: The authentication token element of the request is required for this method.

or this one if i run the app again:

com.microsoft.hsg.HVAccessDeniedException: Access is denied.

I use this to get the sessionToken: connection.getSessionToken()
and it is "fresh" as far as i know...


I have checked the SODA rules for my appid as follows:
Personal Contact Information
Basic Demographic Information


This is my code which i added to the HealthVaultService class. I tried to reset the account etc

I think the trouble is here:
String userAuthToken = connection.getSessionToken();
request.setUserAuthToken(userAuthToken);

What is the correct token to be used in this call?

public void getPersonInfo()
{
    try
    {

        Connection connection = getConnection();
        HVAccessor accessor = new HVAccessor();

        Request request = new Request();
        request.setMethodName("GetPersonInfo");

        // We need the sessiontoken
        String userAuthToken = connection.getSessionToken();

        request.setUserAuthToken(userAuthToken);

        request.setInfo("<info><parameters/></info>");
        accessor.send(request, connection);
        Response response = accessor.getResponse();


        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        factory.setNamespaceAware(false);
        XmlPullParser parser = factory.newPullParser();
        parser.setInput(response.getInputStream(), "utf8");

        XmlUtils.nextStartTag(parser, "response");
        XmlUtils.nextStartTag(parser, "status");
        XmlUtils.skipSubTree(parser);
        XmlUtils.nextStartTag(parser, "wc:info");
        XmlUtils.nextStartTag(parser, "response-results");

        while (parser.nextTag() == XmlPullParser.START_TAG)
        {
            // to be done to parse the result
        }
    } catch (Exception e)
    {
             throw new HVSystemException(e);
    }
    // return personInfoList;
}
Aug 23, 2013 at 2:34 PM
Edited Aug 23, 2013 at 3:00 PM
Ok got access to PersonId but the UUID changes every time you reset the account. So the problem is still there. I need to get the unique id that identifies a HV account. I assume that is available via the GetPersonInfo.

Still the issue remains that i cannot get the method GetPersonInfo working and receive consistently Access Denied exception. What needs to be done to get that working with Android HealthVault SDK?

Peter
Coordinator
Aug 26, 2013 at 4:15 PM
Edited Aug 26, 2013 at 8:01 PM
Hi,

The Android library utilizes the SODA work flow to establish identity on the device. Once an application identifier is assigned to the device and the user has authorized that device for HealthVault, all HealthVault requests use the "offline" model. In the offline model, no user auth token is required. However, requests must have the offline-user-id set on the request. Be sure to create offline rules to access types when creating your application.

If you reset the application information--remove the application-id and application-secret--a new application-id/secret pair must be created. After a new id is created, you will obtain a different person-id for the the same HealthVault user. Each application sees unique person-ids and record-ids for the same underlying data within HealthVault.

In order to call GetPersonInfo with a SODA application, you must know the person-id in advance. Seems like a conundrum? To get the person-id you need to already know it? Web Applications using online connectivity utilize the user auth token, but SODA applications do not have a user auth token. How do you get the person-id? SODA applications must make the HealthVault call GetAuthorizedPeople. The Android SDK wraps this call in HealthVaultService.getPersonInfoList. You can take any of the returned person-ids, use them on request.setOfflineUserId().

Once you have a person-id, you can use the SimpleRequestTemplate from the SDK which will set everything up for you.
PersonInfo personInfo = service.getPersonInfoList().get(0);
SimpleRequestTemplate template = new SimpleRequestTemplate(
                service.getConnection(),
                selectedRecord.getPersonId(),
                selectedRecord.getId());
 Request request = new Request();
        request.setMethodName("GetThings");
        request.setInfo(buildInfo());
        template.makeRequest(request);
--Rob
Aug 27, 2013 at 4:12 AM
Edited Aug 27, 2013 at 4:12 AM
Hi

Thanks for the reply. It was just that missing piece of information that i needed to know. So for those that want to add GetPersonInfo to the Android SDK this is how i did it. It is very easy once you know all the elements :-)



public String getPersonInfo(String offlineUserId)
{
    String personId = "";
    String name = "";


    if (offlineUserId == null || offlineUserId.length() < 3)
    {
        Log.e("TAG", "HealthVaulService: GetPersonInfo: NO proper userID" + offlineUserId);
        return personId;
    }
    try
    {
        Connection connection = getConnection();
        HVAccessor accessor = new HVAccessor();
        Request request = new Request();

        request.setOfflineUserId(offlineUserId);
        request.setMethodName("GetPersonInfo");

        accessor.send(request, connection);
        Response response = accessor.getResponse();

        XmlPullParserFactory factory = XmlPullParserFactory.newInstance();
        factory.setNamespaceAware(false);
        XmlPullParser parser = factory.newPullParser();
        parser.setInput(response.getInputStream(), "utf8");

        XmlUtils.nextStartTag(parser, "response");
        XmlUtils.nextStartTag(parser, "status");
        XmlUtils.skipSubTree(parser);
        XmlUtils.nextStartTag(parser, "wc:info");

        while (parser.nextTag() == XmlPullParser.START_TAG)
        {
            if ("person-info".equals(parser.getName()))
            {
                int valueDepth = parser.getDepth();
                while (parser.nextTag() == XmlPullParser.START_TAG && parser.getDepth() > valueDepth)
                {
                    if ("person-id".equals(parser.getName()))
                        personId = parser.nextText();
                    else if ("name".equals(parser.getName()))
                        name = parser.nextText();
                    else
                        XmlUtils.skipSubTree(parser);
                }
            } else
            {
                XmlUtils.skipSubTree(parser);
            }
        }
    } catch (Exception e)
    {
        Log.e("TAG", "HealthVaultService: getPersonInfo", e);
    }

    // Log.i("TAG", "XML personId: " + personId);
    // Log.i("TAG", "XML name: " + name);

    return name;
}
Aug 27, 2013 at 9:51 AM
Hi

I get now the basic info of an HealthVault Account but this does not uniquely identify an HV Account Holder. They can create multiple HV Accounts with the same basic info. Is it possible to get really the unique id of an account?
Coordinator
Aug 27, 2013 at 6:05 PM
Hi,

There is no way to uniquely identify the account across different application ids. HealthVault purposely obfuscates the account id to different applications.

--Rob