Files
oc-peer/controllers/peer.go
T

745 lines
25 KiB
Go
Raw Normal View History

2024-08-21 16:25:24 +02:00
package controllers
import (
2026-02-23 17:18:16 +01:00
ctx "context"
"encoding/json"
2026-03-04 11:58:13 +01:00
"fmt"
2026-02-23 17:18:16 +01:00
"oc-peer/infrastructure"
2026-04-08 11:29:16 +02:00
"strconv"
2024-08-21 16:25:24 +02:00
oclib "cloud.o-forge.io/core/oc-lib"
2026-06-01 10:30:36 +02:00
"cloud.o-forge.io/core/oc-lib/config"
2026-01-23 08:07:17 +01:00
"cloud.o-forge.io/core/oc-lib/dbs"
2026-06-22 08:00:14 +02:00
"cloud.o-forge.io/core/oc-lib/models/organization"
2024-10-15 16:55:29 +02:00
"cloud.o-forge.io/core/oc-lib/models/peer"
2026-01-23 08:07:17 +01:00
"cloud.o-forge.io/core/oc-lib/tools"
2024-08-21 16:25:24 +02:00
beego "github.com/beego/beego/v2/server/web"
2026-04-01 11:27:05 +02:00
"github.com/gorilla/websocket"
2024-08-21 16:25:24 +02:00
)
// Operations about workflow
type PeerController struct {
beego.Controller
}
// @Title Search
// @Description search workspace
2026-06-01 10:30:36 +02:00
// @Param type path string true "the type you want to get"
2024-08-21 16:25:24 +02:00
// @Param search path string true "the word search you want to get"
2025-01-17 17:22:25 +01:00
// @Param is_draft query string false
2026-04-08 11:29:16 +02:00
// @Param offset query string false
// @Param limit query string false
2024-08-21 16:25:24 +02:00
// @Success 200 {workspace} models.workspace
2026-06-01 10:30:36 +02:00
// @router /:type/search/:search [get]
2024-08-21 16:25:24 +02:00
func (o *PeerController) Search() {
2025-01-17 17:22:25 +01:00
user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
2024-11-07 13:39:45 +01:00
// store and return Id or post with UUIDLibDataEnum
2024-08-21 16:25:24 +02:00
search := o.Ctx.Input.Param(":search")
2026-06-01 10:30:36 +02:00
typ := o.Ctx.Input.Param(":type")
2025-01-17 17:22:25 +01:00
isDraft := o.Ctx.Input.Query("is_draft")
2026-04-08 11:29:16 +02:00
offset, _ := strconv.Atoi(o.Ctx.Input.Query("offset"))
limit, _ := strconv.Atoi(o.Ctx.Input.Query("limit"))
2026-06-01 10:30:36 +02:00
var filter *dbs.Filters
fmt.Println("TYP", typ)
relation := peer.GetRelationPath(typ)
if relation != -1 {
filter = &dbs.Filters{
And: map[string][]dbs.Filter{ // search by name if no filters are provided
"relation": {{Operator: dbs.EQUAL.String(), Value: relation}},
},
Or: map[string][]dbs.Filter{ // search by name if no filters are providedz
"abstractobject.name": {{Operator: dbs.LIKE.String(), Value: search}},
"url": {{Operator: dbs.LIKE.String(), Value: search}},
"peer_id": {{Operator: dbs.LIKE.String(), Value: search}},
},
}
search = ""
}
fmt.Println(filter, relation, "<", search, ">")
2026-04-29 11:43:52 +02:00
o.Data["json"] = oclib.NewRequest(oclib.LibDataEnum(oclib.PEER), user, peerID, groups, nil).Search(
2026-06-01 10:30:36 +02:00
filter, search, isDraft == "true", int64(offset), int64(limit))
2026-04-08 11:29:16 +02:00
o.ServeJSON()
}
// @Title Search
// @Description search workspace
// @Param is_draft query string false
// @Param offset query string false
// @Param limit query string false
// @Param data body json true "body for data content (Json format)"
// @Success 200 {workspace} models.workspace
2026-06-01 10:30:36 +02:00
// @router /:type/extended/search [post]
2026-04-08 11:29:16 +02:00
func (o *PeerController) SearchExtended() {
user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
// store and return Id or post with UUIDLibDataEnum
isDraft := o.Ctx.Input.Query("is_draft")
2026-06-01 10:30:36 +02:00
typ := o.Ctx.Input.Param(":type")
2026-04-08 11:29:16 +02:00
offset, _ := strconv.Atoi(o.Ctx.Input.Query("offset"))
limit, _ := strconv.Atoi(o.Ctx.Input.Query("limit"))
var res map[string]interface{}
json.Unmarshal(o.Ctx.Input.CopyBody(100000), &res)
fmt.Println(res, oclib.FiltersFromFlatMap(res, &peer.Peer{}))
2026-06-01 10:30:36 +02:00
relation := peer.GetRelationPath(typ)
res["relation"] = relation
2026-04-08 11:29:16 +02:00
data := oclib.NewRequest(oclib.LibDataEnum(oclib.PEER), user, peerID, groups, nil).Search(
oclib.FiltersFromFlatMap(res, &peer.Peer{}), "", isDraft == "true", int64(offset), int64(limit))
o.Data["json"] = data
2024-08-21 16:25:24 +02:00
o.ServeJSON()
}
// @Title GetAll
// @Description find all peer
2025-01-17 17:22:25 +01:00
// @Param is_draft query string false
2026-04-08 11:29:16 +02:00
// @Param offset query string false
// @Param limit query string false
2024-08-21 16:25:24 +02:00
// @Success 200 {peer} models.peer
2026-04-01 11:27:05 +02:00
// @router / [get]
2024-08-21 16:25:24 +02:00
func (o *PeerController) GetAll() {
2025-01-17 17:22:25 +01:00
user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
isDraft := o.Ctx.Input.Query("is_draft")
2026-04-08 11:29:16 +02:00
offset, _ := strconv.Atoi(o.Ctx.Input.Query("offset"))
limit, _ := strconv.Atoi(o.Ctx.Input.Query("limit"))
2026-01-23 08:07:17 +01:00
verify := o.Ctx.Input.Query("verify")
if verify == "true" {
o.Data["json"] = oclib.NewRequest(oclib.LibDataEnum(oclib.PEER), user, peerID, groups, nil).Search(&dbs.Filters{
And: map[string][]dbs.Filter{
"verify": {{Operator: dbs.EQUAL.String(), Value: true}},
},
2026-04-08 11:29:16 +02:00
}, "", false, int64(offset), int64(limit))
2026-01-23 08:07:17 +01:00
} else {
2026-04-08 11:29:16 +02:00
o.Data["json"] = oclib.NewRequest(oclib.LibDataEnum(oclib.PEER), user, peerID, groups, nil).LoadAll(isDraft == "true", int64(offset), int64(limit))
2026-01-23 08:07:17 +01:00
}
2024-08-21 16:25:24 +02:00
o.ServeJSON()
}
// @Title Get
// @Description find peer by peerid
// @Param id path string true "the peer id you want to get"
// @Success 200 {peer} models.peer
2026-04-01 11:27:05 +02:00
// @router /:id [get]
2024-08-21 16:25:24 +02:00
func (o *PeerController) Get() {
2025-01-17 17:22:25 +01:00
user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
2024-08-21 16:25:24 +02:00
id := o.Ctx.Input.Param(":id")
2025-01-17 17:22:25 +01:00
o.Data["json"] = oclib.NewRequest(oclib.LibDataEnum(oclib.PEER), user, peerID, groups, nil).LoadOne(id)
2024-08-21 16:25:24 +02:00
o.ServeJSON()
}
2024-10-15 16:55:29 +02:00
2026-03-04 11:58:13 +01:00
// @Title Valid
2026-01-23 08:07:17 +01:00
// @Description find peer by peerid
// @Param id path string true "the peer id you want to get"
// @Success 200 {peer} models.peer
2026-04-01 11:27:05 +02:00
// @router /valid/:id [get]
2026-03-04 11:58:13 +01:00
func (o *PeerController) Valid() {
2026-03-12 09:10:14 +01:00
user, _, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
2026-03-04 11:58:13 +01:00
id := o.Ctx.Input.Param(":id")
if ok, _ := oclib.IsMySelf(id); ok {
2026-01-23 08:07:17 +01:00
o.Data["json"] = map[string]interface{}{
"data": nil,
"code": 400,
2026-03-04 11:58:13 +01:00
"error": "can't validate a link relation for ourself",
2026-01-23 08:07:17 +01:00
}
o.ServeJSON()
return
}
2026-04-01 11:27:05 +02:00
fmt.Println(id)
2026-01-28 16:05:47 +01:00
req := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil)
2026-01-23 08:07:17 +01:00
l := req.LoadOne(id)
2026-03-04 11:58:13 +01:00
if l.Data != nil && l.ToPeer().Verify && (l.ToPeer().Relation == peer.PARTNER || l.ToPeer().Relation == peer.PENDING_PARTNER) {
data := req.UpdateOne(map[string]interface{}{
"verify": false,
"relation": peer.PARTNER,
}, l.ToPeer().GetID())
fmt.Println(l.Data, data.Data)
if data.Data != nil {
b, _ := json.Marshal(data.Data)
2026-03-12 09:10:14 +01:00
go infrastructure.EmitNATS(user, groups, tools.PropalgationMessage{
2026-03-04 11:58:13 +01:00
DataType: tools.PEER.EnumIndex(),
Action: tools.PB_CREATE,
Payload: b,
})
2026-01-23 08:07:17 +01:00
}
2026-03-04 11:58:13 +01:00
o.Data["json"] = data
2026-01-23 08:07:17 +01:00
o.ServeJSON()
return
2026-04-29 11:43:52 +02:00
} else if l.Data != nil && l.ToPeer().Verify && (l.ToPeer().Relation == peer.MASTER || l.ToPeer().Relation == peer.PENDING_MASTER) {
2026-05-27 16:24:35 +02:00
masterPeerID := l.ToPeer().PeerID
2026-04-29 11:43:52 +02:00
data := req.UpdateOne(map[string]interface{}{
"verify": false,
"relation": peer.MASTER,
}, l.ToPeer().GetID())
fmt.Println(l.Data, data.Data)
2026-06-01 10:30:36 +02:00
data.Data.(*peer.Peer).MasterID = masterPeerID
2026-04-29 11:43:52 +02:00
data.Data.(*peer.Peer).Relation = peer.NANO // dest is a nano
if data.Data != nil {
b, _ := json.Marshal(data.Data)
go infrastructure.EmitNATS(user, groups, tools.PropalgationMessage{
DataType: tools.PEER.EnumIndex(),
Action: tools.PB_CREATE,
Payload: b,
})
}
2026-05-27 16:24:35 +02:00
// This node is now a NANO of the confirmed master: stamp its libp2p PeerID on self.
if self, serr := oclib.GetMySelf(); serr == nil && self != nil {
oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil).UpdateOne(map[string]interface{}{
"master_id": masterPeerID,
}, self.GetID())
}
2026-04-29 11:43:52 +02:00
o.Data["json"] = data
o.ServeJSON()
return
2026-06-01 10:30:36 +02:00
} else if l.Data != nil && l.ToPeer().Verify && (l.ToPeer().Relation == peer.NANO || l.ToPeer().Relation == peer.PENDING_NANO) {
masterPeerID, err := oclib.GetMySelf()
if err == nil {
data := req.UpdateOne(map[string]interface{}{
"verify": false,
"relation": peer.NANO,
}, l.ToPeer().GetID())
fmt.Println(l.Data, data.Data)
data.Data.(*peer.Peer).MasterID = masterPeerID.GetID()
data.Data.(*peer.Peer).Relation = peer.MASTER // dest is a nano
if data.Data != nil {
b, _ := json.Marshal(data.Data)
go infrastructure.EmitNATS(user, groups, tools.PropalgationMessage{
DataType: tools.PEER.EnumIndex(),
Action: tools.PB_CREATE,
Payload: b,
})
}
// This node is now a NANO of the confirmed master: stamp its libp2p PeerID on self.
if self, serr := oclib.GetMySelf(); serr == nil && self != nil {
oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil).UpdateOne(map[string]interface{}{
"master_id": masterPeerID.GetID(),
}, self.GetID())
}
o.Data["json"] = data
o.ServeJSON()
return
}
2026-06-22 08:00:14 +02:00
} else if l.Data != nil && l.ToPeer().Verify && (l.ToPeer().Relation == peer.ORGANIZATION_MASTER || l.ToPeer().Relation == peer.ORGANIZATION_MASTER_PENDING) {
// The remote peer asked us to be their organization master.
// We confirm: they become our ORGANIZATION_MEMBER, we become their ORGANIZATION_MASTER.
self, serr := oclib.GetMySelf()
if serr == nil && self != nil {
data := req.UpdateOne(map[string]interface{}{
"verify": false,
"relation": peer.ORGANIZATION_MEMBER,
}, l.ToPeer().GetID())
// Stamp our peer ID as their OrganizationMasterID.
oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil).UpdateOne(map[string]interface{}{
"organization_master_id": self.GetID(),
}, l.ToPeer().GetID())
if data.Data != nil {
b, _ := json.Marshal(data.Data)
go infrastructure.EmitNATS(user, groups, tools.PropalgationMessage{
DataType: tools.PEER.EnumIndex(),
Action: tools.PB_CREATE,
Payload: b,
})
}
o.Data["json"] = data
o.ServeJSON()
return
}
} else if l.Data != nil && l.ToPeer().Verify && (l.ToPeer().Relation == peer.ORGANIZATION_MEMBER || l.ToPeer().Relation == peer.ORGANIZATION_MEMBER_PENDING) {
// The remote peer asked to join our organization as a member.
// We confirm: they are our ORGANIZATION_MEMBER, we are their ORGANIZATION_MASTER.
self, serr := oclib.GetMySelf()
if serr == nil && self != nil {
data := req.UpdateOne(map[string]interface{}{
"verify": false,
"relation": peer.ORGANIZATION_MEMBER,
}, l.ToPeer().GetID())
// Stamp our ID as the OrganizationMasterID on the new member.
oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil).UpdateOne(map[string]interface{}{
"organization_master_id": self.GetID(),
}, l.ToPeer().GetID())
// Set our own OrganizationMasterID on self (we are the master).
if self2, _ := oclib.GetMySelf(); self2 != nil && self2.OrganizationMasterID == "" {
oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil).UpdateOne(map[string]interface{}{
"organization_master_id": self.GetID(),
}, self2.GetID())
}
if data.Data != nil {
b, _ := json.Marshal(data.Data)
go infrastructure.EmitNATS(user, groups, tools.PropalgationMessage{
DataType: tools.PEER.EnumIndex(),
Action: tools.PB_CREATE,
Payload: b,
})
}
o.Data["json"] = data
o.ServeJSON()
return
}
} else if l.Data != nil && l.ToPeer().Verify && l.ToPeer().Relation == peer.ORGANIZATION_PARTNER {
data := req.UpdateOne(map[string]interface{}{
"verify": false,
"relation": peer.ORGANIZATION_PARTNER,
}, l.ToPeer().GetID())
if data.Data != nil {
b, _ := json.Marshal(data.Data)
go infrastructure.EmitNATS(user, groups, tools.PropalgationMessage{
DataType: tools.PEER.EnumIndex(),
Action: tools.PB_CREATE,
Payload: b,
})
}
o.Data["json"] = data
o.ServeJSON()
return
2026-01-23 08:07:17 +01:00
}
o.Data["json"] = map[string]interface{}{
"data": nil,
"code": 404,
2026-03-04 11:58:13 +01:00
"error": "peer to verify not found",
2026-01-23 08:07:17 +01:00
}
o.ServeJSON()
}
2026-04-08 11:29:16 +02:00
// @Title add
// @Description add peer by peerid
// @Param id path string true "the peer id you want to blacklist"
// @Success 200 {peer} models.peer
// @router /add/:id [post]
func (o *PeerController) Add() {
user, _, _ := oclib.ExtractTokenInfo(*o.Ctx.Request)
id := o.Ctx.Input.Param(":id")
infrastructure.SearchMu.Lock()
2026-04-29 11:43:52 +02:00
defer infrastructure.SearchMu.Unlock()
fmt.Println("qdqqds", infrastructure.SearchStreamAction)
2026-04-08 11:29:16 +02:00
if infrastructure.SearchStreamAction[user] != nil {
for _, p := range infrastructure.SearchStreamAction[user] {
if p.GetID() == id {
req := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil)
2026-04-29 11:43:52 +02:00
p.NotInCatalog = false
2026-04-08 11:29:16 +02:00
o.Data["json"] = req.StoreOne(p.Serialize(p))
o.ServeJSON()
return
}
}
}
o.Data["json"] = map[string]interface{}{
"data": nil,
"code": 404,
"error": "peer not received found",
}
o.ServeJSON()
}
2026-06-01 10:30:36 +02:00
// @Title Master
// @Description add master peer by peerid
// @Param id path string true "the peer id you want to blacklist"
// @Success 200 {peer} models.peer
// @router /master/:id [post]
func (o *PeerController) Master() {
if !config.GetConfig().IsNano {
o.Data["json"] = map[string]interface{}{
"data": nil,
"code": 409,
"error": "not nano built can't ask for master",
}
}
user, _, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
id := o.Ctx.Input.Param(":id")
req := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil)
data := req.LoadOne(id)
p := data.ToPeer()
if p.IsNano {
o.Data["json"] = map[string]interface{}{
"data": nil,
"code": 409,
"error": "is not Master built can't ask for master",
}
}
o.changeRelation(id, p, user, groups, peer.MASTER, req)
}
// @Title Nano
// @Description add Nano peer by peerid
// @Param id path string true "the peer id you want to blacklist"
// @Success 200 {peer} models.peer
// @router /nano/:id [post]
func (o *PeerController) Nano() {
if config.GetConfig().IsNano {
o.Data["json"] = map[string]interface{}{
"data": nil,
"code": 409,
"error": "nano built can't ask for nano",
}
}
user, _, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
id := o.Ctx.Input.Param(":id")
req := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil)
data := req.LoadOne(id)
p := data.ToPeer()
if !p.IsNano {
o.Data["json"] = map[string]interface{}{
"data": nil,
"code": 409,
"error": "is not Nano built can't ask for nano",
}
}
o.changeRelation(id, p, user, groups, peer.NANO, req)
}
2026-04-01 11:27:05 +02:00
// @Title known
// @Description add kwown peer by peerid
2026-01-23 08:07:17 +01:00
// @Param id path string true "the peer id you want to blacklist"
// @Success 200 {peer} models.peer
2026-04-08 11:29:16 +02:00
// @router /known/:id [post]
2026-04-01 11:27:05 +02:00
func (o *PeerController) Known() {
2026-03-12 09:10:14 +01:00
user, _, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
2026-01-23 08:07:17 +01:00
id := o.Ctx.Input.Param(":id")
2026-01-28 16:05:47 +01:00
req := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil)
2026-01-23 08:07:17 +01:00
data := req.LoadOne(id)
2026-04-01 11:27:05 +02:00
o.changeRelation(id, data.ToPeer(), user, groups, peer.NONE, req)
2026-01-23 08:07:17 +01:00
}
2024-10-15 16:55:29 +02:00
// @Title Partner
// @Description add partner peer by peerid
2026-01-23 08:07:17 +01:00
// @Param id path string true "the peer id you want to blacklist"
2024-10-15 16:55:29 +02:00
// @Success 200 {peer} models.peer
2026-04-08 11:29:16 +02:00
// @router /partner/:id [post]
2026-01-23 08:07:17 +01:00
func (o *PeerController) Partner() {
2026-06-01 10:30:36 +02:00
if config.GetConfig().IsNano {
o.Data["json"] = map[string]interface{}{
"data": nil,
"code": 409,
"error": "nano built can't ask for partner",
}
}
2026-03-12 09:10:14 +01:00
user, _, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
2024-10-15 16:55:29 +02:00
id := o.Ctx.Input.Param(":id")
2026-01-28 16:05:47 +01:00
req := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil)
2026-01-23 08:07:17 +01:00
data := req.LoadOne(id)
2026-04-01 11:27:05 +02:00
o.changeRelation(id, data.ToPeer(), user, groups, peer.PARTNER, req)
2024-10-15 16:55:29 +02:00
}
// @Title Blacklist
// @Description add blacklist peer by peerid
// @Param id path string true "the peer id you want to blacklist"
// @Success 200 {peer} models.peer
2026-04-08 11:29:16 +02:00
// @router /blacklist/:id [post]
2024-10-15 16:55:29 +02:00
func (o *PeerController) Blacklist() {
2026-03-12 09:10:14 +01:00
user, _, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
2024-10-15 16:55:29 +02:00
id := o.Ctx.Input.Param(":id")
2026-01-28 16:05:47 +01:00
req := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil)
2026-01-26 15:45:13 +01:00
data := req.LoadOne(id)
2026-04-01 11:27:05 +02:00
o.changeRelation(id, data.ToPeer(), user, groups, peer.BLACKLIST, req)
2026-01-23 08:07:17 +01:00
}
// used from : peer ask, or response, only from peer origin is authorized to change...
2026-04-01 11:27:05 +02:00
func (o *PeerController) changeRelation(id string, dest *peer.Peer, user string, groups []string, relation peer.PeerRelation, request *oclib.Request) {
2026-06-01 10:30:36 +02:00
if dest.IsNano && relation != peer.NANO {
o.Data["json"] = map[string]interface{}{
"data": nil,
"code": 409,
"error": "can't change relation on nano",
}
o.ServeJSON()
2026-04-29 11:43:52 +02:00
return
}
2026-04-01 11:27:05 +02:00
infrastructure.SearchMu.Lock()
if dest == nil && infrastructure.SearchStreamAction[user] != nil { // add auto in base if not existing
req := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil)
for _, pp := range infrastructure.SearchStreamAction[user] {
if pp.GetID() == id {
data := req.StoreOne(pp.Serialize(pp))
dest = data.ToPeer()
break
}
2026-01-23 08:07:17 +01:00
}
}
2026-04-01 11:27:05 +02:00
infrastructure.SearchMu.Unlock()
2026-01-23 08:07:17 +01:00
// store and return Id or post with UUID
if dest != nil {
2026-04-01 11:27:05 +02:00
if ok, _ := oclib.IsMySelf(dest.GetID()); ok {
o.Data["json"] = map[string]interface{}{
"data": nil,
"code": 400,
"error": "can't change ourself",
}
o.ServeJSON()
return
}
2026-04-01 15:55:36 +02:00
rRelation := relation
2026-01-26 15:45:13 +01:00
if !dest.Verify {
switch relation {
case peer.PARTNER:
relation = peer.PENDING_PARTNER
2026-04-29 11:43:52 +02:00
case peer.NANO:
relation = peer.PENDING_NANO
2026-01-26 15:45:13 +01:00
case peer.BLACKLIST:
relation = peer.NONE
2026-06-22 08:00:14 +02:00
case peer.ORGANIZATION_MASTER:
relation = peer.ORGANIZATION_MASTER_PENDING
case peer.ORGANIZATION_MEMBER:
relation = peer.ORGANIZATION_MEMBER_PENDING
2026-01-26 15:45:13 +01:00
}
2026-01-23 08:07:17 +01:00
}
if dest.Verify && relation == peer.PENDING_PARTNER {
relation = peer.PARTNER
}
2026-04-29 11:43:52 +02:00
if dest.Verify && relation == peer.PENDING_NANO {
relation = peer.NANO
}
2026-06-22 08:00:14 +02:00
if dest.Verify && relation == peer.ORGANIZATION_MASTER_PENDING {
relation = peer.ORGANIZATION_MASTER
}
if dest.Verify && relation == peer.ORGANIZATION_MEMBER_PENDING {
relation = peer.ORGANIZATION_MEMBER
}
2026-05-27 16:24:35 +02:00
wasMaster := dest.Relation == peer.MASTER
2026-01-23 08:07:17 +01:00
data := request.UpdateOne(map[string]interface{}{
"relation": relation,
}, dest.GetID())
2026-03-04 11:58:13 +01:00
fmt.Println(data.Err, data.Data)
if data.Err == "" && data.Data != nil {
b, _ := json.Marshal(data.Data)
2026-03-12 09:10:14 +01:00
go infrastructure.EmitNATS(user, groups, tools.PropalgationMessage{
2026-03-04 11:58:13 +01:00
DataType: tools.PEER.EnumIndex(),
Action: tools.PB_CREATE,
Payload: b,
})
}
2026-05-27 16:24:35 +02:00
// The peer was our master and is no longer — clear the MasterID on self.
if wasMaster {
if self, serr := oclib.GetMySelf(); serr == nil && self != nil {
oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil).UpdateOne(map[string]interface{}{
"master_id": "",
}, self.GetID())
}
}
2026-04-01 15:55:36 +02:00
if rRelation == peer.BLACKLIST {
request.UpdateOne(map[string]interface{}{
"relation": rRelation,
}, dest.GetID())
}
2026-01-23 08:07:17 +01:00
o.Data["json"] = data
o.ServeJSON()
return
}
o.Data["json"] = map[string]interface{}{
"data": nil,
2026-04-08 11:29:16 +02:00
"code": 404,
2026-01-23 08:07:17 +01:00
"error": "peer not found.",
}
2024-10-15 16:55:29 +02:00
o.ServeJSON()
}
2026-06-22 08:00:14 +02:00
// @Title SetOrganization
// @Description set organization data on self peer (only allowed when peer has no OrganizationMasterID)
// @Param data body json true "organization data"
// @Success 200 {peer} models.peer
// @router /organization [put]
func (o *PeerController) SetOrganization() {
self, err := oclib.GetMySelf()
if err != nil || self == nil {
o.Data["json"] = map[string]interface{}{"data": nil, "code": 404, "error": "self peer not found"}
o.ServeJSON()
return
}
if self.OrganizationMasterID != "" {
o.Data["json"] = map[string]interface{}{"data": nil, "code": 409, "error": "cannot set organization: peer already has an organization master"}
o.ServeJSON()
return
}
var org organization.Organization
if err := json.Unmarshal(o.Ctx.Input.CopyBody(100000), &org); err != nil {
o.Data["json"] = map[string]interface{}{"data": nil, "code": 400, "error": "invalid organization payload: " + err.Error()}
o.ServeJSON()
return
}
req := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil)
data := req.UpdateOne(map[string]interface{}{"organization": org}, self.GetID())
o.Data["json"] = data
o.ServeJSON()
}
// @Title OrganizationMasterRequest
// @Description request to become the organization master of a peer (send them an ORGANIZATION_MEMBER relation)
// @Param id path string true "the peer id to become member of our org"
// @Success 200 {peer} models.peer
// @router /organization_master/:id [post]
func (o *PeerController) OrganizationMasterRequest() {
user, _, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
id := o.Ctx.Input.Param(":id")
self, err := oclib.GetMySelf()
if err != nil || self == nil {
o.Data["json"] = map[string]interface{}{"data": nil, "code": 404, "error": "self peer not found"}
o.ServeJSON()
return
}
req := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil)
data := req.LoadOne(id)
p := data.ToPeer()
if p == nil {
o.Data["json"] = map[string]interface{}{"data": nil, "code": 404, "error": "peer not found"}
o.ServeJSON()
return
}
// Send the target peer an ORGANIZATION_MEMBER relation request (they receive us as their master).
o.changeRelation(id, p, user, groups, peer.ORGANIZATION_MEMBER, req)
}
// @Title OrganizationMemberRequest
// @Description request to join a peer's organization as a member (send them an ORGANIZATION_MASTER relation)
// @Param id path string true "the peer id whose org we want to join"
// @Success 200 {peer} models.peer
// @router /organization_member/:id [post]
func (o *PeerController) OrganizationMemberRequest() {
user, _, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
id := o.Ctx.Input.Param(":id")
self, err := oclib.GetMySelf()
if err != nil || self == nil {
o.Data["json"] = map[string]interface{}{"data": nil, "code": 404, "error": "self peer not found"}
o.ServeJSON()
return
}
if self.OrganizationMasterID != "" {
o.Data["json"] = map[string]interface{}{"data": nil, "code": 409, "error": "cannot request master: peer already has an organization master"}
o.ServeJSON()
return
}
req := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil)
data := req.LoadOne(id)
p := data.ToPeer()
if p == nil {
o.Data["json"] = map[string]interface{}{"data": nil, "code": 404, "error": "peer not found"}
o.ServeJSON()
return
}
// Send the target peer an ORGANIZATION_MASTER relation request (they receive us as a member candidate).
o.changeRelation(id, p, user, groups, peer.ORGANIZATION_MASTER, req)
}
// @Title OrganizationPartner
// @Description request organization partner relation with a peer
// @Param id path string true "the peer id to set as organization partner"
// @Success 200 {peer} models.peer
// @router /organization_partner/:id [post]
func (o *PeerController) OrganizationPartner() {
user, _, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
id := o.Ctx.Input.Param(":id")
req := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil)
data := req.LoadOne(id)
p := data.ToPeer()
if p == nil {
o.Data["json"] = map[string]interface{}{"data": nil, "code": 404, "error": "peer not found"}
o.ServeJSON()
return
}
o.changeRelation(id, p, user, groups, peer.ORGANIZATION_PARTNER, req)
}
// @Title SetPolicy
// @Description assign or clear a policy on a peer
// @Param id path string true "the peer id"
// @Param data body json true "body with policy_id field"
// @Success 200 {peer} models.peer
// @router /:id/policy [put]
func (o *PeerController) SetPolicy() {
user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
id := o.Ctx.Input.Param(":id")
var body map[string]interface{}
json.Unmarshal(o.Ctx.Input.CopyBody(100000), &body)
o.Data["json"] = oclib.NewRequest(oclib.LibDataEnum(oclib.PEER), user, peerID, groups, nil).UpdateOne(map[string]interface{}{
"policy_id": body["policy_id"],
}, id)
o.ServeJSON()
}
2026-04-08 11:29:16 +02:00
// @Title Delete
// @Description delete peer by peerid
2024-10-15 16:55:29 +02:00
// @Param id path string true "the peer id you want to delete state"
// @Success 200 {peer} models.peer
2026-04-08 11:29:16 +02:00
// @router /:id [delete]
func (o *PeerController) Delete() {
2024-10-15 16:55:29 +02:00
id := o.Ctx.Input.Param(":id")
2026-04-08 11:29:16 +02:00
if ok, _ := oclib.IsMySelf(id); ok {
o.Data["json"] = map[string]interface{}{
"data": nil,
"code": 400,
"error": "can't remove myself",
}
o.ServeJSON()
return
}
user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
o.Data["json"] = oclib.NewRequest(oclib.LibDataEnum(oclib.PEER), user, peerID, groups, nil).DeleteOne(id)
fmt.Println(o.Data["json"])
2024-10-15 16:55:29 +02:00
o.ServeJSON()
}
2026-01-26 11:23:04 +01:00
2026-04-29 11:43:52 +02:00
func Websocket(c ctx.Context, user string, conn *websocket.Conn) {
2026-04-01 11:27:05 +02:00
defer conn.Close()
done := make(chan struct{})
go func() {
var discard interface{}
2026-03-13 10:28:45 +01:00
for {
2026-04-01 11:27:05 +02:00
if conn.ReadJSON(&discard) != nil {
close(done)
2026-02-23 17:18:16 +01:00
return
}
}
2026-04-01 11:27:05 +02:00
}()
defer func() {
if ch, ok := infrastructure.SearchStream[user]; ok {
close(ch)
infrastructure.SearchMu.Lock()
delete(infrastructure.SearchStream, user)
delete(infrastructure.SearchStreamAction, user)
2026-04-29 11:43:52 +02:00
fmt.Println("DEFER")
2026-04-01 11:27:05 +02:00
infrastructure.SearchMu.Unlock()
}
infrastructure.EmitNATS(user, nil, tools.PropalgationMessage{
Action: tools.PB_CLOSE_SEARCH,
DataType: tools.PEER.EnumIndex(),
})
}()
for {
select {
case msg, ok := <-infrastructure.SearchStream[user]:
if !ok {
continue
}
2026-04-29 11:43:52 +02:00
// Only accumulate peers in the action list (not online-change events).
if msg.Peer != nil {
fmt.Println("AAADDD")
infrastructure.SearchMu.Lock()
infrastructure.SearchStreamAction[user] = append(infrastructure.SearchStreamAction[user], msg.Peer)
infrastructure.SearchMu.Unlock()
fmt.Println("AAADDD", infrastructure.SearchStreamAction[user])
}
2026-04-01 11:27:05 +02:00
if conn.WriteJSON(msg) != nil {
continue
}
case <-done:
return
2026-04-29 11:43:52 +02:00
case <-c.Done():
2026-04-01 11:27:05 +02:00
return
}
}
2026-02-23 17:18:16 +01:00
}
2026-01-26 11:23:04 +01:00
/*
Un pair change le statut d'un autre pair, alors ce dernier est joins automatiquement, on ne peut pas s'auto lié seul un externe peut faire ce processus de demande.
On change le pair pour pouvoir le mettre à jour, alors, le lien se met à jour automatiquement. p1 -> update status -> link (p2) -> p2 response -> update status -> link (p1)
Que définit le partnership de type : Partner, Blacklist et None.
BlackList : implique qu'on ne peut pas "voir" un pair et ses ressources, d'un coté comme de l'autre. Il suffit qu'un pair définisse la Blacklist, le pair opposant ne peut plus le voir.
(DHT allons plus loin)
Partner : Donne accès à des ressources non publique duquel un partnership à été modélisé, de type * ou dédié.
None : Est visible, et ne donne accès qu'au ressources publique et aux profiles all. Les profiles dédiés ne s'appliquent que si on est dans une situation de partenariat.
Note: L'état PENDING revient à dire qu'une relation est à l'état None,... si il y a une vérification on considère tout status à None. C'est une vérification importante.
*/