diff --git a/controllers/peer.go b/controllers/peer.go index 664f570..5775a2c 100644 --- a/controllers/peer.go +++ b/controllers/peer.go @@ -148,10 +148,9 @@ func (o *PeerController) Partner() { func (o *PeerController) Blacklist() { user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request) id := o.Ctx.Input.Param(":id") - o.Data["json"] = oclib.NewRequest(oclib.LibDataEnum(oclib.PEER), user, peerID, groups, nil).UpdateOne(map[string]interface{}{ - "relation": peer.BLACKLIST, - "state": peer.OFFLINE, - }, id) + req := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), user, peerID, groups, nil) + data := req.LoadOne(id) + o.changeRelation(data.ToPeer(), peer.BLACKLIST, req) } // used from : peer ask, or response, only from peer origin is authorized to change... @@ -176,9 +175,15 @@ func (o *PeerController) changeRelation(dest *peer.Peer, relation peer.PeerRelat } // store and return Id or post with UUID if dest != nil { - if !dest.Verify && relation == peer.PARTNER { - relation = peer.PENDING_PARTNER - if _, err := tools.NewHTTPCaller(map[tools.DataType]map[tools.METHOD]string{}).CallGet(dest.Url, "/"+request.PeerID+"/link/"+relation.Path()); err != nil { + if !dest.Verify { + switch relation { + case peer.PARTNER: + relation = peer.PENDING_PARTNER + case peer.BLACKLIST: + relation = peer.NONE + } + if _, err := tools.NewHTTPCaller(map[tools.DataType]map[tools.METHOD]string{}).CallGet( + dest.Url, "/"+request.PeerID+"/link/"+relation.Path()); err != nil { o.Data["json"] = map[string]interface{}{ "data": nil, "code": 400, diff --git a/go.mod b/go.mod index 7d2e553..988a296 100644 --- a/go.mod +++ b/go.mod @@ -5,7 +5,7 @@ go 1.24.6 toolchain go1.24.11 require ( - cloud.o-forge.io/core/oc-lib v0.0.0-20260126093615-bc94f2b188e6 + cloud.o-forge.io/core/oc-lib v0.0.0-20260126120055-055e6c70cdd7 github.com/beego/beego/v2 v2.3.8 github.com/smartystreets/goconvey v1.7.2 ) diff --git a/go.sum b/go.sum index 92c61a0..576e1b5 100644 --- a/go.sum +++ b/go.sum @@ -18,6 +18,10 @@ cloud.o-forge.io/core/oc-lib v0.0.0-20260123065115-f3d7c65b18d1 h1:K7ind/dAshdoF cloud.o-forge.io/core/oc-lib v0.0.0-20260123065115-f3d7c65b18d1/go.mod h1:vHWauJsS6ryf7UDqq8hRXoYD5RsONxcFTxeZPOztEuI= cloud.o-forge.io/core/oc-lib v0.0.0-20260126093615-bc94f2b188e6 h1:Sxjq1lQwSl+gkUYag4wAb6j74uU/JZviw1hkFavt58o= cloud.o-forge.io/core/oc-lib v0.0.0-20260126093615-bc94f2b188e6/go.mod h1:vHWauJsS6ryf7UDqq8hRXoYD5RsONxcFTxeZPOztEuI= +cloud.o-forge.io/core/oc-lib v0.0.0-20260126113404-85a8857938f5 h1:pl6/u6UXyFcfCU+xyQcSY8Lkby68EVWswxG2Oaq476A= +cloud.o-forge.io/core/oc-lib v0.0.0-20260126113404-85a8857938f5/go.mod h1:vHWauJsS6ryf7UDqq8hRXoYD5RsONxcFTxeZPOztEuI= +cloud.o-forge.io/core/oc-lib v0.0.0-20260126120055-055e6c70cdd7 h1:LAK86efqe2HNV1Tkym1TpvzL1Xsj3F0ClsK/snfejD0= +cloud.o-forge.io/core/oc-lib v0.0.0-20260126120055-055e6c70cdd7/go.mod h1:vHWauJsS6ryf7UDqq8hRXoYD5RsONxcFTxeZPOztEuI= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/beego/beego/v2 v2.3.8 h1:wplhB1pF4TxR+2SS4PUej8eDoH4xGfxuHfS7wAk9VBc= github.com/beego/beego/v2 v2.3.8/go.mod h1:8vl9+RrXqvodrl9C8yivX1e6le6deCK6RWeq8R7gTTg= diff --git a/infrastructure/dht.go b/infrastructure/dht.go index f73b70b..32633d1 100644 --- a/infrastructure/dht.go +++ b/infrastructure/dht.go @@ -8,6 +8,7 @@ import ( "fmt" "oc-peer/conf" "slices" + "sync" "time" oclib "cloud.o-forge.io/core/oc-lib" @@ -39,6 +40,7 @@ type DHTService struct { Host host.Host DHT *dht.IpfsDHT Cache []string + mutex sync.RWMutex } var singletonService *DHTService @@ -93,7 +95,9 @@ func (d *DHTService) RefreshKeys(ctx context.Context, interval time.Duration) { return case <-ticker.C: s := []string{} + d.mutex.Lock() s = append(s, d.Cache...) + d.mutex.Unlock() for _, key := range s { _, _ = d.GetValue(ctx, key) } @@ -111,9 +115,11 @@ func (d *DHTService) PutValue( if err != nil { return err } + d.mutex.Lock() if !slices.Contains(d.Cache, key) { d.Cache = append(d.Cache, key) } + d.mutex.Unlock() return nil } @@ -124,22 +130,27 @@ func (d *DHTService) GetValue( dht, err := d.DHT.GetValue(ctx, key) if err != nil { cache := []string{} + d.mutex.Lock() for _, c := range d.Cache { if c != key { cache = append(cache, c) } } d.Cache = cache + d.mutex.Unlock() return nil, err } + d.mutex.Lock() if !slices.Contains(d.Cache, key) { d.Cache = append(d.Cache, key) } - var data *DHTRecord - json.Unmarshal(dht, data) + d.mutex.Unlock() + var data DHTRecord + json.Unmarshal(dht, &data) - if data == nil { - return nil, errors.New("no record found") + peerID, err := oclib.GenerateNodeID() + if err != nil { + return nil, err } access := pp.NewAccessor(&tools.APIRequest{Admin: true}) @@ -150,7 +161,7 @@ func (d *DHTService) GetValue( }, State: pp.ONLINE, Relation: pp.SELF, - PeerID: d.Host.ID().String(), + PeerID: peerID, PublicKey: string(data.PubKey), Url: data.URL, NATSUrl: oclib.GetConfig().NATSUrl, @@ -168,14 +179,15 @@ func (d *DHTService) GetValue( access.UpdateOne(f, f.GetID()) } - return data, err + return &data, err } -func (d *DHTService) generateKey( - sub string, - name string, -) string { - return "/opencloud/" + sub + "/" + name +func (d *DHTService) generateKey() (string, error) { + s, err := oclib.GenerateNodeID() + if err != nil { + return s, err + } + return "/opencloud/peer/" + s, nil } // Create your peer. @@ -188,14 +200,20 @@ func (d *DHTService) ClaimName( return nil, errors.New("no endpoint found for peer" + name) } + peerID, err := oclib.GenerateNodeID() + if err != nil { + return nil, err + } + pub := d.Host.Peerstore().PubKey(d.Host.ID()) pubBytes, _ := pub.Raw() now := time.Now() expiry := now.Add(1 * time.Hour) + rec := DHTRecord{ Name: name, - PeerID: d.Host.ID().String(), + PeerID: peerID, PubKey: pubBytes, } @@ -210,12 +228,15 @@ func (d *DHTService) ClaimName( data, _ := json.Marshal(rec) - key := d.generateKey("peer", rec.Name) + key, err := d.generateKey() + if err != nil { + return nil, err + } // retrieve your key name in standard old, err := d.GetValue(ctx, key) if err == nil { - if old.PeerID != d.Host.ID().String() { // check if someone claims your name before + if old.PeerID != peerID { // check if someone claims your name before return nil, errors.New("name already claimed by another peer") // TODO : can be fragile if 2 peers connect at the same time } @@ -232,6 +253,9 @@ func (d *DHTService) ClaimName( pubStr := base64.StdEncoding.EncodeToString(pubBytes) d.Key = key access := pp.NewAccessor(&tools.APIRequest{Admin: true}) + if err != nil { + return nil, err + } p := &pp.Peer{ AbstractObject: utils.AbstractObject{ UUID: uuid.New().String(), @@ -239,7 +263,7 @@ func (d *DHTService) ClaimName( }, State: pp.ONLINE, Relation: pp.SELF, - PeerID: d.Host.ID().String(), + PeerID: peerID, PublicKey: pubStr, Url: endPoint, NATSUrl: oclib.GetConfig().NATSUrl, @@ -248,8 +272,12 @@ func (d *DHTService) ClaimName( if founded, _, err := access.Search(nil, fmt.Sprintf("%v", pp.SELF.EnumIndex()), false); err != nil || len(founded) == 0 { access.StoreOne(p) } else if f, _, err := access.LoadOne(founded[0].GetID()); err == nil { + peerID, err := oclib.GenerateNodeID() + if err != nil { + return nil, err + } f.(*pp.Peer).Name = name - f.(*pp.Peer).PeerID = d.Host.ID().String() + f.(*pp.Peer).PeerID = peerID f.(*pp.Peer).State = pp.ONLINE f.(*pp.Peer).Url = endPoint f.(*pp.Peer).NATSUrl = oclib.GetConfig().NATSUrl @@ -340,7 +368,10 @@ func (d *DHTService) DiscoverPeers( name string, ) ([]*pp.Peer, error) { peers := []*pp.Peer{} - key := d.generateKey("peer", name) + key, err := d.generateKey() + if err != nil { + return nil, err + } datas, err := d.DHT.SearchValue(ctx, key) if err != nil { return nil, errors.New("no DHT peer not found") @@ -359,7 +390,10 @@ func (d *DHTService) GetPeer( ctx context.Context, name string, ) (*pp.Peer, error) { - key := d.generateKey("peer", name) + key, err := d.generateKey() + if err != nil { + return nil, err + } data, err := d.GetValue(ctx, key) if err != nil { return nil, errors.New("no DHT peer not found") @@ -393,7 +427,3 @@ func (d *DHTService) existsDHT(ctx context.Context) (*DHTRecord, error) { } return rec, nil } - -/* -Apply Name interlude... -*/