-
Notifications
You must be signed in to change notification settings - Fork 0
/
botserver.py
130 lines (104 loc) · 3.73 KB
/
botserver.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
import json
import os
import threading
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
from bottypes.invalid_console_command import InvalidConsoleCommand
from handlers import *
from handlers import handler_factory
from util.loghandler import log
from util.slack_wrapper import SlackWrapper
from util.storage_service import StorageService
class BotServer:
# Global lock for locking global data in bot server
thread_lock = threading.Lock()
def __init__(self):
log.debug("Parse config file and initialize threading...")
self.running = False
self.config = {}
self.load_config()
self.slack_wrapper = SlackWrapper()
self.storage_service = StorageService()
self.init_bot_data()
def lock(self):
"""Acquire global lock for working with global (not thread-safe) data."""
BotServer.thread_lock.acquire()
def release(self):
"""Release global lock after accessing global (not thread-safe) data."""
BotServer.thread_lock.release()
def quit(self):
"""Inform the application that it is quitting."""
log.info("Shutting down")
self.running = False
def load_config(self):
"""Load configuration file."""
self.lock()
with open("./config/config.json") as f:
self.config = json.load(f)
self.release()
def get_config_option(self, option):
"""Get configuration option."""
self.lock()
result = self.config.get(option)
self.release()
return result
def set_config_option(self, option, value):
"""Set configuration option."""
self.lock()
try:
if option in self.config:
self.config[option] = value
log.info("Updated configuration: %s => %s", option, value)
with open("./config/config.json", "w") as f:
json.dump(self.config, f, indent=4)
else:
raise InvalidConsoleCommand(
"The specified configuration option doesn't exist: {}".format(
option
)
)
finally:
self.release()
def parse_slack_message(self, msg):
"""
Return (message, channel, ts, user) if the message is directed at the bot,
otherwise return (None, None, None, None).
"""
return (
msg.get("command").strip("/") if msg.get("command") else None,
msg.get("text"),
msg.get("channel_id"),
msg.get("thread_ts") if "thread_ts" in msg else msg.get("ts"),
msg.get("user_id"),
)
def init_bot_data(self):
self.running = True
log.info("Initializing handlers...")
handler_factory.initialize(self.slack_wrapper, self, self.storage_service)
def handle_message(self, body):
command, params, channel, time_stamp, user = self.parse_slack_message(body)
try:
log.info(
"Received bot command: %s %s from %s (%s)",
command,
params,
user,
channel,
)
handler_factory.process(
self.slack_wrapper, self.storage_service, command, params, time_stamp, channel, user
)
except Exception as e:
log.exception(e)
app = App(token=os.environ.get("SLACK_BOT_TOKEN"))
botserver = BotServer()
@app.command("/admin")
@app.command("/bot")
@app.command("/ctf")
@app.command("/syscalls")
def handle_message(ack, body):
ack()
botserver.handle_message(body)
if __name__ == "__main__":
handler = SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"])
handler.start()