diff --git a/.gitignore b/.gitignore index 1ae04775509..03a31942445 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ # Misc .DS_Store +.idea .env.local .env.development.local .env.test.local @@ -18,6 +19,7 @@ npm-debug.log* yarn-debug.log* yarn-error.log* +yarn.lock /products/arm/api /products/idn/api/v3 diff --git a/navbar.js b/navbar.js index 99a97104e9c..31cb62e4b9e 100644 --- a/navbar.js +++ b/navbar.js @@ -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', diff --git a/package-lock.json b/package-lock.json index 94e5e3f96af..344aa0a4c0a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27101,4 +27101,4 @@ "version": "1.0.5" } } -} +} \ No newline at end of file diff --git a/products/idn/docs/identity-now/rules/connector-rules/index.md b/products/idn/docs/identity-now/rules/connector-rules/index.md index bb076697fd8..907593333dd 100644 --- a/products/idn/docs/identity-now/rules/connector-rules/index.md +++ b/products/idn/docs/identity-now/rules/connector-rules/index.md @@ -26,12 +26,12 @@ Unlike cloud rules, connector rules do not have a rule review process and are di | [After Modify Rule](./before_after_operation_rule.md) | [ConnectorAfterModify](./before_after_operation_rule.md) | Active Directory, Azure Active Directory | Executes PowerShell commands on the IQService component after a source account is modified. | | [After Delete Rule](./before_after_operation_rule.md) | [ConnectorAfterDelete](./before_after_operation_rule.md) | Active Directory, Azure Active Directory | Executes PowerShell commands on the IQService component after a source account is deleted. | | Build Map Rule | BuildMap | Delimited File | Calculates and transforms data from a parsed file during the aggregation process. _Note: This is only available for the Delimited File source type, not Generic source types._ | -| JDBC Build Map Rule | JDBCBuildMap | JDBC | Calculates and transforms data from a database query result during the aggregation process. It can also perform additional calls back to the database. _Note: This rule is available for the JDBC Generic source, as well as other sources that derive from the JDBC connector (e.g., Oracle EBS, PeopleSoft, etc.)_ | -| JDBC Provision Rule | JDBCProvision | JDBC | Executes database queries to perform provisioning of account and access for all account operations. | -| SAP Build Map Rule | SAPBuildMap | SAP HR, SAP | Calculates and transforms data from SAP during the aggregation process. It can also perform additional calls back to the SAP system using SAP BAPI calls. | -| SAP HR Provisioning Modify Rule | SapHrOperationProvisioning | SAP HR | Performs SAP HR modification operations during provisioning. Often used for attribute sync to custom SAP HR attributes. | -| Web Services Before Operation Rule | WebServiceBeforeOperationRule | Web Services | Executes before the next web-services HTTP(S) operation. Often used to calculate values. | -| Web Services After Operation Rule | WebServiceAfterOperationRule | Web Services | Executes after a web-services HTTP(S) operation. Often used to parse complex data. | +| [JDBC Build Map Rule](./jdbc_build_map_rule.md) | [JDBCBuildMap](./jdbc_build_map_rule.md) | JDBC | Calculates and transforms data from a database query result during the aggregation process. It can also perform additional calls back to the database. _Note: This rule is available for the JDBC Generic source, as well as other sources that derive from the JDBC connector (e.g., Oracle EBS, PeopleSoft, etc.)_ | +| [JDBC Provision Rule](./jdbc_provision_rule.md) | [JDBCProvision](./jdbc_provision_rule.md) | JDBC | Executes database queries to perform provisioning of account and access for all account operations. | +| [SAP Build Map Rule](./sap_buildmap_rule.md) | [SAPBuildMap](./sap_buildmap_rule.md) | SAP HR, SAP | Calculates and transforms data from SAP during the aggregation process. It can also perform additional calls back to the SAP system using SAP BAPI calls. | +| [SAP HR Provisioning Modify Rule](./sap_hr_provisioning_modify_rule.md) | [SapHrOperationProvisioning](./sap_hr_provisioning_modify_rule.md) | SAP HR | Performs SAP HR modification operations during provisioning. Often used for attribute sync to custom SAP HR attributes. | +| [Web Services Before Operation Rule](./web_services_before_operation_rule.md) | [WebServiceBeforeOperationRule](./web_services_before_operation_rule.md) | Web Services | Executes before the next web-services HTTP(S) operation. Often used to calculate values. | +| [Web Services After Operation Rule](./web_services_after_operation_rule.md) | [WebServiceAfterOperationRule](./web_services_after_operation_rule.md) | Web Services | Executes after a web-services HTTP(S) operation. Often used to parse complex data. | ## Configuration Process diff --git a/products/iiq/docs/identity-iq/_category_.json b/products/iiq/docs/identity-iq/_category_.json new file mode 100644 index 00000000000..9e90632aacf --- /dev/null +++ b/products/iiq/docs/identity-iq/_category_.json @@ -0,0 +1,3 @@ +{ + "collapsible": false +} \ No newline at end of file diff --git a/products/iiq/docs/identity-iq/index.mdx b/products/iiq/docs/identity-iq/index.mdx new file mode 100644 index 00000000000..ea5000dab97 --- /dev/null +++ b/products/iiq/docs/identity-iq/index.mdx @@ -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. diff --git a/products/iiq/docs/identity-iq/plugin-developer-guide/appendix-a/index.md b/products/iiq/docs/identity-iq/plugin-developer-guide/appendix-a/index.md new file mode 100644 index 00000000000..16fea54ae60 --- /dev/null +++ b/products/iiq/docs/identity-iq/plugin-developer-guide/appendix-a/index.md @@ -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 and 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 + + + + + + A Service to demo something that runs in the background + + + + + + + + + +``` + +### Example: The same ServiceDefinition in 7.1 + +```xml + + + + + + A Service to demo something that runs in the background + + + + + + + + +``` + +## 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 + + + + + com.acme.todo.rest.TodoResource + com.acme.todo.rest.FlaggedUserResource + com.acme.todo.rest.PageConfigResource + + + + + + + com.acme.todo.server.TodoFlaggingService + + + +``` \ No newline at end of file diff --git a/products/iiq/docs/identity-iq/plugin-developer-guide/appendix-b/index.md b/products/iiq/docs/identity-iq/plugin-developer-guide/appendix-b/index.md new file mode 100644 index 00000000000..299e697af03 --- /dev/null +++ b/products/iiq/docs/identity-iq/plugin-developer-guide/appendix-b/index.md @@ -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) \ No newline at end of file diff --git a/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-1/index.md b/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-1/index.md new file mode 100644 index 00000000000..4dd6d82f3a3 --- /dev/null +++ b/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-1/index.md @@ -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 `: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. \ No newline at end of file diff --git a/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-2/index.md b/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-2/index.md new file mode 100644 index 00000000000..b4f98154ec2 --- /dev/null +++ b/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-2/index.md @@ -0,0 +1,156 @@ +--- +id: plugin-manifest +title: Manifest +pagination_label: Manifest +sidebar_label: Manifest +sidebar_position: 2 +sidebar_class_name: plugin_developer_guide_manifest +keywords: ['plugin'] +description: IdentityIQ Plugin Manifest File +slug: /docs/plugin-developer-guide/manifest +tags: ['plugin','guide','identityiq'] +--- + +# Manifest File + +A plugin is defined in IdentityIQ by the 'Plugin' XML object that defines the parameters of the plugin. Features such as REST resources, snippets, settings, etc. are defined in these parameters. The 'Plugin' object is defined in the 'manifest.xml' file. This is a required artifact. The 'Todo' plugin manifest will be examined: + + ```xml + + + + + + + + + + + + + + + com.acme.todo.rest.TodoResource + com.acme.todo.rest.FlaggedUserResource + com.acme.todo.rest.PageConfigResource + + + + + + + com.acme.todo.server.TodoFlaggingService + + + + + + + + + + + + + + + + + + + ui/js/snippets/header.js + + + ui/css/todo.css + + + + + + + + +``` + +- **Line 3** - contains the plugin's metadata. This is where you will define the object name of your plugin (name value), the name displayed in the UI for your plugin (`displayName`), and the minimum system version (`minSystemVersion`). +- **Line 6** - `minUpgradeableVersion` specifies which version of this plugin has to be installed in order to upgrade to the version specified in the manifest file's metadata. +- **Line 7** - `fullPage` indicates whether this plugin will have a full page element available in the IdentityIQ UI - see the 'page.xhtml' section of this document under 'UI elements'. +- **Line 12-20** - specifies the compiled Java classes, by package, that include the REST web service endpoints that you have written - see REST section of this document under 'Java Classes'. +- **Line 21-27** - specifies the compiled Java classes, by package, that contain the service executors for your plugin - see the Service Executors section of this document under 'Java Classes'. +- **Line 28-37** - specifies the settings that are end-user configurable for this plugin. +- **Line 38-51** - lists the various snippets that can be injected into IdentityIQ pages, the match criteria, and the content and style of the snippet. + + +## Settings + +Plugin settings are attributes that are available for the end-user/system administrator to modify as part of their installation. The example from the 'Todo' plugin has four settings available that control default values for certain elements, as well as whether or not 'Todo' entries can be deleted in the UI. Settings appear to the end user when they click the 'Configure' button for the specific plugin on the 'Plugins' dashboard. + +Settings from the manifest file will be listed in order on the plugin settings page. Also present on the plugin settings page is a visual representation of the meta data in the manifest file (name, version, certification level). + +One concept not shown in the 'Todo' plugin example, the concept of 'allowed values', can be very useful. This concept allows the developer to provide a predefined list of values that a field can adopt. The dataType 'boolean' does this automatically. In the earlier screenshot, there is a dropdown element available on the 'Delete Allowed' setting - the dropdown has two elements: 'True' and 'False'. + +Plugin setting object can be used to represent a single setting the settings/configuration page for a Plugin. Each object is used to represent a single configurable setting on the settings page. + +|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|The default value for the setting| + +## Snippets + +Snippets are small, configurable pieces of code that can be injected into the rendering of normal IdentityIQ UI pages. A snippet contains four equally important components: + +|**Attribute Name**|**Description**| +| --- | --- | +|regexPattern|Regular expression pattern run against the current URL in the browser - if the URL matches the pattern, the snippet will attempt to display.| +|rightRequired|Determines the scope of users allowed to view the snippet element - this should reference an IdentityIQ 'SPRight' object.| +|scripts|List of scripts to run when a particular URL matches the `regexPattern`. Normally this will consist of injecting an element into the DOM of the page. The 'Todo' example's 'hearder.js' file uses JQuery for this purpose.| +|styleSheets|list of any css files that are required by Snippet Scripts| + +The 'Todo' plugin snippet creates a new top level icon on every page of the IdentityIQ UI, which is visible to someone with the `ViewTodoPluginIcon` SPRight. + + ```xml + + + + + + ui/js/snippets/header.js + + + ui/css/todo.css + + + + + +``` + +The script, `header.js` looks for `ul.navbar-right li:first`. Then, using the JQuery operation `.before()`, the script injects an icon link pointing to the fullPage (/plugins/pluginPage.jsf?pn=TodoPlugin) of the 'Todo' plugin. + + +```javascript +var url = SailPoint.CONTEXT_PATH + '/plugins/pluginPage.jsf?pn=TodoPlugin'; + +jQuery(document).ready(function(){ + jQuery("ul.navbar-right li:first") + .before( + '' + ); +}); +``` + +For reference, if you were to inspect any page of the IdentityIQ UI using a utility like Google Chrome's developer tools, you could figure out where to potentially have JQuery inject your snippet scripts. + +The end result of this snippet is shown here, with the icon properly inserted before the other items in the `navbar-right` list: + +![Snippet](../img/snippet.png) \ No newline at end of file diff --git a/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-3/index.md b/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-3/index.md new file mode 100644 index 00000000000..4bc2e99dc33 --- /dev/null +++ b/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-3/index.md @@ -0,0 +1,104 @@ +--- +id: plugin-build-file +title: Build File +pagination_label: Build File +sidebar_label: Build File +sidebar_position: 3 +sidebar_class_name: plugin_developer_guide_build_file +keywords: ['plugin'] +description: IdentityIQ Plugin Build File +slug: /docs/plugin-developer-guide/build-file +tags: ['plugin','guide','identityiq'] +--- + +# Build File + +Apache Ant is a simple, readily available tool you can use to package plugins prior to deployment and distribution. To provide build specific values, the standard is to also include a `build.properties` file with a simple key-value pair for all build specific tokens. + +```text +jdk.home.1.7=/Library/Java/JavaVirtualMachines/jdk1.8.0_66.jdk +iiq.home=/usr/local/apache-tomcat-8.0.30/webapps/identityiq/ +pluginName=TodoPlugin +version=2.0.0 +``` + +The earlier example illustrates how a properties file can be leveraged to allow multiple developers to use the same build process, despite having different build environments. The actual 'build.xml' file is fairly straightforward, and it's responsible for creating the build directory, compiling any java classes, packaging those compiled classes into a .jar archive, and then archiving the complete plugin in .zip format. A more detailed explanation is provided for the 'Todo' plugin build file. + + +```xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +``` + +- **Lines 4 and 5** - specifies the properties file to use during the build. If the 'user.build.properties' file does not exist, it will cascade down and use the 'build.properties'. This can be leveraged to facilitate a 'standard' build, as well as a developer specific build. +- **Lines 14-19** - defines the folder structure where the resulting build artifacts will be placed. +- **Line 21** - creates a directory for any compiled Java classes to be placed. +- **Lines 23-33** - responsible for the compilation of Java classes. It is necessary to add the out of the box IdentityIQ packages to the classpath for compilation, which is done by utilizing the 'iiq.home' token from the build.properties file. +- **Line 35** - creates the 'lib' folder, where the jar'd up plugin .class files will be placed. +- **Line 37-41** - responsible for creating the .jar file. +- **Line 45-56** - copies all other files required for plugin deployment to the build folder. +- **Line 58-59** - creates the archive (.zip) file of the plugin contents and places the .zip file in the /dist folder - this is the archive that can be installed by 'drag and drop' in IdentityIQ. + +## Java versions + +When you're developing a plugin, complications can arise when the plugin is built using a different version of Java (newer) than that deployed on the application server(s) hosting IdentityIQ. To avoid this issue, it is recommended that the 'javac' argument in the build.xml file be parametrized with the most compatible Java version available. IdentityIQ 7.1 supports both Java 1.7 and 1.8, so setting the compilation to be 1.7 compatible is a good idea. To do so, add the property 'target' to the 'javac' directive, and set it equal to '1.7', or whatever version is being targeted. You can find an example of this process in **line 24** of the earlier example. diff --git a/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-4/index.md b/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-4/index.md new file mode 100644 index 00000000000..02c2f828f40 --- /dev/null +++ b/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-4/index.md @@ -0,0 +1,22 @@ +--- +id: plugin-database-scripts +title: Database Scripts +pagination_label: Database Scripts +sidebar_label: Database Scripts +sidebar_position: 4 +sidebar_class_name: plugin_developer_guide_database_scripts +keywords: ['plugin'] +description: IdentityIQ Plugin Database Scripts +slug: /docs/plugin-developer-guide/database-scripts +tags: ['plugin','guide','identityiq'] +--- + +# Database Scripts + +Plugins that require persistence of data outside of that allowed by the IdentityIQ object model will require at minimum the creation, updating, and deletion of unique tablespace. For this purpose, the plugin framework introduced in IdentityIQ 7.1 has created a new database, appropriately named 'identityiqPlugin'. The creation of this database is handled by the installation scripts packaged with every download of IdentityIQ in the WEB-INF/database folder. Additionally, a default user 'identityiqPlugin' is also created to perform operations (plugin installation and deletion) on this new database. Similar to the base IdentityIQ username and password, these can be modified and updated in the IdentityIQ 'iiq.properties' file located in WEB-INF/classes/iiq.properties. + +For plugin creation, create a folder called 'db' in your project directory. Further subdivide this folder into three operation specific folders: install, uninstall, and upgrade. + +![Database Scripts](../img/database_scripts.png) + +The scripts placed in these folders automatically run when a plugin is installed or deleted with the UI. It is recommended that developers include scripts for the four major database types supported by IdentityIQ: MySQL, SQLServer, DB2, and Oracle. Otherwise, developers should ensure that they document which databases are supported. The 'upgrade' folder will contain any deltas in table definitions from prior versions of the plugin. \ No newline at end of file diff --git a/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-5/index.md b/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-5/index.md new file mode 100644 index 00000000000..c57ae6a2fd0 --- /dev/null +++ b/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-5/index.md @@ -0,0 +1,77 @@ +--- +id: plugin-ui-elements +title: UI Elements +pagination_label: UI Elements +sidebar_label: UI Elements +sidebar_position: 5 +sidebar_class_name: plugin_developer_guide_ui_elements +keywords: ['plugin'] +description: IdentityIQ Plugin UI Elements +slug: /docs/plugin-developer-guide/ui-elements +tags: ['plugin','guide','identityiq'] +--- +# UI Elements + +Most plugins will have some additional UI component that will display in IdentityIQ. You can use images, CSS files, HTML templates, and JavaScript to provide the interactions and views required by the plugin. Plugins using a `fullPage` element will look for a file called 'page.xhtml' in the build. + +:::Note + +Any css installed with the plugin will apply to all elements in IdentityIQ. For this reason it is recommended that developers keep their css classes specific to their plugin. + +::: + +The 'page.xhtml' in the 'Todo' example is configured to allow for the input of a new Todo and display all current Todos in the system. The Angular controller used in 'page.xhtml' and all the functions available to the controller are defined in 'TodoModule.js' (located in the '/ui/js' folder). + +```javascript +/** + * Create the module. + */ +var todoModule = angular.module('TodoList', ['ui.bootstrap']); +/** + * Controller for the todo list. + */ +todoModule.controller('TodoController', function(todoService, pageConfigService, $q, $uibModal) { + var me = this, + promises; + /** + * @property Array The todos for a user. + */ + me.todos = []; +/*** +* Lines omitted for clarity +***/ +/** + * Shows the flagged users modal dialog. + */ +me.viewFlaggedUsers = function() { + $uibModal.open({ + animation: false, + controller: 'FlaggedUsersCtrl as ctrl', + templateUrl: PluginHelper.getPluginFileUrl('TodoPlugin', 'ui/html/flagged-template.html') + }); +}; +``` +The 'TodoController' controller (and available methods) can then be referenced in `page.xhtml`. + +```html + +
+
+ +
+
+``` +- **Line 2** - shows the angular controller `ng-controller` defined as 'TodoController' from **line 8** of 'TodoModule.js'. +- **Line 4** - example of accessing controller method `viewFlaggedUsers` from **line 21** of 'TodoModule.js'. + +This example demonstrates how to use the Angular concept of the modal within a plugin. In the 'Todo' plugin, if the user clicks the 'Flagged Users' button as defined on the `fullPage`, it will switch context to the page defined by the ui/`html/flagged-template.html`, and swap the AngularJS controller to `FlaggedUserCtrl`. The behavior of this modal dialogue is essentially the same as the `fullPage` 'page.xhtml' - it accesses information by the controller, which may rely on backend Java classes to produce data. Notice that to reference the .html template for the flagged users, the example uses the `PluginHelper` classes' method `getPluginFileUrl` - this allows for fetching the plugin resource by a relative path as it would display in the installed .zip archive. + +One last aspect to remember for the `page.xhtml` is the necessity to include references to the JavaScript packages the plugin will use. Use this path to reference the packages: `#{plugins.requestContextPath}/plugin//path/to/js/files.js`. + +```html + + + +``` + +The path to the page would be the following: `{serverpath}/plugins/pluginPage.jsf?pn={PluginName}`, where `PluginName` is the name of your plugin, as specified in the manifest, and `serverpath` is the path to your server. \ No newline at end of file diff --git a/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-6/index.md b/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-6/index.md new file mode 100644 index 00000000000..5a69372c6d2 --- /dev/null +++ b/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-6/index.md @@ -0,0 +1,28 @@ +--- +id: plugin-xml-artifacts +title: XML Artifacts +pagination_label: XML Artifacts +sidebar_label: XML Artifacts +sidebar_position: 6 +sidebar_class_name: plugin_developer_guide_xml_artifacts +keywords: ['plugin'] +description: IdentityIQ Plugin XML Artifacts +slug: /docs/plugin-developer-guide/xml-artifacts +tags: ['plugin','guide','identityiq'] +--- + +# XML Artifacts + +Any IdentityIQ objects required as part of a plugin must be represented in XML artifacts. This can mean something as small as a single new SPRight object, such as the 'ViewTodoPluginIcon', or a complex workflow or rule. The mechanism used to import these artifacts during installation is the same as any other IdentityIQ object import, so the normal import actions are also available: merge, include, execute, logConfig. + +You can directly develop these XML artifacts in the build folder or in the IdentityIQ UI. You can then export them either by using the console or by copying and pasting them from the build's debug. + +When you're developing in the UI and then migrating the artifacts to your build folder, it is important to strip out some of the metadata that IdentityIQ attaches to XML objects when they're first created. First and foremost, you should remove the 'id' attribute assigned by 'Hibernate'. Then remove any other hibernate ID value references. For this reason, it is preferable to export the artifacts by using the IdentityIQ console command: './iiq export -clean' + +Everything in the 'import' folder is imported - the SailPoint objects can be separated into individual files or combined into a single file. When a plugin is uninstalled, the imported XML artifacts remain in the IdentityIQ database (not deleted), but the .zip archive where the plugin files are loaded from is removed from the 'spt_file_bucket' and 'spt_persisted_file' tables. + +The development of regular IdentityIQ objects is beyond the scope of this document, but many helpful resources are available: + +[Technical White Papers - IdentityIQ](https://community.sailpoint.com/space/2068) + +[BeanShell Developer's Guide for IdentityIQ](https://community.sailpoint.com/docs/DOC-3375) \ No newline at end of file diff --git a/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-7/index.md b/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-7/index.md new file mode 100644 index 00000000000..333e7588527 --- /dev/null +++ b/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-7/index.md @@ -0,0 +1,93 @@ +--- +id: plugin-java-rest-resources +title: Java Classes - Rest Resources +pagination_label: Java Classes - Rest Resources +sidebar_label: Java Classes - Rest Resources +sidebar_position: 7 +sidebar_class_name: plugin_developer_guide_java_rest_resources +keywords: ['plugin'] +description: IdentityIQ Plugin Java Classes REST Resources +slug: /docs/plugin-developer-guide/java-classes-rest-resources +tags: ['plugin','guide','identityiq'] +--- + +# Java Classes - REST Resources + +The plugin framework relies heavily on REST web services integration for the majority of CRUD (create, read, update, and delete) operations. To create a custom REST resource, there are a couple requirements. This guide will cover those requirements. + +## Extend BasePluginResource + +The first step to creating a custom REST resource is to use the `BasePluginResource` class as the base class for all resources. It provides access to utility methods for accessing plugin settings, getting database connections and more. + +- **getConnection** - Gets connection to the datasource specified in the iiq.properties file for the plugins +- **getPluginName** - This method should be overriden to return the plugin's correct name. +- **getSettingBool** - Gets value of boolean plugin setting for plugin name returned by `getPluginName()`. +- **getSettingInt** - Gets value of int plugin setting for plugin name returned by `getPluginName()`. +- **getSettingString** - Gets value of String plugin setting for plugin name returned by `getPluginName()`. +- **prepareStatement** - Convenience security method for getting Java `PreparedStatement` object for any required database queries - signature is `prepareStatement`(Connection, String, Object...) where the string would be the SQL statement you wish to execute and the object would be a list of the parameters values, if any, to be used. +- **authorize** - This should be overridden by implementers, but by default it only ensures that SystemAdministrator can see everything. + Additional methods should be introduced to handle the various endpoints required by the plugin. + +## Secure endpoints + +The next step to creating a custom REST resource is to prevent unauthorized access to your new endpoints. To do so, you should guard each with an authorization mechanism. The simplest way to do so in the plugin framework is through 'Annotations'. In Java, an annotation is a syntactic metadata that is added, often before a method signature, to describe the parameters used in that method. Here is an example from the 'Todo' plugin: + +```java +@GET +@Path("customplugin/{param}") +@Deferred + +public CustomPluginObject getCustomPluginObject(@PathParam("param") String objectName) throws GeneralException{ + CustomPluginObject cpo = getCustomPluginService().getCustomPluginObject(objectName); + authorize(new CustomPluginAuthorizer(cpo)); + return cpo; +} +``` + +An annotation should have at least three parts + +- **Line 1** - The HTTP method (GET, POST, PUT, DELETE, etc). +- **Line 2** - The path or endpoint - this can be parameterized, which is useful for pulling back a single record. The earlier example uses parameterization by adding the variable within {} tags to the end of the URL and also declaring the @PathParam "appName" in the input arguments of the method signature. +- **Line 3** - The authorization of the method. The following values are allowed: + - **@AllowAll** - Allows anyone to interrogate the endpoint. + - **@RequiredRight("")** - Allows users with the named SPRight to access the endpoint. + - **@SystemAdmin** - System administrator access only. + - **@Deferred** - Authorization is deferred to the method. When this option is selected, the implementer must also create an `Authorizer` class that implements the `sailpoint.authorization.Authorize`r interface. The `Authorizer` class should override the `authorize(UserContext)` method of the base `Authorizer` interface. Inside the REST resource method, the author would then call `authorize()`. Here is a simple example: + +```java +import sailpoint.authorization.Authorizer; +import sailpoint.authorization.UnauthorizedAccessException; +import sailpoint.tools.GeneralException; +import sailpoint.web.UserContext; + +/** +* Created by adam.creaney on 2/6/17. +*/ + +class CustomPluginAuthorizer implements Authorizer{ + /** + * The CustomPluginObject to check. + */ + + private CustomPluginObject cpo; + /** + * Constructor. + * + * @param CustomPluginObject the custom plugin object + */ + public CustomPluginAuthorizer(CustomPluginObject cpo) { + this.cpo = cpo + } + + /** + * {@inheritDoc} + */ + @Override + public void authorize(UserContext userContext) throws GeneralException { + if (!(userContext.getLoggedInUser().getCapabilityManager().hasCapability("SystemAdministrator") || userContext.getLoggedInUser().getCapabilityManager().hasCapability("CustomAdmin"))) { + throw new UnauthorizedAccessException("User does not have access to Custom Plugin"); + } + } + +} +``` \ No newline at end of file diff --git a/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-8/index.md b/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-8/index.md new file mode 100644 index 00000000000..2b430320f79 --- /dev/null +++ b/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-8/index.md @@ -0,0 +1,255 @@ +--- +id: plugin-java-executors +title: Java Classes - Executors +pagination_label: Java Classes - Executors +sidebar_label: Java Classes - Executors +sidebar_position: 8 +sidebar_class_name: plugin_developer_guide_java_executors +keywords: ['plugin'] +description: IdentityIQ Plugin Java Class Plugin Executors +slug: /docs/plugin-developer-guide/java-classes-executors +tags: ['plugin','guide','identityiq'] +--- + +# Java Classes - Plugin Executors + +The plugin framework allows developers to include custom task implementations or services with their plugin. These items rely on executor classes that contain the business logic for these services. The following executors are currently available for use by developers: + +1. Service Executors +2. Task Executors +3. Policy Executors + +## Plugin Object Properties + +When you're defining your plugin object, you must provide a list of service executors that will be included. The list will live inside an attributes map under the key serviceExecutors. Here is what such a list would look like: + +1. Plugin Helper methods +2. All inherited Service methods +3. BasePluginTaskExecutor +4. Plugin Helper methods +5. All inherited TaskExecutor methods +6. BasePluginPolicyExecutor +7. Plugin Helper methods +8. All inherited PolicyExecutor methods. + + +## Plugin Helper Methods + +This is the list of methods included with the `BasePlugin` classes: + +* **getPluginName()** - returns a string value of the plugin's name. +* **getConnection()** - returns a connection object used to query the database. +* **getSettingString(String settingName)** - returns a string setting value from the Plugin Settings. +* **getSettingBool( String settingName)** - returns a boolean value from the Plugin Settings. +* **getSettingInt(String settingName)** - returns a integer value from the Plugin Settings. + +You can think of the `BasePlugin` classes as the foundation for the creation of your specific objects. The biggest advantage to using them is the access to the Plugin Helper Methods. You aren't required to use the `BasePlugin` classes for your implementation though - you're welcome to extend directly from the parent class object you want to implement. + +## Implement a plugin service definition + +When you're implementing a plugin service you will have to implement two parts. The first is your Service class, which will contain the business logic for what you want the service ot actually do. The second is the service definition XML file that will be loaded into IdentityIQ. You can find examples of both below: + +### BasePluginService Class + +This is an abstract class that extends the service class and implements the `PluginContext` interface. You can use this class as the foundation for your custom plugin service: + +```java +public class MyPluginService extends BasePluginService { + /** + * Override the getPluginName method to return our Plugin Name + */ + @Override + + public String getPluginName() { + return "MyPlugin"; + } + + /** + * Override the configure method to handle setup of our Service. Here + we'll use one of the getSetting helper methods to pull values from + our plugin settings + */ + @Override + + public void configure(SailPointContext context) throws GeneralException { + mySetting = getSettingString("mySetting"); + } + /** + * Write our execute method to do some cool stuff + */ + @Override + + public void execute(SailPointContext context) throws GeneralException { + doSomethingCool(); + } + + /** + * Our super cool method. + * + * @param context The context. + * @throws GeneralException + */ + public void doSomethingCool(SailPointContext context) + { + ......insert cool code here ..... + } +} +``` + +### Service Definition + +The Service Definition must specify a `pluginName` attribute. This tells IdentityIQ to use the plugin class loader for this executor. If the `pluginName` attribute isn't specified, the executor class won't be findable. + +```xml + + + + + + + +``` + +## Implement a plugin task executor + +Similar to the implementation of the service plugin, there are two parts to a task executor implementation. The first part is the task executor task, which handles your task's business logic. The second is your `TaskDefinition` XML object, which gets loaded into IdentityIQ. + +### BasePluginTaskExecutor Class + +This is an abstract class that extends the `AbstractTaskExecutor` class and implements the `PluginContext` interface. You can use this class as the foundation for your custom plugin executor task: + +```java +import sailpoint.task.BasePluginTaskExecutor; +/** +* Task executor implementation that does really cool tasks +* +* +*/ + +public class MyTaskExecutor extends BasePluginTaskExecutor { + /** + * Returns our plugin Name + */ + + @Override + public String getPluginName() { + return "MyPlugin"; + } + /** + * Runs our super cool task stuff + */ + + @Override + public void execute(SailPointContext context, TaskSchedule schedule, TaskResult result, Attributes args) throws Exception { + /******* Task implementation goes here *****/ + } + /** + * {@inheritDoc} + */ + + @Override + public boolean terminate() { + return true; + } + +} +``` + +### TaskDefinition + +In your `TaskDefintion`, you must include the `pluginName` attribute because this attribute tells IdentityIQ to to use the plugin class loader instead of the default class loader. If the `pluginName` attribute isn't specified, the executor class won't be findable. + + +```xml + + + + + + + +``` + +## Implement a policy executor + +Similar to the implementation of the service plugin and the task executor plugin, you must implement two parts: an executor class and a `Policy` Xml object. The `Policy` object must contain the `pluginName` attribute: + +### BasePluginPolicyExecutor + +```java +/** + +* Policy executor implementation that checks to see if it's +* Tuesday. +* +* +*/ + +public class MyPolicyExecutor extends BasePluginPolicyExecutor { + /** + * {@inheritDoc} + */ + + @Override + public String getPluginName() { + return "My Plugin"; + } + + + + + + /** + * {@inheritDoc} + **/ + public List evaluate(SailPointContext context, Policy policy, Identity id) throws GeneralException { + + List violations = new ArrayList<>(); + if(today.equals("Tuesday")) + { + violations.add(createViolation(context, policy, id, numActive)); + } + return violations; + } + + + + + + /** + * Creates a policy violation for the identity. + * + * @param context The context. + * @param policy The policy. + * @param identity The identity. + * @param numActive The numer of active todos for the identity. + * @return The violation. + */ + + private PolicyViolation createViolation(SailPointContext context, Policy policy, Identity identity, int numActive) { + + PolicyViolation violation = new PolicyViolation(); + violation.setStatus(PolicyViolation.Status.Open); + violation.setIdentity(identity); + violation.setPolicy(policy); + violation.setAlertable(true); + violation.setOwner(policy.getViolationOwnerForIdentity(context, identity)); + violation.setConstraintName("No one likes Tuesday's"); + return formatViolation(context, identity, policy, null, violation); + + } +} +``` + +### Policy XML + +```xml + + + + + + + +``` \ No newline at end of file diff --git a/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-9/index.md b/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-9/index.md new file mode 100644 index 00000000000..89859443086 --- /dev/null +++ b/products/iiq/docs/identity-iq/plugin-developer-guide/chapter-9/index.md @@ -0,0 +1,32 @@ +--- +id: plugin-installation +title: Installation +pagination_label: Installation +sidebar_label: Installation +sidebar_position: 9 +sidebar_class_name: plugin_developer_guide_installation +keywords: ['plugin'] +description: IdentityIQ Plugin Installation +slug: /docs/plugin-developer-guide/installation +tags: ['plugin','guide','identityiq'] +--- + +# Plugin Installation + +Plugin installation is simple in IdentityIQ 7.1. Navigate to Settings -> Plugins, and then click the 'New' button. + +![New Plugin Button](../img/new_plugin.png) + +Doing so will create a view with a large element that allows for drag and drop installation. Drag your plugin's .zip archive to this element, and the plugin will install. If any errors occur during this process, check the 'SyslogEvent' table for more information. + +![Drag and Drop](../img/drag_and_drop.png) + +But wait, where do I get the .zip archive? If you have downloaded a published plugin from SailPoint, the .zip file should be included with the download. If you have developed the plugin yourself, the .zip file will be the result of executing the build process against your project. Using the build file outlined in this guide as an example, the .zip archive will be created in your project directory under 'build//dist' after executing the 'ant build' command. + +![Plugin Dist File](../img/plugin_dist.png) + +When a plugin is installed, the database scripts from the 'db/install' folder run, creating any necessary tables for the plugin, importing the XML configuration files into the IdentityIQ database from the 'import/install' folder, loading any compiled classes into the unique plugin classloader, and importing the manifest file - this process creates the plugin object. + +Uninstallation follows a similar path. You can launch uninstallation by clicking the small 'X' icon on the appropriate plugin card in the 'Settings->Plugin' interface. Database scripts responsible for cleaning up data run from the 'db/uninstall' folder, and the manifest file (the plugin object) is removed. Remember that the other XML objects created during installation are currently *not* uninstalled when a plugin is removed. + +![Uninstall a Plugin](../img/delete_plugin.png) \ No newline at end of file diff --git a/products/iiq/docs/identity-iq/plugin-developer-guide/img/database_scripts.png b/products/iiq/docs/identity-iq/plugin-developer-guide/img/database_scripts.png new file mode 100644 index 00000000000..43ece9c8312 Binary files /dev/null and b/products/iiq/docs/identity-iq/plugin-developer-guide/img/database_scripts.png differ diff --git a/products/iiq/docs/identity-iq/plugin-developer-guide/img/delete_plugin.png b/products/iiq/docs/identity-iq/plugin-developer-guide/img/delete_plugin.png new file mode 100644 index 00000000000..42093faaa76 Binary files /dev/null and b/products/iiq/docs/identity-iq/plugin-developer-guide/img/delete_plugin.png differ diff --git a/products/iiq/docs/identity-iq/plugin-developer-guide/img/drag_and_drop.png b/products/iiq/docs/identity-iq/plugin-developer-guide/img/drag_and_drop.png new file mode 100644 index 00000000000..4307ae2846f Binary files /dev/null and b/products/iiq/docs/identity-iq/plugin-developer-guide/img/drag_and_drop.png differ diff --git a/products/iiq/docs/identity-iq/plugin-developer-guide/img/new_plugin.png b/products/iiq/docs/identity-iq/plugin-developer-guide/img/new_plugin.png new file mode 100644 index 00000000000..c45b328f2f4 Binary files /dev/null and b/products/iiq/docs/identity-iq/plugin-developer-guide/img/new_plugin.png differ diff --git a/products/iiq/docs/identity-iq/plugin-developer-guide/img/persisted_file.png b/products/iiq/docs/identity-iq/plugin-developer-guide/img/persisted_file.png new file mode 100644 index 00000000000..8852a975e73 Binary files /dev/null and b/products/iiq/docs/identity-iq/plugin-developer-guide/img/persisted_file.png differ diff --git a/products/iiq/docs/identity-iq/plugin-developer-guide/img/plugin_dist.png b/products/iiq/docs/identity-iq/plugin-developer-guide/img/plugin_dist.png new file mode 100644 index 00000000000..3b2a17753db Binary files /dev/null and b/products/iiq/docs/identity-iq/plugin-developer-guide/img/plugin_dist.png differ diff --git a/products/iiq/docs/identity-iq/plugin-developer-guide/img/plugin_structure.png b/products/iiq/docs/identity-iq/plugin-developer-guide/img/plugin_structure.png new file mode 100644 index 00000000000..0e41ac8f026 Binary files /dev/null and b/products/iiq/docs/identity-iq/plugin-developer-guide/img/plugin_structure.png differ diff --git a/products/iiq/docs/identity-iq/plugin-developer-guide/img/snippet.png b/products/iiq/docs/identity-iq/plugin-developer-guide/img/snippet.png new file mode 100644 index 00000000000..5ba352f19f3 Binary files /dev/null and b/products/iiq/docs/identity-iq/plugin-developer-guide/img/snippet.png differ diff --git a/products/iiq/docs/identity-iq/plugin-developer-guide/index.md b/products/iiq/docs/identity-iq/plugin-developer-guide/index.md new file mode 100644 index 00000000000..fc2a7e132ab --- /dev/null +++ b/products/iiq/docs/identity-iq/plugin-developer-guide/index.md @@ -0,0 +1,20 @@ +--- +id: plugin-developer-guide +title: Plugin Developer Guide +pagination_label: Plugin Developer Guide +sidebar_label: Plugin Developer Guide +sidebar_position: 1 +sidebar_class_name: plugin_developer_guide +keywords: ['plugin'] +description: Plugin Developer Guide in IdentityIQ +slug: /docs/plugin-developer-guide +tags: ['plugin','guide','identityiq'] +--- + +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 a upgrade safe and isolated manner. It gives implementers a safe option for creating User Interface extensions, REST services, Custom SailPoint configuration objects, and more. This guide is designed to walk 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 A will discuss 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 the high level - what the components of a plugin are, which components are required, how those objects interact. Language specific tutorials are beyond its scope. Throughout this document, examples will be taken and discussed from the 'TodoPlugin' - located here: [To-do Plugin](https://community.sailpoint.com/t5/Plugin-Framework/TodoPlugin-V3-zip/ta-p/79764) + +This guide is intended to be a community driven effort - please feel free to update and or add chapters based on your use of the Plugin Framework. diff --git a/products/iiq/sidebar.js b/products/iiq/sidebar.js index a55c482d2a4..4d0d163a95b 100644 --- a/products/iiq/sidebar.js +++ b/products/iiq/sidebar.js @@ -14,6 +14,12 @@ const sidebars = { items: require('./api/sidebar.js'), }, ], + idnDocs: [ + { + type: 'autogenerated', + dirName: 'docs', + }, + ] }; module.exports = sidebars; diff --git a/static/api-specs/idn/beta/paths/campaigns.yaml b/static/api-specs/idn/beta/paths/campaigns.yaml index 78738611a6f..34698b7cbfe 100644 --- a/static/api-specs/idn/beta/paths/campaigns.yaml +++ b/static/api-specs/idn/beta/paths/campaigns.yaml @@ -57,7 +57,7 @@ get: example: name responses: '200': - description: A list of campaign objects. + description: A list of campaign objects. By default list of SLIM campaigns is returned. content: application/json: schema: diff --git a/static/api-specs/idn/beta/paths/mfa-kba-authenticate.yaml b/static/api-specs/idn/beta/paths/mfa-kba-authenticate.yaml new file mode 100644 index 00000000000..2f83d59db03 --- /dev/null +++ b/static/api-specs/idn/beta/paths/mfa-kba-authenticate.yaml @@ -0,0 +1,59 @@ +post: + operationId: sendKbaAnswers + tags: + - MFA Controller + summary: Authenticate KBA provided MFA method + description: >- + This API Authenticate user in KBA MFA method. + security: + - UserContextAuth: [idn:mfa-kba:authenticate] + requestBody: + required: true + content: + application/json: + schema: + $ref: "../schemas/KbaAnswerRequest.yaml" + example: + {"answers": [ + { + "questionId": "089899f13a8f4da7824996191587bab9", + "answer": "Your answer" + }, + { + "questionId": "067899f13a8f4da7824996191587bab9", + "answer": "Your answer1" + } + ] + } + + responses: + "200": + description: KBA authenticated status. + content: + application/json: + schema: + $ref: "../schemas/KbaAuthResponse.yaml" + example: + { + "kbaAuthResponseItem": [ + { + "questionId": "089899f13a8f4da7824996191587bab9", + "IsVerified": false + }, + { + "questionId": "089899f13a8f4da7824996191587bda8", + "IsVerified": true + } + ], + "status": "PENDING" + } + "400": + $ref: "../../v3/responses/400.yaml" + "401": + $ref: "../../v3/responses/401.yaml" + "403": + $ref: "../../v3/responses/403.yaml" + "429": + $ref: "../../v3/responses/429.yaml" + "500": + $ref: "../../v3/responses/500.yaml" \ No newline at end of file diff --git a/static/api-specs/idn/beta/paths/mfa-poll.yaml b/static/api-specs/idn/beta/paths/mfa-poll.yaml new file mode 100644 index 00000000000..93455bc02e4 --- /dev/null +++ b/static/api-specs/idn/beta/paths/mfa-poll.yaml @@ -0,0 +1,54 @@ +post: + operationId: pingVerificationStatus + tags: + - MFA Controller + summary: Polling MFA method by VerificationPollRequest + description: >- + This API poll the VerificationPollRequest for the specified MFA method. + A token with ORG_ADMIN authority is required to call this API. + security: + - UserContextAuth: [idn:mfa:poll] + parameters: + - in: path + name: method + schema: + type: string + example: okta-verify + required: true + description: >- + The name of the MFA method. + The currently supported method names are 'okta-verify', 'duo-web', 'kba','token', 'rsa' + requestBody: + required: true + content: + application/json: + schema: + $ref: "../schemas/VerificationPollRequest.yaml" + example: + { + "requestId": "089899f13a8f4da7824996191587bab9" + } + + responses: + "200": + description: MFA VerificationPollRequest status an MFA method. + content: + application/json: + schema: + $ref: "../schemas/VerificationResponse.yaml" + example: + { + "requestId": "089899f13a8f4da7824996191587bab9", + "status": "PENDING", + "error" : "" + } + "400": + $ref: "../../v3/responses/400.yaml" + "401": + $ref: "../../v3/responses/401.yaml" + "403": + $ref: "../../v3/responses/403.yaml" + "429": + $ref: "../../v3/responses/429.yaml" + "500": + $ref: "../../v3/responses/500.yaml" \ No newline at end of file diff --git a/static/api-specs/idn/beta/paths/mfa-token-authenticate.yaml b/static/api-specs/idn/beta/paths/mfa-token-authenticate.yaml new file mode 100644 index 00000000000..e75921e56a7 --- /dev/null +++ b/static/api-specs/idn/beta/paths/mfa-token-authenticate.yaml @@ -0,0 +1,43 @@ +post: + operationId: sendTokenAuthRequest + tags: + - MFA Controller + summary: Authenticate Token provided MFA method + description: >- + This API Authenticate user in Token MFA method. + security: + - UserContextAuth: [idn:mfa:verify] + requestBody: + required: true + content: + application/json: + schema: + $ref: "../schemas/TokenAuthRequest.yaml" + example: + { + "token": "12345", + "userAlias": "will.albin", + "deliveryType": "EMAIL_WORK" + } + + responses: + "200": + description: Token authenticated status. + content: + application/json: + schema: + $ref: "../schemas/TokenAuthResponse.yaml" + example: + { + "status": "PENDING" + } + "400": + $ref: "../../v3/responses/400.yaml" + "401": + $ref: "../../v3/responses/401.yaml" + "403": + $ref: "../../v3/responses/403.yaml" + "429": + $ref: "../../v3/responses/429.yaml" + "500": + $ref: "../../v3/responses/500.yaml" \ No newline at end of file diff --git a/static/api-specs/idn/beta/paths/mfa-token-send.yaml b/static/api-specs/idn/beta/paths/mfa-token-send.yaml new file mode 100644 index 00000000000..b9897212024 --- /dev/null +++ b/static/api-specs/idn/beta/paths/mfa-token-send.yaml @@ -0,0 +1,44 @@ +post: + operationId: createSendToken + tags: + - MFA Controller + summary: Create and send user token + description: + This API send token request. + security: + - UserContextAuth: [idn:mfa:send] + requestBody: + required: true + content: + application/json: + schema: + $ref: "../schemas/SendTokenRequest.yaml" + example: + { + "userAlias": "will.albin", + "deliveryType": "EMAIL_WORK" + } + + responses: + "200": + description: Token send status. + content: + application/json: + schema: + $ref: "../schemas/SendTokenResponse.yaml" + example: + { + "requestId": "089899f13a8f4da7824996191587bab9", + "status": "SUCCESS", + "errorMessage": "" + } + "400": + $ref: "../../v3/responses/400.yaml" + "401": + $ref: "../../v3/responses/401.yaml" + "403": + $ref: "../../v3/responses/403.yaml" + "429": + $ref: "../../v3/responses/429.yaml" + "500": + $ref: "../../v3/responses/500.yaml" \ No newline at end of file diff --git a/static/api-specs/idn/beta/schemas/Campaign.yaml b/static/api-specs/idn/beta/schemas/Campaign.yaml index b9b5f47ec2c..550b2704c52 100644 --- a/static/api-specs/idn/beta/schemas/Campaign.yaml +++ b/static/api-specs/idn/beta/schemas/Campaign.yaml @@ -4,12 +4,6 @@ allOf: - $ref: 'SlimCampaign.yaml' - type: object properties: - created: - type: string - readOnly: true - format: date-time - description: Created time of the campaign - example: '2020-03-03T22:15:13.611Z' modified: type: string readOnly: true @@ -194,22 +188,6 @@ allOf: example: Role Composition Description required: - remediatorRef - alerts: - type: array - description: A list of errors and warnings that have accumulated. - readOnly: true - items: - $ref: './CampaignAlert.yaml' - totalCertifications: - type: integer - description: The total number of certifications in this campaign. - readOnly: true - example: 100 - completedCertifications: - type: integer - description: The number of completed certifications in this campaign. - readOnly: true - example: 10 sourcesWithOrphanEntitlements: type: array description: >- @@ -243,4 +221,4 @@ allOf: - "ALL_DECISIONS" - "REVOKE_ONLY_DECISIONS" - "NO_DECISIONS" - example: NO_DECISIONS \ No newline at end of file + example: NO_DECISIONS diff --git a/static/api-specs/idn/beta/schemas/KbaAnswerRequest.yaml b/static/api-specs/idn/beta/schemas/KbaAnswerRequest.yaml new file mode 100644 index 00000000000..38d02f15c6a --- /dev/null +++ b/static/api-specs/idn/beta/schemas/KbaAnswerRequest.yaml @@ -0,0 +1,18 @@ +type: object +properties: + answers: + nullable: false + type: array + items: + $ref: "../schemas/KbaAnswerRequestItem.yaml" + + description: Kba answers + example: + - questionId: 089899f13a8f4da7824996191587bab9 + answer: Your answer + - questionId: 067899f13a8f4da7824996191587bab9 + answer: Your answer1 +required: + - answers + + diff --git a/static/api-specs/idn/beta/schemas/KbaAnswerRequestItem.yaml b/static/api-specs/idn/beta/schemas/KbaAnswerRequestItem.yaml new file mode 100644 index 00000000000..37d6b9808f3 --- /dev/null +++ b/static/api-specs/idn/beta/schemas/KbaAnswerRequestItem.yaml @@ -0,0 +1,15 @@ +type: object +properties: + questionId: + type: string + nullable: false + description: Question Id + example: 089899f13a8f4da7824996191587bab9 + answer: + type: string + nullable: false + description: An answer for the KBA question + example: Your answer +required: + - questionId + - answer \ No newline at end of file diff --git a/static/api-specs/idn/beta/schemas/KbaAuthResponse.yaml b/static/api-specs/idn/beta/schemas/KbaAuthResponse.yaml new file mode 100644 index 00000000000..95ac3322969 --- /dev/null +++ b/static/api-specs/idn/beta/schemas/KbaAuthResponse.yaml @@ -0,0 +1,19 @@ +type: object +properties: + kbaAuthResponseItems: + type: array + example: + - questionId: 089899f13a8f4da7824996191587bab9 + isVerified: false + items: + $ref: '../schemas/KbaAuthResponseItem.yaml' + status: + type: string + enum: + - PENDING + - SUCCESS + - FAILED + - LOCKOUT + - NOT_ENOUGH_DATA + description: MFA Authentication status + example: PENDING \ No newline at end of file diff --git a/static/api-specs/idn/beta/schemas/KbaAuthResponseItem.yaml b/static/api-specs/idn/beta/schemas/KbaAuthResponseItem.yaml new file mode 100644 index 00000000000..5090787d290 --- /dev/null +++ b/static/api-specs/idn/beta/schemas/KbaAuthResponseItem.yaml @@ -0,0 +1,13 @@ +type: object +properties: + questionId: + type: string + nullable: true + description: The KBA question id + example: 089899f13a8f4da7824996191587bab9 + isVerified: + type: boolean + nullable: true + default: null + description: Return true if verified + example: true \ No newline at end of file diff --git a/static/api-specs/idn/beta/schemas/SendTokenRequest.yaml b/static/api-specs/idn/beta/schemas/SendTokenRequest.yaml new file mode 100644 index 00000000000..f2c2a832893 --- /dev/null +++ b/static/api-specs/idn/beta/schemas/SendTokenRequest.yaml @@ -0,0 +1,24 @@ +type: object +properties: + userAlias: + nullable: false + type: string + description: User alias from table spt_identity field named 'name' + example: will.albin + deliveryType: + nullable: false + type: string + enum: + - SMS_PERSONAL #("sms", "phone") + - VOICE_PERSONAL #("voice", "phone") + - SMS_WORK #("sms", "work") + - VOICE_WORK #("voice","work") + - EMAIL_WORK #("email"L, "email") + - EMAIL_PERSONAL #("email", "personalEmail") + description: Token delivery type + example: "EMAIL_WORK" +required: + - userAlias + - deliveryType + + diff --git a/static/api-specs/idn/beta/schemas/SendTokenResponse.yaml b/static/api-specs/idn/beta/schemas/SendTokenResponse.yaml new file mode 100644 index 00000000000..c1fc36696f6 --- /dev/null +++ b/static/api-specs/idn/beta/schemas/SendTokenResponse.yaml @@ -0,0 +1,19 @@ +type: object +properties: + requestId: + type: string + nullable: true + description: The token request ID + example: 089899f13a8f4da7824996191587bab9 + status: + type: string + enum: + - SUCCESS + - FAILED + description: Status of sending token + example: SUCCESS + errorMessage: + type: string + nullable: true + description: Error messages from token send request + example: Unable to sent text message \ No newline at end of file diff --git a/static/api-specs/idn/beta/schemas/SlimCampaign.yaml b/static/api-specs/idn/beta/schemas/SlimCampaign.yaml index 0089e3ff7ae..d97a0fe4057 100644 --- a/static/api-specs/idn/beta/schemas/SlimCampaign.yaml +++ b/static/api-specs/idn/beta/schemas/SlimCampaign.yaml @@ -77,4 +77,28 @@ properties: enum: - CORRELATED - UNCORRELATED - example: CORRELATED \ No newline at end of file + example: CORRELATED + created: + type: string + readOnly: true + format: date-time + description: Created time of the campaign + example: '2020-03-03T22:15:13.611Z' + totalCertifications: + type: integer + format: int32 + description: The total number of certifications in this campaign. + readOnly: true + example: 100 + completedCertifications: + type: integer + format: int32 + description: The number of completed certifications in this campaign. + readOnly: true + example: 10 + alerts: + type: array + description: A list of errors and warnings that have accumulated. + readOnly: true + items: + $ref: './CampaignAlert.yaml' diff --git a/static/api-specs/idn/beta/schemas/TokenAuthRequest.yaml b/static/api-specs/idn/beta/schemas/TokenAuthRequest.yaml new file mode 100644 index 00000000000..ed384cb0d9c --- /dev/null +++ b/static/api-specs/idn/beta/schemas/TokenAuthRequest.yaml @@ -0,0 +1,28 @@ +type: object +properties: + token: + nullable: false + type: string + description: Token value + example: "12345" + userAlias: + nullable: false + type: string + description: User alias from table spt_identity field named 'name' + example: "will.albin" + deliveryType: + nullable: false + type: string + enum: + - SMS_PERSONAL #("sms", "phone") + - VOICE_PERSONAL #("voice", "phone") + - SMS_WORK #("sms", "work") + - VOICE_WORK #("voice","work") + - EMAIL_WORK #("email"L, "email") + - EMAIL_PERSONAL #("email", "personalEmail") + description: Token delivery type + example: "EMAIL_WORK" +required: + - token + - userAlias + - deliveryType \ No newline at end of file diff --git a/static/api-specs/idn/beta/schemas/TokenAuthResponse.yaml b/static/api-specs/idn/beta/schemas/TokenAuthResponse.yaml new file mode 100644 index 00000000000..7e63f6d8dd0 --- /dev/null +++ b/static/api-specs/idn/beta/schemas/TokenAuthResponse.yaml @@ -0,0 +1,12 @@ +type: object +properties: + status: + type: string + enum: + - PENDING + - SUCCESS + - FAILED + - LOCKOUT + - NOT_ENOUGH_DATA + description: MFA Authentication status + example: PENDING \ No newline at end of file diff --git a/static/api-specs/idn/beta/schemas/VerificationPollRequest.yaml b/static/api-specs/idn/beta/schemas/VerificationPollRequest.yaml new file mode 100644 index 00000000000..0c6c4a15b8f --- /dev/null +++ b/static/api-specs/idn/beta/schemas/VerificationPollRequest.yaml @@ -0,0 +1,9 @@ +type: object +properties: + requestId: + type: string + nullable: false + description: Verification request Id + example: 089899f13a8f4da7824996191587bab9 +required: + - requestId diff --git a/static/api-specs/idn/beta/schemas/VerificationResponse.yaml b/static/api-specs/idn/beta/schemas/VerificationResponse.yaml new file mode 100644 index 00000000000..d5045a4c5ef --- /dev/null +++ b/static/api-specs/idn/beta/schemas/VerificationResponse.yaml @@ -0,0 +1,22 @@ +type: object +properties: + requestId: + type: string + nullable: true + description: The verificationPollRequest request ID + example: 089899f13a8f4da7824996191587bab9 + status: + type: string + enum: + - PENDING + - SUCCESS + - FAILED + - LOCKOUT + - NOT_ENOUGH_DATA + description: MFA Authentication status + example: SUCCESS + error: + type: string + nullable: true + description: Error messages from MFA verification request + example: Unable to connect DUO Service during verification \ No newline at end of file diff --git a/static/api-specs/idn/beta/schemas/campaign/examples/FullCampaigns.yaml b/static/api-specs/idn/beta/schemas/campaign/examples/FullCampaigns.yaml index 6732259e7dc..cd26ad01d08 100644 --- a/static/api-specs/idn/beta/schemas/campaign/examples/FullCampaigns.yaml +++ b/static/api-specs/idn/beta/schemas/campaign/examples/FullCampaigns.yaml @@ -9,7 +9,6 @@ value: emailNotificationEnabled: false autoRevokeAllowed: false recommendationsEnabled: false - created: 2022-08-02T20:29:51.065Z modified: 2022-08-02T20:29:51.331Z filter: type: CAMPAIGN_FILTER @@ -29,14 +28,6 @@ value: - b15d609fc5c8434b865fe552315fda8f query: null description: null - alerts: - - level: ERROR - localizations: - - locale: en - localeOrigin: DEFAULT - text: Composite criterion must have children non-composite criterion must not. - totalCertifications: 0 - completedCertifications: 0 sourcesWithOrphanEntitlements: null mandatoryCommentRequirement: NO_DECISIONS - id: 1be8fc1103914bf0a4e14e316b6a7b7c @@ -48,7 +39,6 @@ value: emailNotificationEnabled: false autoRevokeAllowed: false recommendationsEnabled: false - created: 2022-08-02T19:00:27.731Z modified: 2022-08-02T19:00:34.391Z filter: type: CAMPAIGN_FILTER @@ -58,9 +48,6 @@ value: sourceOwnerCampaignInfo: null searchCampaignInfo: null roleCompositionCampaignInfo: null - alerts: null - totalCertifications: 5 - completedCertifications: 0 sourcesWithOrphanEntitlements: [] mandatoryCommentRequirement: NO_DECISIONS - id: 7e1a731e3fb845cfbe58112ba4673ee4 @@ -72,7 +59,6 @@ value: emailNotificationEnabled: false autoRevokeAllowed: false recommendationsEnabled: false - created: 2022-07-25T15:42:18.276Z modified: 2022-07-25T15:42:53.718Z filter: type: CAMPAIGN_FILTER @@ -91,9 +77,6 @@ value: identityIds: null accessConstraints: [] roleCompositionCampaignInfo: null - alerts: null - totalCertifications: 6 - completedCertifications: 0 sourcesWithOrphanEntitlements: [] mandatoryCommentRequirement: NO_DECISIONS - id: ad3cf3dd50394b1bad646de4bc51b999 @@ -105,7 +88,6 @@ value: emailNotificationEnabled: true autoRevokeAllowed: false recommendationsEnabled: false - created: 2022-07-27T17:04:19.027Z modified: 2022-07-27T17:09:13.925Z filter: type: CAMPAIGN_FILTER @@ -117,9 +99,6 @@ value: - 2c91808781fd5aea01821200dc88318e searchCampaignInfo: null roleCompositionCampaignInfo: null - alerts: null - totalCertifications: 2 - completedCertifications: 0 sourcesWithOrphanEntitlements: [] correlatedStatus: CORRELATED - mandatoryCommentRequirement: NO_DECISIONS \ No newline at end of file + mandatoryCommentRequirement: NO_DECISIONS diff --git a/static/api-specs/idn/beta/schemas/campaign/examples/SlimCampaigns.yaml b/static/api-specs/idn/beta/schemas/campaign/examples/SlimCampaigns.yaml index 4449c162722..cf84e2a1e19 100644 --- a/static/api-specs/idn/beta/schemas/campaign/examples/SlimCampaigns.yaml +++ b/static/api-specs/idn/beta/schemas/campaign/examples/SlimCampaigns.yaml @@ -9,6 +9,15 @@ value: emailNotificationEnabled: false autoRevokeAllowed: false recommendationsEnabled: false + created: 2022-08-02T20:29:51.065Z + totalCertifications: 10 + completedCertifications: 3 + alerts: + - level: ERROR + localizations: + - locale: en + localeOrigin: DEFAULT + text: Composite criterion must have children non-composite criterion must not. - id: 7e1a731e3fb845cfbe58112ba4673ee4 name: Search Campaign description: Search Campaign Info @@ -18,6 +27,10 @@ value: emailNotificationEnabled: false autoRevokeAllowed: false recommendationsEnabled: false + created: 2022-08-02T19:00:27.731Z + totalCertifications: 5 + completedCertifications: 3 + alerts: null - id: 2c918086719eec070171a7e3355a412b name: AD Source Review description: A review of our AD source. @@ -27,6 +40,15 @@ value: emailNotificationEnabled: true autoRevokeAllowed: false recommendationsEnabled: false + created: 2022-07-25T15:42:18.276Z + totalCertifications: 7 + completedCertifications: 3 + alerts: + - level: WARN + localizations: + - locale: en + localeOrigin: DEFAULT + text: Composite criterion is in wrong format. correlatedStatus: CORRELATED - id: 3b2e2e5821e84127b6d693d41c40623b name: Role Composition Campaign @@ -36,4 +58,8 @@ value: status: ACTIVE emailNotificationEnabled: false autoRevokeAllowed: false - recommendationsEnabled: false \ No newline at end of file + recommendationsEnabled: false + created: 2022-07-27T17:04:19.027Z + totalCertifications: 1 + completedCertifications: 1 + alerts: null diff --git a/static/api-specs/idn/sailpoint-api.beta.yaml b/static/api-specs/idn/sailpoint-api.beta.yaml index 8854474613a..303344dd59c 100644 --- a/static/api-specs/idn/sailpoint-api.beta.yaml +++ b/static/api-specs/idn/sailpoint-api.beta.yaml @@ -439,6 +439,8 @@ tags: description: Operations for accessing and managing client Clusters, including Log Configuration - name: MFA Configuration description: Configure and test multifactor authentication (MFA) methods + - name: MFA Controller + description: This API used for multifactor authentication functionality belong to gov-multi-auth service. This controller allow you to verify authentication by specified method - name: Non-Employee Lifecycle Management description: | Use this API to implement non-employee lifecycle management functionality. @@ -1254,6 +1256,14 @@ paths: $ref: './beta/paths/mfa-config-test.yaml' /mfa/{method}/delete: $ref: './beta/paths/mfa-config-delete.yaml' + /mfa/{method}/poll: + $ref: './beta/paths/mfa-poll.yaml' + /mfa/kba/authenticate: + $ref: './beta/paths/mfa-kba-authenticate.yaml' + /mfa/token/authenticate: + $ref: './beta/paths/mfa-token-authenticate.yaml' + /mfa/token/send: + $ref: './beta/paths/mfa-token-send.yaml' /notification-template-defaults: $ref: './beta/paths/notification-template-defaults.yaml' /notification-templates: diff --git a/static/api-specs/idn/v3/paths/campaigns.yaml b/static/api-specs/idn/v3/paths/campaigns.yaml index 974c365fa3e..5f7c62debe5 100644 --- a/static/api-specs/idn/v3/paths/campaigns.yaml +++ b/static/api-specs/idn/v3/paths/campaigns.yaml @@ -56,7 +56,7 @@ get: example: name responses: '200': - description: A list of campaign objects. + description: A list of campaign objects. By default list of SLIM campaigns is returned. content: application/json: schema: diff --git a/static/api-specs/idn/v3/schemas/Campaign.yaml b/static/api-specs/idn/v3/schemas/Campaign.yaml index 5d6bba7ef41..550b2704c52 100644 --- a/static/api-specs/idn/v3/schemas/Campaign.yaml +++ b/static/api-specs/idn/v3/schemas/Campaign.yaml @@ -4,12 +4,6 @@ allOf: - $ref: 'SlimCampaign.yaml' - type: object properties: - created: - type: string - readOnly: true - format: date-time - description: Created time of the campaign - example: '2020-03-03T22:15:13.611Z' modified: type: string readOnly: true @@ -194,22 +188,6 @@ allOf: example: Role Composition Description required: - remediatorRef - alerts: - type: array - description: A list of errors and warnings that have accumulated. - readOnly: true - items: - $ref: './CampaignAlert.yaml' - totalCertifications: - type: integer - description: The total number of certifications in this campaign. - readOnly: true - example: 100 - completedCertifications: - type: integer - description: The number of completed certifications in this campaign. - readOnly: true - example: 10 sourcesWithOrphanEntitlements: type: array description: >- diff --git a/static/api-specs/idn/v3/schemas/SlimCampaign.yaml b/static/api-specs/idn/v3/schemas/SlimCampaign.yaml index 0089e3ff7ae..d97a0fe4057 100644 --- a/static/api-specs/idn/v3/schemas/SlimCampaign.yaml +++ b/static/api-specs/idn/v3/schemas/SlimCampaign.yaml @@ -77,4 +77,28 @@ properties: enum: - CORRELATED - UNCORRELATED - example: CORRELATED \ No newline at end of file + example: CORRELATED + created: + type: string + readOnly: true + format: date-time + description: Created time of the campaign + example: '2020-03-03T22:15:13.611Z' + totalCertifications: + type: integer + format: int32 + description: The total number of certifications in this campaign. + readOnly: true + example: 100 + completedCertifications: + type: integer + format: int32 + description: The number of completed certifications in this campaign. + readOnly: true + example: 10 + alerts: + type: array + description: A list of errors and warnings that have accumulated. + readOnly: true + items: + $ref: './CampaignAlert.yaml' diff --git a/static/api-specs/idn/v3/schemas/campaign/examples/FullCampaigns.yaml b/static/api-specs/idn/v3/schemas/campaign/examples/FullCampaigns.yaml index 6732259e7dc..cd26ad01d08 100644 --- a/static/api-specs/idn/v3/schemas/campaign/examples/FullCampaigns.yaml +++ b/static/api-specs/idn/v3/schemas/campaign/examples/FullCampaigns.yaml @@ -9,7 +9,6 @@ value: emailNotificationEnabled: false autoRevokeAllowed: false recommendationsEnabled: false - created: 2022-08-02T20:29:51.065Z modified: 2022-08-02T20:29:51.331Z filter: type: CAMPAIGN_FILTER @@ -29,14 +28,6 @@ value: - b15d609fc5c8434b865fe552315fda8f query: null description: null - alerts: - - level: ERROR - localizations: - - locale: en - localeOrigin: DEFAULT - text: Composite criterion must have children non-composite criterion must not. - totalCertifications: 0 - completedCertifications: 0 sourcesWithOrphanEntitlements: null mandatoryCommentRequirement: NO_DECISIONS - id: 1be8fc1103914bf0a4e14e316b6a7b7c @@ -48,7 +39,6 @@ value: emailNotificationEnabled: false autoRevokeAllowed: false recommendationsEnabled: false - created: 2022-08-02T19:00:27.731Z modified: 2022-08-02T19:00:34.391Z filter: type: CAMPAIGN_FILTER @@ -58,9 +48,6 @@ value: sourceOwnerCampaignInfo: null searchCampaignInfo: null roleCompositionCampaignInfo: null - alerts: null - totalCertifications: 5 - completedCertifications: 0 sourcesWithOrphanEntitlements: [] mandatoryCommentRequirement: NO_DECISIONS - id: 7e1a731e3fb845cfbe58112ba4673ee4 @@ -72,7 +59,6 @@ value: emailNotificationEnabled: false autoRevokeAllowed: false recommendationsEnabled: false - created: 2022-07-25T15:42:18.276Z modified: 2022-07-25T15:42:53.718Z filter: type: CAMPAIGN_FILTER @@ -91,9 +77,6 @@ value: identityIds: null accessConstraints: [] roleCompositionCampaignInfo: null - alerts: null - totalCertifications: 6 - completedCertifications: 0 sourcesWithOrphanEntitlements: [] mandatoryCommentRequirement: NO_DECISIONS - id: ad3cf3dd50394b1bad646de4bc51b999 @@ -105,7 +88,6 @@ value: emailNotificationEnabled: true autoRevokeAllowed: false recommendationsEnabled: false - created: 2022-07-27T17:04:19.027Z modified: 2022-07-27T17:09:13.925Z filter: type: CAMPAIGN_FILTER @@ -117,9 +99,6 @@ value: - 2c91808781fd5aea01821200dc88318e searchCampaignInfo: null roleCompositionCampaignInfo: null - alerts: null - totalCertifications: 2 - completedCertifications: 0 sourcesWithOrphanEntitlements: [] correlatedStatus: CORRELATED - mandatoryCommentRequirement: NO_DECISIONS \ No newline at end of file + mandatoryCommentRequirement: NO_DECISIONS diff --git a/static/api-specs/idn/v3/schemas/campaign/examples/SlimCampaigns.yaml b/static/api-specs/idn/v3/schemas/campaign/examples/SlimCampaigns.yaml index 4449c162722..3ff178465af 100644 --- a/static/api-specs/idn/v3/schemas/campaign/examples/SlimCampaigns.yaml +++ b/static/api-specs/idn/v3/schemas/campaign/examples/SlimCampaigns.yaml @@ -9,6 +9,15 @@ value: emailNotificationEnabled: false autoRevokeAllowed: false recommendationsEnabled: false + created: 2022-08-02T19:00:27.731Z + totalCertifications: 10 + completedCertifications: 3 + alerts: + - level: ERROR + localizations: + - locale: en + localeOrigin: DEFAULT + text: Composite criterion must have children non-composite criterion must not. - id: 7e1a731e3fb845cfbe58112ba4673ee4 name: Search Campaign description: Search Campaign Info @@ -18,6 +27,10 @@ value: emailNotificationEnabled: false autoRevokeAllowed: false recommendationsEnabled: false + created: 2022-07-25T15:42:18.276Z + totalCertifications: 5 + completedCertifications: 3 + alerts: null - id: 2c918086719eec070171a7e3355a412b name: AD Source Review description: A review of our AD source. @@ -28,6 +41,15 @@ value: autoRevokeAllowed: false recommendationsEnabled: false correlatedStatus: CORRELATED + created: 2022-07-27T17:04:19.027Z + totalCertifications: 7 + completedCertifications: 3 + alerts: + - level: WARN + localizations: + - locale: en + localeOrigin: DEFAULT + text: Composite criterion is in wrong format. - id: 3b2e2e5821e84127b6d693d41c40623b name: Role Composition Campaign description: A review done by a role owner. @@ -36,4 +58,8 @@ value: status: ACTIVE emailNotificationEnabled: false autoRevokeAllowed: false - recommendationsEnabled: false \ No newline at end of file + recommendationsEnabled: false + created: 2022-08-02T20:29:51.065Z + totalCertifications: 1 + completedCertifications: 1 + alerts: null