DependencyTrack / DependencyTrack/dependency-track
Allow PUT /v1/notification/rule to supply notifyOn and publisherConfig parameters
- Dominant language
- Java
- Stars
- 4.2k
- Forks
- 811
- Avg merge
- 8h 39m
- Merged PRs (30d)
- 237
Description
### Current Behavior
The `PUT` call on `/v1/notification/rule` seems to be unable to use any supplied `providerConfig` or `notifyOn` values.
A second `POST` call is needed to add those properties after the rule is created with a `PUT`.
I do not get a HTTP 400 Bad Request, when i try to include `providerConfig` or `notifyOn` in the `PUT` request, those are silently ignored and do not show up in the result.
The only hint at this strange behaviour is the documentation for Notifications, which states:
> Once the alert is created it can be configured. Start with selecting from the list of available notification groups to notify on.
This looks like a hint about the UI flow, but actually describes the backend API behaviour, which is surprising.
This python code demonstrates the behaviour, the first PUT fails to set the `notifyOn` and `providerConfig` values.
```python
import json
import pprint
import sys
import uuid
from urllib.parse import urljoin
import requests
DEPTRACK = 'https://deptrack.example.org'
def get_auth_header():
return {'X-Api-Key': 'verysecret' }
def add_email_channel(project, addresses, publisher, groups):
url = urljoin(DEPTRACK, '/api/v1/notification/rule')
emails = ",".join(addresses)
publisher_config = json.dumps({'destination': emails})
rule_name = '%s_Email' % project
rule_id = str(uuid.uuid4())
req = {
'name': rule_name,
'enabled': True,
'notifyChildren': True,
'scope': 'PORTFOLIO',
'notification_level': 'INFORMATIONAL',
'notifyOn': groups,
'publisher': publisher,
'publisherConfig': publisher_config
'uuid': rule_id,
}
headers = get_auth_header()
headers['Content-Type'] = 'application/json'
resp = requests.put(url, headers=get_auth_header(), json=req)
resp.raise_for_status()
result = resp.json()
print("Created Rule via PUT")
print(result)
result['publisherConfig'] = publisher_config
result['notifyOn'] = groups
resp = requests.post(url, headers=get_auth_header(), json=result)
resp.raise_for_status()
result = resp.json()
print("Updated Rule via POST")
print(result)
return result['uuid']
class Publishers(object):
def __init__(self):
self.url = urljoin(DEPTRACK, "/api/v1/notification/publisher")
self.load()
def load(self):
self.available = self.find_available_publishers()
def get_publisher(self, name):
return self.available[name]
def find_available_publishers(self):
resp = requests.get(self.url, headers=get_auth_header())
resp.raise_for_status()
data = resp.json()
publishers = {}
for pub in data:
publishers[pub['name']] = pub
return publishers
def find_notification_rules():
url = urljoin(DEPTRACK, '/api/v1/notification/rule')
resp = requests.get(url, headers=get_auth_header())
resp.raise_for_status()
data = resp.json()
pprint.pprint(data)
return data
def main():
pubs = Publishers()
email = pubs.get_publisher('Email')
add_email_channel('example', ['user@example.org'], email, groups=['NEW_VULNERABILITY'])
find_notification_rules()
if __name__ == '__main__':
main()
```
### Proposed Behavior
The `PUT` call should accept AND process all parameters of the provided `NotificationRule`. It should not silently ignore parameters given in the NotificationRule object.
This should at least work for:
- `notifyOn`
- `providerConfig`
which are always necessary for a useful `NotificationRule`.
- This would align the actual API behaviour with the OpenAPI documentation for `createNotificationRule`.
- It would also better fit the `PUT` semantics.
- It would improve performance as it reduces the amount of necessary API calls.
### Checklist
- [X] I have read and understand the [contributing guidelines](https://github.com/DependencyTrack/dependency-track/blob/master/CONTRIBUTING.md#filing-issues)
- [X] I have checked the [existing issues](https://github.com/DependencyTrack/dependency-track/issues) for whether this enhancement was already requested
Contributor guide
Assessment
This issue has not been assessed yet.