aboutsummaryrefslogtreecommitdiff
path: root/src/core_modules/channel_access.py
blob: a8c371a85f99f0aaea6370973f442b88964af4eb (about) (plain) (blame)
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
#--depends-on check_mode
#--depends-on commands
#--depends-on permissions

from src import ModuleManager, utils

SPECIAL = ["low", "high", "admin"]

class Module(ModuleManager.BaseModule):
    _name = "ChanAccess"

    def _has_channel_access(self, target, user, names):
        required_access = []
        for name in names.split(","):
            name = name.strip()

            if name in SPECIAL:
                required_access.extend(SPECIAL[:SPECIAL.index(name)+1])
            else:
                required_access.append(name)


        user_access = target.get_user_setting(user.get_id(), "access", [])
        identified = self.exports.get("is-identified")(user)
        matched = list(set(required_access)&set(user_access))

        return ("*" in user_access or matched) and identified

    def _command_check(self, event, channel, require_access):
        if channel:
            if self._has_channel_access(channel, event["user"],
                    require_access):
                return utils.consts.PERMISSION_FORCE_SUCCESS, None
            else:
                return (utils.consts.PERMISSION_ERROR,
                        "You do not have permission to do this")
        else:
            raise ValueError("_command_check requires a channel")

    @utils.hook("preprocess.command")
    def preprocess_command(self, event):
        require_access = event["hook"].get_kwarg("require_access")
        if require_access:
            channel = event["kwargs"].get("channel",
                event["target"] if event["is_channel"] else None)
            return self._command_check(event, channel, require_access)

    @utils.hook("check.command.channel-access")
    def check_command(self, event):
        target = event["target"]
        access = event["request_args"][0]
        if len(event["request_args"]) > 1:
            target = event["request_args"][0]
            access = event["request_args"][1]

        return self._command_check(event, target, access)

    @utils.hook("received.command.access")
    @utils.kwarg("require_mode", "high")
    @utils.spec("!<#channel>r~channel !'list !<nickname>ouser")
    @utils.spec("!<#channel>r~channel !'add,remove,set !<nickname>ouser "
        "!<permissions>string")
    def access(self, event):
        channel = event["spec"][0]
        subcommand = event["spec"][1].lower()
        target = event["spec"][2]
        access = channel.get_user_setting(target.get_id(), "access", [])

        if subcommand == "list":
            event["stdout"].write("Access for %s: %s" % (target.nickname,
                " ".join(access)))
        elif subcommand == "set":
            channel.set_user_setting(target.get_id(), "access",
                event["spec"][3])
        elif subcommand == "add":
            for acc in event["spec"][3].split(" "):
                if acc in access:
                    raise utils.EventError("%s already has '%s' permission" % (
                        target.nickname, acc))
                access.append(acc)
            channel.set_user_setting(target.get_id(), "access", access)
            event["stdout"].write("Added permission to %s: %s" % (
                target.nickname, event["spec"][3]))
        elif subcommand == "remove":
            for acc in event["spec"][3].split(" "):
                if not acc in access:
                    raise utils.EventError("%s does not have '%s' permission" %
                        (target.nickname, acc))
                access.remove(acc)
            if access:
                channel.set_user_setting(target.get_id(), "access",
                    access)
            else:
                channel.del_user_setting(target.get_id(), "access")
            event["stdout"].write("Removed permission from %s: %s" % (
                target.nickname, event["spec"][3]))
        else:
            event["stderr"].write("Unknown command '%s'" % subcommand)