peer change

This commit is contained in:
mr
2026-06-22 08:00:14 +02:00
parent cbd2fb1d46
commit f30b56fa34
10 changed files with 653 additions and 1 deletions
+205
View File
@@ -10,6 +10,7 @@ import (
oclib "cloud.o-forge.io/core/oc-lib"
"cloud.o-forge.io/core/oc-lib/config"
"cloud.o-forge.io/core/oc-lib/dbs"
"cloud.o-forge.io/core/oc-lib/models/organization"
"cloud.o-forge.io/core/oc-lib/models/peer"
"cloud.o-forge.io/core/oc-lib/tools"
beego "github.com/beego/beego/v2/server/web"
@@ -214,6 +215,78 @@ func (o *PeerController) Valid() {
o.ServeJSON()
return
}
} 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
}
o.Data["json"] = map[string]interface{}{
"data": nil,
@@ -399,6 +472,10 @@ func (o *PeerController) changeRelation(id string, dest *peer.Peer, user string,
relation = peer.PENDING_NANO
case peer.BLACKLIST:
relation = peer.NONE
case peer.ORGANIZATION_MASTER:
relation = peer.ORGANIZATION_MASTER_PENDING
case peer.ORGANIZATION_MEMBER:
relation = peer.ORGANIZATION_MEMBER_PENDING
}
}
if dest.Verify && relation == peer.PENDING_PARTNER {
@@ -407,6 +484,12 @@ func (o *PeerController) changeRelation(id string, dest *peer.Peer, user string,
if dest.Verify && relation == peer.PENDING_NANO {
relation = peer.NANO
}
if dest.Verify && relation == peer.ORGANIZATION_MASTER_PENDING {
relation = peer.ORGANIZATION_MASTER
}
if dest.Verify && relation == peer.ORGANIZATION_MEMBER_PENDING {
relation = peer.ORGANIZATION_MEMBER
}
wasMaster := dest.Relation == peer.MASTER
data := request.UpdateOne(map[string]interface{}{
"relation": relation,
@@ -446,6 +529,128 @@ func (o *PeerController) changeRelation(id string, dest *peer.Peer, user string,
o.ServeJSON()
}
// @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()
}
// @Title Delete
// @Description delete peer by peerid
// @Param id path string true "the peer id you want to delete state"
+81
View File
@@ -0,0 +1,81 @@
package controllers
import (
"encoding/json"
"strconv"
oclib "cloud.o-forge.io/core/oc-lib"
beego "github.com/beego/beego/v2/server/web"
)
type PolicyController struct {
beego.Controller
}
// @Title GetAll
// @Description get all policies
// @Param is_draft query string false
// @Param offset query string false
// @Param limit query string false
// @Success 200 {policy} policy.Policy
// @router / [get]
func (o *PolicyController) GetAll() {
user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
isDraft := o.Ctx.Input.Query("is_draft")
offset, _ := strconv.Atoi(o.Ctx.Input.Query("offset"))
limit, _ := strconv.Atoi(o.Ctx.Input.Query("limit"))
o.Data["json"] = oclib.NewRequest(oclib.LibDataEnum(oclib.POLICY), user, peerID, groups, nil).LoadAll(isDraft == "true", int64(offset), int64(limit))
o.ServeJSON()
}
// @Title Get
// @Description get policy by id
// @Param id path string true "the policy id"
// @Success 200 {policy} policy.Policy
// @router /:id [get]
func (o *PolicyController) Get() {
user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
id := o.Ctx.Input.Param(":id")
o.Data["json"] = oclib.NewRequest(oclib.LibDataEnum(oclib.POLICY), user, peerID, groups, nil).LoadOne(id)
o.ServeJSON()
}
// @Title Post
// @Description create a policy
// @Param data body json true "policy body"
// @Success 200 {policy} policy.Policy
// @router / [post]
func (o *PolicyController) Post() {
user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
var body map[string]interface{}
json.Unmarshal(o.Ctx.Input.CopyBody(100000), &body)
o.Data["json"] = oclib.NewRequest(oclib.LibDataEnum(oclib.POLICY), user, peerID, groups, nil).StoreOne(body)
o.ServeJSON()
}
// @Title Put
// @Description update a policy
// @Param id path string true "the policy id"
// @Param data body json true "policy body"
// @Success 200 {policy} policy.Policy
// @router /:id [put]
func (o *PolicyController) Put() {
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.POLICY), user, peerID, groups, nil).UpdateOne(body, id)
o.ServeJSON()
}
// @Title Delete
// @Description delete a policy
// @Param id path string true "the policy id"
// @Success 200 {policy} policy.Policy
// @router /:id [delete]
func (o *PolicyController) Delete() {
user, peerID, groups := oclib.ExtractTokenInfo(*o.Ctx.Request)
id := o.Ctx.Input.Param(":id")
o.Data["json"] = oclib.NewRequest(oclib.LibDataEnum(oclib.POLICY), user, peerID, groups, nil).DeleteOne(id)
o.ServeJSON()
}