-
Notifications
You must be signed in to change notification settings - Fork 6
/
Copy pathprofiles.py
263 lines (199 loc) · 7.1 KB
/
profiles.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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
import fnmatch
from errbot import BotPlugin, botcmd, cmdfilter
BLOCK_COMMAND = (None, None, None)
def get_acl_usr(msg):
if hasattr(msg.frm, 'aclattr'):
return msg.frm.aclattr
return msg.frm.person
def canonize_cmd(cmd_str):
"""
Canonize the command string into 'plugin:command' format
"""
if ':' in cmd_str:
return cmd_str
return '*:' + cmd_str
class Profiles(BotPlugin):
"""
ACLs with user and group management
"""
def activate(self):
super().activate()
if 'groups' not in self:
self['groups'] = {}
if 'access' not in self:
self['access'] = {}
@cmdfilter
def acls(self, msg, cmd, args, dry_run):
cmd_str = "{plugin}:{command}".format(
plugin=self._bot.all_commands[cmd].__self__.name,
command=cmd)
# Get groups allowed to access the command
restricted = False
groups = []
for access, group in self['access'].items():
if fnmatch.fnmatch(cmd_str, access):
restricted = True
groups.extend(group)
# Check if the command is in the access list
if not restricted:
return (msg, cmd, args)
usr = get_acl_usr(msg)
# Check if user is in the groups allowed to access
for group, users in self['groups'].items():
if group in groups:
if usr in users:
return (msg, cmd, args)
# Check if the user is a bot admin
if usr in self.bot_config.BOT_ADMINS:
return (msg, cmd, args)
if not dry_run and not self.bot_config.HIDE_RESTRICTED_ACCESS:
self._bot.send_simple_reply(msg, "You're not allowed to access this command")
return BLOCK_COMMAND
@botcmd(template="access_list")
def access_list(self, msg, args):
"""
Show the access list
"""
summary = []
if self['access']:
summary = [ (access, ' '.join(groups)) for access, groups in self['access'].items() ]
return {'summary': summary}
@botcmd
def access_add(self, msg, cmd_str):
"""
Add an entrie to the access list
"""
if not cmd_str:
return 'usage: !access add <cmd>'
command = canonize_cmd(cmd_str)
# Check if plugin or cmd match existing plugin or command
match = False
for c in self._bot.all_commands:
cmd = "{plugin}:{command}".format(
plugin=self._bot.all_commands[c].__self__.name,
command=c)
if fnmatch.fnmatch(cmd, command):
match = True
break
if not match:
return 'pattern does not match any command'
with self.mutable('access') as access:
if command not in access:
access[command] = []
else:
return 'command already in access list'
return 'command added to the access list'
@botcmd
def access_del(self, msg, cmd_str):
"""
Remove an entrie of the access list
"""
if not cmd_str:
return 'usage: !access del <cmd>'
command = canonize_cmd(cmd_str)
with self.mutable('access') as access:
if command not in access:
return 'command wasnt there in the first place'
else:
del access[command]
return 'command was removed of the access list'
@botcmd(split_args_with=None)
def access_add_group(self, msg, args):
"""
Add a group to an entrie of the access list
"""
if not args or not len(args) == 2:
return 'usage: !access add group <cmd> <group>'
cmd_str = args[0]
group = args[1]
command = canonize_cmd(cmd_str)
with self.mutable('access') as access:
if command not in access:
return 'command not present in the access list'
# TODO: check if the group exists
access[command].append(group)
return 'group added to the access list'
@botcmd(split_args_with=None)
def access_del_group(self, msg, args):
"""
Add a group to an entrie of the access list
"""
if not args or not len(args) == 2:
return 'usage: !access del group <cmd> <group>'
cmd_str = args[0]
group = args[1]
command = canonize_cmd(cmd_str)
with self.mutable('access') as access:
if command not in access:
return 'command not present in the access list'
if group not in access[command]:
return 'group wasnt there in the first place'
access[command].remove(group)
return 'group removed from the access list'
@botcmd(template='group_list')
def group_list(self, msg, args):
"""
Show the group list
"""
summary = []
if self['groups']:
summary = [ (group, ' '.join(users)) for group, users in self['groups'].items() ]
return {'summary': summary}
@botcmd
def group_add(self, msg, group):
"""
Add a group to the group list
"""
if not group:
return 'usage: !group add <group>'
with self.mutable('groups') as groups:
if group not in groups:
groups[group] = []
else:
return 'group already in the group list'
return 'group added to the group list'
@botcmd
def group_del(self, msg, group):
"""
Remove a group from the group list
"""
if not group:
return 'usage: !group del <group>'
with self.mutable('groups') as groups:
if group not in groups:
return 'group wasnt there in the first place'
else:
del groups[group]
return 'group removed from the group list'
@botcmd(split_args_with=None)
def group_add_user(self, msg, args):
"""
Add a user to a group
"""
if not args or not len(args) == 2:
return 'usage: !group add user <group> <user>'
group = args[0]
user = args[1]
with self.mutable('groups') as groups:
if group not in groups:
return 'group not present in the group list'
if user in groups[group]:
return 'user already in the group'
groups[group].append(user)
return 'user was added to the group'
@botcmd(split_args_with=None)
def group_del_user(self, msg, args):
"""
Remove user from a group
"""
if not args or not len(args) == 2:
return 'usage: !group del user <group> <user>'
group = args[0]
user = args[1]
with self.mutable('groups') as groups:
if group not in groups:
return 'group not present in the group list'
if user not in groups[group]:
return 'user wasnt there in the first place'
groups[group].remove(user)
return 'user was removed from the group'