Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add endpoint to import issues to DDB #98

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions hammer/identification/lambdas/api/authorizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ def lambda_handler(event, context):
policy.allowMethod(HttpVerb.GET, full_path)
policy.allowMethod(HttpVerb.POST, '/identify')
policy.allowMethod(HttpVerb.POST, '/remediate')
policy.allowMethod(HttpVerb.POST, '/import')

authResponse = policy.build()

Expand Down
45 changes: 38 additions & 7 deletions hammer/identification/lambdas/api/entrypoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from library.aws.utility import Account, DDB, Sns
from library.config import Config
from library.ddb_issues import Operations as IssueOperations
from library.ddb_issues import Issue, IssueStatus, Operations as IssueOperations
from library.logger import set_logging
from library import utility
from responses import bad_request
Expand Down Expand Up @@ -168,6 +168,35 @@ def get_scan_results(request_id):
}


def validate_issues(issues, valid_issue_types):
required_parameters = ['issue_id', 'issue_type', 'account_id', 'issue_details']
for issue in issues:
for required in required_parameters:
if required not in issue:
raise Exception(f'{required} is required field for issue')
if issue['issue_type'] not in valid_issue_types:
raise Exception(f'{issue["issue_type"]} is not supported issue type')


def add_issues(issues):
config = Config()
main_account = Account(region=config.aws.region)
valid_issue_types = [module.section for module in config.modules]
try:
validate_issues(issues, valid_issue_types)
except Exception as e:
return bad_request(text=str(e))
for issue in issues:
issue_config = config.get_module_config_by_name(issue['issue_type'])
ddb_table = main_account.resource("dynamodb").Table(issue_config.ddb_table_name)
ddb_issue = Issue(issue['account_id'], issue['issue_id'], issue['issue_details'])
ddb_issue.status = IssueStatus.Open
IssueOperations.update(ddb_table, ddb_issue)
return {
'statusCode': 200,
'body': 'Successfully imported issues to DDB'
}

@logger
def lambda_handler(event, context):
try:
Expand All @@ -177,21 +206,23 @@ def lambda_handler(event, context):
logging.exception("failed to parse payload")
return bad_request(text="malformed payload")

account_id = payload.get("account_id", None)
regions = payload.get("regions", [])
security_features = payload.get("security_features", [])
tags = payload.get("tags", None)
ids = payload.get("ids", None)

action = event.get("path", "")[1:]
method = event.get("httpMethod")
# do not forget to allow path in authorizer.py while extending this list
if action.startswith('identify'):
account_id = payload.get("account_id", None)
regions = payload.get("regions", [])
security_features = payload.get("security_features", [])
tags = payload.get("tags", None)
ids = payload.get("ids", None)
if method == "POST":
return start_scan(account_id, regions, security_features, tags, ids)
if method == "GET":
# get request id from url path
request_id = action.split('/')[1]
return get_scan_results(request_id)
elif action.startswith('import'):
issues = payload.get('issues', [])
return add_issues(issues)
else:
return bad_request(text="wrong action")
5 changes: 3 additions & 2 deletions hammer/library/ddb_issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ class Issue(object):
"""
Base class for Hammer security issue. Python representation of DDB item.
"""
def __init__(self, account_id, issue_id):
def __init__(self, account_id, issue_id, issue_details=None):
# account id where issue was found (HASH key)
self.account_id = account_id
# issue id, must be uniq in account (RANGE key)
Expand All @@ -71,7 +71,8 @@ def __init__(self, account_id, issue_id):
# issue status
self.status = IssueStatus.Open
# issue specific details
self.issue_details = Details({})
details = Details(issue_details) if issue_details else Details({})
self.issue_details = details
# jira specific details
self.jira_details = Details({})

Expand Down