mirror of
https://github.com/rkonfj/peerguard.git
synced 2024-08-11 11:00:25 +08:00
peermap: add map exporter api
This commit is contained in:
parent
7325647a35
commit
eba2c1a6da
2
.gitignore
vendored
2
.gitignore
vendored
@ -1,6 +1,6 @@
|
||||
*.exe
|
||||
pgcli-*
|
||||
pgserve-*
|
||||
pgmap-*
|
||||
wintun/
|
||||
*.zip
|
||||
*.dll
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/signal"
|
||||
@ -24,8 +25,16 @@ func main() {
|
||||
Version: fmt.Sprintf("%s, commit %s", Version, Commit),
|
||||
Short: "Run a peermap server daemon",
|
||||
SilenceUsage: true,
|
||||
Args: cobra.NoArgs,
|
||||
RunE: run,
|
||||
PreRunE: func(cmd *cobra.Command, args []string) error {
|
||||
verbose, err := cmd.Flags().GetInt("verbose")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
slog.SetLogLoggerLevel(slog.Level(verbose))
|
||||
return nil
|
||||
},
|
||||
Args: cobra.NoArgs,
|
||||
RunE: run,
|
||||
}
|
||||
serveCmd.Flags().StringP("config", "c", "config.yaml", "config file")
|
||||
serveCmd.Flags().StringP("listen", "l", "127.0.0.1:9987", "listen http address")
|
||||
|
47
peermap/exporter/auth.go
Normal file
47
peermap/exporter/auth.go
Normal file
@ -0,0 +1,47 @@
|
||||
package exporter
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/rkonfj/peerguard/secure"
|
||||
"github.com/rkonfj/peerguard/secure/aescbc"
|
||||
)
|
||||
|
||||
var algo secure.SymmAlgo
|
||||
|
||||
func SetSecretKey(key string) {
|
||||
sum := sha256.Sum256([]byte(key))
|
||||
algo = aescbc.New(func(pubKey string) ([]byte, error) {
|
||||
return sum[:], nil
|
||||
})
|
||||
}
|
||||
|
||||
type Instruction struct {
|
||||
}
|
||||
|
||||
func CheckToken(token string) (*Instruction, error) {
|
||||
b, err := base64.StdEncoding.DecodeString(token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
plain, err := algo.Decrypt(b, "")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var ins Instruction
|
||||
return &ins, json.Unmarshal(plain, &ins)
|
||||
}
|
||||
|
||||
func GenerateToken(ins Instruction) (string, error) {
|
||||
b, err := json.Marshal(ins)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
chiper, err := algo.Encrypt(b, "")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return base64.StdEncoding.EncodeToString(chiper), nil
|
||||
}
|
12
peermap/exporter/exporter.go
Normal file
12
peermap/exporter/exporter.go
Normal file
@ -0,0 +1,12 @@
|
||||
package exporter
|
||||
|
||||
type NetworkHead struct {
|
||||
ID string `json:"n"`
|
||||
PeersCount int `json:"c"`
|
||||
CreateTime string `json:"t"`
|
||||
}
|
||||
|
||||
type Network struct {
|
||||
ID string `json:"n"`
|
||||
Peers []string `json:"p"`
|
||||
}
|
@ -2,7 +2,6 @@ package peermap
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/md5"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
@ -17,16 +16,11 @@ import (
|
||||
cmap "github.com/orcaman/concurrent-map/v2"
|
||||
"github.com/rkonfj/peerguard/peer"
|
||||
"github.com/rkonfj/peerguard/peermap/auth"
|
||||
"github.com/rkonfj/peerguard/peermap/exporter"
|
||||
"github.com/rkonfj/peerguard/peermap/oidc"
|
||||
"golang.org/x/time/rate"
|
||||
)
|
||||
|
||||
type Network struct {
|
||||
ID string `json:"id"`
|
||||
PeersCount int `json:"peersCount"`
|
||||
CreateTime string `json:"createTime"`
|
||||
}
|
||||
|
||||
type Peer struct {
|
||||
peerMap *PeerMap
|
||||
secret auth.JSONSecret
|
||||
@ -236,6 +230,7 @@ func New(cfg Config) (*PeerMap, error) {
|
||||
if err := cfg.applyDefaults(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
exporter.SetSecretKey(cfg.SecretKey)
|
||||
mux := http.NewServeMux()
|
||||
pm := PeerMap{
|
||||
httpServer: &http.Server{Handler: mux, Addr: cfg.Listen},
|
||||
@ -247,6 +242,7 @@ func New(cfg Config) (*PeerMap, error) {
|
||||
mux.HandleFunc("/", pm.handleWebsocket)
|
||||
mux.HandleFunc("/networks", pm.handleQueryNetworks)
|
||||
mux.HandleFunc("/peers", pm.handleQueryNetworkPeers)
|
||||
|
||||
mux.HandleFunc("/network/token", oidc.HandleNotifyToken)
|
||||
mux.HandleFunc("/oidc/", oidc.RedirectAuthURL)
|
||||
mux.HandleFunc("/oidc/authorize/", pm.handleOIDCAuthorize)
|
||||
@ -254,10 +250,17 @@ func New(cfg Config) (*PeerMap, error) {
|
||||
}
|
||||
|
||||
func (pm *PeerMap) handleQueryNetworks(w http.ResponseWriter, r *http.Request) {
|
||||
exporterToken := r.Header.Get("X-Token")
|
||||
_, err := exporter.CheckToken(exporterToken)
|
||||
if err != nil {
|
||||
slog.Debug("ExporterAuthFailed", "details", err)
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
items := pm.networkMap.Items()
|
||||
networks := make([]Network, 0, len(items))
|
||||
networks := make([]exporter.NetworkHead, 0, len(items))
|
||||
for k, v := range items {
|
||||
networks = append(networks, Network{
|
||||
networks = append(networks, exporter.NetworkHead{
|
||||
ID: k,
|
||||
PeersCount: v.Count(),
|
||||
CreateTime: fmt.Sprintf("%d", v.createTime.UnixNano()),
|
||||
@ -267,22 +270,25 @@ func (pm *PeerMap) handleQueryNetworks(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
func (pm *PeerMap) handleQueryNetworkPeers(w http.ResponseWriter, r *http.Request) {
|
||||
jsonSecret, err := pm.authenticator.ParseSecret(r.Header.Get("X-Network"))
|
||||
exporterToken := r.Header.Get("X-Token")
|
||||
_, err := exporter.CheckToken(exporterToken)
|
||||
if err != nil {
|
||||
slog.Debug("Authenticate failed", "err", err, "network", r.Header.Get("X-Network"))
|
||||
w.WriteHeader(http.StatusForbidden)
|
||||
slog.Debug("ExporterAuthFailed", "details", err)
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
if networkContext, ok := pm.networkMap.Get(jsonSecret.Network); ok {
|
||||
items := networkContext.Items()
|
||||
peers := make([]string, 0, len(items))
|
||||
for _, v := range items {
|
||||
peers = append(peers, v.String())
|
||||
var networks []exporter.Network
|
||||
for item := range pm.networkMap.IterBuffered() {
|
||||
var peers []string
|
||||
for _, peer := range item.Val.Items() {
|
||||
peers = append(peers, peer.String())
|
||||
}
|
||||
json.NewEncoder(w).Encode(peers)
|
||||
return
|
||||
networks = append(networks, exporter.Network{
|
||||
ID: item.Key,
|
||||
Peers: peers,
|
||||
})
|
||||
}
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
json.NewEncoder(w).Encode(networks)
|
||||
}
|
||||
|
||||
func (pm *PeerMap) handleOIDCAuthorize(w http.ResponseWriter, r *http.Request) {
|
||||
@ -298,9 +304,7 @@ func (pm *PeerMap) handleOIDCAuthorize(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusBadGateway)
|
||||
return
|
||||
}
|
||||
networkB := md5.Sum([]byte(email))
|
||||
network := base64.URLEncoding.EncodeToString(networkB[:])
|
||||
secret, err := pm.generateSecret(network)
|
||||
secret, err := pm.generateSecret(email)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
|
Loading…
Reference in New Issue
Block a user