-
Notifications
You must be signed in to change notification settings - Fork 0
/
version.go
104 lines (86 loc) · 2.57 KB
/
version.go
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
package xep0092
import (
"context"
"os/exec"
"strings"
"github.com/dantin/cubit/log"
"github.com/dantin/cubit/module/xep0030"
"github.com/dantin/cubit/router"
"github.com/dantin/cubit/util/runqueue"
"github.com/dantin/cubit/version"
"github.com/dantin/cubit/xmpp"
)
const versionNamespace = "jabber:iq:version"
var osString string
func init() {
out, _ := exec.Command("uname", "-rs").Output()
osString = strings.TrimSpace(string(out))
}
// Config represents XMPP Software Version module (XEP-0092) configuration.
type Config struct {
ShowOS bool `yaml:"show_os"`
}
// Version represents a version module.
type Version struct {
cfg *Config
router router.Router
runQueue *runqueue.RunQueue
}
// New returns a version IQ handler module.
func New(config *Config, disco *xep0030.DiscoInfo, router router.Router) *Version {
v := &Version{
cfg: config,
router: router,
runQueue: runqueue.New("xep0092"),
}
if disco != nil {
disco.RegisterServerFeature(versionNamespace)
}
return v
}
// MatchesIQ returns whether or not an IQ should be processed by the version module.
func (x *Version) MatchesIQ(iq *xmpp.IQ) bool {
return iq.IsGet() && iq.Elements().ChildNamespace("query", versionNamespace) != nil && iq.ToJID().IsServer()
}
// ProcessIQ processes a version IQ taking according actions over the associated stream.
func (x *Version) ProcessIQ(ctx context.Context, iq *xmpp.IQ) {
x.runQueue.Run(func() {
x.processIQ(ctx, iq)
})
}
// Shutdown shuts down version module.
func (x *Version) Shutdown() error {
c := make(chan struct{})
x.runQueue.Stop(func() { close(c) })
<-c
return nil
}
func (x *Version) processIQ(ctx context.Context, iq *xmpp.IQ) {
q := iq.Elements().ChildNamespace("query", versionNamespace)
if q == nil || q.Elements().Count() != 0 {
_ = x.router.Route(ctx, iq.BadRequestError())
return
}
x.sendSoftwareVersion(ctx, iq)
}
func (x *Version) sendSoftwareVersion(ctx context.Context, iq *xmpp.IQ) {
userJID := iq.FromJID()
username := userJID.Node()
resource := userJID.Resource()
log.Infof("retrieving software version: %v (%s/%s)", version.ApplicationVersion, username, resource)
result := iq.ResultIQ()
query := xmpp.NewElementNamespace("query", versionNamespace)
name := xmpp.NewElementName("name")
name.SetText("cubit")
query.AppendElement(name)
ver := xmpp.NewElementName("version")
ver.SetText(version.ApplicationVersion.String())
query.AppendElement(ver)
if x.cfg.ShowOS {
os := xmpp.NewElementName("os")
os.SetText(osString)
query.AppendElement(os)
}
result.AppendElement(query)
_ = x.router.Route(ctx, result)
}