2 # Copyright (c) 2016-2021 by Someone <someone@somenet.org> (aka. Jan Vales <jan@jvales.net>)
3 # published under MIT-License
6 class RequireException(Exception):
7 """Required precondition not met-exception. Mostly used for permission checks. Message will be forwarded to command-caller/user"""
10 class AbstractCommand():
14 CONFIG = {"display_name": "somebot-command", "auto_complete": True}
18 mm_secret_token = None
21 def __init__(self, team_id):
22 self.TEAM_ID = team_id
25 return str(self.__class__)+" for team_id: "+str(self.TEAM_ID)
31 # can/should be overridden by the user
32 def on_register(self):
33 """Consider to override. Handles the post-command-registration logic at bot startup."""
34 self._create_slash_command()
36 # can/should be overridden by the user
37 def on_shutdown(self):
38 """Consider to override. Handles the shutdown-procedure."""
41 # can/should be overridden by the user
42 def on_SIGUSR1(self, sigusr1_cnt):
43 """Consider to override. Handles the SIGUSR1-signal."""
46 # should be overridden by the user
47 def on_POST(self, request, data):
48 """Override. Handles the post-command logic."""
51 # should be overridden by the user
52 # manual command authentication needed!
53 def on_POST_interactive(self, request, data):
54 """Consider to override. Handles the interactive-message logic."""
57 # should be overridden by the user
58 # manual command authentication needed!
59 def on_POST_dialog(self, request, data):
60 """Consider to override. Handles the dialog logic."""
64 def _on_register(self, bot):
66 self.URL = self.bot.local_websrv_url+"/"+self.TEAM_ID+"/"+self.TRIGGER
68 self.bot.USETOPICS.setdefault("/"+self.TRIGGER, self.USEINFO)
72 def _on_shutdown(self):
76 def _on_SIGUSR1(self, sigusr1_cnt):
77 self.on_SIGUSR1(sigusr1_cnt)
80 def _on_POST(self, request, data):
82 self._require_not_guest(data)
83 self.on_POST(request, data)
84 except RequireException as ex:
85 request.cmd_respond_text_temp(str(ex))
88 def _on_POST_interactive(self, request, data):
90 self._require_not_guest(data)
91 self.on_POST_interactive(request, data)
92 except RequireException as ex:
93 request.cmd_respond_text_temp(str(ex))
96 def _on_POST_dialog(self, request, data):
98 self._require_not_guest(data)
99 self.on_POST_dialog(request, data)
100 except RequireException as ex:
101 request.cmd_respond_text_temp(str(ex))
104 def _create_slash_command(self):
105 # (possibly) delete old version of command
106 for command in self.bot.api.list_custom_slash_commands_for_team(self.TEAM_ID):
107 if command["url"] == self.URL or command["trigger"].lower() == self.TRIGGER.lower():
108 self.bot.api.delete_slash_command(command["id"])
110 # create slash command
111 res = self.bot.api.create_slash_command(self.TEAM_ID, self.TRIGGER.lower(), self.URL+"/command")
112 res.update(self.CONFIG)
113 self.bot.api.update_slash_command(res)
114 self.mm_secret_token = res["token"]
117 def _require_bot_admin(self, data):
119 Require exactly bot admin priviledges.
120 Throws RequireException if not priviledged.
122 if not data["user_id"] in self.bot.admin_ids:
123 raise RequireException("### Leave me alone. You are not by real dad.")
126 def _require_system_admin(self, data, exc=True):
128 Require at least team admin priviledges.
129 Throws RequireException if not priviledged.
131 user = self.bot.api.get_user(data["user_id"])
132 if "system_admin" not in user["roles"]:
134 raise RequireException("### You are not SYSTEM_ADMIN. :(")
139 def _require_team_admin(self, data, exc=True):
141 Require at least team admin priviledges.
142 Throws RequireException if not priviledged.
144 team_member = self.bot.api.get_team_member(data["team_id"], data["user_id"])
145 if "team_admin" not in team_member["roles"] and not self._require_system_admin(data, exc=False):
147 raise RequireException("### You are not TEAM_ADMIN. :(")
152 def _require_channel_admin(self, data, exc=True):
154 Require at least channel admin priviledges.
155 Throws RequireException if not priviledged.
157 channel_member = self.bot.api.get_channel_member(data["channel_id"], data["user_id"])
158 if "channel_admin" not in channel_member["roles"] and not self._require_team_admin(data, exc=False):
160 raise RequireException("### You are not CHANNEL_ADMIN. :(")
165 def _require_not_guest(self, data, exc=True):
167 Require to not be a guest.
168 Throws RequireException if guest.
170 channel_member = self.bot.api.get_channel_member(data["channel_id"], data["user_id"])
171 if "channel_guest" in channel_member["roles"]:
173 raise RequireException("### The bot cannot be used by guests. :(")