sum7
/
yaja
Archived
1
0
Fork 0

write dirty presence extensions

This commit is contained in:
Martin Geno 2017-12-17 15:39:36 +01:00
parent 5d8c92a76a
commit 1e2e578076
No known key found for this signature in database
GPG Key ID: F0D39A37E925E941
15 changed files with 206 additions and 56 deletions

View File

@ -180,12 +180,14 @@ func reload() {
func init() { func init() {
extensions = append(extensions, extensions = append(extensions,
&extension.Message{}, &extension.Message{},
&extension.Presence{},
extension.IQExtensions{ extension.IQExtensions{
&extension.Private{}, &extension.IQPrivate{},
&extension.Ping{}, &extension.IQPing{},
&extension.Disco{Database: db}, &extension.IQLast{},
&extension.Roster{Database: db}, &extension.IQDisco{Database: db},
&extension.ExtensionDiscovery{GetSpaces: func() []string { &extension.IQRoster{Database: db},
&extension.IQExtensionDiscovery{GetSpaces: func() []string {
return extensions.Spaces() return extensions.Spaces()
}}, }},
}) })

View File

@ -2,7 +2,7 @@ tlsdir = "tmp/ssl"
state_path = "tmp/yaja.json" state_path = "tmp/yaja.json"
[logging] [logging]
level = 6 level = 3
level_client = 6 level_client = 6
[register] [register]

View File

@ -8,14 +8,14 @@ import (
"github.com/genofire/yaja/server/utils" "github.com/genofire/yaja/server/utils"
) )
type Disco struct { type IQDisco struct {
IQExtension IQExtension
Database *database.State Database *database.State
} }
func (r *Disco) Spaces() []string { return []string{} } func (ex *IQDisco) Spaces() []string { return []string{"http://jabber.org/protocol/disco#items"} }
func (r *Disco) Get(msg *messages.IQ, client *utils.Client) bool { func (ex *IQDisco) Get(msg *messages.IQ, client *utils.Client) bool {
log := client.Log.WithField("extension", "disco-item").WithField("id", msg.ID) log := client.Log.WithField("extension", "disco-item").WithField("id", msg.ID)
// query encode // query encode
@ -37,7 +37,7 @@ func (r *Disco) Get(msg *messages.IQ, client *utils.Client) bool {
XMLName xml.Name `xml:"item"` XMLName xml.Name `xml:"item"`
JID string `xml:"jid,attr"` JID string `xml:"jid,attr"`
} }
if acc := r.Database.GetAccount(client.JID); acc != nil { if acc := ex.Database.GetAccount(client.JID); acc != nil {
for jid, _ := range acc.Bookmarks { for jid, _ := range acc.Bookmarks {
itemByte, err := xml.Marshal(&item{ itemByte, err := xml.Marshal(&item{
JID: jid, JID: jid,
@ -58,13 +58,13 @@ func (r *Disco) Get(msg *messages.IQ, client *utils.Client) bool {
} }
// reply // reply
client.Out.Encode(&messages.IQ{ client.Messages <- &messages.IQ{
Type: messages.IQTypeResult, Type: messages.IQTypeResult,
To: client.JID.String(), To: client.JID.String(),
From: client.JID.Domain, From: client.JID.Domain,
ID: msg.ID, ID: msg.ID,
Body: queryByte, Body: queryByte,
}) }
log.Debug("send") log.Debug("send")

View File

@ -7,14 +7,14 @@ import (
"github.com/genofire/yaja/server/utils" "github.com/genofire/yaja/server/utils"
) )
type ExtensionDiscovery struct { type IQExtensionDiscovery struct {
IQExtension IQExtension
GetSpaces func() []string GetSpaces func() []string
} }
func (ex *ExtensionDiscovery) Spaces() []string { return []string{} } func (ex *IQExtensionDiscovery) Spaces() []string { return []string{} }
func (ex *ExtensionDiscovery) Get(msg *messages.IQ, client *utils.Client) bool { func (ex *IQExtensionDiscovery) Get(msg *messages.IQ, client *utils.Client) bool {
log := client.Log.WithField("extension", "roster").WithField("id", msg.ID) log := client.Log.WithField("extension", "roster").WithField("id", msg.ID)
// query encode // query encode
@ -58,13 +58,13 @@ func (ex *ExtensionDiscovery) Get(msg *messages.IQ, client *utils.Client) bool {
} }
// replay // replay
client.Out.Encode(&messages.IQ{ client.Messages <- &messages.IQ{
Type: messages.IQTypeResult, Type: messages.IQTypeResult,
To: client.JID.String(), To: client.JID.String(),
From: client.JID.Domain, From: client.JID.Domain,
ID: msg.ID, ID: msg.ID,
Body: queryByte, Body: queryByte,
}) }
log.Debug("send") log.Debug("send")

View File

@ -0,0 +1,60 @@
package extension
import (
"encoding/xml"
"github.com/genofire/yaja/messages"
"github.com/genofire/yaja/server/utils"
)
//TODO Draft
type IQLast struct {
IQExtension
}
func (ex *IQLast) Spaces() []string { return []string{"jabber:iq:last"} }
func (ex *IQLast) Get(msg *messages.IQ, client *utils.Client) bool {
log := client.Log.WithField("extension", "last").WithField("id", msg.ID)
// query encode
type query struct {
XMLName xml.Name `xml:"jabber:iq:last query"`
Seconds uint `xml:"seconds,attr,omitempty"`
Body []byte `xml:",innerxml"`
}
q := &query{}
err := xml.Unmarshal(msg.Body, q)
if err != nil {
return false
}
// answer query
q.Body = []byte{}
// build answer body
type item struct {
XMLName xml.Name `xml:"item"`
JID string `xml:"jid,attr"`
}
// decode query
queryByte, err := xml.Marshal(q)
if err != nil {
log.Warn(err)
return false
}
// reply
client.Messages <- &messages.IQ{
Type: messages.IQTypeResult,
To: client.JID.String(),
From: client.JID.Domain,
ID: msg.ID,
Body: queryByte,
}
log.Debug("send")
return true
}

View File

@ -7,13 +7,13 @@ import (
"github.com/genofire/yaja/server/utils" "github.com/genofire/yaja/server/utils"
) )
type Ping struct { type IQPing struct {
IQExtension IQExtension
} }
func (p *Ping) Spaces() []string { return []string{"urn:xmpp:ping"} } func (ex *IQPing) Spaces() []string { return []string{"urn:xmpp:ping"} }
func (p *Ping) Get(msg *messages.IQ, client *utils.Client) bool { func (ex *IQPing) Get(msg *messages.IQ, client *utils.Client) bool {
log := client.Log.WithField("extension", "ping").WithField("id", msg.ID) log := client.Log.WithField("extension", "ping").WithField("id", msg.ID)
// ping encode // ping encode
@ -27,12 +27,12 @@ func (p *Ping) Get(msg *messages.IQ, client *utils.Client) bool {
} }
// reply // reply
client.Out.Encode(&messages.IQ{ client.Messages <- &messages.IQ{
Type: messages.IQTypeResult, Type: messages.IQTypeResult,
To: client.JID.String(), To: client.JID.String(),
From: client.JID.Domain, From: client.JID.Domain,
ID: msg.ID, ID: msg.ID,
}) }
log.Debug("send") log.Debug("send")

View File

@ -7,26 +7,26 @@ import (
"github.com/genofire/yaja/server/utils" "github.com/genofire/yaja/server/utils"
) )
type Private struct { type IQPrivate struct {
IQExtension IQExtension
} }
type privateQuery struct { type iqPrivateQuery struct {
XMLName xml.Name `xml:"jabber:iq:private query"` XMLName xml.Name `xml:"jabber:iq:private query"`
Body []byte `xml:",innerxml"` Body []byte `xml:",innerxml"`
} }
type ioPrivateExtension interface { type iqPrivateExtension interface {
Handle(*messages.IQ, *privateQuery, *utils.Client) bool Handle(*messages.IQ, *iqPrivateQuery, *utils.Client) bool
} }
func (p *Private) Spaces() []string { return []string{"jabber:iq:private"} } func (ex *IQPrivate) Spaces() []string { return []string{"jabber:iq:private"} }
func (p *Private) Get(msg *messages.IQ, client *utils.Client) bool { func (ex *IQPrivate) Get(msg *messages.IQ, client *utils.Client) bool {
log := client.Log.WithField("extension", "private").WithField("id", msg.ID) log := client.Log.WithField("extension", "private").WithField("id", msg.ID)
// query encode // query encode
q := &privateQuery{} q := &iqPrivateQuery{}
err := xml.Unmarshal(msg.Body, q) err := xml.Unmarshal(msg.Body, q)
if err != nil { if err != nil {
return false return false
@ -34,9 +34,10 @@ func (p *Private) Get(msg *messages.IQ, client *utils.Client) bool {
// run every extensions // run every extensions
count := 0 count := 0
for _, e := range []ioPrivateExtension{ for _, e := range []iqPrivateExtension{
&PrivateMetacontact{}, &IQPrivateMetacontact{},
&PrivateRoster{}, &IQPrivateRoster{},
&IQPrivateBookmark{},
} { } {
if e.Handle(msg, q, client) { if e.Handle(msg, q, client) {
count++ count++

View File

@ -0,0 +1,50 @@
package extension
import (
"encoding/xml"
"github.com/genofire/yaja/messages"
"github.com/genofire/yaja/server/utils"
)
type IQPrivateBookmark struct {
iqPrivateExtension
}
func (ex *IQPrivateBookmark) Handle(msg *messages.IQ, q *iqPrivateQuery, client *utils.Client) bool {
log := client.Log.WithField("extension", "private").WithField("id", msg.ID)
// storage encode
type storage struct {
XMLName xml.Name `xml:"storage:bookmarks storage"`
}
s := &storage{}
err := xml.Unmarshal(q.Body, s)
if err != nil {
return false
}
/*
TODO full implement
*/
queryByte, err := xml.Marshal(&iqPrivateQuery{
Body: q.Body,
})
if err != nil {
log.Warn(err)
return true
}
// reply
client.Messages <- &messages.IQ{
Type: messages.IQTypeResult,
To: client.JID.String(),
From: client.JID.Domain,
ID: msg.ID,
Body: queryByte,
}
log.Debug("send")
return true
}

View File

@ -7,11 +7,11 @@ import (
"github.com/genofire/yaja/server/utils" "github.com/genofire/yaja/server/utils"
) )
type PrivateMetacontact struct { type IQPrivateMetacontact struct {
ioPrivateExtension iqPrivateExtension
} }
func (p *PrivateMetacontact) Handle(msg *messages.IQ, q *privateQuery, client *utils.Client) bool { func (ex *IQPrivateMetacontact) Handle(msg *messages.IQ, q *iqPrivateQuery, client *utils.Client) bool {
log := client.Log.WithField("extension", "private-metacontact").WithField("id", msg.ID) log := client.Log.WithField("extension", "private-metacontact").WithField("id", msg.ID)
// storage encode // storage encode
@ -28,7 +28,7 @@ func (p *PrivateMetacontact) Handle(msg *messages.IQ, q *privateQuery, client *u
https://xmpp.org/extensions/xep-0209.html https://xmpp.org/extensions/xep-0209.html
*/ */
queryByte, err := xml.Marshal(&privateQuery{ queryByte, err := xml.Marshal(&iqPrivateQuery{
Body: q.Body, Body: q.Body,
}) })
if err != nil { if err != nil {
@ -37,13 +37,13 @@ func (p *PrivateMetacontact) Handle(msg *messages.IQ, q *privateQuery, client *u
} }
// reply // reply
client.Out.Encode(&messages.IQ{ client.Messages <- &messages.IQ{
Type: messages.IQTypeResult, Type: messages.IQTypeResult,
To: client.JID.String(), To: client.JID.String(),
From: client.JID.Domain, From: client.JID.Domain,
ID: msg.ID, ID: msg.ID,
Body: queryByte, Body: queryByte,
}) }
log.Debug("send") log.Debug("send")

View File

@ -7,11 +7,11 @@ import (
"github.com/genofire/yaja/server/utils" "github.com/genofire/yaja/server/utils"
) )
type PrivateRoster struct { type IQPrivateRoster struct {
ioPrivateExtension iqPrivateExtension
} }
func (p *PrivateRoster) Handle(msg *messages.IQ, q *privateQuery, client *utils.Client) bool { func (ex *IQPrivateRoster) Handle(msg *messages.IQ, q *iqPrivateQuery, client *utils.Client) bool {
log := client.Log.WithField("extension", "private").WithField("id", msg.ID) log := client.Log.WithField("extension", "private").WithField("id", msg.ID)
// roster encode // roster encode
@ -32,7 +32,7 @@ func (p *PrivateRoster) Handle(msg *messages.IQ, q *privateQuery, client *utils.
log.Warn(err) log.Warn(err)
return true return true
} }
queryByte, err := xml.Marshal(&privateQuery{ queryByte, err := xml.Marshal(&iqPrivateQuery{
Body: rosterByte, Body: rosterByte,
}) })
if err != nil { if err != nil {
@ -41,13 +41,13 @@ func (p *PrivateRoster) Handle(msg *messages.IQ, q *privateQuery, client *utils.
} }
// reply // reply
client.Out.Encode(&messages.IQ{ client.Messages <- &messages.IQ{
Type: messages.IQTypeResult, Type: messages.IQTypeResult,
To: client.JID.String(), To: client.JID.String(),
From: client.JID.Domain, From: client.JID.Domain,
ID: msg.ID, ID: msg.ID,
Body: queryByte, Body: queryByte,
}) }
log.Debug("send") log.Debug("send")

View File

@ -8,14 +8,14 @@ import (
"github.com/genofire/yaja/server/utils" "github.com/genofire/yaja/server/utils"
) )
type Roster struct { type IQRoster struct {
IQExtension IQExtension
Database *database.State Database *database.State
} }
func (r *Roster) Spaces() []string { return []string{"jabber:iq:roster"} } func (ex *IQRoster) Spaces() []string { return []string{"jabber:iq:roster"} }
func (r *Roster) Get(msg *messages.IQ, client *utils.Client) bool { func (ex *IQRoster) Get(msg *messages.IQ, client *utils.Client) bool {
log := client.Log.WithField("extension", "roster").WithField("id", msg.ID) log := client.Log.WithField("extension", "roster").WithField("id", msg.ID)
// query encode // query encode
@ -39,7 +39,7 @@ func (r *Roster) Get(msg *messages.IQ, client *utils.Client) bool {
XMLName xml.Name `xml:"item"` XMLName xml.Name `xml:"item"`
JID string `xml:"jid,attr"` JID string `xml:"jid,attr"`
} }
if acc := r.Database.GetAccount(client.JID); acc != nil { if acc := ex.Database.GetAccount(client.JID); acc != nil {
for jid, _ := range acc.Roster { for jid, _ := range acc.Roster {
itemByte, err := xml.Marshal(&item{ itemByte, err := xml.Marshal(&item{
JID: jid, JID: jid,
@ -60,13 +60,13 @@ func (r *Roster) Get(msg *messages.IQ, client *utils.Client) bool {
} }
// reply // reply
client.Out.Encode(&messages.IQ{ client.Messages <- &messages.IQ{
Type: messages.IQTypeResult, Type: messages.IQTypeResult,
To: client.JID.String(), To: client.JID.String(),
From: client.JID.Domain, From: client.JID.Domain,
ID: msg.ID, ID: msg.ID,
Body: queryByte, Body: queryByte,
}) }
log.Debug("send") log.Debug("send")

View File

@ -10,6 +10,8 @@ type Message struct {
Extension Extension
} }
//TODO Draft
func (m *Message) Spaces() []string { return []string{} } func (m *Message) Spaces() []string { return []string{} }
func (m *Message) Process(element *xml.StartElement, client *utils.Client) bool { func (m *Message) Process(element *xml.StartElement, client *utils.Client) bool {

View File

@ -0,0 +1,32 @@
package extension
import (
"encoding/xml"
"github.com/genofire/yaja/messages"
"github.com/genofire/yaja/server/utils"
)
type Presence struct {
Extension
}
//TODO Draft
func (p *Presence) Spaces() []string { return []string{} }
func (p *Presence) Process(element *xml.StartElement, client *utils.Client) bool {
log := client.Log.WithField("extension", "presence")
// iq encode
var msg messages.Presence
if err := client.In.DecodeElement(&msg, element); err != nil {
return false
}
client.Messages <- &messages.Presence{
ID: msg.ID,
}
log.Debug("send")
return true
}

View File

@ -20,7 +20,9 @@ func (state *SendingClient) Process(client *utils.Client) (state.State, *utils.C
select { select {
case msg := <-client.Messages: case msg := <-client.Messages:
err := client.Out.Encode(msg) err := client.Out.Encode(msg)
client.Log.Info(err) if err != nil {
client.Log.Warn(err)
}
case <-client.OnClose(): case <-client.OnClose():
return return
} }

View File

@ -26,11 +26,12 @@ func NewClient(conn net.Conn, level log.Level) *Client {
logger := log.New() logger := log.New()
logger.SetLevel(level) logger.SetLevel(level)
client := &Client{ client := &Client{
Conn: conn, Conn: conn,
Log: log.NewEntry(logger), Log: log.NewEntry(logger),
In: xml.NewDecoder(conn), In: xml.NewDecoder(conn),
Out: xml.NewEncoder(conn), Out: xml.NewEncoder(conn),
close: make(chan interface{}), Messages: make(chan interface{}, 1000),
close: make(chan interface{}),
} }
return client return client
} }