80 lines
1.7 KiB
Go
80 lines
1.7 KiB
Go
package main
|
|
|
|
import (
|
|
"crypto/ed25519"
|
|
"encoding/base64"
|
|
"encoding/gob"
|
|
"errors"
|
|
"net/http"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
type user struct {
|
|
dhtVal []byte
|
|
}
|
|
|
|
var users map[string]user
|
|
|
|
// Verify that a body was signed by this ID
|
|
func verify(id string, body []byte) error {
|
|
b, err := base64.RawURLEncoding.DecodeString(id)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if len(body) < ed25519.SignatureSize {
|
|
return errors.New("body too short")
|
|
}
|
|
message := body[:len(body)-ed25519.SignatureSize]
|
|
sig := body[len(body)-ed25519.SignatureSize:]
|
|
if !ed25519.Verify(ed25519.PublicKey(b), message, sig) {
|
|
return errors.New("signature verification failed")
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Persist a user's data to disk
|
|
func persist(id string) {
|
|
writer, err := os.Open(dataDir + "/" + id + "/gob")
|
|
if err != nil {
|
|
return
|
|
}
|
|
enc := gob.NewEncoder(writer)
|
|
enc.Encode(users[id])
|
|
}
|
|
|
|
// Handle user configuration changes
|
|
func userHandler(w http.ResponseWriter, r *http.Request) {
|
|
id := r.URL.Fragment[6:]
|
|
// Resolve ID to server list
|
|
val, err := dhtGet(id)
|
|
if err != nil || verify(id, val) != nil {
|
|
w.WriteHeader(http.StatusNotFound)
|
|
return
|
|
}
|
|
// Check if server list contains this server
|
|
message := string(val[:len(val)-ed25519.SignatureSize])
|
|
if !strings.Contains(message, me) {
|
|
// Delete user if they are no longer associated with this server
|
|
delete(users, id)
|
|
err = os.RemoveAll(id)
|
|
if err != nil {
|
|
w.WriteHeader(http.StatusNotFound)
|
|
return
|
|
}
|
|
w.WriteHeader(http.StatusOK)
|
|
return
|
|
}
|
|
//valSplit := strings.Split(message, "\n")
|
|
//servers := valSplit[1:len(valSplit)-1]
|
|
|
|
if _, ok := users[id]; !ok {
|
|
// Add user
|
|
users[id] = user{
|
|
dhtVal: val,
|
|
}
|
|
os.Mkdir(id, 755)
|
|
persist(id)
|
|
}
|
|
}
|