diff --git a/README.md b/README.md index 043113444..144569d6c 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ $ python -m pip install crowdstrike-falconpy If you'd like to try the *absolute bleeding edge*, an automated GitHub action releases a test package with every merged pull request. To install the testing version: ```shell -$ python -m pip install -i https://test.pypi.org/simple/crowdstrike-falconpy +$ python -m pip install -i https://test.pypi.org/simple crowdstrike-falconpy ``` To uninstall/remove FalconPy: @@ -26,7 +26,7 @@ To uninstall/remove FalconPy: $ python -m pip uninstall crowdstrike-falconpy ``` -# Available Classes +# Service classes | OAuth2-Based API
*(CrowdStrike documentation, requires CrowdStrike customer login)* | Code Location | |:-|:-| | CrowdStrike Device Control API | [./src/falconpy/device_control_policies.py](./src/falconpy/device_control_policies.py) | @@ -56,7 +56,7 @@ $ python -m pip uninstall crowdstrike-falconpy | [Falcon Discover for Cloud and Containers - Azure Subscriptions APIs](https://falcon.crowdstrike.com/support/documentation/118/falcon-discover-for-cloud-and-containers-azure-subscription-apis) | *Coming Soon* | | [Falcon Discover for Cloud and Containers - GCP Projects APIs](https://falcon.crowdstrike.com/support/documentation/117/falcon-discover-for-cloud-and-containers-gcp-projects-apis) | *Coming Soon* | -## Uber-class +## Uber class + [./src/falconpy/api_complete.py](./src/falconpy/api_complete.py) - Provides an interface to all CrowdStrike APIs with a single handler. # Contributing @@ -91,7 +91,7 @@ See the wiki for extended documentation: [https://github.com/CrowdStrike/falconp *Coming soon*. ## Conference Presentations -*Coming soon.* +*Coming soon*. ## Blogs/Articles/Prose *Coming soon*. \ No newline at end of file diff --git a/setup.py b/setup.py index 08e9cb58a..549c17842 100644 --- a/setup.py +++ b/setup.py @@ -10,7 +10,7 @@ setup( name="crowdstrike-falconpy", - version="0.1.10", + version="0.1.11", author="CrowdStrike", maintainer="Joshua Hiller", description="The CrowdStrike Falcon API SDK for Python 3", diff --git a/src/falconpy/__init__.py b/src/falconpy/__init__.py index 7c53c8211..4a351b7a6 100644 --- a/src/falconpy/__init__.py +++ b/src/falconpy/__init__.py @@ -4,7 +4,7 @@ The CrowdStrike Falcon API SDK """ -__version__ = '0.1.10' +__version__ = '0.1.11' __maintainer__ = 'Joshua Hiller' __author__ = 'CrowdStrike' __credits__ = 'CrowdStrike' diff --git a/src/falconpy/api_complete.py b/src/falconpy/api_complete.py index 7dee4c8ed..c64db8fe1 100644 --- a/src/falconpy/api_complete.py +++ b/src/falconpy/api_complete.py @@ -408,7 +408,10 @@ def command(self, action="", parameters={}, body={}, data={}, headers={}, ids=Fa if self.authenticated: try: response = requests.request(CMD[0][1].upper(), FULL_URL, json=BODY, data=DATA, params=PARAMS, headers=HEADERS, files=FILES, verify=False) - returned = self.Result()(status_code=response.status_code, headers=response.headers, body=response.json()) + if response.headers.get('content-type') == "application/json": + returned = self.Result()(status_code=response.status_code, headers=response.headers, body=response.json()) + else: + returned = response.content except Exception as e: returned = self.Result()(status_code=500, headers={}, body=str(e)) else: diff --git a/tests/test_authorization.py b/tests/test_authorization.py new file mode 100644 index 000000000..f668c2f31 --- /dev/null +++ b/tests/test_authorization.py @@ -0,0 +1,86 @@ +# A valid CrowdStrike Falcon API key is required to run these tests. +# API client ID & secret should be stored in tests/test.config in JSON format. +# { +# "falcon_client_id": "CLIENT_ID_GOES_HERE", +# "falcon_client_secret": "CLIENT_SECRET_GOES_HERE" +# } +import json +import os +import sys +#Import our sibling src folder into the path +sys.path.append(os.path.abspath('../src')) +# Classes to test - manually imported from our sibling folder +import falconpy.api_complete as FalconSDK +import falconpy.oauth2 as FalconAuth +import falconpy.cloud_connect_aws as FalconAWS + +# The TestAuthorization class tests authentication and deauthentication +# for both the Uber and Service classes. +class TestAuthorization(): + def getConfig(self): + #Grab our config parameters + with open('%s/test.config' % os.path.dirname(os.path.abspath(__file__)), 'r') as file_config: + self.config = json.loads(file_config.read()) + + def uberAuth(self): + self.getConfig() + self.falcon = FalconSDK.APIHarness(creds={ + "client_id": self.config["falcon_client_id"], + "client_secret": self.config["falcon_client_secret"] + } + ) + self.falcon.authenticate() + if self.falcon.authenticated: + return True + else: + return False + + def uberRevoke(self): + return self.falcon.deauthenticate() + + def serviceAuth(self): + self.getConfig() + self.authorization = FalconAuth.OAuth2(creds={ + 'client_id': self.config["falcon_client_id"], + 'client_secret': self.config["falcon_client_secret"] + }) + + try: + self.token = self.authorization.token()['body']['access_token'] + + except: + self.token = False + + if self.token: + return True + else: + return False + + def serviceRevoke(self): + try: + result = self.authorization.revoke(token=self.token)["status_code"] + if result > 0: + return True + else: + return False + except: + return False + + def test_uberAuth(self): + assert self.uberAuth() == True + self.uberRevoke() + + def test_uberRevoke(self): + self.uberAuth() + assert self.uberRevoke() == True + + def test_serviceAuth(self): + assert self.serviceAuth() == True + self.serviceRevoke() + + def test_serviceRevoke(self): + self.serviceAuth() + assert self.serviceRevoke() == True + + + diff --git a/tests/test_cloud_connect_aws.py b/tests/test_cloud_connect_aws.py new file mode 100644 index 000000000..f6f3bd182 --- /dev/null +++ b/tests/test_cloud_connect_aws.py @@ -0,0 +1,33 @@ +# A valid CrowdStrike Falcon API key is required to run these tests. +# API client ID & secret should be stored in tests/test.config in JSON format. +# { +# "falcon_client_id": "CLIENT_ID_GOES_HERE", +# "falcon_client_secret": "CLIENT_SECRET_GOES_HERE" +# } +import json +import os +import sys +# Authentication via the test_authorization.py +import test_authorization as Authorization + +#Import our sibling src folder into the path +sys.path.append(os.path.abspath('../src')) +# Classes to test - manually imported from sibling folder +import falconpy.cloud_connect_aws as FalconAWS + + +# The TestCloudConnectAWS class tests the cloud_connect_aws service class +class TestCloudConnectAWS: + def serviceCCAWS_GetAWSSettings(self): + auth = Authorization.TestAuthorization() + auth.serviceAuth() + falcon = FalconAWS.Cloud_Connect_AWS(access_token=auth.token) + if falcon.GetAWSSettings()["status_code"] > 0: + auth.serviceRevoke() + return True + else: + auth.serviceRevoke() + return False + + def test_GetAWSSettings(self): + assert self.serviceCCAWS_GetAWSSettings() == True