Added node config

This commit is contained in:
CORNIERE Rémi 2020-01-14 22:47:49 +01:00
parent 9ca9f48c89
commit 20e02cc9ad
6 changed files with 74 additions and 13 deletions

View File

@ -178,5 +178,47 @@ func main() {
purgeRq, _ := stanza.NewPurgeAllItems(serviceName, nodeName) purgeRq, _ := stanza.NewPurgeAllItems(serviceName, nodeName)
client.SendIQ(ctx, purgeRq) client.SendIQ(ctx, purgeRq)
// =============================
// Configure the node :
confRq, _ := stanza.NewConfigureNode(serviceName, nodeName)
confReqCh, err := client.SendIQ(ctx, confRq)
select {
case confForm := <-confReqCh:
fields, err := confForm.GetFormFields()
if err != nil {
log.Fatal("No config fields found !")
}
// These are some common fields expected to be present. Change processing to your liking
if fields["pubsub#max_payload_size"] != nil {
fields["pubsub#max_payload_size"].ValuesList[0] = "100000"
}
if fields["pubsub#notification_type"] != nil {
fields["pubsub#notification_type"].ValuesList[0] = "headline"
}
submitConf, err := stanza.NewFormSubmissionOwner(serviceName,
nodeName,
[]*stanza.Field{
fields["pubsub#max_payload_size"],
fields["pubsub#notification_type"],
})
c, _ := client.SendIQ(ctx, submitConf)
select {
case <-c:
fmt.Println("node configuration was successful")
case <-time.After(300 * time.Millisecond):
cancel()
log.Fatal("No iq response was received in time")
}
case <-time.After(300 * time.Millisecond):
cancel()
log.Fatal("No iq response was received in time")
}
cancel() cancel()
} }

View File

@ -17,7 +17,7 @@ type Form struct {
XMLName xml.Name `xml:"jabber:x:data x"` XMLName xml.Name `xml:"jabber:x:data x"`
Instructions []string `xml:"instructions"` Instructions []string `xml:"instructions"`
Title string `xml:"title,omitempty"` Title string `xml:"title,omitempty"`
Fields []Field `xml:"field,omitempty"` Fields []*Field `xml:"field,omitempty"`
Reported *FormItem `xml:"reported"` Reported *FormItem `xml:"reported"`
Items []FormItem Items []FormItem
Type string `xml:"type,attr"` Type string `xml:"type,attr"`
@ -38,7 +38,7 @@ type Field struct {
Label string `xml:"label,attr,omitempty"` Label string `xml:"label,attr,omitempty"`
} }
func NewForm(fields []Field, formType string) *Form { func NewForm(fields []*Field, formType string) *Form {
return &Form{ return &Form{
Type: formType, Type: formType,
Fields: fields, Fields: fields,

View File

@ -57,7 +57,7 @@ func TestMarshalFormSubmit(t *testing.T) {
Node: serviceNode, Node: serviceNode,
Form: &Form{ Form: &Form{
Type: FormTypeSubmit, Type: FormTypeSubmit,
Fields: []Field{ Fields: []*Field{
{Var: "FORM_TYPE", Type: FieldTypeHidden, ValuesList: []string{"http://jabber.org/protocol/pubsub#node_config"}}, {Var: "FORM_TYPE", Type: FieldTypeHidden, ValuesList: []string{"http://jabber.org/protocol/pubsub#node_config"}},
{Var: "pubsub#title", ValuesList: []string{"Princely Musings (Atom)"}}, {Var: "pubsub#title", ValuesList: []string{"Princely Musings (Atom)"}},
{Var: "pubsub#deliver_notifications", ValuesList: []string{"1"}}, {Var: "pubsub#deliver_notifications", ValuesList: []string{"1"}},

View File

@ -198,7 +198,7 @@ func NewApprovePendingSubRequest(serviceId, sessionId, nodeId string) (IQ, error
form := &Form{ form := &Form{
Type: FormTypeSubmit, Type: FormTypeSubmit,
Fields: []Field{{Var: "pubsub#node", ValuesList: []string{nodeId}}}, Fields: []*Field{{Var: "pubsub#node", ValuesList: []string{nodeId}}},
} }
data, err := xml.Marshal(form) data, err := xml.Marshal(form)
if err != nil { if err != nil {
@ -262,25 +262,44 @@ func NewAffiliationListRequest(serviceId, nodeID string) (IQ, error) {
return iq, nil return iq, nil
} }
// NewFormSubmission builds a form submission pubsub IQ, in the Owner namespace
// This is typically used to respond to a form issued by the server when configuring a node.
// See 8.2.4 Form Submission
func NewFormSubmissionOwner(serviceId, nodeName string, fields []*Field) (IQ, error) {
if serviceId == "" || nodeName == "" {
return IQ{}, errors.New("serviceId and nodeName must be filled for this request to be valid")
}
submitConf := NewIQ(Attrs{Type: IQTypeSet, To: serviceId})
submitConf.Payload = &PubSubOwner{
OwnerUseCase: &ConfigureOwner{
Node: nodeName,
Form: NewForm(fields,
FormTypeSubmit)},
}
return submitConf, nil
}
// GetFormFields gets the fields from a form in a IQ stanza of type result, as a map. // GetFormFields gets the fields from a form in a IQ stanza of type result, as a map.
// Key is the "var" attribute of the field, and field is the value. // Key is the "var" attribute of the field, and field is the value.
// The user can then select and modify the fields they want to alter, and submit a new form to the service using the // The user can then select and modify the fields they want to alter, and submit a new form to the service using the
// NewFormSubmission function to build the IQ. // NewFormSubmission function to build the IQ.
// TODO : remove restriction on IQ type ? // TODO : remove restriction on IQ type ?
func (iq *IQ) GetFormFields() (map[string]Field, error) { func (iq *IQ) GetFormFields() (map[string]*Field, error) {
if iq.Type != IQTypeResult { if iq.Type != IQTypeResult {
return nil, errors.New("this IQ is not a result type IQ. Cannot extract the form from it") return nil, errors.New("this IQ is not a result type IQ. Cannot extract the form from it")
} }
switch payload := iq.Payload.(type) { switch payload := iq.Payload.(type) {
// We support IOT Control IQ // We support IOT Control IQ
case *PubSubGeneric: case *PubSubGeneric:
fieldMap := make(map[string]Field) fieldMap := make(map[string]*Field)
for _, elt := range payload.Configure.Form.Fields { for _, elt := range payload.Configure.Form.Fields {
fieldMap[elt.Var] = elt fieldMap[elt.Var] = elt
} }
return fieldMap, nil return fieldMap, nil
case *PubSubOwner: case *PubSubOwner:
fieldMap := make(map[string]Field) fieldMap := make(map[string]*Field)
co, ok := payload.OwnerUseCase.(*ConfigureOwner) co, ok := payload.OwnerUseCase.(*ConfigureOwner)
if !ok { if !ok {
return nil, errors.New("this IQ does not contain a PubSub payload with a configure tag for the owner namespace") return nil, errors.New("this IQ does not contain a PubSub payload with a configure tag for the owner namespace")
@ -291,7 +310,7 @@ func (iq *IQ) GetFormFields() (map[string]Field, error) {
return fieldMap, nil return fieldMap, nil
default: default:
if iq.Any != nil { if iq.Any != nil {
fieldMap := make(map[string]Field) fieldMap := make(map[string]*Field)
if iq.Any.XMLName.Local != "command" { if iq.Any.XMLName.Local != "command" {
return nil, errors.New("this IQ does not contain a form") return nil, errors.New("this IQ does not contain a form")
} }
@ -307,7 +326,7 @@ func (iq *IQ) GetFormFields() (map[string]Field, error) {
} }
err = xml.Unmarshal(data, &f) err = xml.Unmarshal(data, &f)
if err == nil { if err == nil {
fieldMap[f.Var] = f fieldMap[f.Var] = &f
} }
} }
} }

View File

@ -357,7 +357,7 @@ func TestNewApproveSubRequest(t *testing.T) {
apprForm := &stanza.Form{ apprForm := &stanza.Form{
Type: stanza.FormTypeSubmit, Type: stanza.FormTypeSubmit,
Fields: []stanza.Field{ Fields: []*stanza.Field{
{Var: "FORM_TYPE", Type: stanza.FieldTypeHidden, ValuesList: []string{"http://jabber.org/protocol/pubsub#subscribe_authorization"}}, {Var: "FORM_TYPE", Type: stanza.FieldTypeHidden, ValuesList: []string{"http://jabber.org/protocol/pubsub#subscribe_authorization"}},
{Var: "pubsub#subid", ValuesList: []string{"123-abc"}}, {Var: "pubsub#subid", ValuesList: []string{"123-abc"}},
{Var: "pubsub#node", ValuesList: []string{"princely_musings"}}, {Var: "pubsub#node", ValuesList: []string{"princely_musings"}},
@ -381,7 +381,7 @@ func TestNewApproveSubRequest(t *testing.T) {
for _, f := range frm.Fields { for _, f := range frm.Fields {
if f.Var == "pubsub#allow" { if f.Var == "pubsub#allow" {
allowField = &f allowField = f
} }
} }
if allowField == nil || allowField.ValuesList[0] != "true" { if allowField == nil || allowField.ValuesList[0] != "true" {

View File

@ -8,7 +8,7 @@ import (
"testing" "testing"
) )
var submitFormExample = stanza.NewForm([]stanza.Field{ var submitFormExample = stanza.NewForm([]*stanza.Field{
{Var: "FORM_TYPE", Type: stanza.FieldTypeHidden, ValuesList: []string{"http://jabber.org/protocol/pubsub#node_config"}}, {Var: "FORM_TYPE", Type: stanza.FieldTypeHidden, ValuesList: []string{"http://jabber.org/protocol/pubsub#node_config"}},
{Var: "pubsub#title", ValuesList: []string{"Princely Musings (Atom)"}}, {Var: "pubsub#title", ValuesList: []string{"Princely Musings (Atom)"}},
{Var: "pubsub#deliver_notifications", ValuesList: []string{"1"}}, {Var: "pubsub#deliver_notifications", ValuesList: []string{"1"}},
@ -741,7 +741,7 @@ func TestNewCreateAndConfigNode(t *testing.T) {
"princely_musings", "princely_musings",
&stanza.Form{ &stanza.Form{
Type: stanza.FormTypeSubmit, Type: stanza.FormTypeSubmit,
Fields: []stanza.Field{ Fields: []*stanza.Field{
{Var: "FORM_TYPE", Type: stanza.FieldTypeHidden, ValuesList: []string{"http://jabber.org/protocol/pubsub#node_config"}}, {Var: "FORM_TYPE", Type: stanza.FieldTypeHidden, ValuesList: []string{"http://jabber.org/protocol/pubsub#node_config"}},
{Var: "pubsub#notify_retract", ValuesList: []string{"0"}}, {Var: "pubsub#notify_retract", ValuesList: []string{"0"}},
{Var: "pubsub#notify_sub", ValuesList: []string{"0"}}, {Var: "pubsub#notify_sub", ValuesList: []string{"0"}},