diff --git a/CHANGELOG.md b/CHANGELOG.md index a8ac7d8..8eb8ad4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,29 @@ # Change Log (v2.8.1+) +## v4.0.1 [2025-01-29] + +__What's New:__ + +* None + +__Enhancements:__ + +* None + +__Bug Fixes:__ + +* Withdrawn request now returns `withdrawn` status instead of `cancelled`. +* Always include ITSM `ticket_type` and/or `ticket_id` if they are provided. +* Failing `my_resources.checkout` due to 404 after approval. + +__Dependencies:__ + +* None + +__Other:__ + +* None + ## v4.0.0 [2025-01-17] __What's New:__ diff --git a/src/britive/__init__.py b/src/britive/__init__.py index d6497a8..1a3bef5 100644 --- a/src/britive/__init__.py +++ b/src/britive/__init__.py @@ -1 +1 @@ -__version__ = '4.0.0' +__version__ = '4.0.1' diff --git a/src/britive/my_access.py b/src/britive/my_access.py index 28da3a4..51c0853 100644 --- a/src/britive/my_access.py +++ b/src/britive/my_access.py @@ -22,6 +22,7 @@ 'rejected': ProfileApprovalRejected(), 'cancelled': ProfileApprovalWithdrawn(), 'timeout': ProfileApprovalTimedOut(), + 'withdrawn': ProfileApprovalWithdrawn(), } @@ -202,7 +203,13 @@ def _checkout( ) -> dict: params = {'accessType': 'PROGRAMMATIC' if programmatic else 'CONSOLE'} - data = {'justification': justification} + data = {} + if justification: + data['justification'] = justification + if ticket_type: + data['ticketType'] = ticket_type + if ticket_id: + data['ticketId'] = ticket_id transaction = None @@ -577,7 +584,7 @@ def create_filter(self, filter_name: str, filter_properties: str) -> dict: data = {'name': filter_name, 'filter': filter_properties} - return self.britive.post(f"{self.base_url}/{self.whoami()['userId']}/filters", json=data) + return self.britive.post(f'{self.base_url}/{self.whoami()["userId"]}/filters', json=data) def list_filters(self) -> list: """ @@ -586,7 +593,7 @@ def list_filters(self) -> list: :return: List of filters. """ - return self.britive.get(f"{self.base_url}/{self.whoami()['userId']}/filters") + return self.britive.get(f'{self.base_url}/{self.whoami()["userId"]}/filters') def update_filter(self, filter_id: str, filter_name: str, filter_properties: str) -> dict: """ @@ -619,7 +626,7 @@ def update_filter(self, filter_id: str, filter_name: str, filter_properties: str data = {'name': filter_name, 'filter': filter_properties} - return self.britive.put(f"{self.base_url}/{self.whoami()['userId']}/filters/{filter_id}", json=data) + return self.britive.put(f'{self.base_url}/{self.whoami()["userId"]}/filters/{filter_id}', json=data) def delete_filter(self, filter_id: str) -> None: """ @@ -629,4 +636,4 @@ def delete_filter(self, filter_id: str) -> None: :return: None. """ - return self.britive.delete(f"{self.base_url}/{self.whoami()['userId']}/filters/{filter_id}") + return self.britive.delete(f'{self.base_url}/{self.whoami()["userId"]}/filters/{filter_id}') diff --git a/src/britive/my_requests.py b/src/britive/my_requests.py index 5197b6c..657c64d 100644 --- a/src/britive/my_requests.py +++ b/src/britive/my_requests.py @@ -1,9 +1,9 @@ -import sys import time from typing import Any, Callable from .exceptions import ( ProfileApprovalMaxBlockTimeExceeded, + ProfileApprovalWithdrawn, ProfileCheckoutAlreadyApproved, ) from .helpers import HelperMethods @@ -102,15 +102,14 @@ def _request_approval( # status == timeout or approved or rejected or cancelled return status raise ProfileApprovalMaxBlockTimeExceeded - except KeyboardInterrupt: # handle Ctrl+C (^C) - # the first ^C we get we will try to withdraw the request + except KeyboardInterrupt as e: # handle Ctrl+C (^C) try: + # the first ^C we get we will try to withdraw the request time.sleep(1) # give the caller a small window to ^C again - self.withdraw_approval_request(request_id=request_id) - sys.exit() + self._withdraw_approval_request(request_id=request_id) + raise ProfileApprovalWithdrawn('user interrupt.') from e except KeyboardInterrupt: - sys.exit() - + raise e from None else: return request diff --git a/src/britive/my_resources.py b/src/britive/my_resources.py index 28eec94..8c80c77 100644 --- a/src/britive/my_resources.py +++ b/src/britive/my_resources.py @@ -19,6 +19,7 @@ 'rejected': ProfileApprovalRejected(), 'cancelled': ProfileApprovalWithdrawn(), 'timeout': ProfileApprovalTimedOut(), + 'withdrawn': ProfileApprovalWithdrawn(), } @@ -125,7 +126,13 @@ def _checkout( ticket_type: str = None, wait_time: int = 60, ) -> dict: - data = {'justification': justification} + data = {} + if justification: + data['justification'] = justification + if ticket_type: + data['ticketType'] = ticket_type + if ticket_id: + data['ticketId'] = ticket_id transaction = None @@ -185,7 +192,7 @@ def _checkout( # handle the response based on the value of status if status == 'approved': transaction = self.britive.post( - f'{self.base_url}/{profile_id}/resources/{resource_id}/checkout', json=data + f'{self.base_url}/profiles/{profile_id}/resources/{resource_id}/checkout', json=data ) else: raise approval_exceptions[status](e) from e