2.1.16 • Published 2 years ago

identitynow-sdk v2.1.16

Weekly downloads
6
License
ISC
Repository
-
Last release
2 years ago

Node SDK for IdentityNow

This is a node module for interacting with IdentityNow.

Breaking changes

Version 2.0.0 introduced potentially breaking changes, due to some API calls being updated to newly available v3 APIs. Because of this, some of the objects exported may have a different format, and so existing JSON objects you have exported may not import correctly. If this is the case, revert to the latest pre-2.0 version of the library

Import

const idnClient=require('identitynow-sdk');

Authorization

Authorization needs to be configured during instantiation. The following fields need to be passed in: | | | |---|---| | Tenant | Name of the IDN Tenant | clientID | Client ID for your API Client or Personal Access Token (PAT) | clientSecret | Secret for your API Client or PAT | callbackURL | Address your local listener or server will be running on. Only required for interactive user auth | userAuthenticate | boolean flag to indicate OAuth user authentication should be performed. (Optional)

This can be performed in a block like this:

const idnClient=require('identitynow-sdk');

const config={
    tenant: 'readme',
    clientID: 'b0b15abaddad',
    clientSecret: '900dc0ffee',
    callbackURL: 'http://localhost:5000/auth/identitynow/callback',
    userAuthenticate: true
}

const client=idnClient.Create( config );

ClientID and Secret are generated on the Admin page Global->Security Settings->API Management. a PAT can be generated through REST API calls, or on the 'Preferences' tab of the user menu. Both are outside the scope of this document.

if userAuthenticate is set to true, when a call is made to IdentityNow a browser window will be opened for the user to authenticate. If the user is already authenticated in the browser, then the window will immediately close and execution will continue.

NOTE If you wish to perform API activities that require an ORG_ADMIN connection, you will need to step up in the browser before running your code

ALTERNATIVELY.. If you are using the client from within a server-side Node app, where the app handles the user authentication via browser redirection, you can instantiate the client like so:

const idnClient=require('identitynow-sdk');

const config={
    tenant: 'readme',
    userToken: <Token passed back to the app via oauth redirect>
    userRefreshToken: <Refresh token passed back to the app via oauth redirect>
}

const client=idnClient.Create( config );

Common Options

All object types support the following options:

  • clean: remove attributes that would make no sense in another target system, e.g. id, created, modified, synced, pod, org
  • tokenize: flag to say whether tokenization should be applied during 'get' operations
  • tokens: JSONPath tokens to apply when tokenize is true

Tokenization

Tokenization is the act of replacing specified values in an object with tokens. This process uses JSONPath to identify values that should be replaced. For example, we can replace usernames, passwords and server addresses in a source, that can be replaced with new values when importing into another tenant.

To use, specify tokenize as true in the options of a get call, and then pass an array of tokens as tokens in the options.

For example:

A section of an exported source looks like this:

  "description": "AD Access Requests",
  "owner": {
    "type": "IDENTITY",
    "name": "Bob.Bobsson"
  },
  "cluster": {
    "type": "CLUSTER",
    "name": "DC1 VA Cluster"
  },
  .
  .
  "connectorAttributes": {
    .
    .
    "forestSettings": [
      "user": "DC1\Administrator"
      .
      .      
    ]
  }
  

Passing in a token list like this:

[
  {
    path: '$.owner.name',
      token: 'OWNER'
  },
  {
      path: '$.cluster.name',
      token: 'CLUSTER'
  },
  {
      path: '$.connectorAttributes.forestSettings[0].user',
      token: 'FOREST_USERNAME'
  }
]

Will result in the source looking like this:

  "description": "AD Access Requests",
  "owner": {
    "type": "IDENTITY",
    "name": "%%OWNER%%"
  },
  "cluster": {
    "type": "CLUSTER",
    "name": "%%CLUSTER%%"
  },
  .
  .
  "connectorAttributes": {
    .
    .
    "forestSettings": [
      "user": "%%FOREST_USERNAME%%"
      .
      .      
    ]
  }
  

And also a tokens file that looks like this:

[
  {
    "token": "%%OWNER%%",
    "value": "Bob.Bobsson"
  },
  {
    "token": "%%CLUSTER%%",
    "value": "DC1 VA Cluster"
  },
  {
    "token": "%%FOREST_USERNAME%%",
    "value": "DC1\Administrator"
  }
]

Once you have an authenticated client, the following actions are available

NOTE Unless otherwise specified, all methods will return a Promise

Access Profiles

List

client.AccessProfiles.list( [options] )

  client.AccessProfiles.list().then( function ( profiles ) { 
      ....
  });

List all access profiles.

Options:

  • useV2: Use the V2 API to list Access Profiles. The data returned by V2 is slightly different to V3

Methods to directly use the V2 or V3 API are available as listv2() and listv3() respectively

Search

client.AccessProfiles.search( query )

  client.AccessProfiles.search( 'AD*' ).then( function ( profiles ) { 
      ....
  });

Search access profiles. query can contain wildcards

NOTE Uses the V3 API, so to use the results with any wrapped V2 calls translation will be required

Get By Name

client.AccessProfiles.getByName( name [, options])

  client.AccessProfiles.getByName( name ).then( function ( profile ) { 
      ....
  });

Get an Access Profile by name. This method is designed to return an error if more than one result is found. For multiple results, use AccessProfiles.search()

Options:

  • useV2: Use the V2 API to get the Access Profile. The data returned by V2 is slightly different to V3

Get

client.AccessProfiles.get( id [, options])

  client.AccessProfiles.get( id ).then( function ( profile ) { 
      ....
  });

Get an Access Profile

Options:

  • useV2: Use the V2 API to list Access Profiles. The data returned by V2 is slightly different to V3

Methods to directly use the V2 or V3 API are available as getv2( id ) and getv3( id ) respectively

Delete

client.AccessProfiles.delete( id [, options])

  client.AccessProfiles.delete( id ).then( function ( profile ) { 
      ....
  });

Delete Access Profile

Options:

  • useV2: Use the V2 API to delete Access Profiles

Methods to directly use the V2 or V3 API are available as deletev2( id ) and deletev3( id ) respectively

Delete

client.AccessProfiles.deleteByName( id [, options])

  client.AccessProfiles.deleteByName( id ).then( function ( profile ) { 
      ....
  });

Delete Access Profile (by name)

Options:

  • useV2: Use the V2 API to delete Access Profiles

Create

client.AccessProfiles.create( json [, options])

  client.AccessProfiles.create( json ).then( function ( response ) { 
      ....
  });

Create an Access Profile Using names for owner and source is possible; use the attributes ownerName and sourceName instead of ownerId or sourceId to have the SDK perform a lookup into the target system. entitlements must be specified as IDs (migration to value is a roadmap item)

Options:

  • useV2: Use the V2 API to create Access Profiles. The data required by V2 is slightly different to V3

Methods to directly use the V2 or V3 API are available as createv2( id ) and createv3( id ) respectively NOTE There is currently no V3 API for this; trying to use it will return a rejected promise.

Account Profiles

List

client.AccountProfiles.list()

  client.AccountProfiles.list().then( function ( profiles ) { 
      ....
  });

List all Account profiles.

Get

client.AccountProfiles.get( id )

  client.AccountProfiles.get( id ).then( function ( profile ) { 
      ....
  });

Get an Account Profile

Update

client.AccountProfiles.update( id, json)

  client.AccountProfiles.update( id, json ).then( function ( response ) { 
      ....
  });

Update an Account Profile

Clusters

List

client.Clusters.list()

  client.Clusters.list().then( function ( clusters ) { 
      ....
  });

Get a list of VA Clusters

Get by name

client.Clusters.getByName( name )

  client.Clusters.getByName( name ).then( function ( cluster ) { 
      ....
  });

Get a specific VA Cluster

Entitlements

List

client.Entitlements.list( [ options ])

  client.Entitlements.list().then( function ( entitlements ) { 
      ....
  });

Get a list of entitlements

Options:

  • sourceId: id of source to constrain search
  • sourceName: name of source to constrain search
  • entitlements: list of values to constrain search
  client.Entitlements.list( {
      sourceName: 'Active Directory',
      entitlements: [
          'CN=All_Users,OU=Groups,DC=sailpoint,DC=com',
          'CN=Corporate-VPN,OU=Groups,DC=sailpoint,DC=com'
      ]
  }).then( function ( entitlements ) { 
      ....
  });

Identities

List

client.Identities.list()

  client.Identities.list().then( function ( identities ) { 
      ....
  });

Get a list of identities

Get

client.Identities.get( id )

  client.Identities.get( id ).then( function ( identities ) { 
      ....
  });

Get an identity

Options:

  • useV2: use the V2 API to retrieve the Identity Methods to directly use the V2 or V3 API are available as getv2( id ) and getv3( id ) respectively

Roles

List

client.Roles.list()

  client.Roles.list().then( function ( roles ) { 
      ....
  });

Get a list of roles

Get

client.Roles.get( id )

  client.Roles.get( id, options ).then( function ( role ) { 
      ....
  });

Get a role Available options: useV3: use V3 APIs (search). Note this will produce output incompatible with V2 APIs

  • This becomes important when exporting with get and importing with create. Currently create relies on CC APIs which use the V2 JSON syntax dereferenceAccessProfiles: (default: true) whether or not to convert AccessProfile ids to names on output. If so, stored in the accessProfileNames property

Also available: client.Roles.getv2 and client.Roles.getv3

GetByName

client.Roles.getByName( roleName)

Same as get but uses role name to get the role

Create

client.Roles.create( json )

  client.Roles.create( json ).then( function ( role ) {
    console.log( 'created role' );
    console.log( JSON.stringify( role, null, 2 ) );
  })

Create a role. Uses a JSON object in the format returned by get or getByName. Access Profile names in the accessProfileNames property will be translated to IDs in accessProfileIds as required by the underlying API.

Sources

List

client.Sources.list()

  client.Sources.List().then( function ( sources ) { 
      ....
  });

Get a list of sources

Get

client.Sources.get( id [, options] )

Get a specific source by ID.

    client.Sources.get( 'abcdef1234' ).then( function ( source ) {
        ....
    });

Get a 'clean' version of the source. Strips out all IDs as they will only be accurate in the tenant the source is extracted from

    client.Sources.get( 'abcdef1234', { clean: true } ).then( function ( source) {
        ....
    });

Get an 'exported' version of the source. This will collect sub-objects (such as Schemas) and bundle them in the response.

    client.Sources.get( 'abcdef1234', { clean: true, export: true } ).then( function ( object ) {
        ....
    });

This will return something like:

    source: { <source data> },
    schemas: [
        { <schema data> },
        { <schema data> }
    ]
    ...
    connectorFiles: {
        <filename>:
    }
}

Options:

  • export: Collect sub-objects (such as Schemas) and bundle them in the response.
  • zip: return the source and related objects as a JSZip object

Get by Name

Get a specific source by ID. client.Sources.getByName( name [, options] )

    client.Sources.getByName( 'Active Direectory' ).then( function ( source) {
        ....
    });

The same options as get( id ) are available

Get Zip file

Alternative call to get a zip of a specific source with its associated objects

    client.Sources.getZip( 'abcdef1234' ).then( function ( zip ) {
        ....
    });

This returns a zip object (using the JSZip library) which can then be written to a file. For example:

client.Sources.getZip( 'abcdef1234' ).then( function (zip) {
    zip
    .generateNodeStream({type:'nodebuffer',streamFiles:true})
    .pipe(fs.createWriteStream('out.zip'))
    .on('finish', function () {
        // JSZip generates a readable stream with a "end" event,
        // but is piped here in a writable stream which emits a "finish" event.
        console.log("out.zip written.");
    });
})

Create

Create a new source

client.Sources.create( object );

When creating a source, the object passed in can contain all the sub-objects (schemas etc.) associated with the source. At a minimum, it must contain a definition of the source:

{
    source: {
        description: 'My Source',
        ...
    }
}

It can also contain Schemas (this list continues to be extended)

Owner and Cluster can be specified by name; the SDK will look up the relevant ID in the IDN tenant

Update

TODO

Delete

var source=client.Sources.delete( 'abcdef1234' )

Schemas

List

  var sources = client.Schemas.List();

Get

Get a specific source by ID

    var source = client.Schemas.get( 'abcd1234' );

Create

client.Schemas.create( 'abcdef1234', object );

Create a schema. Pass in the ID of the Source, and the object representing the schema

Update

TODO

Delete

client.Schemas.delete( 'abcdef1234', 'badc0ffee' ).then( function( ok ){
    ....
})

Delete a schema. Pass in the ID of the Source, and the ID of the schema

Transforms

List

  client.Transforms.List().then( function( items ){
      ....
  });

Return value looks like:

[
    {
        "attributes": null,
        "id": "ToUpper",
        "type": "upper"
    },
    {
        "attributes": null,
        "id": "ISO3166 Country Format",
        "type": "iso3166"
    },
    ....
]

Get

Get a specific transform by ID

    client.Schemas.get( 'ToUpper' ).then( function (transform) {
        ....
    });

Create

TODO

Update

TODO

Delete

TODO

Account Profiles

List

client.AccountProfiles.list( 'abcdef1234' ).then( function( profiles ) {
    ....
});

Returns a list of account profiles for the specified source. Returns an Array

Get

client.AccountProfiles.get( 'abcdef1234', 'Create' ).then( function( profile ) {
    ....
});

Returns the account profile for the specified source and Usage

Virtual Appliances

Create a Cluster

client.VirtualAppliances.createCluster( { clusterName: 'My Cluster'} ).then( function( cluster ) {
    ....
});

Creates a new VA cluster. Returns the new cluster object in JSON format

Create Virtual Appliance

client.VirtualAppliances.createVA( { clusterid: <CC cluster ID>} ).then( function( vaConfig ) {
    ....
});

Creates a new VA in the specified cluster. Returns:

{
  id: <VA ID>,
  yamlSource: <VA YAML config file as a string>,
  yamlObject: <VA config as a JSON object>
}
2.1.16

2 years ago

2.1.14

2 years ago

2.1.15

2 years ago

2.1.12

2 years ago

2.1.13

2 years ago

2.1.9

2 years ago

2.1.10

2 years ago

2.1.11

2 years ago

2.1.8

2 years ago

2.1.2

2 years ago

2.1.4

2 years ago

2.1.3

2 years ago

2.1.6

2 years ago

2.1.5

2 years ago

2.1.7

2 years ago

2.1.1

2 years ago

2.1.0

2 years ago

2.0.2-alpha.3

3 years ago

2.0.2-alpha.2

3 years ago

2.0.2-alpha.1

3 years ago

2.0.2

3 years ago

2.0.1

3 years ago

2.0.0

3 years ago

1.2.30

3 years ago

1.2.31

3 years ago

1.2.28

3 years ago

1.2.29

3 years ago

1.2.27

3 years ago

1.2.23

3 years ago

1.2.24

3 years ago

1.2.22

3 years ago

1.2.25

3 years ago

1.2.26

3 years ago

1.2.19

3 years ago

1.2.20

3 years ago

1.2.21

3 years ago

1.2.18

3 years ago

1.2.17

3 years ago

1.2.16

3 years ago

1.2.15

3 years ago

1.2.12

3 years ago

1.2.13

3 years ago

1.2.11

3 years ago

1.2.8

3 years ago

1.2.10

3 years ago

1.2.7

3 years ago

1.2.6

3 years ago

1.2.5

3 years ago

1.2.4

3 years ago

1.2.0

3 years ago

1.2.3

3 years ago

1.2.1

3 years ago

1.1.1

3 years ago

1.1.0

3 years ago

1.0.2

4 years ago

1.0.1

4 years ago

1.0.3

4 years ago

1.0.0

4 years ago