6
1
mirror of https://git.mills.io/saltyim/saltyim.git synced 2024-06-25 16:28:20 +00:00
prologic-saltyim/lookup.go
xuu d1d33e45c6 feat: hax for great justice (#14)
- Dont send message on empty
- inbox flag to override $USER
- Filter messages to only chat with partner.

NOTE: might be better to parse the message in loop to handle events outside the formatting code.

NOTE NOTE: i think we might need to revisit read recipts.. maybe including user@domain?

Co-authored-by: Jon Lundy <jon@xuu.cc>
Reviewed-on: https://git.mills.io/prologic/saltyim/pulls/14
Co-authored-by: xuu <xuu@noreply@mills.io>
Co-committed-by: xuu <xuu@noreply@mills.io>
2022-03-19 21:33:03 +00:00

93 lines
2.4 KiB
Go

package saltyim
import (
"crypto/sha256"
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"strings"
log "github.com/sirupsen/logrus"
)
// Addr represents a Salty IM User's Address
type Addr struct {
User string
Domain string
}
// IsZero returns true if the address is empty
func (a Addr) IsZero() bool {
return a.User == "" && a.Domain == ""
}
func (a Addr) String() string {
return fmt.Sprintf("%s@%s", a.User, a.Domain)
}
// Formatted returns a formatted user used in the Salty Message Format
// <timestamp\t(<user>) <message>\n
func (a Addr) Formatted() string {
return fmt.Sprintf("(%s)", a)
}
// URI returns the Well-Known URI for this Addr
func (a Addr) URI() string {
return fmt.Sprintf("https://%s/.well-known/salty/%s.json", a.Domain, a.User)
}
// HashURI returns the Well-Known HashURI for this Addr
func (a Addr) HashURI() string {
return fmt.Sprintf("https://%s/.well-known/salty/%x.json", a.Domain, sha256.Sum256([]byte(a.String())))
}
// ParseAddr parsers a Salty Address for a user into it's user and domain
// parts and returns an Addr object with the User and Domain and a method
// for returning the expected User's Well-Known URI
func ParseAddr(addr string) (Addr, error) {
parts := strings.Split(addr, "@")
if len(parts) != 2 {
return Addr{}, fmt.Errorf("expected nick@domain found %q", addr)
}
return Addr{parts[0], parts[1]}, nil
}
// Lookup looks up a Salty Address for a User by parsing the user's domain and
// making a request to the user's Well-Known URI expected to be located at
// https://domain/.well-known/salty/<user>.json
func Lookup(addr string) (Config, error) {
a, err := ParseAddr(addr)
if err != nil {
log.WithError(err).Errorf("error parsing addr %q", addr)
return Config{}, err
}
// Attempt using hash
res, err := Request(http.MethodGet, a.HashURI(), nil, nil)
if err != nil {
// Fallback to plain user nick
log.WithError(err).Warn("failed to get hash uri. attempting plaintext.")
res, err = Request(http.MethodGet, a.URI(), nil, nil)
}
if err != nil {
log.WithError(err).Error("error requesting well-known uri")
return Config{}, err
}
data, err := ioutil.ReadAll(res.Body)
if err != nil {
log.WithError(err).Errorf("error reading well-known config")
return Config{}, err
}
var config Config
if err := json.Unmarshal(data, &config); err != nil {
log.WithError(err).Error("error parsing well-known config")
return Config{}, err
}
return config, err
}