Example #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="data"></param>
        public override void Execute(Tag data = null)
        {
            if (data == null)
            {
                var a = TagRegistry.GetTag <Bind>("bind", Namespaces.Bind);
                var b = TagRegistry.GetTag <Iq>("iq", Namespaces.Client);

                if (ProtocolState.Settings.Id.Resource != null)
                {
                    var res = TagRegistry.GetTag <GenericTag>("resource", Namespaces.Bind);
                    res.InnerText = ProtocolState.Settings.Id.Resource;
                    a.AddChildTag(res);
                }

                b.IqType  = IqType.Set;
                b.Payload = a;

                ProtocolState.Socket.Write(b);
            }
            else
            {
                var  iq   = data as Iq;
                Bind bind = null;
                if (iq != null)
                {
                    if (iq.IqType == IqType.Error)
                    {
                        var e = iq["error"];
                        if (e != null)
                        {
                            ProtocolState.Events.Error(this, ErrorType.XmlError, ErrorSeverity.Reconnect, e.InnerText);
                        }
                    }
                    bind = iq.Payload as Bind;
                }
                if (bind != null)
                {
                    ProtocolState.Settings.Id = bind.JidTag.UserJid;
                }

                ProtocolState.State = new SessionState();
                ProtocolState.State.Execute();
            }
        }
Example #2
0
        ///<summary>
        ///</summary>
        ///<exception cref="NotImplementedException"></exception>
        public override Tag Initialize()
        {
            Logger.Debug(this, "Initializing Plain Processor");
            Logger.DebugFormat(this, "ID User: {0}", UbietySettings.Id.User);

            var sb = new StringBuilder();

            sb.Append((char)0);
            sb.Append(UbietySettings.Id.User);
            sb.Append((char)0);
            sb.Append(UbietySettings.Password);

            var auth = TagRegistry.GetTag <Auth>("auth", Namespaces.SASL);

            auth.Text      = Convert.ToBase64String(Encoding.UTF8.GetBytes(sb.ToString()));
            auth.Mechanism = Mechanism.GetMechanism(MechanismType.Plain);

            return(auth);
        }
Example #3
0
    public void should_correctly_remove_relationships()
    {
        var illegalTag = 1;
        var lawfulTag  = 2;

        var existingData = new Dictionary <int, ICollection <TagWeighting> >
        {
            { illegalTag, new List <TagWeighting> {
                  new(lawfulTag, default)
              } }
        };
        var tagRegistry = new TagRegistry(existingData);

        tagRegistry.RemoveTagRelationship(illegalTag, lawfulTag);

        Assert.Equal(1, tagRegistry.TagRelations.Count);
        Assert.True(tagRegistry.TagRelations.ContainsKey(illegalTag));
        Assert.Equal(0, tagRegistry.TagRelations[illegalTag].Count);
    }
Example #4
0
        /// <summary>
        /// </summary>
        /// <returns></returns>
        public override Tag Initialize(string id, string password)
        {
            base.Initialize(id, password);

            _nonce = NextInt64().ToString(CultureInfo.InvariantCulture);
            var msg = new StringBuilder();

            msg.Append("n,,n=");
            msg.Append(Id.User);
            msg.Append(",r=");
            msg.Append(_nonce);

            _clientFirst = msg.ToString().Substring(3);

            var tag = TagRegistry.GetTag <Auth>("auth", Namespaces.Sasl);

            tag.Mechanism = Mechanism.GetMechanism(MechanismType.Scram);
            tag.Bytes     = _utf.GetBytes(msg.ToString());
            return(tag);
        }
Example #5
0
        public override void Execute(Tag data = null)
        {
            if (data == null)
            {
                var iq   = TagRegistry.GetTag <Iq>("iq", Namespaces.Client);
                var sess = TagRegistry.GetTag <GenericTag>("session", Namespaces.Session);

                iq.From    = UbietySettings.Id;
                iq.To      = UbietySettings.Id.Server;
                iq.IqType  = IqType.Set;
                iq.Payload = sess;

                ProtocolState.Socket.Write(iq);
            }
            else
            {
                var p = TagRegistry.GetTag <GenericTag>("presence", Namespaces.Client);
                ProtocolState.Socket.Write(p);

                ProtocolState.State = new RunningState();
            }
        }
Example #6
0
    public void should_return_applicable_tags()
    {
        var illegalTag = 1;
        var lawfulTag  = 2;
        var riskyTag   = 3;

        var expectedWeightedTag1 = new TagWeighting(lawfulTag, -0.8f);
        var expectedWeightedTag2 = new TagWeighting(riskyTag, 0.5f);

        var existingData = new Dictionary <int, ICollection <TagWeighting> >
        {
            { illegalTag, new List <TagWeighting> {
                  expectedWeightedTag1, expectedWeightedTag2
              } }
        };
        var tagRegistry = new TagRegistry(existingData);
        var relatedTags = tagRegistry.GetRelatedTags(illegalTag).ToArray();

        Assert.Equal(2, relatedTags.Length);
        Assert.Contains(expectedWeightedTag1, relatedTags);
        Assert.Contains(expectedWeightedTag2, relatedTags);
    }
Example #7
0
        private static void StartTag()
        {
            var ht = new Hashtable();

            if (_reader.HasAttributes)
            {
                while (_reader.MoveToNextAttribute())
                {
                    if (_reader.Prefix.Equals("xmlns"))
                    {
                        Ns.AddNamespace(_reader.LocalName, _reader.Value);
                    }
                    else if (_reader.Name.Equals("xmlns"))
                    {
                        Ns.AddNamespace(string.Empty, _reader.Value);
                    }
                    else
                    {
                        ht.Add(_reader.Name, _reader.Value);
                    }
                }
                _reader.MoveToElement();
            }

            var        ns   = Ns.LookupNamespace(_reader.Prefix);
            var        q    = new XmlQualifiedName(_reader.LocalName, ns);
            XmlElement elem = TagRegistry.GetTag <Tag>(q) ?? new ubiety.core.GenericTag(q);

            foreach (string attrname in ht.Keys)
            {
                var colon = attrname.IndexOf(':');
                if (colon > 0)
                {
                    var prefix = attrname.Substring(0, colon);
                    var name   = attrname.Substring(colon + 1);

                    var attr = ProtocolState.Document.CreateAttribute(prefix, name, Ns.LookupNamespace(prefix));
                    attr.InnerXml = (string)ht[attrname];

                    elem.SetAttributeNode(attr);
                }
                else
                {
                    var attr = ProtocolState.Document.CreateAttribute(attrname);
                    attr.InnerXml = (string)ht[attrname];

                    elem.SetAttributeNode(attr);
                }
            }

            if (_root == null)
            {
                if (elem.Name != "stream:stream")
                {
                    Errors.SendError(typeof(ProtocolParser), ErrorType.WrongProtocolVersion,
                                     "Missing stream:stream from server");
                    return;
                }

                _root = elem;
            }
            else
            {
                if (_elem != null)
                {
                    _elem.AppendChild(elem);
                }
                _elem = elem;
            }
        }
Example #8
0
        private static void StartTag()
        {
            var ht = new Hashtable();

            if (_reader.HasAttributes)
            {
                while (_reader.MoveToNextAttribute())
                {
                    if (_reader.Prefix.Equals("xmlns"))
                    {
                        NamespaceManager.AddNamespace(_reader.LocalName, _reader.Value);
                    }
                    else if (_reader.Name.Equals("xmlns"))
                    {
                        NamespaceManager.AddNamespace(string.Empty, _reader.Value);
                    }
                    else
                    {
                        ht.Add(_reader.Name, _reader.Value);
                    }
                }
                _reader.MoveToElement();
            }

            var        ns   = NamespaceManager.LookupNamespace(_reader.Prefix);
            var        q    = new XmlQualifiedName(_reader.LocalName, ns);
            XmlElement elem = TagRegistry.GetTag <Tag>(q);

            foreach (string attrname in ht.Keys)
            {
                var colon = attrname.IndexOf(':');
                if (colon > 0)
                {
                    var prefix = attrname.Substring(0, colon);
                    var name   = attrname.Substring(colon + 1);

                    var attr = Tag.Document.CreateAttribute(prefix, name,
                                                            NamespaceManager.LookupNamespace(prefix));
                    attr.InnerXml = (string)ht[attrname];

                    elem.SetAttributeNode(attr);
                }
                else
                {
                    var attr = Tag.Document.CreateAttribute(attrname);
                    attr.InnerXml = (string)ht[attrname];

                    elem.SetAttributeNode(attr);
                }
            }

            if (_root == null)
            {
                if (elem.Name != "stream:stream")
                {
                    ProtocolState.Events.Error(null, ErrorType.WrongProtocolVersion, ErrorSeverity.Fatal, "Missing proper stream:stream header from server.");
                    return;
                }

                _root = elem;
            }
            else
            {
                _element?.AppendChild(elem);
                _element = elem;
            }
        }
Example #9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="data">
        /// A <see cref="Tag"/>
        /// </param>
        public override void Execute(Tag data = null)
        {
            Features f;

            if (data is Stream)
            {
                var s = data as Stream;
                if (!s.Version.StartsWith("1."))
                {
                    Errors.SendError(this, ErrorType.WrongProtocolVersion, "Expecting stream:features from 1.x server");
                    return;
                }
                f = s.Features;
            }
            else
            {
                f = data as Features;
            }

            if (f != null)
            {
                if (f.StartTLS != null && UbietySettings.SSL)
                {
                    ProtocolState.State = new StartTLSState();
                    var tls = TagRegistry.GetTag <StartTLS>("starttls", Namespaces.StartTLS);
                    ProtocolState.Socket.Write(tls);
                    return;
                }

                if (!ProtocolState.Authenticated)
                {
                    Logger.Debug(this, "Creating SASL Processor");
                    ProtocolState.Processor = SASLProcessor.CreateProcessor(f.StartSASL.SupportedTypes);
                    if (ProtocolState.Processor == null)
                    {
                        Logger.Debug(this, "No allowed type available. Allow more authentication options.");
                        ProtocolState.State = new DisconnectState();
                        ProtocolState.State.Execute();
                        return;
                    }
                    Logger.Debug(this, "Sending auth with mechanism type");
                    ProtocolState.Socket.Write(ProtocolState.Processor.Initialize());

                    ProtocolState.State = new SASLState();
                    return;
                }

                // Takes place after authentication according to XEP-0170
                if (!ProtocolState.Compressed && CompressionRegistry.AlgorithmsAvailable && !UbietySettings.SSL && f.Compression != null)
                {
                    Logger.Info(this, "Starting compression");
                    // Do we have a stream for any of the compressions supported by the server?
                    foreach (var algorithm in
                             f.Compression.Algorithms.Where(CompressionRegistry.SupportsAlgorithm))
                    {
                        Logger.DebugFormat(this, "Using {0} for compression", algorithm);
                        var c = TagRegistry.GetTag <GenericTag>("compress", Namespaces.CompressionProtocol);
                        var m = TagRegistry.GetTag <GenericTag>("method", Namespaces.CompressionProtocol);

                        m.InnerText = ProtocolState.Algorithm = algorithm;
                        c.AddChildTag(m);
                        ProtocolState.Socket.Write(c);
                        ProtocolState.State = new CompressedState();
                        return;
                    }
                }
            }

            Logger.Debug(this, "Authenticated");
            ProtocolState.State = new BindingState();
            ProtocolState.State.Execute();
        }
Example #10
0
        /// <summary>
        /// </summary>
        /// <param name="data">
        ///     A <see cref="Tag" />
        /// </param>
        public override void Execute(Tag data = null)
        {
            Features f;

            if (data is Stream)
            {
                var s = data as Stream;
                if (!s.Version.StartsWith("1."))
                {
                    ProtocolState.Events.Error(this, ErrorType.WrongProtocolVersion, ErrorSeverity.Fatal, "Didn't receive expected stream:features tag from 1.x compliant server.");
                    return;
                }
                f = s.Features;
            }
            else
            {
                f = data as Features;
            }

            if (f != null)
            {
                if (f.StartTls != null && ProtocolState.Settings.Ssl)
                {
                    ProtocolState.State = new StartTlsState();
                    var tls = TagRegistry.GetTag <StartTls>("starttls", Namespaces.StartTls);
                    ProtocolState.Socket.Write(tls);
                    return;
                }

                if (!ProtocolState.Authenticated)
                {
                    ProtocolState.Processor = SaslProcessor.CreateProcessor(f.StartSasl.SupportedTypes, ProtocolState.Settings.AuthenticationTypes);
                    if (ProtocolState.Processor == null)
                    {
                        ProtocolState.State = new DisconnectState();
                        ProtocolState.State.Execute();
                        return;
                    }
                    ProtocolState.Socket.Write(ProtocolState.Processor.Initialize(ProtocolState.Settings.Id, ProtocolState.Settings.Password));

                    ProtocolState.State = new SaslState();
                    return;
                }

                // Takes place after authentication according to XEP-0170
                if (!ProtocolState.Compressed && CompressionRegistry.AlgorithmsAvailable && !ProtocolState.Settings.Ssl &&
                    f.Compression != null)
                {
                    // Do we have a stream for any of the compressions supported by the server?
                    foreach (string algorithm in
                             f.Compression.Algorithms.Where(CompressionRegistry.SupportsAlgorithm))
                    {
                        var c = TagRegistry.GetTag <GenericTag>("compress", Namespaces.CompressionProtocol);
                        var m = TagRegistry.GetTag <GenericTag>("method", Namespaces.CompressionProtocol);

                        m.InnerText = ProtocolState.Algorithm = algorithm;
                        c.AddChildTag(m);
                        ProtocolState.Socket.Write(c);
                        ProtocolState.State = new CompressedState();
                        return;
                    }
                }
            }

            ProtocolState.State = new BindingState();
            ProtocolState.State.Execute();
        }
Example #11
0
        /// <summary>
        /// </summary>
        public static void OnStart()
        {
            Statistic.Instantiate();

            ScmManager = new ScmManager();
            IOQueue    = new AsyncIOQueue();
            ManifestDownloadManager = new ManifestDownloadManager();

            DownloadManager = new DownloadManager();
            DownloadManager.OnRequestReplicatedBuilds += (List <Guid> SelectTags, List <Guid> IgnoreTags, DateTime NewerThan) =>
            {
                NetClient.RequestFilteredBuilds(SelectTags, IgnoreTags, NewerThan);

                Settings.ReplicationNewerThanTime = DownloadManager.ReplicationNewerThanTime;
                SaveSettings();
            };

            Logger.Log(LogLevel.Info, LogCategory.Main, "OnStart: Initializing settings");
            InitSettings();

            NetClient          = new Core.Client.Client();
            RemoteActionClient = new RemoteActionClient(NetClient, ManifestDownloadManager);

            TagRegistry   = new TagRegistry();
            RouteRegistry = new RouteRegistry(null, TagRegistry);
            BuildRegistry = new BuildManifestRegistry(TagRegistry);

            StorageManager = new StorageManager(Settings.StorageLocations, ManifestDownloadManager, BuildRegistry, IOQueue, Settings.StorageHeuristic, Settings.PrioritizeKeepingBuildTagIds, Settings.PrioritizeDeletingBuildTagIds);

            Logger.Log(LogLevel.Info, LogCategory.Main, "OnStart: Setting up network client");
            BuildRegistry.Open(Path.Combine(AppDataDir, "Manifests"), int.MaxValue);

            Logger.Log(LogLevel.Info, LogCategory.Main, "OnStart: Setting up network client");
            NetClient.Start(
                Settings.ServerHostname,
                Settings.ServerPort,
                Settings.ClientPortRangeMin,
                Settings.ClientPortRangeMax,
                Settings.AllowRemoteActions,
                Settings.TagIds,
                BuildRegistry,
                StorageManager,
                ManifestDownloadManager,
                TagRegistry,
                RouteRegistry
                );
            NetClient.TagIds = new List <Guid>(Settings.TagIds);

            // Setup the virtual file system we will store our available builds in.
            Logger.Log(LogLevel.Info, LogCategory.Main, "OnStart: Setting up build file system");

            BuildFileSystem = new VirtualFileSystem();
            NetClient.OnClientTagsUpdatedByServer += () =>
            {
                Settings.TagIds = NetClient.TagIds;

                NetClient.RestartConnections();
                SaveSettings();
            };
            NetClient.OnTagListRecieved += (List <Tag> InTags) =>
            {
                TagRenderer.InvalidateResources();
            };
            NetClient.OnPermissionsUpdated += () =>
            {
                BuildFileSystem.ForceRefresh();
                DownloadManager.ForceRefresh();
            };
            NetClient.OnBuildPublished += (string Path, Guid Id) =>
            {
                BuildFileSystem.ForceRefresh();
                DownloadManager.ForceRefresh();
            };
            NetClient.OnBuildUpdated += (string Path, Guid Id) =>
            {
                BuildFileSystem.ForceRefresh();
                DownloadManager.ForceRefresh();
            };
            NetClient.OnConnectedToServer      += () => { BuildFileSystem.ForceRefresh(); };
            NetClient.OnFilteredBuildsRecieved += (Builds) =>
            {
                DownloadManager.RecieveReplicatedBuilds(Builds);
            };
            NetClient.OnBuildsRecieved += (RootPath, Builds) =>
            {
                List <VirtualFileSystemInsertChild> NewChildren = new List <VirtualFileSystemInsertChild>();
                foreach (NetMessage_GetBuildsResponse.BuildInfo Build in Builds)
                {
                    NewChildren.Add(
                        new VirtualFileSystemInsertChild
                    {
                        VirtualPath = Build.VirtualPath,
                        CreateTime  = Build.Guid == Guid.Empty ? DateTime.UtcNow : Build.CreateTime,
                        Metadata    = Build
                    }
                        );
                }

                BuildFileSystem.ReconcileChildren(RootPath, NewChildren);
            };
            BuildFileSystem.OnRequestChildren += (FileSystem, Path) =>
            {
                if (NetClient.IsConnected)
                {
                    NetClient.RequestBuilds(Path);
                }
            };
            BuildFileSystem.Init();

            // Setup download managers for the manifest and app level.
            Logger.Log(LogLevel.Info, LogCategory.Main, "OnStart: Setting up manifest download manager");

            ManifestDownloadManager.Start(
                StorageManager,
                Settings.ManifestDownloadStates,
                BuildRegistry,
                IOQueue
                );

            Logger.Log(LogLevel.Info, LogCategory.Main, "OnStart: Setting up download manager");

            DownloadManager.Start(
                ManifestDownloadManager,
                Settings.DownloadStates,
                BuildFileSystem,
                ScmManager,
                Settings.ReplicationNewerThanTime
                );

            Logger.Log(LogLevel.Info, LogCategory.Main, "OnStart: Setting up update download");

            // Ensure we are downloading the latest update.
            string UpdateDownloadName = "$ Buildsync Update $";

            foreach (DownloadState State in DownloadManager.States.States)
            {
                if (State.Name == UpdateDownloadName)
                {
                    InternalUpdateDownload = State;
                    break;
                }
            }

            if (InternalUpdateDownload == null)
            {
                InternalUpdateDownload = DownloadManager.AddDownload(UpdateDownloadName, "$Internal$/Updates", 2, BuildSelectionRule.Newest, BuildSelectionFilter.None, "", "", true, false, "", "", new List <Guid>(), new List <Guid>());
            }

            // Make sure we have to get the latest manifest id before updating.
            InternalUpdateDownload.ActiveManifestId = Guid.Empty;

            // Clean up any orphan builds.
            StorageManager.CleanUpOrphanBuilds();

            Logger.Log(LogLevel.Info, LogCategory.Main, "OnStart: Complete");
        }
Example #12
0
 /// <summary>
 /// Initializes a new instance of the <see cref="XMPP"/> class.
 /// </summary>
 public XMPP()
 {
     TagRegistry.AddAssembly(typeof(XMPP).Assembly);
     Errors.OnError      += OnError;
     ProtocolState.Socket = new AsyncSocket();
 }
Example #13
0
        /// <summary>
        /// </summary>
        /// <param name="data">
        ///     A <see cref="Tag" />
        /// </param>
        public void Execute(Tag data = null)
        {
            Features features;

            var stream = data as Stream;

            if (stream != null)
            {
                var s = stream;
                if (!s.Version.StartsWith("1."))
                {
                    ProtocolState.Events.Error(this, ErrorType.WrongProtocolVersion, ErrorSeverity.Fatal,
                                               "Didn't receive expected stream:features tag from 1.x compliant server.");
                    return;
                }
                features = s.Features;
            }
            else
            {
                features = data as Features;
            }

            if (features != null)
            {
                // We have features available so make sure we have them set
                features.Update();

                // Should we use SSL and is it required
                if ((ProtocolState.Features.HasFlag(ProtocolFeatures.StartTls) && ProtocolState.Settings.Ssl) ||
                    (ProtocolState.Features.HasFlag(ProtocolFeatures.StartTls) &&
                     ProtocolState.Features.HasFlag(ProtocolFeatures.SslRequired)) && !ProtocolState.Encrypted)
                {
                    Log.Debug("Starting SSL...");
                    ProtocolState.State = new StartTlsState();
                    var tls = TagRegistry.GetTag <StartTls>("starttls", Namespaces.StartTls);
                    ProtocolState.Socket.Write(tls);
                    return;
                }

                if (!ProtocolState.Authenticated)
                {
                    Log.Debug("Starting Authentication...");
                    ProtocolState.Processor = SaslProcessor.CreateProcessor(features.StartSasl.SupportedTypes,
                                                                            ProtocolState.Settings.AuthenticationTypes);
                    if (ProtocolState.Processor == null)
                    {
                        ProtocolState.State = new DisconnectState();
                        ProtocolState.State.Execute();
                        return;
                    }
                    ProtocolState.Socket.Write(
                        ProtocolState.Processor.Initialize(ProtocolState.Settings.Id, ProtocolState.Settings.Password));

                    ProtocolState.State = new SaslState();
                    return;
                }

                // Takes place after authentication according to XEP-0170
                if (!ProtocolState.Compressed && CompressionRegistry.AlgorithmsAvailable &&
                    !ProtocolState.Settings.Ssl &&
                    features.Compression != null)
                {
                    Log.Debug("Starting Compression...");
                    // Do we have a stream for any of the compressions supported by the server?
                    foreach (var algorithm in
                             features.Compression.Algorithms.Where(CompressionRegistry.SupportsAlgorithm))
                    {
                        var c = TagRegistry.GetTag <GenericTag>("compress", Namespaces.CompressionProtocol);
                        var m = TagRegistry.GetTag <GenericTag>("method", Namespaces.CompressionProtocol);

                        m.InnerText = ProtocolState.Algorithm = algorithm;
                        c.AddChildTag(m);
                        ProtocolState.Socket.Write(c);
                        ProtocolState.State = new CompressedState();
                        return;
                    }
                }

                if (ProtocolState.Authenticated)
                {
                    Log.Debug("Switching to Binding state");
                    ProtocolState.State = new BindingState();
                    ProtocolState.State.Execute();
                }
            }
        }
Example #14
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="tag"></param>
        /// <returns></returns>
        public override Tag Step(Tag tag)
        {
            switch (tag.Name)
            {
            case "challenge":
            {
                _serverFirst = tag.Bytes;
                var response = _utf.GetString(tag.Bytes);
                Logger.DebugFormat(this, "Challenge: {0}", response);

                // Split challenge into pieces
                var tokens = response.Split(',');

                _snonce = tokens[0].Substring(2);
                // Ensure that the first length of nonce is the same nonce we sent.
                var r = _snonce.Substring(0, _nonce.Length);
                if (0 != String.Compare(r, _nonce))
                {
                    Logger.DebugFormat(this, "{0} does not match {1}", r, _nonce);
                }

                Logger.Debug(this, "Getting Salt");
                var a = tokens[1].Substring(2);
                _salt = Convert.FromBase64String(a);

                Logger.Debug(this, "Getting Iterations");
                var i = tokens[2].Substring(2);
                _i = int.Parse(i);
                Logger.DebugFormat(this, "Iterations: {0}", _i);

                var final = new StringBuilder();
                final.Append("c=biws,r=");
                final.Append(_snonce);

                _clientFinal = final.ToString();

                CalculateProofs();

                final.Append(",p=");
                final.Append(_clientProof);

                Logger.DebugFormat(this, "Final Message: {0}", final.ToString());

                var resp = TagRegistry.GetTag <GenericTag>("response", Namespaces.SASL);
                resp.Bytes = _utf.GetBytes(final.ToString());

                return(resp);
            }

            case "success":
            {
                var response  = _utf.GetString(tag.Bytes);
                var signature = Convert.FromBase64String(response.Substring(2));
                return(_utf.GetString(signature) == _utf.GetString(_serverSignature) ? tag : null);
            }

            case "failure":
                return(tag);
            }

            return(null);
        }
Example #15
0
        public void TestGetRegion()
        {
            Region r = TagRegistry.GetRegion("US");

            Assert.IsTrue(r.Descriptions.Contains("United States"));
        }
Example #16
0
        public void TestGetLanguage()
        {
            Language lang = TagRegistry.GetLanguage("en");

            Assert.IsTrue(lang.Descriptions.Contains("English"));
        }