Skip to content

Commit

Permalink
Merge pull request #412 from sailpoint-oss/feature/iiq-plugin-develop…
Browse files Browse the repository at this point in the history
…er-guide

Feature/iiq plugin developer guide
  • Loading branch information
tyler-mairose-sp authored Nov 29, 2023
2 parents db1daf6 + efdd859 commit b19f538
Show file tree
Hide file tree
Showing 26 changed files with 1,060 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

# Misc
.DS_Store
.idea
.env.local
.env.development.local
.env.test.local
Expand All @@ -18,6 +19,7 @@
npm-debug.log*
yarn-debug.log*
yarn-error.log*
yarn.lock

/products/arm/api
/products/idn/api/v3
Expand Down
2 changes: 2 additions & 0 deletions navbar.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ module.exports = {
items: [
{to: '#', label: 'API Specifications', className: 'navbar__section'},
{to: '/iiq/api', label: 'IIQ APIs', className: 'indent'},
{to: '#', label: 'Documentation', className: 'navbar__section'},
{to: 'iiq/docs', label: 'IIQ Documentation', className: 'indent'},
{to: '#', label: 'External Links', className: 'navbar__section'},
{
href: 'https://documentation.sailpoint.com/#identityiq',
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions products/iiq/docs/identity-iq/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"collapsible": false
}
37 changes: 37 additions & 0 deletions products/iiq/docs/identity-iq/index.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
id: docs
title: IdentityIQ
pagination_label: Introduction
sidebar_label: IdentityIQ
sidebar_position: 1
sidebar_class_name: IdentityIQ
hide_title: true
keywords:
[
'IdentityIQ',
'development',
'developer',
'portal',
'getting started',
'docs',
'documentation',
]
description: This is the intoduction documentation to development on the IdentityIQ platform.
slug: /docs
tags: ['Introduction', 'Getting Started']
---

import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';

🧭 There are many different ways to extend the IdentityIQ platform beyond what comes out of the box. Explore our documentation and see what is possible! This documentation assumes that you are a current customer or partner and already have access to the IdentityIQ application.

:::info Are you a partner?

Looking to become a partner? If you are interested in becoming a partner, be it an ISV or Channel/Implementation partner, [click here](https://www.sailpoint.com/partners/become-partner/).

:::

## Glossary

Identity is a complex topic, and there are many terms used, and they're used quite often! Please [refer to this glossary](https://documentation.sailpoint.com/saas/help/common/glossary.html) whenever possible if you aren't sure what something means.
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
---
id: plugin-appendix-7.1-migration
title: Appendix A 7.1 Migration
pagination_label: Appendix A 7.0 to 7.1 Migration
sidebar_label: Appendix A 7.0 to 7.1 Migration
sidebar_position: 10
sidebar_class_name: plugin_developer_guide_appendix_migration
keywords: ['plugin']
description: Migration from IdentityIQ 7.0 to 7.1
slug: /docs/plugin-developer-guide/appendix-migration
tags: ['plugin','guide','identityiq']
---

# Appendix A - Plugin Migration 7.0 to 7.1

Originally, the plugin framework was developed as an add-on to an IdentityIQ 7.0 installation. Due to the overwhelming popularity amongst clients and partners, SailPoint made the decision to migrate the frameworks into the core IdentityIQ product, starting with version 7.1.

The 7.1 Plugin Framework provides a dynamic, plugin-specific class loader. It also introduces a simple, supportable, and upgradeable user experience. The dynamic class loader provides protection for the base classes from modification, and it allows for additional security and upgradability.

The object model for plugins has also changed somewhat. This table maps the old (7.0) plugin object model to the new (7.1+) plugin object model:

|**7.0 Object Model**|**7.1 Object Model**|
| --- | --- |
|uniqueName|name|
|displayName|displayName|
|enabled|disabled|
|installationDate|installDate|
|version|version|
|order|position|
|vendorName|n/a|
|vendorID|n/a|
|visible|n/a|
|allowDisable|n/a|
|allowUninstall|n/a|
|minUpgradeableVersion|minUpgradeableVersion|
|minFrameworkVersion|minSystemVersion|
|maxFrameworkVersion|maxSystemVersion|
|installationMode|n/a|
|configurationSettings|attributes|
|certificationLevel|certificationLevel|
|pluginAccessRight|rightRequired|

Gone in 7.1 is the idea of a plugin configuration model, and a snippet model. Instead, these elements have been rolled into the 'PluginAttributes' map that appears in the 'manifest.xml' file required by each plugin. The 'fullPage' object is now a single entry in the attributes mapping, which only holds the title of the 'fullPage'. Snippets move into a 'List' entry key in the attributes map. For each snippet entry in the 'List', implementers can define a regular expression 'regexPattern' to match against, the 'rightRequired' to see the snippet, and then a list of <Scripts/> and <StyleSheets/> that determine the look and action of the snippet.

The most readily apparent change in plugin definition going from 7.0 to 7.1 is the location of each setting's plugins. Previously, developers could define a URL to a settings page ('settingsPageTemplateURL') that they could completely customize. In 7.1, in order to support future portability and support, the settings page has been removed, and individual plugin settings have been internalized to the 'manifest.xm'l file. These settings are now defined in a 'Settings' list in the 'PluginAttributes' map. Each element of the list is a 'Setting', which can have the following defined:

|Attribute Name|Description|
|---|---|
|name|Name of the current setting|
|dataType|Setting type (Ex. string or int or boolean)|
|value|Value for the setting|
|label|Display label for the setting|
|helpText|Associated help text for the setting|
|allowedValues|List of allowed values for dropdown population|
|defaultValue|Default value for the setting|

## Convert manifest

The first step in migrating a plugin from 7.0 to 7.1 is to review the changes that are required to move the 'manifest.xml' file to the 7.1 format. Refer to the previous chart when you're mapping old attributes to new ones. Move any plugin related settings from the unique page previously specified in the 'settingsPageTemplateURL' to the attributes map of the manifest object itself. If the previous unique page was complex, you may need to refactor the way these settings are selected.

## Update UI

Move the code from your 'fullPage' file previously located on that path specified by 'desktopIncludePath' and 'mobileIncludePath' to a new file in the /ui folder named 'page.xhtml'

## Refactor REST service classes

Refactor old JAX-RS based REST service classes that extended 'sailpoint.plugin.rest.AbstractPluginRestResource' to now extend 'sailpoint.rest.plugin.BasePluginResource'. You can find details on this new class in [Java Classes - Rest Resources](../chapter-7/index.md). Because of this change, the new Java classes should not be part of the 'sailpoint.plugin.rest' package but should belong to the plugin specific package developed by the implementer.

## Refactor background services

Any 7.0 plugins that extended the 'AbstractPluginBackgroundService' for a background service will now need to extend 'sailpoint.server.BasePluginService'. Details on this new class are elsewhere in this document. In addition to refactoring the service class itself, care should be taken to also modify the 'ServiceDefinition' XML object. The 'implementationClass' attribute entry is now gone. Instead, the 'executor' attribute will now change from 'sailpoint.plugin.server.PluginServiceExecutor' to the actual service that used to be listed in the 'implementationClass' entry.


### Example: A prior ServiceDefinition in 7.0

```xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE sailpoint PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<sailpoint>
<ServiceDefinition interval="10" hosts="global" executor="sailpoint.plugin.server.PluginServiceExecutor" name="HelloService">
<Description>
A Service to demo something that runs in the background
</Description>
<Attributes>
<Map>
<entry key='pluginUniqueName' value='HelloWorld'/>
<entry key='implementationClass' value='sailpoint.plugin.helloworld.server.HelloService'/>
</Map>
</Attributes>
</ServiceDefinition>
</sailpoint>
```

### Example: The same ServiceDefinition in 7.1

```xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE sailpoint PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<sailpoint>
<ServiceDefinition interval="10" hosts="global" executor="sailpoint.plugin.helloworld.server.HelloService" name="HelloService">
<Description>
A Service to demo something that runs in the background
</Description>
<Attributes>
<Map>
<entry key='pluginName' value='HelloWorld'/>
</Map>
</Attributes>
</ServiceDefinition>
</sailpoint>
```

## List custom classes in manifest

Due to the changes in how plugins are loaded and the inheritance of the object classes, it is now necessary to list the custom classes in the 'manifest.xml' file. There are a few new valid entry keys for this purpose: 'restResources', 'serviceExecutors', 'policyExecutors', and 'taskExecutors'. These entries expect a list of strings that provide the various classes. Explicitly list all your new class files that are required for the plugin in these entries - remember to use package notation. This is an example from the 'Todo' plugin manifest.xml:

```xml

<entry key="restResources">
<value>
<List>
<String>com.acme.todo.rest.TodoResource</String>
<String>com.acme.todo.rest.FlaggedUserResource</String>
<String>com.acme.todo.rest.PageConfigResource</String>
</List>
</value>
</entry>
<entry key="serviceExecutors">
<value>
<List>
<String>com.acme.todo.server.TodoFlaggingService</String>
</List>
</value>
</entry>
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
---
id: plugin-appendix-8.0-updates
title: Appendix B 8.0 Updates
pagination_label: Appendix B 8.0 Updates
sidebar_label: Appendix B 8.0 Updates
sidebar_position: 11
sidebar_class_name: plugin_developer_guide_updates
keywords: ['plugin']
description: IdentityIQ 8.0 Updates
slug: /docs/plugin-developer-guide/updates
tags: ['plugin','guide','identityiq']
---
# Appendix B - 8.0 Updates

Version 8.0 of IdentityIQ offers a number of enhancements to plugins:

* Classes contained in a plugin can be leveraged from any area or feature of IdentityIQ where BeanShell can be used, such as rules, workflow steps, and scriptlets. Version 8.0 also provides mechanisms for limiting or blocking scripting access to plugin classes as needed, and some new IIQ console commands to support troubleshooting of plugin classes.
* Support for forms in the plugin configuration UI, giving you new ways to present complex or dynamic options in the plugin's configuration page.
* Stricter handling of executors for tasks, services, and policies, with a global configuration option allowing you to "relax" the stricter declarations for legacy plugins, to help with forward compatibility.

A further detailed explanation of enhancements can be found here: [IdentityIQ 8.0: Plugin Enhancements](https://community.sailpoint.com/docs/DOC-13331)
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
id: plugin-overview
title: Overview
pagination_label: Overview
sidebar_label: Overview
sidebar_position: 1
sidebar_class_name: plugin_developer_guide_overview
keywords: ['plugin']
description: IdentityIQ Plugin Developer Guide Overview
slug: /docs/plugin-developer-guide/overview
tags: ['plugin','guide','identityiq']
---

# Overview

Introduced with IdentityIQ 7.1, the plugin framework provides the infrastructure and tools to enable developers to extend the Open Identity Platform to meet a variety of specialized use cases that one might encounter in a non-standard deployment. The plugin framework allows developers to create packaged functionality that integrates with IdentityIQ, in an upgrade safe and isolated manner. It gives implementers a safe option for creating UI (user interface) extensions, REST services, custom SailPoint configuration objects, and more. This guide will walk you through the basics of plugin development and installation.

The first iteration of the plugin framework was released as an add-on to IdentityIQ 7.0 - the development process for this legacy version is slightly different and is not the subject of this document. However, [Appendix B](../appendix-b/index.md) discusses the differences between versions, and the strategy for migrating a plugin developed for the 7.0 frameworks to the 7.1 framework.

Developing a plugin requires a fairly robust knowledge of IdentityIQ and its object model, Java, JavaScript, CSS, and SQL. This document is designed to provide development guidance at a high level - it goes over what the components of a plugin are, which components are required, and how those objects interact. Language specific tutorials are beyond its scope. Throughout this document, examples will be taken and discussed from the 'TodoPlugin'.

*A quick note about plugin loading...*

Before getting into the structure of a plugin project and why it is important, it may be helpful to understand how a plugin is represented in IdentityIQ once installed. IdentityIQ stores the '.zip' archive file of the plugin in the IdentityIQ database in a data LONGBLOB in the 'spt_file_bucket' table. The data in the 'spt_file_bucket' table is referenced (by 'id') to an entry in the 'spt_persisted_file' table as shown below.

![Persisted File](../img/persisted_file.png)

Plugins load from this .zip file after installation or an application server restart. The .zip file is extracted, and all important (html, css, js, etc) files are cached for later use. The plugin framework in 7.1 has several accessor methods to reference the cached files, but they can basically be referenced by the url prefix `<hostname>:8080/identityiq/plugin/{pluginName}` followed by the path found in the build structure. Compiled java classes are loaded (and cached) from the .zip archive via the 'PluginClassLoader' class - more on this later.

## Plugin Object Model

A plugin is defined in IdentityIQ by the 'Plugin' XML object. This object defines the parameters of the plugin, such as REST resources, snippets, settings, etc. This 'Plugin' object is defined in the 'manifest.xml' file. The plugin object is an XML object that defines the features of the plugin. This object tells IdentityIQ which features will be in your plugin by defining them as attributes of a plugin object. In the plugin object, you'll define the name of your plugin, the rights required for using your plugin, version, snippets, REST resources, etc.

**Plugin Model Attributes**

|**Attribute Name**|**Description**|
| --- | --- |
|name|Unique Name of the Plugin|
|installDate|Date when plugin was installed|
|displayName|Plugin's display name|
|certificationLevel|Plugin's certification level|
|disabled|Plugin's status|
|rightRequired|SPRIGHT required for this plugin|
|position|TBD|
|version|Plugin's version|
|minSystemVersion|Minimum IdentityIQ version the plugin will run on|
|maxSystemVersion|Maximum IdentityIQ version the plugin will run on|
|attributes|List of configurable attributes|
|file|Reference to the persisted file in the database|

## Plugin Structure

A basic plugin will consist of a manifest file, database scripts, IdentityIQ objects, REST endpoints, UI elements (.css, xhtml, javascript, etc.) and compiled java classes. Not all these components are required for a simple plugin - the process can be as simple as creating the manifest and some javascript/xhtml pages. To understand how a plugin operates and how best to create one, it is important to understand what each of these components does, and how they interact.

![File Structure](../img/plugin_structure.png)

These are the main build components:

1. Manifest file
2. Build file(s)
3. Database Scripts
4. UI Elements
5. XML Artifacts
6. Java Classes

Each build component is described in more detail in each chapter of this guide.
Loading

0 comments on commit b19f538

Please sign in to comment.