Skip to content

Commit 72665fe

Browse files
Servicenow 8.1.0 release (#3245)
* [SOAR-18683] Servicenow Extend OAuth with client credentials flow (#3210) * [SOAR-18683] Servicenow Extend OAuth with client credentials flow * Update requirements.txt * adding parameterized back in to test unit test * removing * Fixing unit tests attempt #1 * Revert "Fixing unit tests attempt #1" This reverts commit 230ad57. * Fixing unit tests attempt #2 * Revert "Fixing unit tests attempt #2" This reverts commit 48d76c3. * Update requirements.txt * Handling edge cases * Removing an f-string that does not have any interpolated variable * REfactor spec for SDK automation * Removing unnecessary imports * Fixing linter --------- Co-authored-by: rjmurray <ryanj_murray@rapid7.com> * Adjusting versioning * Versioning fix --------- Co-authored-by: rjmurray <ryanj_murray@rapid7.com>
1 parent 8ff8525 commit 72665fe

File tree

11 files changed

+287
-152
lines changed

11 files changed

+287
-152
lines changed

plugins/servicenow/.CHECKSUM

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
2-
"spec": "c3ae1da25557460ad543d9434f6eeb51",
3-
"manifest": "de3b4607248ad49ab38f25c2899f629a",
4-
"setup": "dead9576e6a14815dcb13463a4315083",
2+
"spec": "e524d85b72b2ae93a17ae6bfa1964504",
3+
"manifest": "4799c70cc2e26ddf494b81ca4e645b7d",
4+
"setup": "4b5b45a5d64ecdda6705da62b7939bb3",
55
"schemas": [
66
{
77
"identifier": "create_change_request/schema.py",
@@ -105,7 +105,7 @@
105105
},
106106
{
107107
"identifier": "connection/schema.py",
108-
"hash": "bf06fa84b9beae4dda71f8ecb2946931"
108+
"hash": "dbd0b4a113640886661a53e5f8b96d1b"
109109
},
110110
{
111111
"identifier": "incident_changed/schema.py",

plugins/servicenow/Dockerfile

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM --platform=linux/amd64 rapid7/insightconnect-python-3-slim-plugin:6.2.2
1+
FROM --platform=linux/amd64 rapid7/insightconnect-python-3-slim-plugin:6.2.5
22

33
LABEL organization=rapid7
44
LABEL sdk=python
@@ -12,7 +12,7 @@ RUN if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
1212

1313
ADD . /python/src
1414

15-
RUN python setup.py build && python setup.py install
15+
RUN pip install .
1616

1717
# User to run plugin code. The two supported users are: root, nobody
1818
USER nobody

plugins/servicenow/bin/icon_servicenow

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ from sys import argv
66

77
Name = "ServiceNow"
88
Vendor = "rapid7"
9-
Version = "8.0.4"
9+
Version = "8.1.0"
1010
Description = "[ServiceNow](https://www.servicenow.com/) is a tool for managing incidents and configuration management. This plugin allows users to manage all aspects of incidents including creation, search, and updates. Additionally, incident changes can be monitored and processed for use in a Rapid7 InsightConnect workflow.Note: This plugin affects only the underlying tables in a ServiceNow instance, not its UI. Hence, this plugin will work seamlessly with Virtual Task Boards"
1111

1212

plugins/servicenow/help.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,8 @@ Note: This plugin affects only the underlying tables in a ServiceNow instance, n
1414
# Requirements
1515

1616
* ServiceNow username and password (for basic authentication)
17-
* ServiceNow username, password, client ID, and client secret (for OAuth authentication)
17+
* ServiceNow client ID, and client secret (for OAuth authentication client credentials grant type)
18+
* ServiceNow username, password, client ID, and client secret (for OAuth authentication password grant type)
1819
* ServiceNow instance name
1920

2021
* Please note that to use certain actions it's necessary to use scopes that have permissions on certain tables. Depending on the actions, it's necessary to add specific auth scopes:
@@ -37,7 +38,7 @@ The connection configuration accepts the following parameters:
3738
|Name|Type|Default|Required|Description|Enum|Example|Placeholder|Tooltip|
3839
| :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- | :--- |
3940
|client_id|string|None|False|Client ID for an application within your application registry|None|ad0bc2109c2642106907050c2ca6ef0c|None|None|
40-
|client_login|credential_username_password|None|True|The ServiceNow username and password for basic authentication API interaction|None|{"username":"user1", "password":"mypassword"}|None|None|
41+
|client_login|credential_username_password|None|False|The ServiceNow username and password for basic authentication API interaction|None|{"username":"user1", "password":"mypassword"}|None|None|
4142
|client_secret|credential_secret_key|None|False|Client secret for an application within your application registry|None|ad0bc2109c2642106907050c2ca6ef0c|None|None|
4243
|instance|string|None|True|The instance of ServiceNow from the URL, e.g. https://{instance}.service-now.com|None|instance|None|None|
4344
|timeout|integer|30|False|The interval in seconds before abandoning an attempt to access ServiceNow|None|30|None|None|
@@ -1686,6 +1687,7 @@ Example output:
16861687

16871688
# Version History
16881689

1690+
* 8.1.0 - Add ability to use OAuth 2.0 flow named client credentials | Updated SDK to the latest version (v6.2.5)
16891691
* 8.0.4 - Updated SDK to the latest version (v6.2.2) | Address vulnerabilities
16901692
* 8.0.3 - Update to resolve issue parsing response from ServiceNow if XML is received
16911693
* 8.0.2 - Initial updates for fedramp compliance | Updated SDK to the latest version

plugins/servicenow/icon_servicenow/connection/connection.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import insightconnect_plugin_runtime
2-
from .schema import ConnectionSchema, Input
32

43
# Custom imports below
5-
import requests
6-
from requests.auth import HTTPBasicAuth
74
from icon_servicenow.util.request_helper import RequestHelper, AuthenticationType
8-
from insightconnect_plugin_runtime.exceptions import ConnectionTestException
5+
from insightconnect_plugin_runtime.exceptions import ConnectionTestException, PluginException
6+
7+
from .schema import ConnectionSchema, Input
98

109

1110
class Connection(insightconnect_plugin_runtime.Connection):
@@ -29,7 +28,13 @@ def connect(self, params):
2928
oauth_client_id = params.get(Input.CLIENT_ID)
3029
oauth_client_secret = params.get(Input.CLIENT_SECRET, {}).get("secretKey")
3130

32-
if not oauth_client_id or not oauth_client_secret:
31+
if all([not username, not password, not oauth_client_id, not oauth_client_secret]):
32+
raise PluginException(
33+
cause="No credentials were provided.",
34+
assistance="Ensure credentials and ServiceNow endpoint are correct.",
35+
)
36+
37+
if not oauth_client_id or not oauth_client_secret and username and password:
3338
self.logger.info(
3439
"Either client ID or client secret (or both) were not provided, using basic authentication"
3540
)

plugins/servicenow/icon_servicenow/connection/schema.py

-1
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ class ConnectionSchema(insightconnect_plugin_runtime.Input):
5050
}
5151
},
5252
"required": [
53-
"client_login",
5453
"instance"
5554
],
5655
"definitions": {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
MISSING_CREDENTIALS = "Either `client_id` or `client_secret` must be provided"

plugins/servicenow/icon_servicenow/util/request_helper.py

+30-7
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99

1010
from insightconnect_plugin_runtime.exceptions import PluginException
1111

12+
from icon_servicenow.util.error_messages import MISSING_CREDENTIALS
13+
1214

1315
class BearerAuth(AuthBase):
1416
"""
@@ -132,15 +134,36 @@ def get_attachment(connection, sys_id):
132134
return str(base64.b64encode(result), "utf-8")
133135

134136
def _get_oauth_token(self) -> str:
137+
"""
138+
Sends a POST request to an OAuth server, automatically determining 'grant_password'
139+
140+
- If `username` and `password` are provided, grant_type = 'password'
141+
- If `username` and `password` are not provided, grant_type = 'client_credentials'
142+
"""
143+
144+
if not self.client_id and not self.client_secret:
145+
raise PluginException(status_code=400, cause=MISSING_CREDENTIALS)
146+
147+
# Automatic grant_type detection
148+
if self.username and self.password:
149+
grant_type = "password"
150+
else:
151+
grant_type = "client_credentials"
152+
153+
# Building the payload
154+
payload = {
155+
"grant_type": grant_type,
156+
"client_id": self.client_id,
157+
"client_secret": self.client_secret,
158+
}
159+
160+
if grant_type == "password":
161+
payload["username"] = self.username
162+
payload["password"] = self.password
163+
135164
response = requests.post(
136165
url=f"{self.base_url}oauth_token.do",
137-
data={
138-
"grant_type": "password",
139-
"client_id": self.client_id,
140-
"client_secret": self.client_secret,
141-
"username": self.username,
142-
"password": self.password,
143-
},
166+
data=payload,
144167
timeout=30,
145168
)
146169

0 commit comments

Comments
 (0)