-
Notifications
You must be signed in to change notification settings - Fork 2
PR : Add reporting for API #25
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
Merged
Merged
Changes from 73 commits
Commits
Show all changes
84 commits
Select commit
Hold shift + click to select a range
a36fc35
Create a basic new Agent class
5062dfe
Create the super class for API's
3b403fc
create an HTTP API class
4ba6703
Install and import requests
211421c
Linting
f81f549
Rename to timeout_in_sec
adbfa83
Send data using requests.post
1e88fcc
Create a class that encapsulates the token
465c746
Give back api response in http_api file
87a71ae
update the way to_api_response() function works
9689a29
Add tests for token class
9eecfc0
Add tests for ReportingApi class
434d830
Move token file into a helper module with new function get_token_from…
d25f1c1
Create a should_block helper function
58e0201
Linting
3ff2bf3
Create agent and add get_token_from_env func
24f1869
add send_heartbeat and some auxiliary funcs
20bf490
self.token needs to be defined for these 2 funcs
c6705e5
Use self.timeout_in_sec
41c5b05
add on_start function
db277ed
Update get_agent_info function
cd6a24f
Linting
164eae3
Add some stuff already to on_detected_attack
e0e5fef
Add new helper function limit_length_metadata
b04031b
Use new helper function in agent.py to limit metadata
78f6599
Change interval to 10 minutes
2305285
Merge remote-tracking branch 'origin/AIK-3167' into AIK-3210
d3914f4
Renaming agent to reporter and fixing left scars of merge
747d825
Validate token using Token class in Reporter
1bceaba
Use .timestamp() on datetime
0d3b1d3
Bugfix, should be json= instead of data=
ca25686
Only parse if status code is 200, use json.loads and debug if error
0a47b8f
Fix bug, unixtime needs to be sent in ms
dbfa324
Use a PKG_VERSION const
2bce5f6
Create a get_ip() function
66fcb28
Update blocking in the updateConfig function
224a864
Linting
177c9fc
Add a heartbeats.py file with heartbeat logic (interval, event sched)
f5e6a3b
Add missing data (empty) to the request
19cda6b
linting for if statement in token.py
1c8a006
Mistake with 2x token wrappin
00548d4
Merge branch 'AIK-3199' into AIK-3210
633e182
Merge branch 'AIK-3199' into AIK-3210
1ac32d0
Flask shouldn't reload, messes up our bg job
739f18a
Create a reporter with a local api url
caece69
Using an array as data for send_data function is pointless
bbc0b1e
Add aikido as host in docker
1b9fd0f
Run on_start when initiating a Reporter
0ffe068
Check if result is successfull of API
1e869ea
Fix bug with not detecting the timeout error
058ab89
Forgotten import + report attacks when emptying queue
3d2143e
Make context object picklable
0121d6a
Update the on_detected_attack function
bd98fe7
Linting
c5bce7d
Extract extra nformation and user-agent from headers
49e41f0
Allow polling for config, and do it to see if we should block
ae4c585
Report route to aikido server
cd3bfab
Fix bug with hung connection
771c949
Create get_subdomains_from_url helper function
f42108d
Add subdomains to context
c55eaaa
Create a scheduler in reporting thread, send out heartbeats using it
f5b5c3e
Fix bug with blocking not being updated by using hasattr
706ca0e
Merge branch 'AIK-3167' into AIK-3210
1bfa13a
Make sure the url is a string
b47aea8
Merge branch 'main' into AIK-3210
bitterpanda63 9877d00
Don't raise an exception at HTTPApi, just logger.error it
310f538
Rename to context_contains_sql_injection
5c50abf
Rename s to event_scheduler in heartbeats.py
a83ab91
Fix merge issues, add back lost code
f76ea56
Replac with contains_injection and add blocking code to mysqlclient
6a92882
Linting
87eb9f9
Heartbeat every 10 minutes
9523f51
Report sec interval needs to be near instant (5 seconds)
bde23b8
Split all helper functions for reporter up into files
d6a5d32
Add tests for get_ua_from_context
89dd55c
Add tests for get_unixtime_ms
7202571
Add tests for get_ip
cdf840d
Bugfix where http_api would still try and parse if an exception occured
6d8bae6
Add testing for http_api
fce720b
Add comments clarifying timeout_in_sec variable
a359dc3
Add tests for heartbeats.py
4e6dbba
REPORT_SEC_INTERVAL to EMPTY_QUEUE_INTERVAL
b2203d2
Update aikido_firewall/background_process/aikido_background_process.py
willem-delbare 34ef86f
Create a new Reporter using named arguments for clarity
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
""" | ||
init.py file for api/ folder. Includes abstract class ReportingApi | ||
""" | ||
|
||
import json | ||
from aikido_firewall.helpers.logging import logger | ||
|
||
|
||
class ReportingApi: | ||
"""This is the super class for the reporting API's""" | ||
|
||
def to_api_response(self, res): | ||
"""Converts results into an Api response obj""" | ||
status = res.status_code | ||
if status == 429: | ||
return {"success": False, "error": "rate_limited"} | ||
elif status == 401: | ||
return {"success": False, "error": "invalid_token"} | ||
elif status == 200: | ||
try: | ||
return json.loads(res.text) | ||
except Exception as e: | ||
logger.debug(e) | ||
logger.debug(res.text) | ||
return {"success": False, "error": "unknown_error"} | ||
|
||
def report(self, token, event, timeout_in_sec): | ||
"""Report event to aikido server""" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
""" | ||
Exports the HTTP API class | ||
""" | ||
|
||
import requests | ||
from aikido_firewall.background_process.api import ReportingApi | ||
from aikido_firewall.helpers.logging import logger | ||
|
||
|
||
class ReportingApiHTTP(ReportingApi): | ||
"""HTTP Reporting API""" | ||
|
||
def __init__(self, reporting_url): | ||
self.reporting_url = reporting_url | ||
|
||
def report(self, token, event, timeout_in_sec): | ||
try: | ||
res = requests.post( | ||
self.reporting_url + "api/runtime/events", | ||
json=event, | ||
timeout=timeout_in_sec, | ||
headers=get_headers(token), | ||
) | ||
except requests.exceptions.ConnectionError: | ||
return {"success": False, "error": "timeout"} | ||
except Exception as e: | ||
logger.error(e) | ||
return self.to_api_response(res) | ||
|
||
|
||
def get_headers(token): | ||
"""Returns headers""" | ||
return {"Content-Type": "application/json", "Authorization": str(token)} | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
import pytest | ||
from aikido_firewall.background_process.api import ReportingApi | ||
|
||
# Test ReportingApi Class : | ||
from requests.models import Response | ||
|
||
|
||
@pytest.fixture | ||
def reporting_api(): | ||
return ReportingApi() | ||
|
||
|
||
def test_to_api_response_rate_limited(reporting_api): | ||
res = Response() | ||
res.status_code = 429 | ||
assert reporting_api.to_api_response(res) == { | ||
"success": False, | ||
"error": "rate_limited", | ||
} | ||
|
||
|
||
def test_to_api_response_invalid_token(reporting_api): | ||
res = Response() | ||
res.status_code = 401 | ||
assert reporting_api.to_api_response(res) == { | ||
"success": False, | ||
"error": "invalid_token", | ||
} | ||
|
||
|
||
def test_to_api_response_unknown_error(reporting_api): | ||
res = Response() | ||
res.status_code = 500 # Simulating an unknown error status code | ||
assert reporting_api.to_api_response(res) == { | ||
"success": False, | ||
"error": "unknown_error", | ||
} | ||
|
||
|
||
def test_to_api_response_valid_json(reporting_api): | ||
res = Response() | ||
res.status_code = 200 | ||
res._content = b'{"key": "value"}' # Simulating valid JSON response | ||
assert reporting_api.to_api_response(res) == {"key": "value"} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
""" | ||
The code to send out a heartbeat is in here | ||
""" | ||
|
||
from aikido_firewall.helpers.logging import logger | ||
|
||
|
||
def send_heartbeats_every_x_secs(reporter, interval_in_secs, event_scheduler): | ||
""" | ||
Start sending out heartbeats every x seconds | ||
""" | ||
if reporter.serverless: | ||
logger.debug("Running in serverless environment, not starting heartbeats") | ||
return | ||
if not reporter.token: | ||
logger.debug("No token provided, not starting heartbeats") | ||
return | ||
|
||
logger.debug("Starting heartbeats") | ||
|
||
event_scheduler.enter( | ||
0, 1, send_heartbeat_wrapper, (reporter, interval_in_secs, event_scheduler) | ||
) | ||
|
||
|
||
def send_heartbeat_wrapper(rep, interval_in_secs, event_scheduler): | ||
""" | ||
Wrapper function for send_heartbeat so we get an interval | ||
""" | ||
event_scheduler.enter( | ||
interval_in_secs, | ||
1, | ||
send_heartbeat_wrapper, | ||
(rep, interval_in_secs, event_scheduler), | ||
) | ||
logger.debug("Heartbeat...") | ||
rep.send_heartbeat() | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.