sum7
/
yaja
Archived
1
0
Fork 0

rename and split xmpp xml structs packages

This commit is contained in:
Martin/Geno 2018-02-14 18:49:26 +01:00
parent aacc788efe
commit e2a59cb3ba
No known key found for this signature in database
GPG Key ID: F0D39A37E925E941
70 changed files with 660 additions and 546 deletions

View File

@ -7,8 +7,9 @@
[![chat on our conference room](https://camo.githubusercontent.com/a839cc0a3d4dac7ec82237381b165dd144365b6d/68747470733a2f2f74696e7975726c2e636f6d2f6a6f696e7468656d7563)](https://conversations.im/j/yaja@conference.chat.sum7.eu)
## Features
- Messages XML Library (first version - PR are welcome)
- Full RFC 6120 (XMPP - Core)
- XMPP Library (first version - PR are welcome)
- RFC 6120 (XMPP - Core)
- XEP 0030: Service Discovery
- XEP-0199: XMPP Ping
- Client Library (WIP)
- Stream: TLS Required
@ -29,11 +30,12 @@
## Library
### Messages
### XMPP
all implementation of all comman (RFCs and XEPs) xml element
**Version**
- RFC 6120 (XMPP - Core)
- XEP 0030: Service Discovery
- XEP-0199: XMPP Ping
### Client

View File

@ -9,7 +9,7 @@ import (
"math/big"
"strings"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/xmpp"
)
func (client *Client) auth(password string) error {
@ -19,8 +19,8 @@ func (client *Client) auth(password string) error {
}
//auth:
mechanism := ""
challenge := &messages.SASLChallenge{}
response := &messages.SASLResponse{}
challenge := &xmpp.SASLChallenge{}
response := &xmpp.SASLResponse{}
for _, m := range f.Mechanisms.Mechanism {
client.Logging.Debugf("try auth with '%s'", m)
if m == "SCRAM-SHA-1" {
@ -34,7 +34,7 @@ func (client *Client) auth(password string) error {
if m == "DIGEST-MD5" {
mechanism = m
// Digest-MD5 authentication
client.Send(&messages.SASLAuth{
client.Send(&xmpp.SASLAuth{
Mechanism: m,
})
if err := client.ReadDecode(challenge); err != nil {
@ -61,8 +61,8 @@ func (client *Client) auth(password string) error {
cnonceStr := cnonce()
digestURI := "xmpp/" + client.JID.Domain
nonceCount := fmt.Sprintf("%08x", 1)
digest := saslDigestResponse(client.JID.Local, realm, password, nonce, cnonceStr, "AUTHENTICATE", digestURI, nonceCount)
message := "username=\"" + client.JID.Local + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", cnonce=\"" + cnonceStr +
digest := saslDigestResponse(client.JID.Node, realm, password, nonce, cnonceStr, "AUTHENTICATE", digestURI, nonceCount)
message := "username=\"" + client.JID.Node + "\", realm=\"" + realm + "\", nonce=\"" + nonce + "\", cnonce=\"" + cnonceStr +
"\", nc=" + nonceCount + ", qop=" + qop + ", digest-uri=\"" + digestURI + "\", response=" + digest + ", charset=" + charset
response.Body = base64.StdEncoding.EncodeToString([]byte(message))
@ -72,10 +72,10 @@ func (client *Client) auth(password string) error {
if m == "PLAIN" {
mechanism = m
// Plain authentication: send base64-encoded \x00 user \x00 password.
raw := "\x00" + client.JID.Local + "\x00" + password
raw := "\x00" + client.JID.Node + "\x00" + password
enc := make([]byte, base64.StdEncoding.EncodedLen(len(raw)))
base64.StdEncoding.Encode(enc, []byte(raw))
client.Send(&messages.SASLAuth{
client.Send(&xmpp.SASLAuth{
Mechanism: "PLAIN",
Body: string(enc),
})
@ -92,14 +92,14 @@ func (client *Client) auth(password string) error {
if err != nil {
return err
}
fail := messages.SASLFailure{}
fail := xmpp.SASLFailure{}
if err := client.Decode(&fail, element); err == nil {
if txt := fail.Text; txt != nil {
return errors.New(messages.XMLChildrenString(fail) + " : " + txt.Body)
return errors.New(xmpp.XMLChildrenString(fail) + " : " + txt.Body)
}
return errors.New(messages.XMLChildrenString(fail))
return errors.New(xmpp.XMLChildrenString(fail))
}
if err := client.Decode(&messages.SASLSuccess{}, element); err != nil {
if err := client.Decode(&xmpp.SASLSuccess{}, element); err != nil {
return errors.New("auth failed - with unexpected answer")
}
return nil

View File

@ -10,7 +10,8 @@ import (
log "github.com/sirupsen/logrus"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
// Client holds XMPP connection opitons
@ -23,17 +24,17 @@ type Client struct {
Logging *log.Logger
JID *messages.JID
JID *xmppbase.JID
reply map[string]chan *messages.IQClient
reply map[string]chan *xmpp.IQClient
skipError bool
iq chan *messages.IQClient
presence chan *messages.PresenceClient
mesage chan *messages.MessageClient
iq chan *xmpp.IQClient
presence chan *xmpp.PresenceClient
mesage chan *xmpp.MessageClient
}
func NewClient(jid *messages.JID, password string) (*Client, error) {
func NewClient(jid *xmppbase.JID, password string) (*Client, error) {
client := &Client{
Protocol: "tcp",
JID: jid,

1
client/client_test.go Normal file
View File

@ -0,0 +1 @@
package client

View File

@ -3,7 +3,7 @@ package client
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/xmpp"
)
func (client *Client) Read() (*xml.StartElement, error) {
@ -15,7 +15,7 @@ func (client *Client) Read() (*xml.StartElement, error) {
switch nextToken.(type) {
case xml.StartElement:
element := nextToken.(xml.StartElement)
client.Logging.Debug("recv xml: ", messages.XMLStartElementToString(&element))
client.Logging.Debug("recv xml: ", xmpp.XMLStartElementToString(&element))
return &element, nil
}
}
@ -23,9 +23,9 @@ func (client *Client) Read() (*xml.StartElement, error) {
func (client *Client) Decode(p interface{}, element *xml.StartElement) error {
err := client.in.DecodeElement(p, element)
if err != nil {
client.Logging.Debugf("decode failed xml: %s to: %v", messages.XMLStartElementToString(element), p)
client.Logging.Debugf("decode failed xml: %s to: %v", xmpp.XMLStartElementToString(element), p)
} else {
client.Logging.Debugf("decode xml: %s to: %v with children %s", messages.XMLStartElementToString(element), p, messages.XMLChildrenString(p))
client.Logging.Debugf("decode xml: %s to: %v with children %s", xmpp.XMLStartElementToString(element), p, xmpp.XMLChildrenString(p))
}
return err
}
@ -34,15 +34,15 @@ func (client *Client) ReadDecode(p interface{}) error {
if err != nil {
return err
}
var iq *messages.IQClient
iq, ok := p.(*messages.IQClient)
var iq *xmpp.IQClient
iq, ok := p.(*xmpp.IQClient)
if !ok {
iq = &messages.IQClient{}
iq = &xmpp.IQClient{}
}
err = client.Decode(iq, element)
if err == nil && iq.Ping != nil {
client.Logging.Info("ReadElement: auto answer ping")
iq.Type = messages.IQTypeResult
iq.Type = xmpp.IQTypeResult
iq.To = iq.From
iq.From = client.JID
client.Send(iq)
@ -58,23 +58,23 @@ func (client *Client) encode(p interface{}) error {
if err != nil {
client.Logging.Debugf("encode failed %v", p)
} else {
client.Logging.Debugf("encode %v with children %s", p, messages.XMLChildrenString(p))
client.Logging.Debugf("encode %v with children %s", p, xmpp.XMLChildrenString(p))
}
return err
}
func (client *Client) Send(p interface{}) error {
msg, ok := p.(*messages.MessageClient)
msg, ok := p.(*xmpp.MessageClient)
if ok {
msg.From = client.JID
return client.encode(msg)
}
iq, ok := p.(*messages.IQClient)
iq, ok := p.(*xmpp.IQClient)
if ok {
iq.From = client.JID
return client.encode(iq)
}
pc, ok := p.(*messages.PresenceClient)
pc, ok := p.(*xmpp.PresenceClient)
if ok {
pc.From = client.JID
return client.encode(pc)

View File

@ -7,8 +7,9 @@ import (
"fmt"
"net"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/model"
"dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
func (client *Client) setConnection(conn net.Conn) {
@ -17,12 +18,12 @@ func (client *Client) setConnection(conn net.Conn) {
client.out = xml.NewEncoder(client.conn)
}
func (client *Client) startStream() (*messages.StreamFeatures, error) {
func (client *Client) startStream() (*xmpp.StreamFeatures, error) {
// XMPP-Connection
_, err := fmt.Fprintf(client.conn, "<?xml version='1.0'?>\n"+
"<stream:stream to='%s' xmlns='%s'\n"+
" xmlns:stream='%s' version='1.0'>\n",
model.XMLEscape(client.JID.Domain), messages.NSClient, messages.NSStream)
model.XMLEscape(client.JID.Domain), xmpp.NSClient, xmpp.NSStream)
if err != nil {
return nil, err
}
@ -30,10 +31,10 @@ func (client *Client) startStream() (*messages.StreamFeatures, error) {
if err != nil {
return nil, err
}
if element.Name.Space != messages.NSStream || element.Name.Local != "stream" {
if element.Name.Space != xmpp.NSStream || element.Name.Local != "stream" {
return nil, errors.New("is not stream")
}
f := &messages.StreamFeatures{}
f := &xmpp.StreamFeatures{}
if err := client.ReadDecode(f); err != nil {
return nil, err
}
@ -63,11 +64,11 @@ func (client *Client) connect(password string) error {
if _, err := client.startStream(); err != nil {
return err
}
if err := client.Send(&messages.TLSStartTLS{}); err != nil {
if err := client.Send(&xmpp.TLSStartTLS{}); err != nil {
return err
}
var p messages.TLSProceed
var p xmpp.TLSProceed
if err := client.ReadDecode(&p); err != nil {
return err
}
@ -97,29 +98,29 @@ func (client *Client) connect(password string) error {
if client.JID.Resource != "" {
bind.Resource = client.JID.Resource
}
if err := client.Send(&messages.IQClient{
Type: messages.IQTypeSet,
To: messages.NewJID(client.JID.Domain),
if err := client.Send(&xmpp.IQClient{
Type: xmpp.IQTypeSet,
To: xmppbase.NewJID(client.JID.Domain),
Bind: bind,
}); err != nil {
return err
}
var iq messages.IQClient
var iq xmpp.IQClient
if err := client.ReadDecode(&iq); err != nil {
return err
}
if iq.Error != nil {
return errors.New(fmt.Sprintf("recv error on iq>bind: %s[%s]: %s -> %s -> %s", iq.Error.Code, iq.Error.Type, iq.Error.Text, messages.XMLChildrenString(iq.Error.StanzaErrorGroup), messages.XMLChildrenString(iq.Error.Other)))
return errors.New(fmt.Sprintf("recv error on iq>bind: %s[%s]: %s -> %s -> %s", iq.Error.Code, iq.Error.Type, iq.Error.Text, xmpp.XMLChildrenString(iq.Error.StanzaErrorGroup), xmpp.XMLChildrenString(iq.Error.Other)))
} else if iq.Bind == nil {
return errors.New("iq>bind is nil :" + messages.XMLChildrenString(iq.Other))
return errors.New("iq>bind is nil :" + xmpp.XMLChildrenString(iq.Other))
}
bind = iq.Bind
}
if bind == nil {
return errors.New("bind is nil")
} else if bind.JID != nil {
client.JID.Local = bind.JID.Local
client.JID.Node = bind.JID.Node
client.JID.Domain = bind.JID.Domain
client.JID.Resource = bind.JID.Resource
client.Logging.Infof("set jid by server bind '%s'", bind.JID.Full())
@ -127,8 +128,8 @@ func (client *Client) connect(password string) error {
client.JID.Resource = bind.Resource
client.Logging.Infof("set resource by server bind '%s'", bind.Resource)
} else {
return errors.New("bind>jid is nil" + messages.XMLChildrenString(bind))
return errors.New("bind>jid is nil" + xmpp.XMLChildrenString(bind))
}
// set status
return client.Send(&messages.PresenceClient{Show: messages.PresenceShowXA, Status: "online"})
return client.Send(&xmpp.PresenceClient{Show: xmpp.PresenceShowXA, Status: "online"})
}

View File

@ -3,16 +3,16 @@ package client
import (
"fmt"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/xmpp"
)
var DefaultChannelSize = 30
func (client *Client) Start() error {
client.iq = make(chan *messages.IQClient, DefaultChannelSize)
client.presence = make(chan *messages.PresenceClient, DefaultChannelSize)
client.mesage = make(chan *messages.MessageClient, DefaultChannelSize)
client.reply = make(map[string]chan *messages.IQClient)
client.iq = make(chan *xmpp.IQClient, DefaultChannelSize)
client.presence = make(chan *xmpp.PresenceClient, DefaultChannelSize)
client.mesage = make(chan *xmpp.MessageClient, DefaultChannelSize)
client.reply = make(map[string]chan *xmpp.IQClient)
for {
@ -21,18 +21,18 @@ func (client *Client) Start() error {
return err
}
errMSG := &messages.StreamError{}
errMSG := &xmpp.StreamError{}
err = client.Decode(errMSG, element)
if err == nil {
return fmt.Errorf("recv stream error: %s: %s -> %s", errMSG.Text, messages.XMLChildrenString(errMSG.StreamErrorGroup), messages.XMLChildrenString(errMSG.Other))
return fmt.Errorf("recv stream error: %s: %s -> %s", errMSG.Text, xmpp.XMLChildrenString(errMSG.StreamErrorGroup), xmpp.XMLChildrenString(errMSG.Other))
}
iq := &messages.IQClient{}
iq := &xmpp.IQClient{}
err = client.Decode(iq, element)
if err == nil {
if iq.Ping != nil {
client.Logging.Debug("answer ping")
iq.Type = messages.IQTypeResult
iq.Type = xmpp.IQTypeResult
iq.To = iq.From
iq.From = client.JID
client.Send(iq)
@ -50,7 +50,7 @@ func (client *Client) Start() error {
continue
}
pres := &messages.PresenceClient{}
pres := &xmpp.PresenceClient{}
err = client.Decode(pres, element)
if err == nil {
if client.skipError && pres.Error != nil {
@ -60,7 +60,7 @@ func (client *Client) Start() error {
continue
}
msg := &messages.MessageClient{}
msg := &xmpp.MessageClient{}
err = client.Decode(msg, element)
if err == nil {
if client.skipError && msg.Error != nil {
@ -73,25 +73,25 @@ func (client *Client) Start() error {
}
}
func (client *Client) SendRecv(iq *messages.IQClient) *messages.IQClient {
func (client *Client) SendRecv(iq *xmpp.IQClient) *xmpp.IQClient {
if iq.ID == "" {
iq.ID = messages.CreateCookieString()
iq.ID = xmpp.CreateCookieString()
}
ch := make(chan *messages.IQClient, 1)
ch := make(chan *xmpp.IQClient, 1)
client.reply[iq.ID] = ch
client.Send(iq)
defer close(ch)
return <-ch
}
func (client *Client) RecvIQ() *messages.IQClient {
func (client *Client) RecvIQ() *xmpp.IQClient {
return <-client.iq
}
func (client *Client) RecvPresence() *messages.PresenceClient {
func (client *Client) RecvPresence() *xmpp.PresenceClient {
return <-client.presence
}
func (client *Client) RecvMessage() *messages.MessageClient {
func (client *Client) RecvMessage() *xmpp.MessageClient {
return <-client.mesage
}

View File

@ -11,7 +11,7 @@ import (
"dev.sum7.eu/genofire/golang-lib/worker"
"dev.sum7.eu/genofire/yaja/client"
"dev.sum7.eu/genofire/yaja/daemon/tester"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/xmpp"
"github.com/spf13/cobra"
)
@ -56,7 +56,7 @@ var TesterCMD = &cobra.Command{
defer mainClient.Close()
for _, admin := range configTester.Admins {
mainClient.Send(&messages.MessageClient{
mainClient.Send(&xmpp.MessageClient{
To: admin,
Type: "chat",
Body: "yaja tester starts",

View File

@ -1,9 +1,9 @@
package tester
import "dev.sum7.eu/genofire/yaja/messages"
import "dev.sum7.eu/genofire/yaja/xmpp/base"
type Account struct {
JID *messages.JID `json:"jid"`
JID *xmppbase.JID `json:"jid"`
Password string `json:"password"`
Admins map[string]interface{} `json:"admins"`
}

View File

@ -6,7 +6,8 @@ import (
log "github.com/sirupsen/logrus"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
func (t *Tester) StartBot(status *Status) {
@ -24,60 +25,60 @@ func (t *Tester) StartBot(status *Status) {
return
}
errMSG := &messages.StreamError{}
errMSG := &xmpp.StreamError{}
err = status.client.Decode(errMSG, element)
if err == nil {
status.Disconnect(fmt.Sprintf("recv stream error: %s: %s -> %s", errMSG.Text, messages.XMLChildrenString(errMSG.StreamErrorGroup), messages.XMLChildrenString(errMSG.Other)))
status.Disconnect(fmt.Sprintf("recv stream error: %s: %s -> %s", errMSG.Text, xmpp.XMLChildrenString(errMSG.StreamErrorGroup), xmpp.XMLChildrenString(errMSG.Other)))
return
}
iq := &messages.IQClient{}
iq := &xmpp.IQClient{}
err = status.client.Decode(iq, element)
if err == nil {
if iq.Ping != nil {
logCTX.Debug("answer ping")
iq.Type = messages.IQTypeResult
iq.Type = xmpp.IQTypeResult
iq.To = iq.From
iq.From = status.client.JID
status.client.Send(iq)
} else {
logCTX.Warnf("recv iq unsupport: %s", messages.XMLChildrenString(iq))
logCTX.Warnf("recv iq unsupport: %s", xmpp.XMLChildrenString(iq))
}
continue
}
pres := &messages.PresenceClient{}
pres := &xmpp.PresenceClient{}
err = status.client.Decode(pres, element)
if err == nil {
sender := pres.From
logPres := logCTX.WithField("from", sender.Full())
if pres.Type == messages.PresenceTypeSubscribe {
if pres.Type == xmpp.PresenceTypeSubscribe {
logPres.Debugf("recv presence subscribe")
pres.Type = messages.PresenceTypeSubscribed
pres.Type = xmpp.PresenceTypeSubscribed
pres.To = sender
pres.From = nil
status.client.Send(pres)
logPres.Debugf("accept new subscribe")
pres.Type = messages.PresenceTypeSubscribe
pres.Type = xmpp.PresenceTypeSubscribe
pres.ID = ""
status.client.Send(pres)
logPres.Info("request also subscribe")
} else if pres.Type == messages.PresenceTypeSubscribed {
} else if pres.Type == xmpp.PresenceTypeSubscribed {
logPres.Info("recv presence accepted subscribe")
} else if pres.Type == messages.PresenceTypeUnsubscribe {
} else if pres.Type == xmpp.PresenceTypeUnsubscribe {
logPres.Info("recv presence remove subscribe")
} else if pres.Type == messages.PresenceTypeUnsubscribed {
} else if pres.Type == xmpp.PresenceTypeUnsubscribed {
logPres.Info("recv presence removed subscribe")
} else if pres.Type == messages.PresenceTypeUnavailable {
} else if pres.Type == xmpp.PresenceTypeUnavailable {
logPres.Debug("recv presence unavailable")
} else {
logCTX.Warnf("recv presence unsupported: %s -> %s", pres.Type, messages.XMLChildrenString(pres))
logCTX.Warnf("recv presence unsupported: %s -> %s", pres.Type, xmpp.XMLChildrenString(pres))
}
continue
}
msg := &messages.MessageClient{}
msg := &xmpp.MessageClient{}
err = status.client.Decode(msg, element)
if err != nil {
logCTX.Warnf("unsupport xml recv: %s <-> %v", err, element)
@ -89,7 +90,7 @@ func (t *Tester) StartBot(status *Status) {
status.Disconnect("recv msg with error not auth")
return
}
logCTX.Debugf("recv msg with error %s[%s]: %s -> %s -> %s", msg.Error.Code, msg.Error.Type, msg.Error.Text, messages.XMLChildrenString(msg.Error.StanzaErrorGroup), messages.XMLChildrenString(msg.Error.Other))
logCTX.Debugf("recv msg with error %s[%s]: %s -> %s -> %s", msg.Error.Code, msg.Error.Type, msg.Error.Text, xmpp.XMLChildrenString(msg.Error.StanzaErrorGroup), xmpp.XMLChildrenString(msg.Error.Other))
continue
}
@ -98,12 +99,12 @@ func (t *Tester) StartBot(status *Status) {
switch msgText[0] {
case "ping":
status.client.Send(messages.MessageClient{Type: msg.Type, To: msg.From, Body: "pong"})
status.client.Send(xmpp.MessageClient{Type: msg.Type, To: msg.From, Body: "pong"})
case "admin":
if len(msgText) == 2 {
botAdmin(strings.SplitN(msgText[1], " ", 2), logCTX, status, msg.From, botAllowed(t.Admins, status.account.Admins))
} else {
status.client.Send(messages.MessageClient{Type: msg.Type, To: msg.From, Body: "list, add JID-BARE, del JID-BARE"})
status.client.Send(xmpp.MessageClient{Type: msg.Type, To: msg.From, Body: "list, add JID-BARE, del JID-BARE"})
}
case "disconnect":
first := true
@ -118,7 +119,7 @@ func (t *Tester) StartBot(status *Status) {
}
if jid.Bare() == msg.From.Bare() {
isAdmin = true
status.client.Send(messages.MessageClient{Type: msg.Type, To: jid, Body: "last message, disconnect requested by " + msg.From.Bare()})
status.client.Send(xmpp.MessageClient{Type: msg.Type, To: jid, Body: "last message, disconnect requested by " + msg.From.Bare()})
}
}
@ -126,7 +127,7 @@ func (t *Tester) StartBot(status *Status) {
status.Disconnect(fmt.Sprintf("disconnect by admin '%s'", msg.From.Bare()))
return
}
status.client.Send(messages.MessageClient{Type: msg.Type, To: msg.From, Body: "not allowed, ask " + allAdmins})
status.client.Send(xmpp.MessageClient{Type: msg.Type, To: msg.From, Body: "not allowed, ask " + allAdmins})
case "checkmsg":
if len(msgText) == 2 {
@ -140,15 +141,15 @@ func (t *Tester) StartBot(status *Status) {
}
}
}
func botAllowed(list []*messages.JID, toConvert map[string]interface{}) []*messages.JID {
func botAllowed(list []*xmppbase.JID, toConvert map[string]interface{}) []*xmppbase.JID {
alist := list
for jid := range toConvert {
alist = append(alist, messages.NewJID(jid))
alist = append(alist, xmppbase.NewJID(jid))
}
return alist
}
func botAdmin(cmd []string, log *log.Entry, status *Status, from *messages.JID, allowed []*messages.JID) {
func botAdmin(cmd []string, log *log.Entry, status *Status, from *xmppbase.JID, allowed []*xmppbase.JID) {
msg := ""
if len(cmd) == 2 {
isAdmin := false
@ -169,7 +170,7 @@ func botAdmin(cmd []string, log *log.Entry, status *Status, from *messages.JID,
delete(status.account.Admins, cmd[1])
msg = "ack"
} else {
msg = "unkown command"
msg = "unknown command"
}
} else {
if len(cmd) == 1 && cmd[0] == "list" {
@ -181,8 +182,8 @@ func botAdmin(cmd []string, log *log.Entry, status *Status, from *messages.JID,
}
}
} else {
msg = "unkown command"
msg = "unknown command"
}
}
status.client.Send(messages.MessageClient{Type: messages.MessageTypeChat, To: from, Body: msg})
status.client.Send(xmpp.MessageClient{Type: xmpp.MessageTypeChat, To: from, Body: msg})
}

View File

@ -0,0 +1 @@
package tester

View File

@ -1,9 +1,10 @@
package tester
import (
"dev.sum7.eu/genofire/yaja/messages"
"github.com/FreifunkBremen/yanic/lib/duration"
log "github.com/sirupsen/logrus"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
type Config struct {
@ -15,9 +16,9 @@ type Config struct {
LoggingBots log.Level `toml:"logging_bots"`
Timeout duration.Duration `toml:"timeout"`
Interval duration.Duration `toml:"interval"`
Admins []*messages.JID `toml:"admins"`
Admins []*xmppbase.JID `toml:"admins"`
Client struct {
JID *messages.JID `toml:"jid"`
JID *xmppbase.JID `toml:"jid"`
Password string `toml:"password"`
} `toml:"client"`
}

View File

@ -4,8 +4,9 @@ import (
"fmt"
"strings"
"dev.sum7.eu/genofire/yaja/messages"
"github.com/FreifunkBremen/yanic/lib/jsontime"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
type Output struct {
@ -53,7 +54,7 @@ func (t *Tester) Output() *Output {
}
continue
}
toJID := messages.NewJID(to)
toJID := xmppbase.NewJID(to)
link := &Link{
Source: status.JID.Domain,
SourceJID: status.JID.Bare(),

View File

@ -6,14 +6,15 @@ import (
"time"
"dev.sum7.eu/genofire/yaja/client"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
type Status struct {
backupClient *client.Client
client *client.Client
account *Account
JID *messages.JID `json:"jid"`
JID *xmppbase.JID `json:"jid"`
Domain string `json:"domain"`
Login bool `json:"is_online"`
MessageForConnection map[string]string `json:"-"`
@ -35,12 +36,12 @@ func NewStatus(backupClient *client.Client, acc *Account) *Status {
}
func (s *Status) Disconnect(reason string) {
if s.Login {
msg := &messages.MessageClient{
Type: messages.MessageTypeChat,
Body: fmt.Sprintf("you recieve a notify that '%s' disconnect: %s", s.JID.Full(), reason),
msg := &xmpp.MessageClient{
Type: xmpp.MessageTypeChat,
Body: fmt.Sprintf("you receive a notify that '%s' disconnect: %s", s.JID.Full(), reason),
}
for jid := range s.account.Admins {
msg.To = messages.NewJID(jid)
msg.To = xmppbase.NewJID(jid)
if err := s.backupClient.Send(msg); err != nil {
s.client.Send(msg)
}
@ -58,7 +59,7 @@ func (s *Status) Update(timeout time.Duration) {
}
c := &client.Client{
JID: messages.NewJID(s.account.JID.Bare()),
JID: xmppbase.NewJID(s.account.JID.Bare()),
Protocol: "tcp4",
Logging: s.client.Logging,
Timeout: timeout / 2,
@ -71,7 +72,7 @@ func (s *Status) Update(timeout time.Duration) {
s.IPv4 = false
}
c.JID = messages.NewJID(s.account.JID.Bare())
c.JID = xmppbase.NewJID(s.account.JID.Bare())
c.Protocol = "tcp6"
if err := c.Connect(s.account.Password); err == nil {

View File

@ -7,7 +7,8 @@ import (
log "github.com/sirupsen/logrus"
"dev.sum7.eu/genofire/yaja/client"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
type Tester struct {
@ -18,7 +19,7 @@ type Tester struct {
mux sync.Mutex
LoggingClients *log.Logger `json:"-"`
LoggingBots log.Level `json:"-"`
Admins []*messages.JID `json:"-"`
Admins []*xmppbase.JID `json:"-"`
}
func NewTester() *Tester {
@ -88,7 +89,7 @@ func (t *Tester) Connect(acc *Account) {
}
}
func (t *Tester) UpdateConnectionStatus(from, to *messages.JID, recvmsg string) {
func (t *Tester) UpdateConnectionStatus(from, to *xmppbase.JID, recvmsg string) {
logCTX := log.WithFields(log.Fields{
"jid": to.Full(),
"from": from.Full(),
@ -154,12 +155,12 @@ func (t *Tester) CheckStatus() {
logCTXTo.Debug("could not recv msg")
}
}
msg = messages.CreateCookieString()
msg = xmpp.CreateCookieString()
logCTXTo = logCTXTo.WithField("msg-send", msg)
own.client.Send(&messages.MessageClient{
own.client.Send(&xmpp.MessageClient{
Body: "checkmsg " + msg,
Type: messages.MessageTypeChat,
Type: xmpp.MessageTypeChat,
To: s.JID,
})
own.MessageForConnection[s.JID.Bare()] = msg

1
daemon/tester_test.go Normal file
View File

@ -0,0 +1 @@
package daemon

View File

@ -4,9 +4,10 @@ import (
"errors"
"sync"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/model"
log "github.com/sirupsen/logrus"
"dev.sum7.eu/genofire/yaja/model"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
type State struct {
@ -15,7 +16,7 @@ type State struct {
}
func (s *State) AddAccount(a *model.Account) error {
if a.Local == "" {
if a.Node == "" {
return errors.New("No localpart exists in account")
}
if d := a.Domain; d != nil {
@ -38,22 +39,22 @@ func (s *State) AddAccount(a *model.Account) error {
if domain.Accounts == nil {
domain.Accounts = make(map[string]*model.Account)
}
_, ok = domain.Accounts[a.Local]
_, ok = domain.Accounts[a.Node]
if ok {
return errors.New("exists already")
}
domain.Accounts[a.Local] = a
domain.Accounts[a.Node] = a
a.Domain = d
return nil
}
return errors.New("no give domain")
}
func (s *State) Authenticate(jid *messages.JID, password string) (bool, error) {
func (s *State) Authenticate(jid *xmppbase.JID, password string) (bool, error) {
logger := log.WithField("database", "auth")
if domain, ok := s.Domains[jid.Domain]; ok {
if acc, ok := domain.Accounts[jid.Local]; ok {
if acc, ok := domain.Accounts[jid.Node]; ok {
if acc.ValidatePassword(password) {
return true, nil
} else {
@ -68,11 +69,11 @@ func (s *State) Authenticate(jid *messages.JID, password string) (bool, error) {
return false, nil
}
func (s *State) GetAccount(jid *messages.JID) *model.Account {
func (s *State) GetAccount(jid *xmppbase.JID) *model.Account {
logger := log.WithField("database", "get")
if domain, ok := s.Domains[jid.Domain]; ok {
if acc, ok := domain.Accounts[jid.Local]; ok {
if acc, ok := domain.Accounts[jid.Node]; ok {
return acc
} else {
logger.Debug("account not found")

View File

@ -1,23 +0,0 @@
package messages
import (
"encoding/xml"
)
// RFC 6120 - A.5 Client Namespace (a part)
type IQClient struct {
XMLName xml.Name `xml:"jabber:client iq"`
From *JID `xml:"from,attr,omitempty"`
ID string `xml:"id,attr"` // required
To *JID `xml:"to,attr,omitempty"`
Type IQType `xml:"type,attr"` // required
Error *ErrorClient
Bind *Bind // which XEP ?
Ping *Ping // which XEP ?
PrivateQuery *IQPrivateQuery // which XEP ?
PrivateRegister *IQPrivateRegister // which XEP ?
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

View File

@ -1,25 +0,0 @@
package messages
import (
"encoding/xml"
)
// RFC 6120 - A.5 Client Namespace (a part)
type MessageClient struct {
XMLName xml.Name `xml:"jabber:client message"`
From *JID `xml:"from,attr,omitempty"`
ID string `xml:"id,attr,omitempty"`
To *JID `xml:"to,attr,omitempty"`
Type MessageType `xml:"type,attr,omitempty"` // default: normal
Lang string `xml:"lang,attr,omitempty"`
Subject string `xml:"subject,omitempty"`
Body string `xml:"body,omitempty"`
Thread string `xml:"thread,omitempty"`
Error *ErrorClient
Delay *Delay `xml:"delay"` // which XEP ?
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

View File

@ -1,29 +0,0 @@
package messages
import (
"encoding/xml"
)
// RFC 6120 - A.5 Client Namespace (a part)
type PresenceClient struct {
XMLName xml.Name `xml:"jabber:client presence"`
From *JID `xml:"from,attr,omitempty"`
ID string `xml:"id,attr,omitempty"`
To *JID `xml:"to,attr,omitempty"`
Type PresenceType `xml:"type,attr,omitempty"`
Lang string `xml:"lang,attr,omitempty"`
Show PresenceShow `xml:"show,omitempty"`
Status string `xml:"status,omitempty"`
Priority uint `xml:"priority,omitempty"` // default: 0
Error *ErrorClient
Delay *Delay `xml:"delay"` // which XEP ?
// which XEP ?
// Caps *ClientCaps `xml:"c"`
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

View File

@ -1,33 +0,0 @@
package messages
const (
// RFC 6120 - A.1 Stream Namespace
NSStream = "http://etherx.jabber.org/streams"
// RFC 6120 - A.2 Stream Error Namespace
NSStreamError = "urn:ietf:params:xml:ns:xmpp-streams"
// RFC 6120 - A.3 StartTLS Namespace
NSStartTLS = "urn:ietf:params:xml:ns:xmpp-tls"
// RFC 6120 - A.4 SASL Namespace
NSSASL = "urn:ietf:params:xml:ns:xmpp-sasl"
// RFC 6120 - A.5 Client Namespace
NSClient = "jabber:client"
// RFC 6120 - A.6 Server Namespace
NSServer = "jabber:server"
// RFC 6120 - A.7 Resource Binding Namespace
NSBind = "urn:ietf:params:xml:ns:xmpp-bind"
// RFC 6120 - A.8 Stanza Error Binding Namespace
NSStanzaError = "urn:ietf:params:xml:ns:xmpp-stanzas"
NSIQRegister = "jabber:iq:register"
NSFeaturesIQRegister = "http://jabber.org/features/iq-register"
NSDisco = "http://jabber.org/protocol/disco#info"
)

View File

@ -1,19 +0,0 @@
package messages
// which XEP ????
import (
"encoding/xml"
)
type ClientQuery struct {
Item []RosterItem
}
type RosterItem struct {
XMLName xml.Name `xml:"jabber:iq:roster item"`
JID *JID `xml:",attr"`
Name string `xml:",attr"`
Subscription string `xml:",attr"`
Group []string
}

View File

@ -1,23 +0,0 @@
package messages
import (
"encoding/xml"
)
// RFC 6120 - A.6 Server Namespace (a part)
type IQServer struct {
XMLName xml.Name `xml:"jabber:server iq"`
From *JID `xml:"from,attr,omitempty"`
ID string `xml:"id,attr"` // required
To *JID `xml:"to,attr"` // required
Type IQType `xml:"type,attr"` // required
Error *ErrorServer
Bind *Bind // which XEP ?
Ping *Ping // which XEP ?
PrivateQuery *IQPrivateQuery // which XEP ?
PrivateRegister *IQPrivateRegister // which XEP ?
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

View File

@ -1,25 +0,0 @@
package messages
import (
"encoding/xml"
)
// RFC 6120 - A.6 Server Namespace (a part)
type MessageServer struct {
XMLName xml.Name `xml:"jabber:server message"`
From *JID `xml:"from,attr"` // required
ID string `xml:"id,attr,omitempty"`
To *JID `xml:"to,attr"` // required
Type MessageType `xml:"type,attr,omitempty"` // default: normal
Lang string `xml:"lang,attr,omitempty"`
Subject string `xml:"subject,omitempty"`
Body string `xml:"body,omitempty"`
Thread string `xml:"thread,omitempty"`
Error *ErrorServer
Delay *Delay `xml:"delay"` // which XEP ?
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

View File

@ -1,29 +0,0 @@
package messages
import (
"encoding/xml"
)
// RFC 6120 - A.6 Server Namespace (a part)
type PresenceServer struct {
XMLName xml.Name `xml:"jabber:server presence"`
From *JID `xml:"from,attr"` // required
ID string `xml:"id,attr,omitempty"`
To *JID `xml:"to,attr"` // required
Type PresenceType `xml:"type,attr,omitempty"`
Lang string `xml:"lang,attr,omitempty"`
Show PresenceShow `xml:"show,omitempty"`
Status string `xml:"status,omitempty"`
Priority uint `xml:"priority,omitempty"` // default: 0
Error *ErrorServer
Delay *Delay `xml:"delay"` // which XEP ?
// which XEP ?
// Caps *ClientCaps `xml:"c"`
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

View File

@ -4,7 +4,7 @@ import (
"errors"
"sync"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
type Domain struct {
@ -13,37 +13,37 @@ type Domain struct {
sync.Mutex
}
func (d *Domain) GetJID() *messages.JID {
return &messages.JID{
func (d *Domain) GetJID() *xmppbase.JID {
return &xmppbase.JID{
Domain: d.FQDN,
}
}
func (d *Domain) UpdateAccount(a *Account) error {
if a.Local == "" {
if a.Node == "" {
return errors.New("No localpart exists in account")
}
d.Lock()
d.Accounts[a.Local] = a
d.Accounts[a.Node] = a
d.Unlock()
a.Domain = d
return nil
}
type Account struct {
Local string `json:"-"`
Node string `json:"-"`
Domain *Domain `json:"-"`
Password string `json:"password"`
Roster map[string]*Buddy `json:"roster"`
Bookmarks map[string]*Bookmark `json:"bookmarks"`
}
func NewAccount(jid *messages.JID, password string) *Account {
func NewAccount(jid *xmppbase.JID, password string) *Account {
if jid == nil {
return nil
}
return &Account{
Local: jid.Local,
Node: jid.Node,
Domain: &Domain{
FQDN: jid.Domain,
},
@ -51,10 +51,10 @@ func NewAccount(jid *messages.JID, password string) *Account {
}
}
func (a *Account) GetJID() *messages.JID {
return &messages.JID{
func (a *Account) GetJID() *xmppbase.JID {
return &xmppbase.JID{
Domain: a.Domain.FQDN,
Local: a.Local,
Node: a.Node,
}
}

View File

@ -3,16 +3,16 @@ package extension
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/server/utils"
"dev.sum7.eu/genofire/yaja/xmpp"
)
type IQExtensions []IQExtension
type IQExtension interface {
Extension
Get(*messages.IQClient, *utils.Client) bool
Set(*messages.IQClient, *utils.Client) bool
Get(*xmpp.IQClient, *utils.Client) bool
Set(*xmpp.IQClient, *utils.Client) bool
}
func (iex IQExtensions) Spaces() (result []string) {
@ -27,7 +27,7 @@ func (iex IQExtensions) Process(element *xml.StartElement, client *utils.Client)
log := client.Log.WithField("extension", "iq")
// iq encode
var msg messages.IQClient
var msg xmpp.IQClient
if err := client.In.DecodeElement(&msg, element); err != nil {
return false
}
@ -38,11 +38,11 @@ func (iex IQExtensions) Process(element *xml.StartElement, client *utils.Client)
count := 0
for _, extension := range iex {
switch msg.Type {
case messages.IQTypeGet:
case xmpp.IQTypeGet:
if extension.Get(&msg, client) {
count++
}
case messages.IQTypeSet:
case xmpp.IQTypeSet:
if extension.Set(&msg, client) {
count++
}
@ -51,7 +51,7 @@ func (iex IQExtensions) Process(element *xml.StartElement, client *utils.Client)
// not extensions found
if count != 1 {
log.Debugf("%s - %s: %s", msg.XMLName.Space, msg.Type, messages.XMLChildrenString(msg.Other))
log.Debugf("%s - %s: %s", msg.XMLName.Space, msg.Type, xmpp.XMLChildrenString(msg.Other))
}
return true

View File

@ -4,7 +4,7 @@ import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/database"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/model"
"dev.sum7.eu/genofire/yaja/server/utils"
)
@ -16,7 +16,7 @@ type IQDisco struct {
func (ex *IQDisco) Spaces() []string { return []string{"http://jabber.org/protocol/disco#items"} }
func (ex *IQDisco) Get(msg *messages.IQClient, client *utils.Client) bool {
func (ex *IQDisco) Get(msg *xmpp.IQClient, client *utils.Client) bool {
log := client.Log.WithField("extension", "disco-item").WithField("id", msg.ID)
// query encode
@ -58,10 +58,10 @@ func (ex *IQDisco) Get(msg *messages.IQClient, client *utils.Client) bool {
}
// reply
client.Messages <- &messages.IQClient{
Type: messages.IQTypeResult,
client.Messages <- &xmpp.IQClient{
Type: xmpp.IQTypeResult,
To: client.JID,
From: messages.NewJID(client.JID.Domain),
From: xmpp.NewJID(client.JID.Domain),
ID: msg.ID,
Body: queryByte,
}

View File

@ -3,7 +3,7 @@ package extension
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/model"
"dev.sum7.eu/genofire/yaja/server/utils"
)
@ -15,7 +15,7 @@ type IQExtensionDiscovery struct {
func (ex *IQExtensionDiscovery) Spaces() []string { return []string{} }
func (ex *IQExtensionDiscovery) Get(msg *messages.IQClient, client *utils.Client) bool {
func (ex *IQExtensionDiscovery) Get(msg *xmpp.IQClient, client *utils.Client) bool {
log := client.Log.WithField("extension", "roster").WithField("id", msg.ID)
// query encode
@ -58,10 +58,10 @@ func (ex *IQExtensionDiscovery) Get(msg *messages.IQClient, client *utils.Client
}
// replay
client.Messages <- &messages.IQClient{
Type: messages.IQTypeResult,
client.Messages <- &xmpp.IQClient{
Type: xmpp.IQTypeResult,
To: client.JID,
From: messages.NewJID(client.JID.Domain),
From: xmpp.NewJID(client.JID.Domain),
ID: msg.ID,
Body: queryByte,
}

View File

@ -3,7 +3,7 @@ package extension
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/model"
"dev.sum7.eu/genofire/yaja/server/utils"
)
@ -16,7 +16,7 @@ type IQLast struct {
func (ex *IQLast) Spaces() []string { return []string{"jabber:iq:last"} }
func (ex *IQLast) Get(msg *messages.IQClient, client *utils.Client) bool {
func (ex *IQLast) Get(msg *xmpp.IQClient, client *utils.Client) bool {
log := client.Log.WithField("extension", "last").WithField("id", msg.ID)
// query encode
@ -46,10 +46,10 @@ func (ex *IQLast) Get(msg *messages.IQClient, client *utils.Client) bool {
}
// reply
client.Messages <- &messages.IQClient{
Type: messages.IQTypeResult,
client.Messages <- &xmpp.IQClient{
Type: xmpp.IQTypeResult,
To: client.JID,
From: messages.NewJID(client.JID.Domain),
From: xmpp.NewJID(client.JID.Domain),
ID: msg.ID,
Body: queryByte,
}

View File

@ -1,8 +1,9 @@
package extension
import (
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/server/utils"
"dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
type IQPing struct {
@ -11,7 +12,7 @@ type IQPing struct {
func (ex *IQPing) Spaces() []string { return []string{"urn:xmpp:ping"} }
func (ex *IQPing) Get(msg *messages.IQClient, client *utils.Client) bool {
func (ex *IQPing) Get(msg *xmpp.IQClient, client *utils.Client) bool {
log := client.Log.WithField("extension", "ping").WithField("id", msg.ID)
if msg.Ping == nil {
@ -19,10 +20,10 @@ func (ex *IQPing) Get(msg *messages.IQClient, client *utils.Client) bool {
}
// reply
client.Messages <- &messages.IQClient{
Type: messages.IQTypeResult,
client.Messages <- &xmpp.IQClient{
Type: xmpp.IQTypeResult,
To: client.JID,
From: messages.NewJID(client.JID.Domain),
From: xmppbase.NewJID(client.JID.Domain),
ID: msg.ID,
}

View File

@ -3,7 +3,7 @@ package extension
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/model"
"dev.sum7.eu/genofire/yaja/server/utils"
)
@ -12,7 +12,7 @@ type IQPrivateBookmark struct {
IQExtension
}
func (ex *IQPrivateBookmark) Handle(msg *messages.IQClient, client *utils.Client) bool {
func (ex *IQPrivateBookmark) Handle(msg *xmpp.IQClient, client *utils.Client) bool {
log := client.Log.WithField("extension", "private").WithField("id", msg.ID)
// storage encode
@ -36,10 +36,10 @@ func (ex *IQPrivateBookmark) Handle(msg *messages.IQClient, client *utils.Client
}
// reply
client.Messages <- &messages.IQClient{
Type: messages.IQTypeResult,
client.Messages <- &xmpp.IQClient{
Type: xmpp.IQTypeResult,
To: client.JID,
From: messages.NewJID(client.JID.Domain),
From: xmpp.NewJID(client.JID.Domain),
ID: msg.ID,
Body: queryByte,
}

View File

@ -3,7 +3,7 @@ package extension
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/model"
"dev.sum7.eu/genofire/yaja/server/utils"
)
@ -12,7 +12,7 @@ type IQPrivateMetacontact struct {
IQExtension
}
func (ex *IQPrivateMetacontact) Handle(msg *messages.IQClient, client *utils.Client) bool {
func (ex *IQPrivateMetacontact) Handle(msg *xmpp.IQClient, client *utils.Client) bool {
log := client.Log.WithField("extension", "private-metacontact").WithField("id", msg.ID)
// storage encode
@ -37,10 +37,10 @@ func (ex *IQPrivateMetacontact) Handle(msg *messages.IQClient, client *utils.Cli
}
// reply
client.Messages <- &messages.IQClient{
Type: messages.IQTypeResult,
client.Messages <- &xmpp.IQClient{
Type: xmpp.IQTypeResult,
To: client.JID,
From: messages.NewJID(client.JID.Domain),
From: xmpp.NewJID(client.JID.Domain),
ID: msg.ID,
Body: queryByte,
}

View File

@ -3,7 +3,7 @@ package extension
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/model"
"dev.sum7.eu/genofire/yaja/server/utils"
)
@ -12,7 +12,7 @@ type IQPrivateRoster struct {
IQExtension
}
func (ex *IQPrivateRoster) Handle(msg *messages.IQClient, client *utils.Client) bool {
func (ex *IQPrivateRoster) Handle(msg *xmpp.IQClient, client *utils.Client) bool {
log := client.Log.WithField("extension", "private").WithField("id", msg.ID)
// roster encode
@ -41,10 +41,10 @@ func (ex *IQPrivateRoster) Handle(msg *messages.IQClient, client *utils.Client)
}
// reply
client.Messages <- &messages.IQClient{
Type: messages.IQTypeResult,
client.Messages <- &xmpp.IQClient{
Type: xmpp.IQTypeResult,
To: client.JID,
From: messages.NewJID(client.JID.Domain),
From: xmpp.NewJID(client.JID.Domain),
ID: msg.ID,
Body: queryByte,
}

View File

@ -4,7 +4,7 @@ import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/database"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/server/utils"
)
@ -15,7 +15,7 @@ type IQRoster struct {
func (ex *IQRoster) Spaces() []string { return []string{"jabber:iq:roster"} }
func (ex *IQRoster) Get(msg *messages.IQClient, client *utils.Client) bool {
func (ex *IQRoster) Get(msg *xmpp.IQClient, client *utils.Client) bool {
log := client.Log.WithField("extension", "roster").WithField("id", msg.ID)
// query encode
@ -59,8 +59,8 @@ func (ex *IQRoster) Get(msg *messages.IQClient, client *utils.Client) bool {
}
// reply
client.Messages <- &messages.IQClient{
Type: messages.IQTypeResult,
client.Messages <- &xmpp.IQClient{
Type: xmpp.IQTypeResult,
To: client.JID.String(),
From: client.JID.Domain,
ID: msg.ID,

View File

@ -3,8 +3,8 @@ package extension
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/server/utils"
"dev.sum7.eu/genofire/yaja/xmpp"
)
type Presence struct {
@ -19,11 +19,11 @@ func (p *Presence) Process(element *xml.StartElement, client *utils.Client) bool
log := client.Log.WithField("extension", "presence")
// iq encode
var msg messages.PresenceClient
var msg xmpp.PresenceClient
if err := client.In.DecodeElement(&msg, element); err != nil {
return false
}
client.Messages <- &messages.PresenceClient{
client.Messages <- &xmpp.PresenceClient{
ID: msg.ID,
}
log.Debug("send")

View File

@ -4,14 +4,15 @@ import (
"crypto/tls"
"net"
log "github.com/sirupsen/logrus"
"golang.org/x/crypto/acme/autocert"
"dev.sum7.eu/genofire/yaja/database"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/server/extension"
"dev.sum7.eu/genofire/yaja/server/toclient"
"dev.sum7.eu/genofire/yaja/server/toserver"
"dev.sum7.eu/genofire/yaja/server/utils"
log "github.com/sirupsen/logrus"
"golang.org/x/crypto/acme/autocert"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
type Server struct {
@ -109,7 +110,7 @@ func (srv *Server) handleClient(conn net.Conn) {
}
}
func (srv *Server) DomainRegisterAllowed(jid *messages.JID) bool {
func (srv *Server) DomainRegisterAllowed(jid *xmppbase.JID) bool {
if jid.Domain == "" {
return false
}

View File

@ -4,9 +4,11 @@ import (
"crypto/tls"
"fmt"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/server/utils"
"golang.org/x/crypto/acme/autocert"
"dev.sum7.eu/genofire/yaja/server/utils"
"dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
// Start state
@ -26,13 +28,13 @@ func (state *Start) Process() State {
state.Client.Log.Warn("unable to read: ", err)
return nil
}
if element.Name.Space != messages.NSStream || element.Name.Local != "stream" {
if element.Name.Space != xmpp.NSStream || element.Name.Local != "stream" {
state.Client.Log.Warn("is no stream")
return state
}
for _, attr := range element.Attr {
if attr.Name.Local == "to" {
state.Client.JID = &messages.JID{Domain: attr.Value}
state.Client.JID = &xmppbase.JID{Domain: attr.Value}
state.Client.Log = state.Client.Log.WithField("jid", state.Client.JID.Full())
}
}
@ -43,14 +45,14 @@ func (state *Start) Process() State {
fmt.Fprintf(state.Client.Conn, `<?xml version='1.0'?>
<stream:stream id='%x' version='1.0' xmlns='%s' xmlns:stream='%s'>`,
messages.CreateCookie(), messages.NSClient, messages.NSStream)
xmpp.CreateCookie(), xmpp.NSClient, xmpp.NSStream)
fmt.Fprintf(state.Client.Conn, `<stream:features>
<starttls xmlns='%s'>
<required/>
</starttls>
</stream:features>`,
messages.NSStream)
xmpp.NSStream)
return state.Next
}
@ -74,11 +76,11 @@ func (state *TLSUpgrade) Process() State {
state.Client.Log.Warn("unable to read: ", err)
return nil
}
if element.Name.Space != messages.NSStartTLS || element.Name.Local != "starttls" {
if element.Name.Space != xmpp.NSStartTLS || element.Name.Local != "starttls" {
state.Client.Log.Warn("is no starttls", element)
return nil
}
fmt.Fprintf(state.Client.Conn, "<proceed xmlns='%s'/>", messages.NSStartTLS)
fmt.Fprintf(state.Client.Conn, "<proceed xmlns='%s'/>", xmpp.NSStartTLS)
// perform the TLS handshake
var tlsConfig *tls.Config
if m := state.TLSManager; m != nil {

View File

@ -11,7 +11,7 @@ type SendingClient struct {
Client *utils.Client
}
// Process messages
// Process xmpp
func (state *SendingClient) Process() State {
state.Client.Log = state.Client.Log.WithField("state", "normal")
state.Client.Log.Debug("sending")
@ -37,7 +37,7 @@ type ReceivingClient struct {
Client *utils.Client
}
// Process messages
// Process xmpp
func (state *ReceivingClient) Process() State {
element, err := state.Client.Read()
if err != nil {

View File

@ -6,12 +6,15 @@ import (
"fmt"
"strings"
"golang.org/x/crypto/acme/autocert"
"dev.sum7.eu/genofire/yaja/database"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/server/extension"
"dev.sum7.eu/genofire/yaja/server/state"
"dev.sum7.eu/genofire/yaja/server/utils"
"golang.org/x/crypto/acme/autocert"
"dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/xmpp/base"
"dev.sum7.eu/genofire/yaja/xmpp/iq"
)
// ConnectionStartup return steps through TCP TLS state
@ -47,7 +50,7 @@ type TLSStream struct {
domainRegisterAllowed utils.DomainRegisterAllowed
}
// Process messages
// Process xmpp
func (state *TLSStream) Process() state.State {
state.Client.Log = state.Client.Log.WithField("state", "tls stream")
state.Client.Log.Debug("running")
@ -58,7 +61,7 @@ func (state *TLSStream) Process() state.State {
state.Client.Log.Warn("unable to read: ", err)
return nil
}
if element.Name.Space != messages.NSStream || element.Name.Local != "stream" {
if element.Name.Space != xmpp.NSStream || element.Name.Local != "stream" {
state.Client.Log.Warn("is no stream")
return state
}
@ -72,8 +75,8 @@ func (state *TLSStream) Process() state.State {
<mechanism>PLAIN</mechanism>
</mechanisms>
</stream:features>`,
messages.CreateCookie(), messages.NSClient, messages.NSStream,
messages.NSSASL, messages.NSFeaturesIQRegister)
xmpp.CreateCookie(), xmpp.NSClient, xmpp.NSStream,
xmpp.NSSASL, xmppiq.NSFeaturesIQRegister)
} else {
fmt.Fprintf(state.Client.Conn, `<?xml version='1.0'?>
<stream:stream id='%x' version='1.0' xmlns='%s' xmlns:stream='%s'>
@ -82,8 +85,8 @@ func (state *TLSStream) Process() state.State {
<mechanism>PLAIN</mechanism>
</mechanisms>
</stream:features>`,
messages.CreateCookie(), messages.NSClient, messages.NSStream,
messages.NSSASL)
xmpp.CreateCookie(), xmpp.NSClient, xmpp.NSStream,
xmpp.NSSASL)
}
return state.Next
@ -97,7 +100,7 @@ type SASLAuth struct {
domainRegisterAllowed utils.DomainRegisterAllowed
}
// Process messages
// Process xmpp
func (state *SASLAuth) Process() state.State {
state.Client.Log = state.Client.Log.WithField("state", "sasl auth")
state.Client.Log.Debug("running")
@ -109,7 +112,7 @@ func (state *SASLAuth) Process() state.State {
state.Client.Log.Warn("unable to read: ", err)
return nil
}
var auth messages.SASLAuth
var auth xmpp.SASLAuth
if err = state.Client.In.DecodeElement(&auth, element); err != nil {
state.Client.Log.Info("start substate for registration")
return &RegisterFormRequest{
@ -131,7 +134,7 @@ func (state *SASLAuth) Process() state.State {
}
info := strings.Split(string(data), "\x00")
// should check that info[1] starts with state.Client.JID
state.Client.JID.Local = info[1]
state.Client.JID.Node = info[1]
state.Client.Log = state.Client.Log.WithField("jid", state.Client.JID.Full())
success, err := state.database.Authenticate(state.Client.JID, info[2])
if err != nil {
@ -140,11 +143,11 @@ func (state *SASLAuth) Process() state.State {
}
if success {
state.Client.Log.Info("success auth")
fmt.Fprintf(state.Client.Conn, "<success xmlns='%s'/>", messages.NSSASL)
fmt.Fprintf(state.Client.Conn, "<success xmlns='%s'/>", xmpp.NSSASL)
return state.Next
}
state.Client.Log.Warn("failed auth")
fmt.Fprintf(state.Client.Conn, "<failure xmlns='%s'><not-authorized/></failure>", messages.NSSASL)
fmt.Fprintf(state.Client.Conn, "<failure xmlns='%s'><not-authorized/></failure>", xmpp.NSSASL)
return nil
}
@ -155,7 +158,7 @@ type AuthedStart struct {
Client *utils.Client
}
// Process messages
// Process xmpp
func (state *AuthedStart) Process() state.State {
state.Client.Log = state.Client.Log.WithField("state", "authed started")
state.Client.Log.Debug("running")
@ -173,8 +176,8 @@ func (state *AuthedStart) Process() state.State {
<required/>
</bind>
</stream:features>`,
messages.NSStream, state.Client.JID.Domain, messages.CreateCookie(), messages.NSClient,
messages.NSBind)
xmpp.NSStream, state.Client.JID.Domain, xmpp.CreateCookie(), xmpp.NSClient,
xmpp.NSBind)
return state.Next
}
@ -185,7 +188,7 @@ type AuthedStream struct {
Client *utils.Client
}
// Process messages
// Process xmpp
func (state *AuthedStream) Process() state.State {
state.Client.Log = state.Client.Log.WithField("state", "authed stream")
state.Client.Log.Debug("running")
@ -198,12 +201,12 @@ func (state *AuthedStream) Process() state.State {
state.Client.Log.Warn("unable to read: ", err)
return nil
}
var msg messages.IQClient
var msg xmpp.IQClient
if err = state.Client.In.DecodeElement(&msg, element); err != nil {
state.Client.Log.Warn("is no iq: ", err)
return nil
}
if msg.Type != messages.IQTypeSet {
if msg.Type != xmpp.IQTypeSet {
state.Client.Log.Warn("is no set iq")
return nil
}
@ -222,12 +225,12 @@ func (state *AuthedStream) Process() state.State {
state.Client.JID.Resource = msg.Bind.Resource
}
state.Client.Log = state.Client.Log.WithField("jid", state.Client.JID.Full())
state.Client.Out.Encode(&messages.IQClient{
Type: messages.IQTypeResult,
state.Client.Out.Encode(&xmpp.IQClient{
Type: xmpp.IQTypeResult,
To: state.Client.JID,
From: messages.NewJID(state.Client.JID.Domain),
From: xmppbase.NewJID(state.Client.JID.Domain),
ID: msg.ID,
Bind: &messages.Bind{JID: state.Client.JID},
Bind: &xmpp.Bind{JID: state.Client.JID},
})
return state.Next

View File

@ -4,10 +4,12 @@ import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/database"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/model"
"dev.sum7.eu/genofire/yaja/server/state"
"dev.sum7.eu/genofire/yaja/server/utils"
"dev.sum7.eu/genofire/yaja/xmpp"
"dev.sum7.eu/genofire/yaja/xmpp/base"
"dev.sum7.eu/genofire/yaja/xmpp/iq"
)
type RegisterFormRequest struct {
@ -28,12 +30,12 @@ func (state *RegisterFormRequest) Process() state.State {
return nil
}
var msg messages.IQClient
var msg xmpp.IQClient
if err := state.Client.In.DecodeElement(&msg, state.element); err != nil {
state.Client.Log.Warn("is no iq: ", err)
return state
}
if msg.Type != messages.IQTypeGet {
if msg.Type != xmpp.IQTypeGet {
state.Client.Log.Warn("is no get iq")
return state
}
@ -46,12 +48,12 @@ func (state *RegisterFormRequest) Process() state.State {
state.Client.Log.Warn("is no iq register")
return nil
}
state.Client.Out.Encode(&messages.IQClient{
Type: messages.IQTypeResult,
state.Client.Out.Encode(&xmpp.IQClient{
Type: xmpp.IQTypeResult,
To: state.Client.JID,
From: messages.NewJID(state.Client.JID.Domain),
From: xmppbase.NewJID(state.Client.JID.Domain),
ID: msg.ID,
PrivateRegister: &messages.IQPrivateRegister{
PrivateRegister: &xmppiq.IQPrivateRegister{
Instructions: "Choose a username and password for use with this service.",
Username: "",
Password: "",
@ -83,12 +85,12 @@ func (state *RegisterRequest) Process() state.State {
state.Client.Log.Warn("unable to read: ", err)
return nil
}
var msg messages.IQClient
var msg xmpp.IQClient
if err = state.Client.In.DecodeElement(&msg, element); err != nil {
state.Client.Log.Warn("is no iq: ", err)
return state
}
if msg.Type != messages.IQTypeGet {
if msg.Type != xmpp.IQTypeGet {
state.Client.Log.Warn("is no get iq")
return state
}
@ -101,21 +103,21 @@ func (state *RegisterRequest) Process() state.State {
return nil
}
state.Client.JID.Local = msg.PrivateRegister.Username
state.Client.JID.Node = msg.PrivateRegister.Username
state.Client.Log = state.Client.Log.WithField("jid", state.Client.JID.Full())
account := model.NewAccount(state.Client.JID, msg.PrivateRegister.Password)
err = state.database.AddAccount(account)
if err != nil {
state.Client.Out.Encode(&messages.IQClient{
Type: messages.IQTypeResult,
state.Client.Out.Encode(&xmpp.IQClient{
Type: xmpp.IQTypeResult,
To: state.Client.JID,
From: messages.NewJID(state.Client.JID.Domain),
From: xmppbase.NewJID(state.Client.JID.Domain),
ID: msg.ID,
PrivateRegister: msg.PrivateRegister,
Error: &messages.ErrorClient{
Error: &xmpp.ErrorClient{
Code: "409",
Type: "cancel",
StanzaErrorGroup: messages.StanzaErrorGroup{
StanzaErrorGroup: xmpp.StanzaErrorGroup{
Conflict: &xml.Name{},
},
},
@ -123,10 +125,10 @@ func (state *RegisterRequest) Process() state.State {
state.Client.Log.Warn("database error: ", err)
return state
}
state.Client.Out.Encode(&messages.IQClient{
Type: messages.IQTypeResult,
state.Client.Out.Encode(&xmpp.IQClient{
Type: xmpp.IQTypeResult,
To: state.Client.JID,
From: messages.NewJID(state.Client.JID.Domain),
From: xmppbase.NewJID(state.Client.JID.Domain),
ID: msg.ID,
})

View File

@ -6,12 +6,13 @@ import (
"encoding/xml"
"fmt"
"golang.org/x/crypto/acme/autocert"
"dev.sum7.eu/genofire/yaja/database"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/server/extension"
"dev.sum7.eu/genofire/yaja/server/state"
"dev.sum7.eu/genofire/yaja/server/utils"
"golang.org/x/crypto/acme/autocert"
"dev.sum7.eu/genofire/yaja/xmpp"
)
// ConnectionStartup return steps through TCP TLS state
@ -41,7 +42,7 @@ type Dailback struct {
Client *utils.Client
}
// Process messages
// Process xmpp
func (state *Dailback) Process() state.State {
state.Client.Log = state.Client.Log.WithField("state", "dialback")
state.Client.Log.Debug("running")
@ -73,7 +74,7 @@ type TLSStream struct {
domainRegisterAllowed utils.DomainRegisterAllowed
}
// Process messages
// Process xmpp
func (state *TLSStream) Process() state.State {
state.Client.Log = state.Client.Log.WithField("state", "tls stream")
state.Client.Log.Debug("running")
@ -84,7 +85,7 @@ func (state *TLSStream) Process() state.State {
state.Client.Log.Warn("unable to read: ", err)
return nil
}
if element.Name.Space != messages.NSStream || element.Name.Local != "stream" {
if element.Name.Space != xmpp.NSStream || element.Name.Local != "stream" {
state.Client.Log.Warn("is no stream")
return state
}
@ -97,8 +98,8 @@ func (state *TLSStream) Process() state.State {
</mechanisms>
<bidi xmlns='urn:xmpp:features:bidi'/>
</stream:features>`,
messages.CreateCookie(), messages.NSClient, messages.NSStream,
messages.NSSASL)
xmpp.CreateCookie(), xmpp.NSClient, xmpp.NSStream,
xmpp.NSSASL)
return state.Next
}
@ -111,7 +112,7 @@ type SASLAuth struct {
domainRegisterAllowed utils.DomainRegisterAllowed
}
// Process messages
// Process xmpp
func (state *SASLAuth) Process() state.State {
state.Client.Log = state.Client.Log.WithField("state", "sasl auth")
state.Client.Log.Debug("running")
@ -123,7 +124,7 @@ func (state *SASLAuth) Process() state.State {
state.Client.Log.Warn("unable to read: ", err)
return nil
}
var auth messages.SASLAuth
var auth xmpp.SASLAuth
if err = state.Client.In.DecodeElement(&auth, element); err != nil {
return nil
}
@ -136,6 +137,6 @@ func (state *SASLAuth) Process() state.State {
state.Client.Log.Debug(auth.Mechanism, string(data))
state.Client.Log.Info("success auth")
fmt.Fprintf(state.Client.Conn, "<success xmlns='%s'/>", messages.NSSASL)
fmt.Fprintf(state.Client.Conn, "<success xmlns='%s'/>", xmpp.NSSASL)
return state.Next
}

View File

@ -4,9 +4,10 @@ import (
"encoding/xml"
"net"
"dev.sum7.eu/genofire/yaja/messages"
"dev.sum7.eu/genofire/yaja/model"
log "github.com/sirupsen/logrus"
"dev.sum7.eu/genofire/yaja/model"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
type Client struct {
@ -16,7 +17,7 @@ type Client struct {
Out *xml.Encoder
In *xml.Decoder
JID *messages.JID
JID *xmppbase.JID
account *model.Account
Messages chan interface{}

View File

@ -1,5 +1,5 @@
package utils
import "dev.sum7.eu/genofire/yaja/messages"
import "dev.sum7.eu/genofire/yaja/xmpp/base"
type DomainRegisterAllowed func(*messages.JID) bool
type DomainRegisterAllowed func(*xmppbase.JID) bool

View File

@ -1,4 +1,4 @@
package messages
package xmppbase
import (
"errors"
@ -13,7 +13,7 @@ func init() {
// JID struct
type JID struct {
Local string
Node string
Domain string
Resource string
}
@ -28,7 +28,7 @@ func NewJID(jidString string) *JID {
jidSplit := jidSplitTmp[0]
return &JID{
Local: jidSplit[1],
Node: jidSplit[1],
Domain: jidSplit[2],
Resource: jidSplit[3],
}
@ -39,13 +39,16 @@ func (jid *JID) Bare() string {
if jid == nil {
return ""
}
if jid.Local != "" {
return jid.Local + "@" + jid.Domain
if jid.Node != "" {
return jid.Node + "@" + jid.Domain
}
return jid.Domain
}
func (jid *JID) String() string { return jid.Bare() }
// IsBare checks if jid has node and domain but no resource
func (jid *JID) IsBare() bool {
return jid != nil && jid.Node != "" && jid.Domain != "" && jid.Resource == ""
}
// Full get the "full" jid as string
func (jid *JID) Full() string {
@ -58,6 +61,13 @@ func (jid *JID) Full() string {
return jid.Bare()
}
// IsFull checks if jid has all three parts of a JID
func (jid *JID) IsFull() bool {
return jid != nil && jid.Node != "" && jid.Domain != "" && jid.Resource != ""
}
func (jid *JID) String() string { return jid.Bare() }
//MarshalText to bytearray
func (jid JID) MarshalText() ([]byte, error) {
return []byte(jid.Full()), nil
@ -69,7 +79,7 @@ func (jid *JID) UnmarshalText(data []byte) (err error) {
if newJID == nil {
return errors.New("not a valid jid")
}
jid.Local = newJID.Local
jid.Node = newJID.Node
jid.Domain = newJID.Domain
jid.Resource = newJID.Resource
return nil

View File

@ -1,4 +1,4 @@
package messages
package xmppbase
import (
"testing"
@ -13,57 +13,57 @@ func TestNewJID(t *testing.T) {
checkList := map[string]*JID{
"juliet@example.com": {
Local: "juliet",
Node: "juliet",
Domain: "example.com",
},
"juliet@example.com/foo": {
Local: "juliet",
Node: "juliet",
Domain: "example.com",
Resource: "foo",
},
"juliet@example.com/foo bar": {
Local: "juliet",
Node: "juliet",
Domain: "example.com",
Resource: "foo bar",
},
"juliet@example.com/foo@bar": {
Local: "juliet",
Node: "juliet",
Domain: "example.com",
Resource: "foo@bar",
},
"foo\\20bar@example.com": {
Local: "foo\\20bar",
Node: "foo\\20bar",
Domain: "example.com",
},
"fussball@example.com": {
Local: "fussball",
Node: "fussball",
Domain: "example.com",
},
"fu&#xDF;ball@example.com": {
Local: "fu&#xDF;ball",
Node: "fu&#xDF;ball",
Domain: "example.com",
},
"&#x3C0;@example.com": {
Local: "&#x3C0;",
Node: "&#x3C0;",
Domain: "example.com",
},
"&#x3A3;@example.com/foo": {
Local: "&#x3A3;",
Node: "&#x3A3;",
Domain: "example.com",
Resource: "foo",
},
"&#x3C3;@example.com/foo": {
Local: "&#x3C3;",
Node: "&#x3C3;",
Domain: "example.com",
Resource: "foo",
},
"&#x3C2;@example.com/foo": {
Local: "&#x3C2;",
Node: "&#x3C2;",
Domain: "example.com",
Resource: "foo",
},
"king@example.com/&#x265A;": {
Local: "king",
Node: "king",
Domain: "example.com",
Resource: "&#x265A;",
},
@ -97,7 +97,7 @@ func TestNewJID(t *testing.T) {
continue
}
assert.Equal(jidValid.Local, jid.Local, "the local part was not right detectet:"+jidString)
assert.Equal(jidValid.Node, jid.Node, "the local part was not right detectet:"+jidString)
assert.Equal(jidValid.Domain, jid.Domain, "the domain part was not right detectet:"+jidString)
assert.Equal(jidValid.Resource, jid.Resource, "the resource part was not right detectet:"+jidString)
assert.Equal(jidValid.Full(), jidString, "the function full of jid did not work")
@ -113,11 +113,11 @@ func TestJIDBare(t *testing.T) {
checkList := map[string]*JID{
"aaa@example.com": {
Local: "aaa",
Node: "aaa",
Domain: "example.com",
},
"aab@example.com": {
Local: "aab",
Node: "aab",
Domain: "example.com",
Resource: "foo",
},
@ -140,7 +140,7 @@ func TestMarshal(t *testing.T) {
err := jid.UnmarshalText([]byte("juliet@example.com/foo"))
assert.NoError(err)
assert.Equal(jid.Local, "juliet")
assert.Equal(jid.Node, "juliet")
assert.Equal(jid.Domain, "example.com")
assert.Equal(jid.Resource, "foo")
@ -149,7 +149,7 @@ func TestMarshal(t *testing.T) {
assert.Error(err)
jid = &JID{
Local: "romeo",
Node: "romeo",
Domain: "example.com",
Resource: "bar",
}

View File

@ -1,8 +1,8 @@
package messages
package xmpp
import "encoding/xml"
// RFC 6120 - A.5 Client Namespace (a part)
// ErrorClient implements RFC 6120 - A.5 Client Namespace (a part)
type ErrorClient struct {
XMLName xml.Name `xml:"jabber:client error"`
Code string `xml:"code,attr,omitempty"`

26
xmpp/client_iq.go Normal file
View File

@ -0,0 +1,26 @@
package xmpp
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/xmpp/base"
"dev.sum7.eu/genofire/yaja/xmpp/iq"
)
// IQClient implements RFC 6120 - A.5 Client Namespace (a part)
type IQClient struct {
XMLName xml.Name `xml:"jabber:client iq"`
From *xmppbase.JID `xml:"from,attr,omitempty"`
ID string `xml:"id,attr"` // required
To *xmppbase.JID `xml:"to,attr,omitempty"`
Type IQType `xml:"type,attr"` // required
Error *ErrorClient
Bind *Bind // RFC 6120 A.7 Resource binding namespace (But in a IQ?)
Ping *xmppiq.Ping // XEP-0199: XMPP Ping (see iq/ping.go)
PrivateQuery *xmppiq.IQPrivateQuery // which XEP ?
PrivateRegister *xmppiq.IQPrivateRegister // which XEP ?
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

27
xmpp/client_message.go Normal file
View File

@ -0,0 +1,27 @@
package xmpp
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
// MessageClient implements RFC 6120 - A.5 Client Namespace (a part)
type MessageClient struct {
XMLName xml.Name `xml:"jabber:client message"`
From *xmppbase.JID `xml:"from,attr,omitempty"`
ID string `xml:"id,attr,omitempty"`
To *xmppbase.JID `xml:"to,attr,omitempty"`
Type MessageType `xml:"type,attr,omitempty"` // default: normal
Lang string `xml:"lang,attr,omitempty"`
Subject string `xml:"subject,omitempty"`
Body string `xml:"body,omitempty"`
Thread string `xml:"thread,omitempty"`
Error *ErrorClient
Delay *Delay `xml:"delay"` // which XEP ?
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

31
xmpp/client_presence.go Normal file
View File

@ -0,0 +1,31 @@
package xmpp
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
// PresenceClient implements RFC 6120 - A.5 Client Namespace (a part)
type PresenceClient struct {
XMLName xml.Name `xml:"jabber:client presence"`
From *xmppbase.JID `xml:"from,attr,omitempty"`
ID string `xml:"id,attr,omitempty"`
To *xmppbase.JID `xml:"to,attr,omitempty"`
Type PresenceType `xml:"type,attr,omitempty"`
Lang string `xml:"lang,attr,omitempty"`
Show PresenceShow `xml:"show,omitempty"`
Status string `xml:"status,omitempty"`
Priority uint `xml:"priority,omitempty"` // default: 0
Error *ErrorClient
Delay *Delay `xml:"delay"` // which XEP ?
// which XEP ?
// Caps *ClientCaps `xml:"c"`
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

View File

@ -1,10 +1,12 @@
package messages
package xmpp
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
// RFC 6120 - A.1 Stream Namespace
// StreamFeatures implements RFC 6120 - A.1 Stream Namespace
type StreamFeatures struct {
XMLName xml.Name `xml:"http://etherx.jabber.org/streams features"`
StartTLS *TLSStartTLS
@ -13,25 +15,25 @@ type StreamFeatures struct {
Session bool
}
// RFC 6120 - A.3 StartTLS Namespace
// TLSStartTLS implements RFC 6120 - A.3 StartTLS Namespace
type TLSStartTLS struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-tls starttls"`
Required *string `xml:"required"`
}
// RFC 6120 - A.3 StartTLS Namespace
// TLSProceed implements RFC 6120 - A.3 StartTLS Namespace
type TLSProceed struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-tls proceed"`
}
// RFC 6120 - A.3 StartTLS Namespace
// TLSFailure implements RFC 6120 - A.3 StartTLS Namespace
type TLSFailure struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-tls failure"`
}
// RFC 6120 A.7 Resource binding namespace
// Bind implements RFC 6120 A.7 Resource binding namespace
type Bind struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-bind bind"`
Resource string `xml:"resource"`
JID *JID `xml:"jid"`
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-bind bind"`
Resource string `xml:"resource"`
JID *xmppbase.JID `xml:"jid"`
}

View File

@ -1,5 +1,6 @@
package messages
package xmpp
// ErrorType is a Enum of error attribute type
type ErrorType string
// RFC 6120 part of A.5 Client Namespace and A.6 Server Namespace

View File

@ -1,5 +1,6 @@
package messages
package xmpp
// IQType is a Enum of iq attribute type
type IQType string
// RFC 6120 part of A.5 Client Namespace and A.6 Server Namespace

View File

@ -1,5 +1,6 @@
package messages
package xmpp
// MessageType is a Enum of message attribute type
type MessageType string
// RFC 6120 part of A.5 Client Namespace and A.6 Server Namespace

View File

@ -1,5 +1,6 @@
package messages
package xmpp
// PresenceType is a Enum of presence attribute type
type PresenceType string
// RFC 6120 part of A.5 Client Namespace and A.6 Server Namespace
@ -13,6 +14,7 @@ const (
PresenceTypeUnsubscribed PresenceType = "unsubscribed"
)
// PresenceShow is a Enum of presence element show
type PresenceShow string
// RFC 6120 part of A.5 Client Namespace and A.6 Server Namespace

View File

@ -1,8 +1,8 @@
package messages
package xmpp
import "encoding/xml"
// RFC 6120 A.8 Resource binding namespace
// StanzaErrorGroup implements RFC 6120 A.8 Resource binding namespace
type StanzaErrorGroup struct {
BadRequest *xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-stanzas bad-request"`
Conflict *xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-stanzas conflict"`

View File

@ -1,8 +1,8 @@
package messages
package xmpp
import "encoding/xml"
// RFC 6120 A.2 Stream Error Namespace
// StreamErrorGroup implements RFC 6120 A.2 Stream Error Namespace
type StreamErrorGroup struct {
BadFormat *xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-streams bad-format"`
BadNamespacePrefix *xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-streams bad-namespace-prefix"`
@ -31,7 +31,7 @@ type StreamErrorGroup struct {
UnsupportedVersion *xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-streams unsupported-version"`
}
// RFC 6120 A.2 Stream Error Namespace
// StreamError implements RFC 6120 A.2 Stream Error Namespace
type StreamError struct {
XMLName xml.Name `xml:"http://etherx.jabber.org/streams error"`
Text *Text

View File

@ -1,8 +1,8 @@
package messages
package xmpp
import "encoding/xml"
// RFC 6120 part of A.2 Stream Error Namespace, A.4 SASL Namespace and A.8 Stanza Error Namespace
// Text implements RFC 6120 part of A.2 Stream Error Namespace, A.4 SASL Namespace and A.8 Stanza Error Namespace
type Text struct {
// `xml:"urn:ietf:params:xml:ns:xmpp-streams text"`
// `xml:"urn:ietf:params:xml:ns:xmpp-sasl text"`
@ -12,13 +12,13 @@ type Text struct {
Body string `xml:",innerxml"`
}
// Fallback - any hasn't matched element
// XMLElement is for Unmarshal undefined structs a fallback - any hasn't matched element
type XMLElement struct {
XMLName xml.Name
InnerXML string `xml:",innerxml"`
}
// which XEP ?
// Delay implements which XEP ?
type Delay struct {
Stamp string `xml:"stamp,attr"`
}

18
xmpp/iq/namespaces.go Normal file
View File

@ -0,0 +1,18 @@
package xmppiq
const (
// NSIQPing implements XEP-0199: XMPP Ping - 10
NSIQPing = "urn:xmpp:ping"
// NSIQDiscoInfo implements XEP 0030: Service Discovery - 11.1 disco#info
NSIQDiscoInfo = "http://jabber.org/protocol/disco#info"
// NSIQDiscoItems implements XEP 0030: Service Discovery - 11.2 disco#items
NSIQDiscoItems = "http://jabber.org/protocol/disco#items"
// NSIQRegister implements which XEP ?
NSIQRegister = "jabber:iq:register"
// NSFeaturesIQRegister implements which XEP ?
NSFeaturesIQRegister = "http://jabber.org/features/iq-register"
)

10
xmpp/iq/ping.go Normal file
View File

@ -0,0 +1,10 @@
package xmppiq
import (
"encoding/xml"
)
// XEP-0199: XMPP Ping
type Ping struct {
XMLName xml.Name `xml:"urn:xmpp:ping ping"`
}

View File

@ -0,0 +1,44 @@
package xmppiq
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
// IQDiscoQueryInfo implements XEP 0030: Service Discovery - 11.1 disco#info
type IQDiscoQueryInfo struct {
XMLName xml.Name `xml:"http://jabber.org/protocol/disco#info query"`
Node *string `xml:"node,attr"`
Identities []*IQDiscoIdentity
Features []*IQDiscoFeature
}
// IQDiscoIdentity implements XEP 0030: Service Discovery - 11.1 disco#info
type IQDiscoIdentity struct {
XMLName xml.Name `xml:"http://jabber.org/protocol/disco#info identity"`
Category string `xml:"category"` //required
Name *string `xml:"name"`
Type string `xml:"type"` //required
}
// IQDiscoFeature implements XEP 0030: Service Discovery - 11.1 disco#info
type IQDiscoFeature struct {
XMLName xml.Name `xml:"http://jabber.org/protocol/disco#info feature"`
Var string `xml:"var"` //required
}
// IQDiscoQueryItem implements XEP 0030: Service Discovery - 11.2 disco#items
type IQDiscoQueryItem struct {
XMLName xml.Name `xml:"http://jabber.org/protocol/disco#items query"`
Node *string `xml:"node,attr"`
Items []*IQDiscoItem
}
// IQDiscoItem implements XEP 0030: Service Discovery - 11.2 disco#items
type IQDiscoItem struct {
XMLName xml.Name `xml:"http://jabber.org/protocol/disco#items item"`
JID *xmppbase.JID `xml:"jid"`
Node *string `xml:"node"`
Name *string `xml:"name"`
}

View File

@ -1,14 +1,9 @@
package messages
package xmppiq
import (
"encoding/xml"
)
// XEP-0199: XMPP Ping
type Ping struct {
XMLName xml.Name `xml:"urn:xmpp:ping ping"`
}
// which XEP ????
// where to put: (server part debug? is it part)
type IQPrivateQuery struct {

27
xmpp/namespaces.go Normal file
View File

@ -0,0 +1,27 @@
package xmpp
const (
// NSStream implements RFC 6120 - A.1 Stream Namespace
NSStream = "http://etherx.jabber.org/streams"
// NSStreamError implements RFC 6120 - A.2 Stream Error Namespace
NSStreamError = "urn:ietf:params:xml:ns:xmpp-streams"
// NSStartTLS implements RFC 6120 - A.3 StartTLS Namespace
NSStartTLS = "urn:ietf:params:xml:ns:xmpp-tls"
// NSSASL implements RFC 6120 - A.4 SASL Namespace
NSSASL = "urn:ietf:params:xml:ns:xmpp-sasl"
// NSClient implements RFC 6120 - A.5 Client Namespace
NSClient = "jabber:client"
// NSServer implements RFC 6120 - A.6 Server Namespace
NSServer = "jabber:server"
// NSBind implements RFC 6120 - A.7 Resource Binding Namespace
NSBind = "urn:ietf:params:xml:ns:xmpp-bind"
// NSStanzaError implements RFC 6120 - A.8 Stanza Error Binding Namespace
NSStanzaError = "urn:ietf:params:xml:ns:xmpp-stanzas"
)

21
xmpp/roster.go Normal file
View File

@ -0,0 +1,21 @@
package xmpp
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
// ClientQuery implements which XEP ????
type ClientQuery struct {
Item []RosterItem
}
// RosterItem implements which XEP ????
type RosterItem struct {
XMLName xml.Name `xml:"jabber:iq:roster item"`
JID *xmppbase.JID `xml:",attr"`
Name string `xml:",attr"`
Subscription string `xml:",attr"`
Group []string
}

View File

@ -1,46 +1,46 @@
package messages
package xmpp
import (
"encoding/xml"
)
// RFC 6120 - A.4 SASL Namespace
// SASLMechanisms implements RFC 6120 - A.4 SASL Namespace
type SASLMechanisms struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-sasl mechanisms"`
Mechanism []string `xml:"mechanism"`
}
// SASLAuth element
// SASLAuth implements SASLAuth element
type SASLAuth struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-sasl auth"`
Mechanism string `xml:"mechanism,attr"`
Body string `xml:",chardata"`
}
// SASLChallenge element
// SASLChallenge implements SASLChallenge element
type SASLChallenge struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-sasl challenge"`
Body string `xml:",chardata"`
}
// SASLResponse element
// SASLResponse implements SASLResponse element
type SASLResponse struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-sasl response"`
Body string `xml:",chardata"`
}
// SASLSuccess element
// SASLSuccess implements SASLSuccess element
type SASLSuccess struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-sasl success"`
Body string `xml:",chardata"`
}
// SASLAbout element
// SASLAbout implements SASLAbout element
type SASLAbout struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-sasl abort"`
}
// RFC 6120 - A.4 SASL Namespace
// SASLFailure implements RFC 6120 - A.4 SASL Namespace
type SASLFailure struct {
XMLName xml.Name `xml:"urn:ietf:params:xml:ns:xmpp-sasl failure"`

View File

@ -1,8 +1,8 @@
package messages
package xmpp
import "encoding/xml"
// RFC 6120 - A.6 Server Namespace (a part)
// ErrorServer implements RFC 6120 - A.6 Server Namespace (a part)
type ErrorServer struct {
XMLName xml.Name `xml:"jabber:server error"`
Code string `xml:"code,attr,omitempty"`

24
xmpp/server_iq.go Normal file
View File

@ -0,0 +1,24 @@
package xmpp
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/xmpp/base"
"dev.sum7.eu/genofire/yaja/xmpp/iq"
)
// IQServer implements RFC 6120 - A.6 Server Namespace (a part)
type IQServer struct {
XMLName xml.Name `xml:"jabber:server iq"`
From *xmppbase.JID `xml:"from,attr,omitempty"`
ID string `xml:"id,attr"` // required
To *xmppbase.JID `xml:"to,attr"` // required
Type IQType `xml:"type,attr"` // required
Error *ErrorServer
Bind *Bind // RFC 6120 A.7 Resource binding namespace (But in a IQ?)
Ping *xmppiq.Ping // XEP-0199: XMPP Ping (see iq/ping.go)
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

27
xmpp/server_message.go Normal file
View File

@ -0,0 +1,27 @@
package xmpp
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
// MessageServer implements RFC 6120 - A.6 Server Namespace (a part)
type MessageServer struct {
XMLName xml.Name `xml:"jabber:server message"`
From *xmppbase.JID `xml:"from,attr"` // required
ID string `xml:"id,attr,omitempty"`
To *xmppbase.JID `xml:"to,attr"` // required
Type MessageType `xml:"type,attr,omitempty"` // default: normal
Lang string `xml:"lang,attr,omitempty"`
Subject string `xml:"subject,omitempty"`
Body string `xml:"body,omitempty"`
Thread string `xml:"thread,omitempty"`
Error *ErrorServer
Delay *Delay `xml:"delay"` // which XEP ?
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

31
xmpp/server_presence.go Normal file
View File

@ -0,0 +1,31 @@
package xmpp
import (
"encoding/xml"
"dev.sum7.eu/genofire/yaja/xmpp/base"
)
// PresenceServer implements RFC 6120 - A.6 Server Namespace (a part)
type PresenceServer struct {
XMLName xml.Name `xml:"jabber:server presence"`
From *xmppbase.JID `xml:"from,attr"` // required
ID string `xml:"id,attr,omitempty"`
To *xmppbase.JID `xml:"to,attr"` // required
Type PresenceType `xml:"type,attr,omitempty"`
Lang string `xml:"lang,attr,omitempty"`
Show PresenceShow `xml:"show,omitempty"`
Status string `xml:"status,omitempty"`
Priority uint `xml:"priority,omitempty"` // default: 0
Error *ErrorServer
Delay *Delay `xml:"delay"` // which XEP ?
// which XEP ?
// Caps *ClientCaps `xml:"c"`
// Any hasn't matched element
Other []XMLElement `xml:",any"`
}

View File

@ -1,4 +1,4 @@
package messages
package xmpp
import (
"crypto/rand"
@ -21,7 +21,6 @@ func XMLStartElementToString(element *xml.StartElement) string {
}
func XMLChildrenString(o interface{}) (result string) {
first := true
val := reflect.ValueOf(o)
if val.Kind() == reflect.Interface && !val.IsNil() {
elm := val.Elem()
@ -29,25 +28,24 @@ func XMLChildrenString(o interface{}) (result string) {
val = elm
}
}
if val.Kind() != reflect.Struct {
return
}
// struct
for i := 0; i < val.NumField(); i++ {
valueField := val.Field(i)
if valueField.Kind() == reflect.Interface && !valueField.IsNil() {
elm := valueField.Elem()
if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr {
valueField = elm
if val.Kind() == reflect.Struct {
first := true
for i := 0; i < val.NumField(); i++ {
valueField := val.Field(i)
if valueField.Kind() == reflect.Interface && !valueField.IsNil() {
elm := valueField.Elem()
if elm.Kind() == reflect.Ptr && !elm.IsNil() && elm.Elem().Kind() == reflect.Ptr {
valueField = elm
}
}
}
if xmlElement, ok := valueField.Interface().(*xml.Name); ok && xmlElement != nil {
if first {
first = false
result += xmlElement.Local
} else {
result += ", " + xmlElement.Local
if xmlElement, ok := valueField.Interface().(*xml.Name); ok && xmlElement != nil {
if first {
first = false
result += xmlElement.Local
} else {
result += ", " + xmlElement.Local
}
}
}
}