mirror of
https://github.com/FAUSheppy/atlantis-event-dispatcher
synced 2025-12-06 06:21:36 +01:00
feat: direct token auth & webhook path auth support
This commit is contained in:
@@ -12,7 +12,7 @@ import json
|
||||
HTTP_NOT_FOUND = 404
|
||||
|
||||
DISPATCH_SERVER = None
|
||||
AUTH = None
|
||||
DISPATCH_ACCESS_TOKEN = None
|
||||
|
||||
def debug_send(uuid, data, fail_it=False):
|
||||
'''Dummy function to print and ack a dispatch for debugging'''
|
||||
@@ -92,7 +92,7 @@ def report_failed_dispatch(uuid, error):
|
||||
'''Inform the server that the dispatch has failed'''
|
||||
|
||||
payload = [{ "uuid" : uuid, "error" : error }]
|
||||
response = requests.post(DISPATCH_SERVER + "/report-dispatch-failed", json=payload, auth=AUTH)
|
||||
response = requests.post(DISPATCH_SERVER + "/report-dispatch-failed", json=payload)
|
||||
|
||||
if response.status_code not in [200, 204]:
|
||||
print("Failed to report back failed dispatch for {} ({})".format(
|
||||
@@ -102,7 +102,7 @@ def confirm_dispatch(uuid):
|
||||
'''Confirm to server that message has been dispatched and can be removed'''
|
||||
|
||||
payload = [{ "uuid" : uuid }]
|
||||
response = requests.post(DISPATCH_SERVER + "/confirm-dispatch", json=payload, auth=AUTH)
|
||||
response = requests.post(DISPATCH_SERVER + "/confirm-dispatch", json=payload)
|
||||
|
||||
if response.status_code not in [200, 204]:
|
||||
print("Failed to confirm dispatch with server for {} ({})".format(
|
||||
@@ -115,8 +115,7 @@ if __name__ == "__main__":
|
||||
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
|
||||
|
||||
parser.add_argument('--dispatch-server')
|
||||
parser.add_argument('--dispatch-user')
|
||||
parser.add_argument('--dispatch-password')
|
||||
parser.add_argument('--dispatch-access-token')
|
||||
|
||||
parser.add_argument('--ntfy-api-server')
|
||||
parser.add_argument('--ntfy-api-token')
|
||||
@@ -136,12 +135,11 @@ if __name__ == "__main__":
|
||||
|
||||
|
||||
dispatch_server = args.dispatch_server or os.environ.get("DISPATCH_SERVER")
|
||||
dispatch_user = args.dispatch_user or os.environ.get("DISPATCH_USER")
|
||||
dispatch_password = args.dispatch_password or os.environ.get("DISPATCH_PASSWORD")
|
||||
dispatch_access_token = args.dispatch_access_token or os.environ.get("DISPATCH_ACCESS_TOKEN")
|
||||
|
||||
# set dispatch server & authentication global #
|
||||
DISPATCH_SERVER = dispatch_server
|
||||
AUTH = (dispatch_user, dispatch_password)
|
||||
DISPATCH_ACCESS_TOKEN = dispatch_access_token
|
||||
|
||||
ntfy_api_server = args.ntfy_api_server or os.environ.get("NTFY_API_SERVER")
|
||||
ntfy_api_token = args.ntfy_api_token or os.environ.get("NTFY_API_TOKEN")
|
||||
@@ -159,7 +157,8 @@ if __name__ == "__main__":
|
||||
while args.loop or first_run:
|
||||
|
||||
# request dispatches #
|
||||
response = requests.get(dispatch_server + "/get-dispatch?method=all&timeout=0", auth=AUTH)
|
||||
response = requests.get(dispatch_server +
|
||||
"/get-dispatch?method=all&timeout=0&dispatch-access-token={}".format(DISPATCH_ACCESS_TOKEN))
|
||||
|
||||
# check status #
|
||||
if response.status_code == HTTP_NOT_FOUND:
|
||||
|
||||
@@ -25,6 +25,15 @@ app = flask.Flask("Signal Notification Gateway")
|
||||
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///sqlite.db"
|
||||
db = SQLAlchemy(app)
|
||||
|
||||
BAD_DISPATCH_ACCESS_TOKEN = "Invalid or missing dispatch-access-token parameter in URL"
|
||||
|
||||
class WebHookPaths(db.Model):
|
||||
|
||||
__tablename__ = "webhook_paths"
|
||||
|
||||
username = Column(String, primary_key=True)
|
||||
path = Column(String, primary_key=True)
|
||||
|
||||
class UserSettings(db.Model):
|
||||
|
||||
__tablename__ = "user_settings"
|
||||
@@ -153,6 +162,10 @@ def get_dispatch():
|
||||
timeout = flask.request.args.get("timeout") or 5 # timeout in seconds
|
||||
timeout = int(timeout)
|
||||
|
||||
dispatch_acces_token = flask.request.args.get("dispatch-access-token") or ""
|
||||
if dispatch_acces_token != app.config["DISPATCH_ACCESS_TOKEN"]:
|
||||
return (BAD_DISPATCH_ACCESS_TOKEN, 401)
|
||||
|
||||
if not method:
|
||||
return (500, "Missing Dispatch Target (signal|email|phone|ntfy|all|any)")
|
||||
|
||||
@@ -259,8 +272,9 @@ def confirm_dispatch():
|
||||
return ("", 204)
|
||||
|
||||
|
||||
@app.route('/smart-send/<path:path>', methods=["POST"])
|
||||
@app.route('/smart-send', methods=["POST"])
|
||||
def smart_send_to_clients():
|
||||
def smart_send_to_clients(path=None):
|
||||
'''Send to clients based on querying the LDAP
|
||||
requests MAY include:
|
||||
- list of usernames under key "users"
|
||||
@@ -280,6 +294,19 @@ def smart_send_to_clients():
|
||||
title = instructions.get("title")
|
||||
method = instructions.get("method")
|
||||
|
||||
# authenticated by access token or webhook path #
|
||||
dispatch_acces_token = flask.request.args.get("dispatch-access-token") or ""
|
||||
print(path)
|
||||
if path:
|
||||
webhook_path = db.session.query(WebHookPaths).filter(WebHookPaths.path==path).first()
|
||||
if webhook_path:
|
||||
users = webhook_path.username
|
||||
groups = None
|
||||
else:
|
||||
return ("Invalid Webhook path", 401)
|
||||
elif dispatch_acces_token != app.config["DISPATCH_ACCESS_TOKEN"]:
|
||||
return (BAD_DISPATCH_ACCESS_TOKEN, 401)
|
||||
|
||||
# allow single use string instead of array #
|
||||
if type(users) == str:
|
||||
users = [users]
|
||||
@@ -346,6 +373,7 @@ def create_app():
|
||||
}
|
||||
app.config["LDAP_ARGS"] = ldap_args
|
||||
app.config["SETTINGS_ACCESS_TOKEN"] = os.environ["SETTINGS_ACCESS_TOKEN"]
|
||||
app.config["DISPATCH_ACCESS_TOKEN"] = os.environ["DISPATCH_ACCESS_TOKEN"]
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -363,6 +391,7 @@ if __name__ == "__main__":
|
||||
parser.add_argument('--ldap-manager-password')
|
||||
|
||||
parser.add_argument('--settings-access-token')
|
||||
parser.add_argument('--dispatch-access-token')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
@@ -376,6 +405,7 @@ if __name__ == "__main__":
|
||||
app.config["LDAP_NO_READ_ENV"] = True
|
||||
|
||||
app.config["SETTINGS_ACCESS_TOKEN"] = args.settings_access_token
|
||||
app.config["DISPATCH_ACCESS_TOKEN"] = args.dispatch_access_token
|
||||
|
||||
if not any([value is None for value in ldap_args.values()]):
|
||||
app.config["LDAP_ARGS"] = ldap_args
|
||||
|
||||
@@ -51,8 +51,8 @@ if __name__ == "__main__":
|
||||
signal_cli_bin = args.signal_cli_bin
|
||||
|
||||
# request dispatches #
|
||||
response = requests.get(args.target + "/get-dispatch?method={}".format(args.method),
|
||||
auth=(args.user, args.password))
|
||||
response = requests.get(args.target +
|
||||
"/get-dispatch?method={}&dispatch-access-token={}".format(args.method), args.password)
|
||||
|
||||
# check status #
|
||||
if response.status_code == HTTP_NOT_FOUND:
|
||||
|
||||
Reference in New Issue
Block a user