Browse Source

Add auth for commands

tags/v0.1.0
Russ Garrett 7 years ago
parent
commit
60870c31e9
No account linked to committer's email address
3 changed files with 102 additions and 62 deletions
  1. 33
    0
      auth.go
  2. 61
    0
      command.go
  3. 8
    62
      main.go

+ 33
- 0
auth.go View File

@@ -0,0 +1,33 @@
1
+package main
2
+
3
+import (
4
+	"github.com/spf13/viper"
5
+	"github.com/thoj/go-ircevent"
6
+	"strings"
7
+)
8
+
9
+func (i *IRCCat) authorisedUser(nick string) bool {
10
+	_, exists := i.auth_users[nick]
11
+	return exists
12
+}
13
+
14
+func (i *IRCCat) handleJoin(e *irc.Event) {
15
+	if e.Arguments[0] == viper.GetString("commands.auth_channel") {
16
+		i.auth_users[e.Nick] = true
17
+	}
18
+}
19
+
20
+func (i *IRCCat) handlePart(e *irc.Event) {
21
+	if e.Arguments[0] == viper.GetString("commands.auth_channel") {
22
+		delete(i.auth_users, e.Nick)
23
+	}
24
+}
25
+
26
+func (i *IRCCat) handleNames(e *irc.Event) {
27
+	if e.Arguments[2] == viper.GetString("commands.auth_channel") {
28
+		nicks := strings.Split(e.Arguments[3], " ")
29
+		for _, nick := range nicks {
30
+			i.auth_users[nick] = true
31
+		}
32
+	}
33
+}

+ 61
- 0
command.go View File

@@ -0,0 +1,61 @@
1
+package main
2
+
3
+import (
4
+	"bytes"
5
+	"github.com/spf13/viper"
6
+	"github.com/thoj/go-ircevent"
7
+	"os/exec"
8
+	"strings"
9
+)
10
+
11
+func (i *IRCCat) handleCommand(event *irc.Event) {
12
+	msg := event.Message()
13
+	channel := ""
14
+	respond_to := event.Arguments[0]
15
+	if respond_to[0] != '#' {
16
+		respond_to = event.Nick
17
+	} else {
18
+		channel = respond_to
19
+	}
20
+
21
+	if event.Arguments[0][0] != '#' && !i.authorisedUser(event.Nick) {
22
+		// Command not in a channel, or not from an authorised user
23
+		log.Infof("Unauthorised command: %s (%s) %s", event.Nick, respond_to, msg)
24
+		return
25
+	}
26
+	log.Infof("Authorised command: %s (%s) %s", event.Nick, respond_to, msg)
27
+
28
+	parts := strings.SplitN(msg, " ", 1)
29
+
30
+	var cmd *exec.Cmd
31
+	if len(parts) == 1 {
32
+		cmd = exec.Command(viper.GetString("commands.handler"), event.Nick, channel, respond_to, parts[0][1:])
33
+	} else {
34
+		cmd = exec.Command(viper.GetString("commands.handler"), event.Nick, channel, respond_to, parts[0][1:], parts[1])
35
+	}
36
+	i.runCommand(cmd, respond_to)
37
+}
38
+
39
+// Run a command with the output going to the nick/channel identified by respond_to
40
+func (i *IRCCat) runCommand(cmd *exec.Cmd, respond_to string) {
41
+	var out bytes.Buffer
42
+	cmd.Stdout = &out
43
+	cmd.Stderr = &out
44
+	err := cmd.Run()
45
+	if err != nil {
46
+		log.Errorf("Running command %s failed: %s", cmd.Args, err)
47
+		i.irc.Privmsgf(respond_to, "Command failed: %s", err)
48
+	}
49
+
50
+	lines := strings.Split(out.String(), "\n")
51
+	line_count := len(lines)
52
+	if line_count > viper.GetInt("commands.max_response_lines") {
53
+		line_count = viper.GetInt("commands.max_response_lines")
54
+	}
55
+
56
+	for _, line := range lines[0:line_count] {
57
+		if line != "" {
58
+			i.irc.Privmsg(respond_to, line)
59
+		}
60
+	}
61
+}

+ 8
- 62
main.go View File

@@ -1,7 +1,6 @@
1 1
 package main
2 2
 
3 3
 import (
4
-	"bytes"
5 4
 	"crypto/tls"
6 5
 	"fmt"
7 6
 	"github.com/irccloud/irccat/httplistener"
@@ -10,9 +9,7 @@ import (
10 9
 	"github.com/spf13/viper"
11 10
 	"github.com/thoj/go-ircevent"
12 11
 	"os"
13
-	"os/exec"
14 12
 	"os/signal"
15
-	"strings"
16 13
 	"syscall"
17 14
 )
18 15
 
@@ -20,6 +17,7 @@ var log = loggo.GetLogger("main")
20 17
 
21 18
 type IRCCat struct {
22 19
 	control_chan string
20
+	auth_users   map[string]bool
23 21
 	irc          *irc.Connection
24 22
 	tcp          *tcplistener.TCPListener
25 23
 	signals      chan os.Signal
@@ -38,9 +36,8 @@ func main() {
38 36
 		log.Errorf("Error reading config file - exiting. I'm looking for irccat.[json|yaml|toml|hcl] in . or /etc")
39 37
 		return
40 38
 	}
39
+	irccat := IRCCat{auth_users: map[string]bool{}, signals: make(chan os.Signal, 1)}
41 40
 
42
-	irccat := IRCCat{}
43
-	irccat.signals = make(chan os.Signal, 1)
44 41
 	signal.Notify(irccat.signals, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
45 42
 	go irccat.signalHandler()
46 43
 
@@ -71,10 +68,9 @@ func (i *IRCCat) signalHandler() {
71 68
 
72 69
 func (i *IRCCat) connectIRC() error {
73 70
 	irccon := irc.IRC(viper.GetString("irc.nick"), viper.GetString("irc.realname"))
74
-	irccon.Debug = true
75 71
 	irccon.UseTLS = viper.GetBool("irc.tls")
76 72
 	if viper.GetBool("irc.tls_skip_verify") {
77
-		irccon.TLSConfig = &tls.Config{InsecureSkipVerify: true, MaxVersion: tls.VersionTLS11}
73
+		irccon.TLSConfig = &tls.Config{InsecureSkipVerify: true}
78 74
 	}
79 75
 
80 76
 	err := irccon.Connect(viper.GetString("irc.server"))
@@ -89,67 +85,17 @@ func (i *IRCCat) connectIRC() error {
89 85
 		}
90 86
 	})
91 87
 
88
+	irccon.AddCallback("353", i.handleNames)
89
+	irccon.AddCallback("JOIN", i.handleJoin)
90
+	irccon.AddCallback("PART", i.handlePart)
91
+	irccon.AddCallback("QUIT", i.handlePart)
92
+
92 93
 	i.irc = irccon
93 94
 	return nil
94 95
 }
95 96
 
96
-func (i *IRCCat) authorisedUser(nick string) bool {
97
-	return false
98
-}
99
-
100 97
 func (i *IRCCat) handleWelcome(e *irc.Event) {
101 98
 	for _, channel := range viper.GetStringSlice("irc.channels") {
102 99
 		i.irc.Join(channel)
103 100
 	}
104 101
 }
105
-
106
-func (i *IRCCat) handleCommand(event *irc.Event) {
107
-	msg := event.Message()
108
-	respond_to := event.Arguments[0]
109
-
110
-	if respond_to[0] != '#' && !i.authorisedUser(event.Nick) {
111
-		// Command not in a channel, or not from an authorised user
112
-		log.Infof("Unauthorised command: %s (%s) %s", event.Nick, respond_to, msg)
113
-		return
114
-	}
115
-	log.Infof("Authorised command: %s (%s) %s", event.Nick, respond_to, msg)
116
-
117
-	channel := ""
118
-	if respond_to[0] == '#' {
119
-		channel = respond_to
120
-	}
121
-
122
-	parts := strings.SplitN(msg, " ", 1)
123
-
124
-	var cmd *exec.Cmd
125
-	if len(parts) == 1 {
126
-		cmd = exec.Command(viper.GetString("commands.handler"), event.Nick, channel, respond_to, parts[0][1:])
127
-	} else {
128
-		cmd = exec.Command(viper.GetString("commands.handler"), event.Nick, channel, respond_to, parts[0][1:], parts[1])
129
-	}
130
-	i.runCommand(cmd, respond_to)
131
-}
132
-
133
-// Run a command with the output going to the nick/channel identified by respond_to
134
-func (i *IRCCat) runCommand(cmd *exec.Cmd, respond_to string) {
135
-	var out bytes.Buffer
136
-	cmd.Stdout = &out
137
-	cmd.Stderr = &out
138
-	err := cmd.Run()
139
-	if err != nil {
140
-		log.Errorf("Running command %s failed: %s", cmd.Args, err)
141
-		i.irc.Privmsgf(respond_to, "Command failed: %s", err)
142
-	}
143
-
144
-	lines := strings.Split(out.String(), "\n")
145
-	line_count := len(lines)
146
-	if line_count > viper.GetInt("commands.max_response_lines") {
147
-		line_count = viper.GetInt("commands.max_response_lines")
148
-	}
149
-
150
-	for _, line := range lines[0:line_count] {
151
-		if line != "" {
152
-			i.irc.Privmsg(respond_to, line)
153
-		}
154
-	}
155
-}

Loading…
Cancel
Save