forked from KaindorfCTF/ctfd-notifier
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathblueprint.py
143 lines (121 loc) · 5.07 KB
/
blueprint.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
from CTFd.utils.challenges import get_all_challenges
from flask import request, render_template, Blueprint, abort, redirect
from .db_utils import DBAchievements, DBUtils
from CTFd.utils.decorators import admins_only, authed_only
import requests as rq
import tweepy
from .hooks import discord_achievement_notify
notifier_bp = Blueprint("notifier", __name__, template_folder="templates")
def load_bp(plugin_route):
@notifier_bp.route(plugin_route, methods=["GET"])
@admins_only
def get_config():
config = DBUtils.get_config()
achievements = DBAchievements.get_all_achievements()
challenges = get_all_challenges(admin=True)
user_achievements = DBAchievements.get_all_unlocked_achievements()
return render_template(
"ctfd_notifier/config.html",
config=config,
achievements=achievements,
user_achievements=user_achievements,
challenges=challenges,
)
@notifier_bp.route(plugin_route, methods=["POST"])
@admins_only
def update_config():
config = request.form.to_dict()
del config["nonce"]
errors = test_config(config)
if len(errors) > 0:
return render_template(
"ctfd_notifier/config.html", config=DBUtils.get_config(), errors=errors
)
else:
DBUtils.save_config(config.items())
return render_template(
"ctfd_notifier/config.html", config=DBUtils.get_config()
)
@notifier_bp.route(plugin_route + "/achievements", methods=["POST"])
@admins_only
def create_achievement():
achievement = request.form.to_dict()
achievement["enabled"] = (
True if achievement.get("enabled", "off") == "on" else False
)
del achievement["nonce"]
chal_ids = request.form.getlist("chall_ids") or []
achievement["chall_ids"] = [int(x.strip()) for x in chal_ids]
# Validate here maybe?
DBAchievements.create_achievement(**achievement)
return redirect("/admin/notifier", code=302)
@notifier_bp.route(plugin_route + "/achievements/delete", methods=["POST"])
@admins_only
def delete_achievement():
achievement = request.form.to_dict()
achievement_id = int(achievement["id"])
DBAchievements.delete_achievement(id=achievement_id)
return redirect("/admin/notifier", code=302)
@notifier_bp.route(plugin_route + "/achievements/toggle_enabled", methods=["POST"])
@admins_only
def toggle_enabled_achievement():
achievement = request.form.to_dict()
achievement_id = int(achievement["id"])
DBAchievements.toggle_enabled(id=achievement_id)
return redirect("/admin/notifier", code=302)
@notifier_bp.route(plugin_route + "/achievements/run", methods=["POST"])
@admins_only
def achievements_run():
achievements = DBAchievements.create_achievements_for_all_users()
print(achievements)
return redirect("/admin/notifier", code=302)
@notifier_bp.route(plugin_route + "/achievements/notify", methods=["POST"])
@admins_only
def achievements_notify():
form = request.form.to_dict()
config = DBUtils.get_config()
user_achievement = DBAchievements.get_user_achievelent_relation(
form["achievement_user"], form["achievement_id"]
)
DBAchievements.update_user_achievement(
form["achievement_user"], form["achievement_id"], {"notified": True}
)
discord_achievement_notify(
user_achievement[-1],
user_achievement[-2],
config.get("discord_webhook_url"),
)
return redirect("/admin/notifier", code=302)
return notifier_bp
def test_config(config):
errors = list()
if "discord_notifier" in config:
if config["discord_notifier"]:
webhookurl = config["discord_webhook_url"]
if not webhookurl.startswith(
"https://discordapp.com/api/webhooks/"
) and not webhookurl.startswith("https://discord.com/api/webhooks"):
errors.append("Invalid Webhook URL!")
else:
try:
r = rq.get(webhookurl)
if not r.status_code == 200:
errors.append("Could not verify that the Webhook is working!")
except rq.exceptions.RequestException as e:
errors.append("Invalid Webhook URL!")
if "twitter_notifier" in config:
if config["twitter_notifier"]:
try:
AUTH = tweepy.OAuthHandler(
config.get("twitter_consumer_key"),
config.get("twitter_consumer_secret"),
)
AUTH.set_access_token(
config.get("twitter_access_token"),
config.get("twitter_access_token_secret"),
)
API = tweepy.API(AUTH)
API.home_timeline()
except tweepy.TweepError:
errors.append("Invalid authentication Data!")
return errors