-
Notifications
You must be signed in to change notification settings - Fork 5.4k
New Components - sailpoint #14935
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
New Components - sailpoint #14935
Changes from all commits
1969631
e9e3d23
5f51c13
13ef83b
bb6ee2e
fe3efcf
eb7f1c6
a208f80
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import sailpoint from "../../sailpoint.app.mjs"; | ||
|
||
export default { | ||
key: "sailpoint-list-certification-campaigns", | ||
name: "List Certification Campaigns", | ||
description: "Retrieves multiple certification campaigns in IdentityNow. [See the documentation](https://developer.sailpoint.com/docs/api/v2024/get-active-campaigns)", | ||
version: "0.0.1", | ||
type: "action", | ||
props: { | ||
sailpoint, | ||
filter: { | ||
propDefinition: [ | ||
"sailpoint", | ||
"filter", | ||
], | ||
optional: true, | ||
}, | ||
}, | ||
async run({ $ }) { | ||
const response = this.sailpoint.paginate({ | ||
fn: this.sailpoint.listCertificationCampaigns, | ||
params: { | ||
detail: "full", | ||
}, | ||
}); | ||
|
||
const responseArray = []; | ||
|
||
for await (const item of response) { | ||
responseArray.push(item); | ||
} | ||
|
||
$.export("$summary", `Successfully retrieved ${responseArray.length} certification campaigns`); | ||
return responseArray; | ||
}, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { REQUEST_TYPE_OPTIONS } from "../../common/constants.mjs"; | ||
import sailpoint from "../../sailpoint.app.mjs"; | ||
|
||
export default { | ||
key: "sailpoint-submit-access-request", | ||
name: "Submit Access Request", | ||
description: "Sends an access request to IdentityNow. [See the documentation](https://developer.sailpoint.com/docs/api/v2024/create-access-request)", | ||
version: "0.0.1", | ||
type: "action", | ||
props: { | ||
sailpoint, | ||
requestedFor: { | ||
propDefinition: [ | ||
sailpoint, | ||
"requestedFor", | ||
], | ||
}, | ||
requestType: { | ||
type: "string", | ||
label: "Request Type", | ||
description: "Type of access request.", | ||
options: REQUEST_TYPE_OPTIONS, | ||
default: REQUEST_TYPE_OPTIONS[0].value, | ||
}, | ||
requestedItems: { | ||
type: "string[]", | ||
label: "Requested Items", | ||
description: "List of requested items as JSON strings. **Example: [{\"type\": \"ROLE\",\"id\": \"2c9180835d2e5168015d32f890ca1581\",\"comment\": \"Requesting access profile for John Doe\",\"clientMetadata\": {\"requestedAppId\":\"2c91808f7892918f0178b78da4a305a1\",\"requestedAppName\":\"test-app\"},\"removeDate\": \"2020-07-11T21:23:15.000Z\"}]**. [See the documentation](https://developer.sailpoint.com/docs/api/v2024/create-access-request) for forther information.", | ||
}, | ||
jcortes marked this conversation as resolved.
Show resolved
Hide resolved
|
||
clientMetadata: { | ||
type: "object", | ||
label: "Client Metadata", | ||
description: "Arbitrary key-value pairs. They will never be processed by the IdentityNow system but will be returned on associated APIs such as /account-activities. **Example: {\"requestedAppId\":\"2c91808f7892918f0178b78da4a305a1\",\"requestedAppName\":\"test-app\"}**.", | ||
optional: true, | ||
}, | ||
}, | ||
async run({ $ }) { | ||
const response = await this.sailpoint.submitAccessRequest({ | ||
$, | ||
data: { | ||
requestedFor: this.requestedFor, | ||
requestType: this.requestType, | ||
resquestItems: this.resquestItems, | ||
clientMetadata: this.clientMetadata, | ||
jcortes marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}, | ||
}); | ||
Comment on lines
+38
to
+46
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Codebase verification Fix typo in request payload property name There's a typo in the request payload:
Additionally, the property name in the payload doesn't match the actual prop name defined in the component's configuration, which could cause the request to fail. 🔗 Analysis chainVerify API implementation against latest documentation Please verify that the implementation matches the latest SailPoint API documentation, especially the request payload structure. Let me search the codebase for more information about the API implementation. Let me check the specific implementation of the submit-access-request component. 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Description: Check if the API documentation URL is valid and accessible
curl -I "https://developer.sailpoint.com/docs/api/v2024/create-access-request"
Length of output: 1032 Script: #!/bin/bash
# Search for SailPoint API related files and documentation
fd sailpoint --type f --exec cat {}
# Also search for any test files that might contain example payloads
fd "sailpoint.*test|test.*sailpoint" --type f --exec cat {}
Length of output: 3605 Script: #!/bin/bash
# Check the submit-access-request component implementation
cat components/sailpoint/actions/submit-access-request/submit-access-request.mjs
# Search for any related test files
fd "submit-access-request.*test" --type f --exec cat {}
Length of output: 2217 |
||
$.export("$summary", "Access request submitted successfully."); | ||
return response; | ||
}, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
import FormData from "form-data"; | ||
import fs from "fs"; | ||
import { checkTmp } from "../../common/utils.mjs"; | ||
import sailpoint from "../../sailpoint.app.mjs"; | ||
|
||
export default { | ||
key: "sailpoint-upload-account-source-file", | ||
name: "Upload Account Source File", | ||
description: "Uploads a CSV-formatted account source file to IdentityNow. [See the documentation]()", | ||
version: "0.0.1", | ||
type: "action", | ||
props: { | ||
sailpoint, | ||
sourceId: { | ||
propDefinition: [ | ||
sailpoint, | ||
"sourceId", | ||
], | ||
}, | ||
filePath: { | ||
type: "string", | ||
label: "File Path", | ||
description: "The path to a file in the `/tmp` directory. [See the documentation on working with files](https://pipedream.com/docs/code/nodejs/working-with-files/#writing-a-file-to-tmp).", | ||
}, | ||
jcortes marked this conversation as resolved.
Show resolved
Hide resolved
|
||
}, | ||
async run({ $ }) { | ||
const data = new FormData(); | ||
|
||
data.append("file", fs.createReadStream(checkTmp(this.filePath))); | ||
|
||
const response = await this.sailpoint.uploadSourceAccountFile({ | ||
$, | ||
sourceId: this.sourceId, | ||
data, | ||
headers: data.getHeaders(), | ||
}); | ||
jcortes marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
$.export("$summary", `Successfully uploaded file for source account: ${response.id} (${response.name})`); | ||
return response; | ||
}, | ||
}; |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
export const LIMIT = 100; | ||
|
||
export const REQUEST_TYPE_OPTIONS = [ | ||
{ | ||
label: "Grant Access", | ||
value: "GRANT_ACCESS", | ||
}, | ||
{ | ||
label: "Revoke Access", | ||
value: "REVOKE_ACCESS", | ||
}, | ||
]; | ||
|
||
export const WEBHOOK_TYPE_OPTIONS = [ | ||
"HTTP", | ||
"EVENTBRIDGE", | ||
"INLINE", | ||
"SCRIPT", | ||
"WORKFLOW", | ||
]; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
export default { | ||
checkTmp(filename) { | ||
if (!filename.startsWith("/tmp")) { | ||
return `/tmp/${filename}`; | ||
} | ||
return filename; | ||
}, | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,19 @@ | ||
{ | ||
"name": "@pipedream/sailpoint", | ||
"version": "0.0.3", | ||
"version": "0.1.0", | ||
"description": "Pipedream SailPoint Components", | ||
"main": "dist/app/sailpoint.app.mjs", | ||
"main": "sailpoint.app.mjs", | ||
"keywords": [ | ||
"pipedream", | ||
"sailpoint" | ||
], | ||
"files": ["dist"], | ||
"homepage": "https://pipedream.com/apps/sailpoint", | ||
"author": "Pipedream <support@pipedream.com> (https://pipedream.com/)", | ||
"publishConfig": { | ||
"access": "public" | ||
}, | ||
"dependencies": { | ||
"@pipedream/platform": "^3.0.3" | ||
} | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
import { axios } from "@pipedream/platform"; | ||
import { LIMIT } from "./common/constants.mjs"; | ||
|
||
export default { | ||
type: "app", | ||
app: "sailpoint", | ||
propDefinitions: { | ||
requestedFor: { | ||
type: "string[]", | ||
label: "Requested For", | ||
description: "List of Identity IDs for whom the Access is requested.", | ||
async options({ page }) { | ||
const data = await this.listIdentityIds({ | ||
params: { | ||
limit: LIMIT, | ||
offset: LIMIT * page, | ||
}, | ||
}); | ||
|
||
return data.map(({ | ||
id: value, name: label, | ||
}) => ({ | ||
label, | ||
value, | ||
})); | ||
}, | ||
}, | ||
sourceId: { | ||
type: "string", | ||
label: "Source ID", | ||
description: "ID of the source to upload the account file.", | ||
async options({ page }) { | ||
const data = await this.listSoruceIds({ | ||
jcortes marked this conversation as resolved.
Show resolved
Hide resolved
|
||
params: { | ||
limit: LIMIT, | ||
offset: LIMIT * page, | ||
}, | ||
}); | ||
|
||
return data.map(({ | ||
id: value, name: label, | ||
}) => ({ | ||
label, | ||
value, | ||
})); | ||
}, | ||
}, | ||
}, | ||
methods: { | ||
_baseUrl() { | ||
return "https://sailpoint.api.identitynow.com/v2024"; | ||
}, | ||
_headers(headers = {}) { | ||
return { | ||
...headers, | ||
Accept: "application/json", | ||
Authorization: `Bearer ${this.$auth.oauth_access_token}`, | ||
}; | ||
}, | ||
_makeRequest({ | ||
$ = this, path, headers, ...opts | ||
}) { | ||
return axios($, { | ||
url: this._baseUrl() + path, | ||
headers: this._headers(headers), | ||
...opts, | ||
}); | ||
}, | ||
listIdentityIds(opts = {}) { | ||
return this._makeRequest({ | ||
path: "/identities", | ||
headers: { | ||
"X-SailPoint-Experimental": true, | ||
}, | ||
...opts, | ||
}); | ||
}, | ||
listSoruceIds(opts = {}) { | ||
return this._makeRequest({ | ||
path: "/sources", | ||
...opts, | ||
}); | ||
}, | ||
submitAccessRequest(opts = {}) { | ||
return this._makeRequest({ | ||
method: "POST", | ||
path: "/access-requests", | ||
...opts, | ||
}); | ||
}, | ||
uploadSourceAccountFile({ | ||
sourceId, ...opts | ||
}) { | ||
return this._makeRequest({ | ||
method: "POST", | ||
path: `/sources/${sourceId}/schemas/accounts`, | ||
...opts, | ||
}); | ||
}, | ||
createWebhook(opts = {}) { | ||
return this._makeRequest({ | ||
method: "POST", | ||
path: "/trigger-subscriptions", | ||
headers: { | ||
"X-SailPoint-Experimental": true, | ||
}, | ||
...opts, | ||
}); | ||
}, | ||
deleteWebhook(webhookId) { | ||
return this._makeRequest({ | ||
method: "POST", | ||
path: `/trigger-subscriptions/${webhookId}`, | ||
headers: { | ||
"X-SailPoint-Experimental": true, | ||
}, | ||
}); | ||
}, | ||
}, | ||
async *paginate({ | ||
fn, params = {}, maxResults = null, ...opts | ||
}) { | ||
let hasMore = false; | ||
let count = 0; | ||
let page = 0; | ||
|
||
do { | ||
params.page = ++page; | ||
const data = await fn({ | ||
params, | ||
...opts, | ||
}); | ||
for (const d of data) { | ||
yield d; | ||
|
||
if (maxResults && ++count === maxResults) { | ||
return count; | ||
} | ||
} | ||
|
||
hasMore = data.length; | ||
|
||
} while (hasMore); | ||
}, | ||
}; |
Uh oh!
There was an error while loading. Please reload this page.