refactor out into packages for easier unit test writing
This commit is contained in:
48
pkg/app/vcard/app.go
Normal file
48
pkg/app/vcard/app.go
Normal file
@@ -0,0 +1,48 @@
|
||||
package app_vcard
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/mail"
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"gosrc.io/xmpp"
|
||||
)
|
||||
|
||||
type app struct {
|
||||
conn *connection
|
||||
}
|
||||
|
||||
func New(ctx context.Context, xmppConfig *xmpp.Config) (*app, error) {
|
||||
conn, err := NewXMPP(ctx, xmppConfig)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &app{conn: conn}, nil
|
||||
}
|
||||
func (app *app) Routes(r *chi.Mux) {
|
||||
r.MethodFunc("GET", "/vcard/{jid}", app.getVCard)
|
||||
}
|
||||
func (app *app) getVCard(w http.ResponseWriter, r *http.Request) {
|
||||
jid := chi.URLParam(r, "jid")
|
||||
if _, err := mail.ParseAddress(jid); err != nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
fmt.Fprint(w, err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
vcard, err := app.conn.GetXMPPVCard(r.Context(), jid)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
fmt.Fprint(w, err)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/xml")
|
||||
w.WriteHeader(200)
|
||||
fmt.Fprint(w, vcard)
|
||||
}
|
||||
36
pkg/app/vcard/vcard.go
Normal file
36
pkg/app/vcard/vcard.go
Normal file
@@ -0,0 +1,36 @@
|
||||
package app_vcard
|
||||
|
||||
import (
|
||||
"encoding/xml"
|
||||
|
||||
"gosrc.io/xmpp/stanza"
|
||||
)
|
||||
|
||||
type VCard struct {
|
||||
XMLName xml.Name `xml:"vcard-temp vCard"`
|
||||
FullName string `xml:"FN"`
|
||||
NickName string `xml:"NICKNAME"`
|
||||
Description string `xml:"DESC"`
|
||||
URL string `xml:"URL"`
|
||||
}
|
||||
|
||||
func NewVCard() *VCard {
|
||||
return &VCard{}
|
||||
}
|
||||
|
||||
func (c *VCard) Namespace() string {
|
||||
return c.XMLName.Space
|
||||
}
|
||||
|
||||
func (c *VCard) GetSet() *stanza.ResultSet {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *VCard) String() string {
|
||||
b, _ := xml.MarshalIndent(c, "", " ")
|
||||
return string(b)
|
||||
}
|
||||
|
||||
func init() {
|
||||
stanza.TypeRegistry.MapExtension(stanza.PKTIQ, xml.Name{Space: "vcard-temp", Local: "vCard"}, VCard{})
|
||||
}
|
||||
76
pkg/app/vcard/xmpp.go
Normal file
76
pkg/app/vcard/xmpp.go
Normal file
@@ -0,0 +1,76 @@
|
||||
package app_vcard
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/xml"
|
||||
"fmt"
|
||||
|
||||
"github.com/rs/zerolog/log"
|
||||
"github.com/sour-is/keyproofs/pkg/graceful"
|
||||
"gosrc.io/xmpp"
|
||||
"gosrc.io/xmpp/stanza"
|
||||
)
|
||||
|
||||
type connection struct {
|
||||
client xmpp.StreamClient
|
||||
}
|
||||
|
||||
func NewXMPP(ctx context.Context, config *xmpp.Config) (*connection, error) {
|
||||
log := log.Ctx(ctx)
|
||||
wg := graceful.WaitGroup(ctx)
|
||||
|
||||
router := xmpp.NewRouter()
|
||||
conn := &connection{}
|
||||
|
||||
cl, err := xmpp.NewClient(config, router, func(err error) { log.Error().Err(err).Send() })
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
conn.client = cl
|
||||
|
||||
sc := xmpp.NewStreamManager(cl, func(c xmpp.Sender) { log.Info().Msg("XMPP Client connected.") })
|
||||
|
||||
wg.Go(func() error {
|
||||
log.Debug().Msg("starting XMPP")
|
||||
return sc.Run()
|
||||
})
|
||||
|
||||
go func() {
|
||||
<-ctx.Done()
|
||||
sc.Stop()
|
||||
log.Info().Msg("XMPP Client shutdown.")
|
||||
}()
|
||||
|
||||
return conn, err
|
||||
}
|
||||
|
||||
func (conn *connection) GetXMPPVCard(ctx context.Context, jid string) (vc *VCard, err error) {
|
||||
log := log.Ctx(ctx)
|
||||
|
||||
var iq *stanza.IQ
|
||||
iq, err = stanza.NewIQ(stanza.Attrs{To: jid, Type: "get"})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
iq.Payload = NewVCard()
|
||||
|
||||
var ch chan stanza.IQ
|
||||
ch, err = conn.client.SendIQ(ctx, iq)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
select {
|
||||
case result := <-ch:
|
||||
b, _ := xml.MarshalIndent(result, "", " ")
|
||||
log.Debug().Msgf("%s", b)
|
||||
if vcard, ok := result.Payload.(*VCard); ok {
|
||||
return vcard, nil
|
||||
}
|
||||
return nil, fmt.Errorf("bad response: %s", result.Payload)
|
||||
|
||||
case <-ctx.Done():
|
||||
}
|
||||
|
||||
return nil, fmt.Errorf("timeout requesting vcard for %s", jid)
|
||||
}
|
||||
Reference in New Issue
Block a user