Skip to content

Commit

Permalink
Additional refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
jshcodes committed Jan 20, 2023
1 parent 919442e commit 9173f7c
Show file tree
Hide file tree
Showing 20 changed files with 615 additions and 393 deletions.
7 changes: 4 additions & 3 deletions src/falconpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,10 @@
from ._version import _VERSION, _MAINTAINER, _AUTHOR, _AUTHOR_EMAIL
from ._version import _CREDITS, _DESCRIPTION, _TITLE, _PROJECT_URL
from ._version import _DOCS_URL, _KEYWORDS
from ._service_class import ServiceClass
from ._auth_object import BaseFalconAuth, FalconAuth, UberInterface
from ._service_class import BaseServiceClass, ServiceClass
from ._util import confirm_base_region, confirm_base_url
from ._base_url import BaseURL
from ._container_base_url import ContainerBaseURL
from ._enum import BaseURL, ContainerBaseURL, TokenFailReason
from .alerts import Alerts
from .api_complete import APIHarness
from .cloud_connect_aws import CloudConnectAWS
Expand Down Expand Up @@ -91,6 +91,7 @@
__keywords__ = _KEYWORDS
__all__ = [
"confirm_base_url", "confirm_base_region", "BaseURL", "ServiceClass", "Alerts",
"BaseServiceClass", "BaseFalconAuth", "FalconAuth", "UberInterface", "TokenFailReason",
"APIHarness", "CloudConnectAWS", "CSPMRegistration", "CustomIOA", "D4CRegistration",
"Detects", "DeviceControlPolicies", "Discover", "EventStreams", "CompleteDashboard",
"FalconContainer", "FalconXSandbox", "FirewallManagement", "FirewallPolicies", "HostGroup",
Expand Down
5 changes: 5 additions & 0 deletions src/falconpy/_auth_object/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from ._base_falcon_auth import BaseFalconAuth
from ._falcon_auth import FalconAuth
from ._uber_interface import UberInterface

__all__ = ["BaseFalconAuth", "FalconAuth", "UberInterface"]
103 changes: 103 additions & 0 deletions src/falconpy/_auth_object/_base_falcon_auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
"""Authentication Object Base Class.
This file contains the definition of the base class that provides the
necessary functions to authenticate to the CrowdStrike Falcon OAuth2 API.
_______ __ _______ __ __ __
| _ .----.-----.--.--.--.--| | _ | |_.----|__| |--.-----.
|. 1___| _| _ | | | | _ | 1___| _| _| | <| -__|
|. |___|__| |_____|________|_____|____ |____|__| |__|__|__|_____|
|: 1 | |: 1 |
|::.. . | CROWDSTRIKE FALCON |::.. . | FalconPy
`-------' `-------'
OAuth2 API - Customer SDK
This is free and unencumbered software released into the public domain.
Anyone is free to copy, modify, publish, use, compile, sell, or
distribute this software, either in source code form or as a compiled
binary, for any purpose, commercial or non-commercial, and by any
means.
In jurisdictions that recognize copyright laws, the author or authors
of this software dedicate any and all copyright interest in the
software to the public domain. We make this dedication for the benefit
of the public at large and to the detriment of our heirs and
successors. We intend this dedication to be an overt act of
relinquishment in perpetuity of all present and future rights to this
software under copyright law.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
For more information, please refer to <https://unlicense.org>
"""
from abc import ABC, abstractmethod
from typing import Dict


class BaseFalconAuth(ABC):
"""Abstract class to provide an interface to the CrowdStrike Falcon OAuth2 API.
This class does not implement a generic constructor and is not intended to be used by
developers directly. You must work with a derivative of this class, such as a FalconAuth object.
"""
# ______ _______ _______ _______ _ _ _______
# | \ |______ |______ |_____| | | | |
# |_____/ |______ | | | |_____| |_____ |

# _______ _______ _______ _ _ _____ ______ _______
# | | | |______ | |_____| | | | \ |______
# | | | |______ | | | |_____| |_____/ ______|

# The generic login and logout handlers must be individually defined by all
# inheriting classes. The private methods defined here are used to allow for
# easy overridding of login and logout processing by inheriting classes without
# altering the parent handler method that may be leveraged by other inheriting
# class types.
@abstractmethod
def _login_handler(self) -> dict or bool:
"""Login to the Falcon API by requesting a new token."""

@abstractmethod
def _logout_handler(self) -> dict or bool:
"""Log out of the Falcon API by revoking the current token."""

@abstractmethod
def login(self) -> dict or bool:
"""Generic login handler interface."""

@abstractmethod
def logout(self) -> dict or bool:
"""Generic logout handler interface."""

# _____ ______ _____ _____ _______ ______ _______ _____ _______ _______
# |_____] |_____/ | | |_____] |______ |_____/ | | |______ |______
# | | \_ |_____| | |______ | \_ | __|__ |______ ______|
#
# These properties are present within all BaseFalconAuth derivatives.
@property
@abstractmethod
def auth_headers(self) -> Dict[str, str]:
"""Get a dictionary of headers that can authenticate an HTTP request."""

@property
@abstractmethod
def authenticated(self) -> bool:
"""Read-only property to return whether authentication is successful."""

@property
@abstractmethod
def token_expired(self) -> bool:
"""Read-only property that returns the current token expiration status."""

@property
@abstractmethod
def cred_format_valid(self) -> bool:
"""Read-only property that returns a boolean if the creds dictionary is valid."""
Original file line number Diff line number Diff line change
Expand Up @@ -39,72 +39,11 @@
For more information, please refer to <https://unlicense.org>
"""
import time
from abc import ABC, abstractmethod
from typing import Dict, Optional
from ._token_fail_reason import TokenFailReason
from ._util import generate_b64cred, autodiscover_region, perform_request, generate_error_result
from ._endpoint._oauth2 import _oauth2_endpoints as AuthEndpoints


class BaseFalconAuth(ABC):
"""Abstract class to provide an interface to the CrowdStrike Falcon OAuth2 API.
This class does not implement a generic constructor and is not intended to be used by
developers directly. You must work with a derivative of this class, such as a FalconAuth object.
"""
# ______ _______ _______ _______ _ _ _______
# | \ |______ |______ |_____| | | | |
# |_____/ |______ | | | |_____| |_____ |

# _______ _______ _______ _ _ _____ ______ _______
# | | | |______ | |_____| | | | \ |______
# | | | |______ | | | |_____| |_____/ ______|

# The generic login and logout handlers must be individually defined by all
# inheriting classes. The private methods defined here are used to allow for
# easy overridding of login and logout processing by inheriting classes without
# altering the parent handler method that may be leveraged by other inheriting
# class types.
@abstractmethod
def _login_handler(self) -> dict or bool:
"""Login to the Falcon API by requesting a new token."""

@abstractmethod
def _logout_handler(self) -> dict or bool:
"""Log out of the Falcon API by revoking the current token."""

@abstractmethod
def login(self) -> dict or bool:
"""Generic login handler interface."""

@abstractmethod
def logout(self) -> dict or bool:
"""Generic logout handler interface."""

# _____ ______ _____ _____ _______ ______ _______ _____ _______ _______
# |_____] |_____/ | | |_____] |______ |_____/ | | |______ |______
# | | \_ |_____| | |______ | \_ | __|__ |______ ______|
#
# These properties are present within all BaseFalconAuth derivatives.
@property
@abstractmethod
def auth_headers(self) -> Dict[str, str]:
"""Get a dictionary of headers that can authenticate an HTTP request."""

@property
@abstractmethod
def authenticated(self) -> bool:
"""Read-only property to return whether authentication is successful."""

@property
@abstractmethod
def token_expired(self) -> bool:
"""Read-only property that returns the current token expiration status."""

@property
@abstractmethod
def cred_format_valid(self) -> bool:
"""Read-only property that returns a boolean if the creds dictionary is valid."""
from ._base_falcon_auth import BaseFalconAuth
from .._enum import TokenFailReason
from .._util import generate_b64cred, autodiscover_region, perform_request, generate_error_result
from .._endpoint._oauth2 import _oauth2_endpoints as AuthEndpoints


class FalconAuth(BaseFalconAuth):
Expand Down Expand Up @@ -290,121 +229,4 @@ def auth_headers(self) -> Dict[str, str]:
if self.token_expired and self.refreshable:
self.login()

return {"Authorization": f"Bearer {self.token_value}"}


class UberInterface(FalconAuth):
"""Uber Class specific interface."""

# ____ ___ ___ ____ _ ___ _ _ ___ ____ ____
# |__| | | |__/ | |__] | | | |___ [__
# | | | | | \ | |__] |__| | |___ ___]
#
# Attributes present only within the Uber Class.
#
# A dictionary of every available API operation provided by the library.
commands: dict = {}

# ____ ____ _ _ ____ ___ ____ _ _ ____ ___ ____ ____
# | | | |\ | [__ | |__/ | | | | | | |__/
# |___ |__| | \| ___] | | \ |__| |___ | |__| | \
#
# Starting in v1.3.0, the Uber Class constructs itself leveraging the generic
# FalconAuth constructor. This results in the Uber Class benefiting from a new
# authentication style; Legacy / Token authentication.
def __init__(self,
access_token: Optional[str or bool] = False,
base_url: Optional[str] = "https://api.crowdstrike.com",
creds: Optional[dict] = None,
client_id: Optional[str] = None,
client_secret: Optional[str] = None,
member_cid: Optional[str] = None,
ssl_verify: Optional[bool] = True,
proxy: Optional[dict] = None,
timeout: Optional[float or tuple] = None,
user_agent: Optional[str] = None,
renew_window: Optional[int] = 120
) -> "UberInterface":
"""Construct an instance of the UberInterface class."""
super().__init__(base_url=base_url,
ssl_verify=ssl_verify,
timeout=timeout,
proxy=proxy,
user_agent=user_agent,
access_token=access_token,
creds=creds,
client_id=client_id,
client_secret=client_secret,
member_cid=member_cid,
renew_window=renew_window
)

# _ _ ____ ___ _ _ ____ ___ ____
# |\/| |___ | |__| | | | \ [__
# | | |___ | | | |__| |__/ ___]
#
# Override the default login and logout handlers to
# provide Uber Class-specific functionality.
def _login_handler(self) -> bool:
"""Generate an authorization token."""
super()._login_handler()

return self.authenticated

def _logout_handler(self) -> bool:
"""Revoke the current authorization token."""
result = super()._logout_handler()

return bool(result["status_code"] == 200)

# _ ____ ____ ____ ____ _ _ _ _ ____ _ _ ___ _ ____ ____ ____
# | |___ | __ |__| | \_/ |__| |__| |\ | | \ | |___ |__/ [__
# |___ |___ |__] | | |___ | | | | | | \| |__/ |___ |___ | \ ___]
#
# These handlers provide legacy Uber Class-specific functionality that will be
# maintained for provide backwards compatibility purposes.
def authenticate(self) -> bool:
"""Legacy Uber Class functionality handler.
DEPRECATED
----
Consider updating your code to leverage the login method.
"""
return super().login()

def deauthenticate(self) -> bool:
"""Legacy Uber Class functionality handler.
DEPRECATED
----
Consider updating your code to leverage the logout method.
"""
return super().logout()

def valid_cred_format(self) -> bool:
"""Legacy property to confirm credential dictionary format.
DEPRECATED
----
Consider updating your code to leverage the cred_format_valid property.
"""
return self.cred_format_valid

def headers(self) -> Dict[str, str]:
"""Legacy property getter for the current authorization headers.
DEPRECATED
----
Consider updating your code to leverage the auth_headers property.
"""
return self.auth_headers

@property
def token(self) -> str:
"""Legacy attribute handler to return the token string.
DEPRECATED
----
Consider updating your code to leverage the token_value property.
"""
return self.token_value
return {"Authorization": f"Bearer {self.token_value}"}
Loading

0 comments on commit 9173f7c

Please sign in to comment.