diff --git a/controllers/peer.go b/controllers/peer.go
index 65b224c..7a7ffc0 100644
--- a/controllers/peer.go
+++ b/controllers/peer.go
@@ -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"
diff --git a/controllers/policy.go b/controllers/policy.go
new file mode 100644
index 0000000..8d52ccd
--- /dev/null
+++ b/controllers/policy.go
@@ -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()
+}
diff --git a/go.mod b/go.mod
index 88465d1..f453af6 100644
--- a/go.mod
+++ b/go.mod
@@ -3,7 +3,7 @@ module oc-peer
go 1.25.0
require (
- cloud.o-forge.io/core/oc-lib v0.0.0-20260528142936-26948da3c1ff
+ cloud.o-forge.io/core/oc-lib v0.0.0-20260605135650-1425a3149455
github.com/beego/beego/v2 v2.3.8
github.com/smartystreets/goconvey v1.7.2
)
diff --git a/go.sum b/go.sum
index 8b2f99a..8767000 100644
--- a/go.sum
+++ b/go.sum
@@ -1,5 +1,9 @@
cloud.o-forge.io/core/oc-lib v0.0.0-20260528142936-26948da3c1ff h1:Pqjt/IBv+AajJkvwqPCUpYunm6ZfXapT1pIXej1iQuc=
cloud.o-forge.io/core/oc-lib v0.0.0-20260528142936-26948da3c1ff/go.mod h1:JynnOb3eMr9VZW1mHq+Vsl3tzx6gPhPsGKpQD/dtEBc=
+cloud.o-forge.io/core/oc-lib v0.0.0-20260604070031-d19ff1f8b206 h1:HRbUR9H9CIblNC0Z8obgp2J3jW4d9nO0MLNw/aiZRRs=
+cloud.o-forge.io/core/oc-lib v0.0.0-20260604070031-d19ff1f8b206/go.mod h1:JynnOb3eMr9VZW1mHq+Vsl3tzx6gPhPsGKpQD/dtEBc=
+cloud.o-forge.io/core/oc-lib v0.0.0-20260605135650-1425a3149455 h1:hDsqGw1EUY2b4mB+aUFSuQO75t+l+Ow9vZgjHZDK3uw=
+cloud.o-forge.io/core/oc-lib v0.0.0-20260605135650-1425a3149455/go.mod h1:JynnOb3eMr9VZW1mHq+Vsl3tzx6gPhPsGKpQD/dtEBc=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
diff --git a/infrastructure/nats.go b/infrastructure/nats.go
index 8cfaac3..5075f26 100644
--- a/infrastructure/nats.go
+++ b/infrastructure/nats.go
@@ -45,6 +45,70 @@ var self *peer.Peer
func ListenNATS() {
tools.NewNATSCaller().ListenNats(map[tools.NATSMethod]func(tools.NATSResponse){
+ // ORG_PARTNER_EVENT is delivered by our local oc-discovery after receiving a
+ // libp2p stream from the remote. The payload "type" field routes to one of two
+ // sub-flows:
+ // "check" — we are master: validate candidate, emit confirm via PROPALGATION
+ // "confirm" — we are requester: upgrade (or discard) the candidate's relation
+ tools.ORG_PARTNER_EVENT: func(resp tools.NATSResponse) {
+ if resp.FromApp == config.GetAppName() {
+ return
+ }
+ var msg struct {
+ Type string `json:"type"`
+ RequesterID string `json:"requester_id"`
+ RequesterPeerID string `json:"requester_peer_id"`
+ CandidateID string `json:"candidate_id"`
+ MasterID string `json:"master_id"`
+ Confirmed bool `json:"confirmed"`
+ }
+ if err := json.Unmarshal(resp.Payload, &msg); err != nil || msg.CandidateID == "" {
+ return
+ }
+ switch msg.Type {
+ case "check":
+ self, _ := oclib.GetMySelf()
+ if self == nil || self.GetID() != msg.MasterID {
+ return
+ }
+ access := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil)
+ candidate := access.LoadOne(msg.CandidateID)
+ confirmed := candidate.Data != nil && candidate.ToPeer().Relation == peer.ORGANIZATION_MEMBER
+
+ confirmPayload, _ := json.Marshal(map[string]interface{}{
+ "type": "confirm",
+ "requester_peer_id": msg.RequesterPeerID,
+ "candidate_id": msg.CandidateID,
+ "confirmed": confirmed,
+ })
+ propMsg := tools.PropalgationMessage{
+ Action: tools.PB_ORG_PARTNER,
+ DataType: int(tools.PEER),
+ Payload: confirmPayload,
+ }
+ b, _ := json.Marshal(propMsg)
+ tools.NewNATSCaller().SetNATSPub(tools.PROPALGATION_EVENT, tools.NATSResponse{
+ FromApp: config.GetAppName(),
+ Datatype: tools.PEER,
+ User: resp.User,
+ Groups: resp.Groups,
+ Method: int(tools.PROPALGATION_EVENT),
+ Payload: b,
+ })
+
+ case "confirm":
+ access := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil)
+ relation := peer.NONE
+ if msg.Confirmed {
+ relation = peer.ORGANIZATION_PARTNER
+ }
+ access.UpdateOne(map[string]interface{}{
+ "relation": relation,
+ "verify": false,
+ }, msg.CandidateID)
+ }
+ },
+
tools.CREATE_RESOURCE: func(resp tools.NATSResponse) {
if resp.FromApp == config.GetAppName() || !slices.Contains(ressourceCols, oclib.LibDataEnum(resp.Datatype)) {
return
@@ -101,6 +165,12 @@ func ListenNATS() {
p.Relation = peer.PENDING_PARTNER
}
p.IsNano = config.GetConfig().IsNano
+ // If the incoming peer shares our OrganizationMasterID, initiate org partner
+ // verification with our master before accepting them as org partner.
+ if self != nil && self.OrganizationMasterID != "" && p.OrganizationMasterID == self.OrganizationMasterID {
+ go requestOrgPartnerVerification(self, p, resp.User, resp.Groups)
+ return
+ }
access.StoreOne(p.Serialize(p))
}
}
@@ -161,3 +231,37 @@ func ListenNATS() {
},
})
}
+
+// requestOrgPartnerVerification stores the candidate as KNOWN and asks our
+// OrganizationMaster (via PROPALGATION_EVENT → oc-discovery → libp2p stream)
+// whether the candidate is really one of its ORGANIZATION_MEMBERs.
+// The ORG_PARTNER_EVENT "confirm" branch upgrades the relation once the master replies.
+func requestOrgPartnerVerification(self *peer.Peer, candidate *peer.Peer, user string, groups []string) {
+ // Store candidate as NONE (path "known") — no privilege until master confirms.
+ access := oclib.NewRequestAdmin(oclib.LibDataEnum(oclib.PEER), nil)
+ candidate.Relation = peer.NONE
+ candidate.Verify = false
+ access.StoreOne(candidate.Serialize(candidate))
+
+ checkPayload, _ := json.Marshal(map[string]interface{}{
+ "type": "check",
+ "requester_id": self.GetID(),
+ "requester_peer_id": self.PeerID,
+ "candidate_id": candidate.GetID(),
+ "master_id": self.OrganizationMasterID,
+ })
+ propMsg := tools.PropalgationMessage{
+ Action: tools.PB_ORG_PARTNER,
+ DataType: int(tools.PEER),
+ Payload: checkPayload,
+ }
+ b, _ := json.Marshal(propMsg)
+ tools.NewNATSCaller().SetNATSPub(tools.PROPALGATION_EVENT, tools.NATSResponse{
+ FromApp: config.GetAppName(),
+ Datatype: tools.PEER,
+ User: user,
+ Groups: groups,
+ Method: int(tools.PROPALGATION_EVENT),
+ Payload: b,
+ })
+}
diff --git a/oc-peer b/oc-peer
index 88c281f..e72bc81 100755
Binary files a/oc-peer and b/oc-peer differ
diff --git a/routers/commentsRouter.go b/routers/commentsRouter.go
index 15ed303..c313bfd 100644
--- a/routers/commentsRouter.go
+++ b/routers/commentsRouter.go
@@ -25,6 +25,15 @@ func init() {
Filters: nil,
Params: nil})
+ beego.GlobalControllerRouter["oc-peer/controllers:PeerController"] = append(beego.GlobalControllerRouter["oc-peer/controllers:PeerController"],
+ beego.ControllerComments{
+ Method: "SetPolicy",
+ Router: `/:id/policy`,
+ AllowHTTPMethods: []string{"put"},
+ MethodParams: param.Make(),
+ Filters: nil,
+ Params: nil})
+
beego.GlobalControllerRouter["oc-peer/controllers:PeerController"] = append(beego.GlobalControllerRouter["oc-peer/controllers:PeerController"],
beego.ControllerComments{
Method: "Delete",
@@ -97,6 +106,42 @@ func init() {
Filters: nil,
Params: nil})
+ beego.GlobalControllerRouter["oc-peer/controllers:PeerController"] = append(beego.GlobalControllerRouter["oc-peer/controllers:PeerController"],
+ beego.ControllerComments{
+ Method: "SetOrganization",
+ Router: `/organization`,
+ AllowHTTPMethods: []string{"put"},
+ MethodParams: param.Make(),
+ Filters: nil,
+ Params: nil})
+
+ beego.GlobalControllerRouter["oc-peer/controllers:PeerController"] = append(beego.GlobalControllerRouter["oc-peer/controllers:PeerController"],
+ beego.ControllerComments{
+ Method: "OrganizationMasterRequest",
+ Router: `/organization_master/:id`,
+ AllowHTTPMethods: []string{"post"},
+ MethodParams: param.Make(),
+ Filters: nil,
+ Params: nil})
+
+ beego.GlobalControllerRouter["oc-peer/controllers:PeerController"] = append(beego.GlobalControllerRouter["oc-peer/controllers:PeerController"],
+ beego.ControllerComments{
+ Method: "OrganizationMemberRequest",
+ Router: `/organization_member/:id`,
+ AllowHTTPMethods: []string{"post"},
+ MethodParams: param.Make(),
+ Filters: nil,
+ Params: nil})
+
+ beego.GlobalControllerRouter["oc-peer/controllers:PeerController"] = append(beego.GlobalControllerRouter["oc-peer/controllers:PeerController"],
+ beego.ControllerComments{
+ Method: "OrganizationPartner",
+ Router: `/organization_partner/:id`,
+ AllowHTTPMethods: []string{"post"},
+ MethodParams: param.Make(),
+ Filters: nil,
+ Params: nil})
+
beego.GlobalControllerRouter["oc-peer/controllers:PeerController"] = append(beego.GlobalControllerRouter["oc-peer/controllers:PeerController"],
beego.ControllerComments{
Method: "Partner",
@@ -115,6 +160,51 @@ func init() {
Filters: nil,
Params: nil})
+ beego.GlobalControllerRouter["oc-peer/controllers:PolicyController"] = append(beego.GlobalControllerRouter["oc-peer/controllers:PolicyController"],
+ beego.ControllerComments{
+ Method: "GetAll",
+ Router: `/`,
+ AllowHTTPMethods: []string{"get"},
+ MethodParams: param.Make(),
+ Filters: nil,
+ Params: nil})
+
+ beego.GlobalControllerRouter["oc-peer/controllers:PolicyController"] = append(beego.GlobalControllerRouter["oc-peer/controllers:PolicyController"],
+ beego.ControllerComments{
+ Method: "Get",
+ Router: `/:id`,
+ AllowHTTPMethods: []string{"get"},
+ MethodParams: param.Make(),
+ Filters: nil,
+ Params: nil})
+
+ beego.GlobalControllerRouter["oc-peer/controllers:PolicyController"] = append(beego.GlobalControllerRouter["oc-peer/controllers:PolicyController"],
+ beego.ControllerComments{
+ Method: "Post",
+ Router: `/`,
+ AllowHTTPMethods: []string{"post"},
+ MethodParams: param.Make(),
+ Filters: nil,
+ Params: nil})
+
+ beego.GlobalControllerRouter["oc-peer/controllers:PolicyController"] = append(beego.GlobalControllerRouter["oc-peer/controllers:PolicyController"],
+ beego.ControllerComments{
+ Method: "Put",
+ Router: `/:id`,
+ AllowHTTPMethods: []string{"put"},
+ MethodParams: param.Make(),
+ Filters: nil,
+ Params: nil})
+
+ beego.GlobalControllerRouter["oc-peer/controllers:PolicyController"] = append(beego.GlobalControllerRouter["oc-peer/controllers:PolicyController"],
+ beego.ControllerComments{
+ Method: "Delete",
+ Router: `/:id`,
+ AllowHTTPMethods: []string{"delete"},
+ MethodParams: param.Make(),
+ Filters: nil,
+ Params: nil})
+
beego.GlobalControllerRouter["oc-peer/controllers:StatusController"] = append(beego.GlobalControllerRouter["oc-peer/controllers:StatusController"],
beego.ControllerComments{
Method: "Status",
diff --git a/routers/router.go b/routers/router.go
index bd665c9..3e5c7b1 100644
--- a/routers/router.go
+++ b/routers/router.go
@@ -38,6 +38,11 @@ func init() {
beego.NSInclude(
&controllers.PeerController{},
),
+ beego.NSNamespace("/policy",
+ beego.NSInclude(
+ &controllers.PolicyController{},
+ ),
+ ),
beego.NSNamespace("/version",
beego.NSInclude(
&controllers.VersionController{},
diff --git a/swagger/swagger.json b/swagger/swagger.json
index 7dd50b5..ba5dd15 100644
--- a/swagger/swagger.json
+++ b/swagger/swagger.json
@@ -164,6 +164,100 @@
}
}
},
+ "/organization": {
+ "put": {
+ "tags": [
+ "oc-peer/controllersPeerController"
+ ],
+ "description": "set organization data on self peer (only allowed when peer has no OrganizationMasterID)\n\u003cbr\u003e",
+ "operationId": "PeerController.SetOrganization",
+ "parameters": [
+ {
+ "in": "body",
+ "name": "data",
+ "description": "organization data",
+ "required": true,
+ "schema": {
+ "$ref": "#/definitions/json"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{peer} models.peer"
+ }
+ }
+ }
+ },
+ "/organization_master/{id}": {
+ "post": {
+ "tags": [
+ "oc-peer/controllersPeerController"
+ ],
+ "description": "request to become the organization master of a peer (send them an ORGANIZATION_MEMBER relation)\n\u003cbr\u003e",
+ "operationId": "PeerController.OrganizationMasterRequest",
+ "parameters": [
+ {
+ "in": "path",
+ "name": "id",
+ "description": "the peer id to become member of our org",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{peer} models.peer"
+ }
+ }
+ }
+ },
+ "/organization_member/{id}": {
+ "post": {
+ "tags": [
+ "oc-peer/controllersPeerController"
+ ],
+ "description": "request to join a peer's organization as a member (send them an ORGANIZATION_MASTER relation)\n\u003cbr\u003e",
+ "operationId": "PeerController.OrganizationMemberRequest",
+ "parameters": [
+ {
+ "in": "path",
+ "name": "id",
+ "description": "the peer id whose org we want to join",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{peer} models.peer"
+ }
+ }
+ }
+ },
+ "/organization_partner/{id}": {
+ "post": {
+ "tags": [
+ "oc-peer/controllersPeerController"
+ ],
+ "description": "request organization partner relation with a peer\n\u003cbr\u003e",
+ "operationId": "PeerController.OrganizationPartner",
+ "parameters": [
+ {
+ "in": "path",
+ "name": "id",
+ "description": "the peer id to set as organization partner",
+ "required": true,
+ "type": "string"
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "{peer} models.peer"
+ }
+ }
+ }
+ },
"/partner/{id}": {
"post": {
"tags": [
diff --git a/swagger/swagger.yml b/swagger/swagger.yml
index d141cdc..b00a393 100644
--- a/swagger/swagger.yml
+++ b/swagger/swagger.yml
@@ -218,6 +218,75 @@ paths:
responses:
"200":
description: '{peer} models.peer'
+ /organization:
+ put:
+ tags:
+ - oc-peer/controllersPeerController
+ description: |-
+ set organization data on self peer (only allowed when peer has no OrganizationMasterID)
+
+ operationId: PeerController.SetOrganization
+ parameters:
+ - in: body
+ name: data
+ description: organization data
+ required: true
+ schema:
+ $ref: '#/definitions/json'
+ responses:
+ "200":
+ description: '{peer} models.peer'
+ /organization_master/{id}:
+ post:
+ tags:
+ - oc-peer/controllersPeerController
+ description: |-
+ request to become the organization master of a peer (send them an ORGANIZATION_MEMBER relation)
+
+ operationId: PeerController.OrganizationMasterRequest
+ parameters:
+ - in: path
+ name: id
+ description: the peer id to become member of our org
+ required: true
+ type: string
+ responses:
+ "200":
+ description: '{peer} models.peer'
+ /organization_member/{id}:
+ post:
+ tags:
+ - oc-peer/controllersPeerController
+ description: |-
+ request to join a peer's organization as a member (send them an ORGANIZATION_MASTER relation)
+
+ operationId: PeerController.OrganizationMemberRequest
+ parameters:
+ - in: path
+ name: id
+ description: the peer id whose org we want to join
+ required: true
+ type: string
+ responses:
+ "200":
+ description: '{peer} models.peer'
+ /organization_partner/{id}:
+ post:
+ tags:
+ - oc-peer/controllersPeerController
+ description: |-
+ request organization partner relation with a peer
+
+ operationId: PeerController.OrganizationPartner
+ parameters:
+ - in: path
+ name: id
+ description: the peer id to set as organization partner
+ required: true
+ type: string
+ responses:
+ "200":
+ description: '{peer} models.peer'
/partner/{id}:
post:
tags: