Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

PDS Client 2.0 JavaScript API

Revision as of 10:40, 12 November 2010 by Mmcintosh.azigo.com (Talk | contribs) (Context Identifier)

Introduction

The JavaScript API allows the developer (the API consumer) to simply treat the PDS Client and any personal or managed data stores in the cloud as one big database. It allows you to read or write in a single operation a set of attributes and their values.

The JavaScript API is implemented by a NPAPI browser plugin that is used in the user’s “regular” browser as well as the Dashboard’s embedded browser. This API is intended to support a variety of apps that need access to data about the current user.

Applications

The following apps being developed in Higgins consume this API by Javascript calls specified by an app-card:

  • Password Manager
  • Form filler
  • App-Card Framework

Complexity Hiding

This API supports two ways of accessing the underlying data.

"Flat" APIs

In the "flat" version of the API calls, the consumer doesn't need to understand nor have to navigate the structured nature of that some attributes in the Persona Data Model 2.0 (PDM) have. Similarly it doesn't require the consumer to understand nor have to navigate the graph structure of the underlying p:Person nodes in this data model. Instead it hides all of these complexities.

For example, the fact that in the PDM we might have a p:person node of role “payer” with a vcard:adr link to a v:Address object that in turn has a vcard:street-name attribute and value is hidden. The getRPAttributes() consumer simply has to ask for the "payer street name" attribute and they will get back a literal string value like "123 main street”.

By hiding the underlying structures the API implementation, code can protect the underlying data structures from being directly accessed and possibly accidentally or maliciously modified such that they are in an inconsistent state.

"Structured" APIs

One consequence of the structure flattening and information hiding described above is that apps that by their very nature require read/write access to most or all of the underlying PDM objects can not use this API. This kind of app needs access to lower level APIs closer to the “raw” IdAS API that exposes all contexts and contained entities.

Types

Consumer Identifier

When a JavaScript app calls one of those APIs we need to identify: the current user, the AppCard, and relying party (web site where data is being shared) for access control purposes. For that purpose, we define the following structure:

struct consumer_id
{
   string app_id; //AppCard's ID
   string relying_party; // source/destination of shared data
};

Note that the current user can be determined inside the PDS Client and therefore needn't be passed as a parameter.

Context Identifier

When a JavaScript app calls one of those APIs we need to identify the context to read the data from or write the data to. This requires the following fields: the user that owns the context, the app that owns the context, and the issuer of the data. For that purpose, we define the following structure:

struct context_id
{
string user_id; // Ownering user's ID
string app_id; // Owning AppCard's ID
string issuer; // source/destination of data
};

Attribute Values

In 'simple input arg style' case, we need to transfer attributes with their values by the following structure:

{code} struct att_vals { string att_type; //Attribute string array values; //Array of its values }; {code}

Return Codes

{code} 0 - success other - error code {code}

Functions

JavaScript Functions

Flat Data Model Functions

setRPAttributes

getRPAttributes

getRPAttributes(rp1, app, (att, optional, issuers)[])

Master flow steps:

  1. If no Profile Context for this RP exists [1] then
    1. Instantiate a Profile Context setting its contextId to rp1
      1. If a template context containing an AttributeMap can be found for this RP (e.g. staples.com) then
        1. Use it as the template (h:control) for the new context
      2. Else
        1. Use the generic FlatPersona template as the template (h:control) for the new context
      3. Instantiate a new p:Person within the context
      4. Add a link from RootMe to this new p:Person
    2. Create candidate source list, CSL, p:Person nodes:
      1. Traverse p:Person graph breadth first starting from RootMe
      2. For each p:Person node, P and for each requested attribute, RA,
        1. If the issuer of the containing context of P is not trusted by RP for attribute RA, then skip to the next requested attribute
        2. Lookup A’s associated mapping rule, R
        3. If R cannot be found, then skip this attribute
        4. Else lookup the mapped attribute, MA of R
        5. Trace R’s mapping path from P to see if P has a value for attribute MA
        6. If it does, then add P to CSL
    3. Display the card selector window in the Dashboard app showing the containing card-contexts of each node in the CSL. Note: multiple alternative cards may contribute attributes to the overall list of required attributes.
      1. Wait for the user to click a card
      2. By clicking a card the user is giving consent to release these attributes (not only this one time but from now on) and (in the case where there were multiple cards that could contribute the same attribute(s) the user is disambiguating the situation—making a personal choice as to which card among the set of alternatives should be used.
      3. Each time a card is clicked, any remaining redundant card should be greyed out (or perhaps completely hidden)
      4. Repeat the above until there are no more cards to pick.
    4. Create a Disclosure instance and list all attributes that are being disclosed to the RP
    5. Instantiate the p:source links from the new p:Person to the p:Person node(s) in the selected card/contexts. At this point the Profile Context exists…
  2. Use the p:Person node within the RP Profile Context as the "base" p:Person node from which to read values of requested attributes
  3. For each requested attribute, RA,
    1. If RA is not on the “approved for release” list [3] of the Profile Context list then skip to the next requested attribute
    2. Lookup A’s associated mapping rule, R
    3. Lookup the mapped attribute, MA of R
    4. Trace R’s mapping path from P to see if P has a value for attribute MA
    5. If it does then
      1. Record this value to be returned
    6. Else
      1. Follow the p:source link that is a source for RA
      2. Repeat the above procedure using the target of p:source as the new “base” p:Person node
  4. Return attributes/values

Errata (mistakes and omissions in the above master flow):

  1. An extra level of logical indirection is built into AppCard contexts and support for this needs to be added to the logic above. Let me explain. Whereas most contexts directly contain data (most notably p:Person and related objects), some contexts, namely AppCard contexts, are really pointers to data. Their p:Person node points to an entity in its associated AppData context. This is the extra level of indirection. If a p:subCorrelation link from, say, RootMe points to p:Person node P within an AppCard context, then the “real” person data lies at the entity pointed to by P’s resource-udr attribute.

References:

getSuggestions

Structured Data Model Functions

addEntityAttributes

setEntityAttributes

delEntityAttributes

getEntityAttributes

{code} short getEntityAttributes( in consumer_id, // issuer, appId - identifies app which asks the data in supplier_id, // issuer, appId - identifies app which provides the data in string atts, // json request, see below in string array token_type // see Action Support wiki page out string res // json result, see below ); {code}

Dashboard Functions

The following APIs are not exposed to JavaScript running in browsers other than the Dashboard's embedded browser.

removePWData

getPWException

removePWException

removeRMCard

Back to the top