prologic-saltyim/types.go

154 lines
4.1 KiB
Go

package saltyim
import (
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"go.mills.io/salty"
)
// RegisterRequest is the request used by clients to register to a broker
type RegisterRequest struct {
Hash string
Key string
}
// NewRegisterRequest reads the signed request body from a client, verifies its signature
// and returns the resulting `RegisterRequest` and key used to sign the request on success
// otherwise an empty object and en error on failure.
func NewRegisterRequest(r io.Reader) (req RegisterRequest, signer string, err error) {
body, err := io.ReadAll(r)
if err != nil {
return
}
out, key, err := salty.Verify(body)
if err != nil {
return
}
signer = key.ID().String()
err = json.Unmarshal(out, &req)
return
}
// SendRequest is the request used by clients to send messages via a broker
type SendRequest struct {
Endpoint string
Message string
Capabilities Capabilities
}
// NewSendRequest reads the signed request body from a client, verifies its signature
// and returns the resulting `SendRequest` and key used to sign the request on success
// otherwise an empty object and en error on failure.
func NewSendRequest(r io.Reader) (req SendRequest, signer string, err error) {
body, err := io.ReadAll(r)
if err != nil {
return
}
out, key, err := salty.Verify(body)
if err != nil {
return
}
signer = key.ID().String()
err = json.Unmarshal(out, &req)
return
}
// AvatarRequest is the request used by clients to update avatars stored on a broker's avatar service.
type AvatarRequest struct {
Addr Addr
Content []byte
}
// NewAvatarRequest reads the signed request body from a client, verifies its signature
// and returns the resulting `AvatarRequest` and key used to sign the request on success
// otherwise an empty object and en error on failure.
func NewAvatarRequest(r io.Reader) (req AvatarRequest, signer string, err error) {
body, err := io.ReadAll(r)
if err != nil {
return
}
out, key, err := salty.Verify(body)
if err != nil {
return
}
signer = key.ID().String()
err = json.Unmarshal(out, &req)
return
}
// Blob defines the type, filename and whether or not a blob is publicly accessible or not.
// A Blob also holds zero or more properties as a map of key/value pairs of string interpreted
// by the client.
type Blob struct {
r io.ReadSeekCloser
Type string
Public bool
Filename string
Properties map[string]string
}
// Close closes the blob and the underlying io.ReadSeekCloser
func (b *Blob) Close() error { return b.r.Close() }
// Read reads data from the blob from the underlying io.ReadSeekCloser
func (b *Blob) Read(p []byte) (n int, err error) { return b.r.Read(p) }
// SetHeaders sets HTTP headers on the net/http.Request object based on the blob's type, filename
// and various other properties (if any).
func (b *Blob) SetHeaders(r *http.Request) {
// TODO: Implement this...
}
// OpenBlob opens a blob at the given path and returns a Blob object
func OpenBlob(fn string) (*Blob, error) {
f, err := os.Open(fn)
if err != nil {
return nil, fmt.Errorf("error opening blob %s: %w", fn, err)
}
return &Blob{r: f}, nil
}
// BlobRequest is the request used by clients to update blob metadata for blobs stored on a broker.
type BlobRequest struct {
Blob
}
// NewBlobRequest reads the signed request body from a client, verifies its signature
// and returns the resulting `BlobRequest` and key used to sign the request on success
// otherwise an empty object and an error on failure.
func NewBlobRequest(r io.Reader) (req BlobRequest, signer string, err error) {
body, err := io.ReadAll(r)
if err != nil {
return
}
out, key, err := salty.Verify(body)
if err != nil {
return
}
signer = key.ID().String()
err = json.Unmarshal(out, &req)
return
}
// NewRawRequest reads the signed request body from a client, verifies its signature
// and returns the resulting `[]byte` slice and key used to sign the request on success
// otherwise an empty object and an error on failure.
func NewRawRequest(r io.Reader) (out []byte, signer string, err error) {
body, err := io.ReadAll(r)
if err != nil {
return
}
out, key, err := salty.Verify(body)
if err != nil {
return
}
signer = key.ID().String()
return
}