Example #1
0
        private async void SetHandler(object Sender, IqEventArgs e)
        {
            try
            {
                string ServiceToken = XML.Attribute(e.Query, "st");
                string DeviceToken  = XML.Attribute(e.Query, "dt");
                string UserToken    = XML.Attribute(e.Query, "ut");

                LinkedList <IThingReference>    Nodes          = null;
                SortedDictionary <string, bool> ParameterNames = this.provisioningClient is null ? null : new SortedDictionary <string, bool>();
                LinkedList <ControlOperation>   Operations     = new LinkedList <ControlOperation>();
                ControlParameter Parameter;
                DataForm         Form = null;
                XmlElement       E;
                string           Name;

                foreach (XmlNode N in e.Query.ChildNodes)
                {
                    E = N as XmlElement;
                    if (E is null)
                    {
                        continue;
                    }

                    switch (E.LocalName)
                    {
                    case "nd":
                        if (Nodes is null)
                        {
                            Nodes = new LinkedList <IThingReference>();
                        }

                        string NodeId    = XML.Attribute(E, "id");
                        string SourceId  = XML.Attribute(E, "src");
                        string Partition = XML.Attribute(E, "pt");

                        if (this.OnGetNode is null)
                        {
                            Nodes.AddLast(new ThingReference(NodeId, SourceId, Partition));
                        }
                        else
                        {
                            IThingReference Ref = await this.OnGetNode(NodeId, SourceId, Partition);

                            if (Ref is null)
                            {
                                throw new ItemNotFoundException("Node not found.", e.IQ);
                            }

                            Nodes.AddLast(Ref);
                        }
                        break;

                    case "b":
                    case "cl":
                    case "d":
                    case "dt":
                    case "db":
                    case "dr":
                    case "e":
                    case "i":
                    case "l":
                    case "s":
                    case "t":
                        if (ParameterNames != null)
                        {
                            ParameterNames[XML.Attribute(E, "n")] = true;
                        }
                        break;

                    case "x":
                        Form = new DataForm(this.client, E, null, null, e.From, e.To);
                        if (Form.Type != FormType.Submit)
                        {
                            ParameterBadRequest(e);
                            return;
                        }

                        if (ParameterNames != null)
                        {
                            foreach (Field Field in Form.Fields)
                            {
                                ParameterNames[Field.Var] = true;
                            }
                        }
                        break;

                    default:
                        ParameterBadRequest(e);
                        return;
                    }
                }

                foreach (XmlNode N in e.Query.ChildNodes)
                {
                    E = N as XmlElement;
                    if (E is null)
                    {
                        continue;
                    }

                    switch (E.LocalName)
                    {
                    case "b":
                        Name = XML.Attribute(E, "n");
                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameter = await this.GetParameter(Node, Name, e);

                            if (Parameter is null)
                            {
                                return;
                            }

                            BooleanControlParameter BooleanControlParameter = Parameter as BooleanControlParameter;
                            if (BooleanControlParameter is null)
                            {
                                ParameterWrongType(Name, e);
                                return;
                            }

                            Operations.AddLast(new BooleanControlOperation(Node, BooleanControlParameter, XML.Attribute(E, "v", false), e));
                        }
                        break;

                    case "cl":
                        Name = XML.Attribute(E, "n");
                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameter = await this.GetParameter(Node, Name, e);

                            if (Parameter is null)
                            {
                                return;
                            }

                            ColorControlParameter ColorControlParameter = Parameter as ColorControlParameter;
                            if (ColorControlParameter is null)
                            {
                                ParameterWrongType(Name, e);
                                return;
                            }

                            Operations.AddLast(new ColorControlOperation(Node, ColorControlParameter, XML.Attribute(E, "v"), e));
                        }
                        break;

                    case "d":
                        Name = XML.Attribute(E, "n");
                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameter = await this.GetParameter(Node, Name, e);

                            if (Parameter is null)
                            {
                                return;
                            }

                            DateControlParameter DateControlParameter = Parameter as DateControlParameter;
                            if (DateControlParameter is null)
                            {
                                ParameterWrongType(Name, e);
                                return;
                            }

                            Operations.AddLast(new DateControlOperation(Node, DateControlParameter, XML.Attribute(E, "v", DateTime.MinValue), e));
                        }
                        break;

                    case "dt":
                        Name = XML.Attribute(E, "n");
                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameter = await this.GetParameter(Node, Name, e);

                            if (Parameter is null)
                            {
                                return;
                            }

                            DateTimeControlParameter DateTimeControlParameter = Parameter as DateTimeControlParameter;
                            if (DateTimeControlParameter is null)
                            {
                                ParameterWrongType(Name, e);
                                return;
                            }

                            Operations.AddLast(new DateTimeControlOperation(Node, DateTimeControlParameter, XML.Attribute(E, "v", DateTime.MinValue), e));
                        }
                        break;

                    case "db":
                        Name = XML.Attribute(E, "n");
                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameter = await this.GetParameter(Node, Name, e);

                            if (Parameter is null)
                            {
                                return;
                            }

                            DoubleControlParameter DoubleControlParameter = Parameter as DoubleControlParameter;
                            if (DoubleControlParameter is null)
                            {
                                ParameterWrongType(Name, e);
                                return;
                            }

                            Operations.AddLast(new DoubleControlOperation(Node, DoubleControlParameter, XML.Attribute(E, "v", 0.0), e));
                        }
                        break;

                    case "dr":
                        Name = XML.Attribute(E, "n");
                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameter = await this.GetParameter(Node, Name, e);

                            if (Parameter is null)
                            {
                                return;
                            }

                            DurationControlParameter DurationControlParameter = Parameter as DurationControlParameter;
                            if (DurationControlParameter is null)
                            {
                                ParameterWrongType(Name, e);
                                return;
                            }

                            Operations.AddLast(new DurationControlOperation(Node, DurationControlParameter, XML.Attribute(E, "v", Duration.Zero), e));
                        }
                        break;

                    case "e":
                        Name = XML.Attribute(E, "n");
                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameter = await this.GetParameter(Node, Name, e);

                            if (Parameter is null)
                            {
                                return;
                            }

                            string StringValue = XML.Attribute(E, "v");

                            if (Parameter is EnumControlParameter EnumControlParameter)
                            {
                                Type T = Types.GetType(XML.Attribute(E, "t"));
                                if (T is null)
                                {
                                    e.IqError("<error type='modify'><bad-request xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/><paramError xmlns=\"" +
                                              ControlClient.NamespaceControl + "\" n=\"" + Name + "\">Type not found.</paramError></error>");
                                    return;
                                }

                                if (!T.GetTypeInfo().IsEnum)
                                {
                                    e.IqError("<error type='modify'><bad-request xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/><paramError xmlns=\"" +
                                              ControlClient.NamespaceControl + "\" n=\"" + Name + "\">Type is not an enumeration.</paramError></error>");
                                    return;
                                }

                                Enum Value;

                                try
                                {
                                    Value = (Enum)Enum.Parse(T, StringValue);
                                }
                                catch (Exception)
                                {
                                    e.IqError("<error type='modify'><bad-request xmlns=\"urn:ietf:params:xml:ns:xmpp-stanzas\"/><paramError xmlns=\"" +
                                              ControlClient.NamespaceControl + "\" n=\"" + Name + "\">Value not valid element of enumeration.</paramError></error>");
                                    return;
                                }

                                Operations.AddLast(new EnumControlOperation(Node, EnumControlParameter, Value, e));
                            }
                            else if (Parameter is StringControlParameter StringControlParameter)
                            {
                                Operations.AddLast(new StringControlOperation(Node, StringControlParameter, StringValue, e));
                            }
                            else if (Parameter is MultiLineTextControlParameter MultiLineTextControlParameter)
                            {
                                Operations.AddLast(new MultiLineTextControlOperation(Node, MultiLineTextControlParameter, StringValue, e));
                            }
                            else
                            {
                                ParameterWrongType(Name, e);
                                return;
                            }
                        }
                        break;

                    case "i":
                        Name = XML.Attribute(E, "n");
                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameter = await this.GetParameter(Node, Name, e);

                            if (Parameter is null)
                            {
                                return;
                            }

                            Int32ControlParameter Int32ControlParameter = Parameter as Int32ControlParameter;
                            if (Int32ControlParameter is null)
                            {
                                ParameterWrongType(Name, e);
                                return;
                            }

                            Operations.AddLast(new Int32ControlOperation(Node, Int32ControlParameter, XML.Attribute(E, "v", 0), e));
                        }
                        break;

                    case "l":
                        Name = XML.Attribute(E, "n");
                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameter = await this.GetParameter(Node, Name, e);

                            if (Parameter is null)
                            {
                                return;
                            }

                            Int64ControlParameter Int64ControlParameter = Parameter as Int64ControlParameter;
                            if (Int64ControlParameter is null)
                            {
                                ParameterWrongType(Name, e);
                                return;
                            }

                            Operations.AddLast(new Int64ControlOperation(Node, Int64ControlParameter, XML.Attribute(E, "v", 0L), e));
                        }
                        break;

                    case "s":
                        Name = XML.Attribute(E, "n");
                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameter = await this.GetParameter(Node, Name, e);

                            if (Parameter is null)
                            {
                                return;
                            }

                            if (Parameter is StringControlParameter StringControlParameter)
                            {
                                Operations.AddLast(new StringControlOperation(Node, StringControlParameter, XML.Attribute(E, "v"), e));
                            }
                            else if (Parameter is MultiLineTextControlParameter MultiLineTextControlParameter)
                            {
                                Operations.AddLast(new MultiLineTextControlOperation(Node, MultiLineTextControlParameter, XML.Attribute(E, "v"), e));
                            }
                            else
                            {
                                ParameterWrongType(Name, e);
                                return;
                            }
                        }
                        break;

                    case "t":
                        Name = XML.Attribute(E, "n");
                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameter = await this.GetParameter(Node, Name, e);

                            if (Parameter is null)
                            {
                                return;
                            }

                            TimeControlParameter TimeControlParameter = Parameter as TimeControlParameter;
                            if (TimeControlParameter is null)
                            {
                                ParameterWrongType(Name, e);
                                return;
                            }

                            Operations.AddLast(new TimeControlOperation(Node, TimeControlParameter, XML.Attribute(E, "v", TimeSpan.Zero), e));
                        }
                        break;

                    case "x":
                        Dictionary <string, ControlParameter> Parameters;

                        foreach (IThingReference Node in Nodes ?? NoNodes)
                        {
                            Parameters = await this.GetControlParametersByName(Node);

                            if (Parameters is null)
                            {
                                NotFound(e);
                                return;
                            }

                            foreach (Field Field in Form.Fields)
                            {
                                if (!Parameters.TryGetValue(Field.Var, out Parameter))
                                {
                                    ParameterNotFound(Field.Var, e);
                                    return;
                                }

                                Operations.AddLast(new FormControlOperation(Node, Parameter, Field.ValueString, e));
                            }
                        }
                        break;
                    }
                }

                if (this.provisioningClient != null)
                {
                    string[] ParameterNames2 = new string[ParameterNames.Count];
                    ParameterNames.Keys.CopyTo(ParameterNames2, 0);

                    this.provisioningClient.CanControl(e.FromBareJid, Nodes, ParameterNames2,
                                                       ServiceToken.Split(space, StringSplitOptions.RemoveEmptyEntries),
                                                       DeviceToken.Split(space, StringSplitOptions.RemoveEmptyEntries),
                                                       UserToken.Split(space, StringSplitOptions.RemoveEmptyEntries),
                                                       (sender2, e2) =>
                    {
                        if (e2.Ok && e2.CanControl)
                        {
                            LinkedList <ControlOperation> Operations2 = null;
                            bool Restricted;

                            if (e2.Nodes != null || e2.ParameterNames != null)
                            {
                                Dictionary <IThingReference, bool> AllowedNodes = null;
                                Dictionary <string, bool> AllowedParameterNames = null;

                                Operations2 = new LinkedList <ControlOperation>();
                                Restricted  = false;

                                if (e2.Nodes != null)
                                {
                                    AllowedNodes = new Dictionary <IThingReference, bool>();
                                    foreach (IThingReference Node in e2.Nodes)
                                    {
                                        AllowedNodes[Node] = true;
                                    }
                                }

                                if (e2.ParameterNames != null)
                                {
                                    AllowedParameterNames = new Dictionary <string, bool>();
                                    foreach (string ParameterName in e2.ParameterNames)
                                    {
                                        AllowedParameterNames[ParameterName] = true;
                                    }
                                }

                                foreach (ControlOperation Operation in Operations)
                                {
                                    if (AllowedNodes != null && !AllowedNodes.ContainsKey(Operation.Node ?? ThingReference.Empty))
                                    {
                                        Restricted = true;
                                        continue;
                                    }

                                    if (AllowedParameterNames != null && !AllowedParameterNames.ContainsKey(Operation.ParameterName))
                                    {
                                        Restricted = true;
                                        continue;
                                    }

                                    Operations2.AddLast(Operation);
                                }
                            }
                            else
                            {
                                Restricted = false;
                            }

                            if (Restricted)
                            {
                                this.PerformOperations(Operations2, e, e2.Nodes, e2.ParameterNames);
                            }
                            else
                            {
                                this.PerformOperations(Operations, e, null, null);
                            }
                        }
                        else
                        {
                            e.IqError("<error type='cancel'><forbidden xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'/>" +
                                      "<text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' xml:lang='en'>Access denied.</text></error>");
                        }
                    }, null);
                }
                else
                {
                    this.PerformOperations(Operations, e, null, null);
                }
            }
            catch (Exception ex)
            {
                e.IqError(ex);
            }
        }
 /// <summary>
 /// DateTime control operation.
 /// </summary>
 /// <param name="Node">Node on which operation is to be performed.</param>
 /// <param name="Parameter">Control parameter.</param>
 /// <param name="Value">Value to set.</param>
 /// <param name="request">Original request.</param>
 public DateTimeControlOperation(ThingReference Node, DateTimeControlParameter Parameter, DateTime Value, IqEventArgs request)
     : base(Node, request, Parameter)
 {
     this.parameter = Parameter;
     this.value     = Value;
 }