Beispiel #1
0
        public void MetadataCommand_Run_CallsNotifications()
        {
            var request = new HttpRequestData("GET", new Uri("http://localhost/Saml2"));

            var options = StubFactory.CreateOptions();

            options.Notifications.MetadataCreated = (md, urls) =>
            {
                md.CacheDuration = new XsdDuration(seconds: 17);
                urls.ApplicationUrl.Host.Should().Be("localhost");
            };

            CommandResult notifiedCommandResult = null;

            options.Notifications.MetadataCommandResultCreated = cr =>
            {
                notifiedCommandResult = cr;
            };

            var subject             = new MetadataCommand();
            var actualCommandResult = subject.Run(request, options);

            actualCommandResult.Should().BeSameAs(notifiedCommandResult);

            var parsedResult = XElement.Parse(actualCommandResult.Content);

            parsedResult.Attribute("cacheDuration").Value
            .Should().Be("PT17S");
        }
Beispiel #2
0
        public void MetadataCommand_Run_MinimalMetadata()
        {
            var spOptions = new SPOptions()
            {
                EntityId = new EntityId("http://localhost/AuthServices"),
            };
            var options = new Options(spOptions);

            var subject = new MetadataCommand().Run(request, options);

            XDocument payloadXml = XDocument.Parse(subject.Content);

            // Ignore the ID attribute, it is just filled with a GUID that can't be easily tested.
            payloadXml.Root.Attribute("ID").Remove();

            var expectedXml = new XDocument(new XElement(Saml2Namespaces.Saml2Metadata + "EntityDescriptor",
                                                         new XAttribute("entityID", "http://localhost/AuthServices"),
                                                         new XAttribute("cacheDuration", "PT1H"),
                                                         // Have to manually add the xmlns attribute here, as it will be present in the subject
                                                         // data and the xml tree comparison will fail if it is not present in both. Just setting the
                                                         // namespace of the elements does not inject the xmlns attribute into the node tree. It is
                                                         // only done when outputting a string.
                                                         // See http://stackoverflow.com/questions/24156689/xnode-deepequals-unexpectedly-returns-false
                                                         new XAttribute("xmlns", Saml2Namespaces.Saml2MetadataName),
                                                         new XAttribute(XNamespace.Xmlns + "saml2", Saml2Namespaces.Saml2),
                                                         new XElement(Saml2Namespaces.Saml2Metadata + "SPSSODescriptor",
                                                                      new XAttribute("protocolSupportEnumeration", "urn:oasis:names:tc:SAML:2.0:protocol"),
                                                                      new XElement(Saml2Namespaces.Saml2Metadata + "AssertionConsumerService",
                                                                                   new XAttribute("Binding", Saml2Binding.HttpPostUri),
                                                                                   new XAttribute("Location", "http://localhost/AuthServices/Acs"),
                                                                                   new XAttribute("index", 0),
                                                                                   new XAttribute("isDefault", true)))));

            payloadXml.ShouldBeEquivalentTo(expectedXml, opt => opt.IgnoringCyclicReferences());
        }
        public void MetadataCommand_Run_SuccessfulResult()
        {
            var subject = new MetadataCommand().Run(Substitute.For<HttpRequestBase>());

            XDocument payloadXml = XDocument.Parse(subject.Content);

            var expectedXml = new XDocument(new XElement(Saml2Namespaces.Saml2Metadata + "EntityDescriptor",
                new XAttribute("entityId", "https://github.com/KentorIT/authservices"),
                new XAttribute("cacheDuration", 42),
                // Have to manually add the xmlns attribute here, as it will be present in the subject
                // data and the xml tree comparison will fail if it is not present in both. Just setting the
                // namespace of the elements does not inject the xmlns attribute into the node tree. It is
                // only done when outputting a string.
                // See http://stackoverflow.com/questions/24156689/xnode-deepequals-unexpectedly-returns-false
                new XAttribute("xmlns", Saml2Namespaces.Saml2MetadataName),
                new XElement(Saml2Namespaces.Saml2Metadata + "SPSSODescriptor",
                    new XElement(Saml2Namespaces.Saml2Metadata + "AssertionConsumerService",
                        new XAttribute("isDefault", true),
                        new XAttribute("index", 0),
                        new XAttribute("Binding", Saml2Binding.HttpPostUri),
                        new XAttribute("Location", "http://localhost/Saml2AuthenticationModule/acs")))));

            payloadXml.ShouldBeEquivalentTo(expectedXml, opt => opt.IgnoringCyclicReferences());
            subject.ContentType.Should().Be("application/samlmetadata+xml");
        }
        public void MetadataCommand_Run_SuccessfulResult()
        {
            var subject = new MetadataCommand().Run(Substitute.For <HttpRequestBase>());

            XDocument payloadXml = XDocument.Parse(subject.Content);

            var expectedXml = new XDocument(new XElement(Saml2Namespaces.Saml2Metadata + "EntityDescriptor",
                                                         new XAttribute("entityId", "https://github.com/KentorIT/authservices"),
                                                         new XAttribute("cacheDuration", 42),
                                                         // Have to manually add the xmlns attribute here, as it will be present in the subject
                                                         // data and the xml tree comparison will fail if it is not present in both. Just setting the
                                                         // namespace of the elements does not inject the xmlns attribute into the node tree. It is
                                                         // only done when outputting a string.
                                                         // See http://stackoverflow.com/questions/24156689/xnode-deepequals-unexpectedly-returns-false
                                                         new XAttribute("xmlns", Saml2Namespaces.Saml2MetadataName),
                                                         new XElement(Saml2Namespaces.Saml2Metadata + "SPSSODescriptor",
                                                                      new XElement(Saml2Namespaces.Saml2Metadata + "AssertionConsumerService",
                                                                                   new XAttribute("isDefault", true),
                                                                                   new XAttribute("index", 0),
                                                                                   new XAttribute("Binding", Saml2Binding.HttpPostUri),
                                                                                   new XAttribute("Location", "http://localhost/Saml2AuthenticationModule/acs")))));

            payloadXml.ShouldBeEquivalentTo(expectedXml, opt => opt.IgnoringCyclicReferences());
            subject.ContentType.Should().Be("application/samlmetadata+xml");
        }
 public MetadataEventArgs(MetadataCommand command, MetadataCategory category, MetadataScope scope, bool finished, string reason, int successCount, int totalCount, bool canceled)
 {
     Command      = command;
     Category     = category;
     Scope        = scope;
     Finished     = finished;
     Reason       = reason;
     SuccessCount = successCount;
     TotalCount   = totalCount;
     Canceled     = canceled;
 }
        public void TestMetadataCommand_FromCSProject()
        {
            // Create default project
            var projectFile = Path.Combine(_projectFolder, "test.csproj");
            var sourceFile  = Path.Combine(_projectFolder, "test.cs");

            File.Copy("Assets/test.csproj.sample.1", projectFile);
            File.Copy("Assets/test.cs.sample.1", sourceFile);

            ParseResult result = new MetadataCommand(
                new Options
            {
                CurrentSubCommand = CommandType.Metadata,
                MetadataCommand   = new MetadataCommandOptions
                {
                    OutputFolder = Path.Combine(Environment.CurrentDirectory, _outputFolder),
                    Projects     = new List <String> {
                        projectFile
                    },
                }
            }
                , null).Exec(null);

            Assert.Equal(ResultLevel.Success, result.ResultLevel);
            Assert.True(File.Exists(Path.Combine(_outputFolder, ".manifest")));

            var file = Path.Combine(_outputFolder, "toc.yml");

            Assert.True(File.Exists(file));
            var tocViewModel = YamlUtility.Deserialize <TocViewModel>(file);

            Assert.Equal("Foo", tocViewModel[0].Uid);
            Assert.Equal("Foo", tocViewModel[0].Name);
            Assert.Equal("Foo.yml", tocViewModel[0].Href);
            Assert.Equal("Foo.Bar", tocViewModel[0].Items[0].Uid);
            Assert.Equal("Bar", tocViewModel[0].Items[0].Name);
            Assert.Equal("Foo.Bar.yml", tocViewModel[0].Items[0].Href);

            file = Path.Combine(_outputFolder, "Foo.yml");
            Assert.True(File.Exists(file));
            var memberViewModel = YamlUtility.Deserialize <PageViewModel>(file);

            Assert.Equal("Foo", memberViewModel.Items[0].Uid);
            Assert.Equal("Foo", memberViewModel.Items[0].Id);
            Assert.Equal("Foo", memberViewModel.Items[0].Name);
            Assert.Equal("Foo", memberViewModel.Items[0].FullName);

            file = Path.Combine(_outputFolder, "Foo.Bar.yml");
            Assert.True(File.Exists(file));
            memberViewModel = YamlUtility.Deserialize <PageViewModel>(file);
            Assert.Equal("Foo.Bar", memberViewModel.Items[0].Uid);
            Assert.Equal("Bar", memberViewModel.Items[0].Id);
            Assert.Equal("Bar", memberViewModel.Items[0].Name);
            Assert.Equal("Foo.Bar", memberViewModel.Items[0].FullName);
            Assert.Equal("Foo.Bar.FooBar``1(System.Int32[],System.Byte*,``0,System.Collections.Generic.List{``0[]})", memberViewModel.Items[1].Uid);
            Assert.Equal("FooBar``1(System.Int32[],System.Byte*,``0,System.Collections.Generic.List{``0[]})", memberViewModel.Items[1].Id);
            Assert.Equal("FooBar<TArg>(Int32[], Byte*, TArg, List<TArg[]>)", memberViewModel.Items[1].Name);
            Assert.Equal("Foo.Bar.FooBar<TArg>(System.Int32[], System.Byte*, TArg, System.Collections.Generic.List<TArg[]>)", memberViewModel.Items[1].FullName);
            Assert.NotNull(memberViewModel.References.Find(
                               s => s.Uid.Equals("System.Collections.Generic.List{System.String}")
                               ));
            Assert.NotNull(memberViewModel.References.Find(
                               s => s.Uid.Equals("System.Int32[]")
                               ));
            Assert.NotNull(memberViewModel.References.Find(
                               s => s.Uid.Equals("System.Byte*")
                               ));
            Assert.NotNull(memberViewModel.References.Find(
                               s => s.Uid.Equals("{TArg}")
                               ));
            Assert.NotNull(memberViewModel.References.Find(
                               s => s.Uid.Equals("System.Collections.Generic.List{{TArg}[]}")
                               ));
        }
Beispiel #7
0
        public void MetadataCommand_Run_CompleteMetadata()
        {
            var options = StubFactory.CreateOptions();

            options.SPOptions.DiscoveryServiceUrl = new Uri("http://ds.example.com");
            options.SPOptions.AuthenticateRequestSigningBehavior = SigningBehavior.Always;
            options.SPOptions.OutboundSigningAlgorithm           = SecurityAlgorithms.RsaSha384Signature;
            options.SPOptions.ServiceCertificates.Add(new ServiceCertificate()
            {
                Certificate             = SignedXmlHelper.TestCertSignOnly,
                Use                     = CertificateUse.Signing,
                MetadataPublishOverride = MetadataPublishOverrideType.PublishUnspecified
            });

            var subject = new MetadataCommand().Run(request, options);

            var payloadXml = XmlHelpers.XmlDocumentFromString(subject.Content);

            // Validate signature, location of it  and then drop it. It contains
            // a reference to the ID which makes it unsuitable for string matching.
            payloadXml.DocumentElement.IsSignedBy(SignedXmlHelper.TestCertSignOnly).Should().BeTrue();
            payloadXml.DocumentElement.FirstChild.LocalName.Should().Be("Signature");
            payloadXml.DocumentElement.FirstChild["KeyInfo"].Should().NotBeNull();
            payloadXml.DocumentElement.FirstChild["SignedInfo"]["SignatureMethod"].GetAttribute("Algorithm")
            .Should().Be(SecurityAlgorithms.RsaSha384Signature);
            payloadXml.DocumentElement.RemoveChild("Signature", SignedXml.XmlDsigNamespaceUrl);

            // Ignore the ID attribute, it is just filled with a GUID that can't be easily tested.
            payloadXml.DocumentElement.Attributes.Remove("ID");

            // Test and then drop validUntil, can't be text compared.
            DateTime.Parse(payloadXml.DocumentElement.Attributes["validUntil"].Value).ToUniversalTime()
            .Should().BeCloseTo(DateTime.UtcNow.AddDays(24), 2000);
            payloadXml.DocumentElement.Attributes.Remove("validUntil");

            var expectedXml =
                "<EntityDescriptor entityID=\"https://github.com/SustainsysIT/Saml2\" cacheDuration=\"PT42S\" xmlns:saml2=\"urn:oasis:names:tc:SAML:2.0:assertion\" xmlns=\"urn:oasis:names:tc:SAML:2.0:metadata\">"
                + "<SPSSODescriptor AuthnRequestsSigned=\"true\" WantAssertionsSigned=\"true\" protocolSupportEnumeration=\"urn:oasis:names:tc:SAML:2.0:protocol\">"
                + "<Extensions>"
                + "<DiscoveryResponse Binding=\"urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol\" Location=\"http://localhost/Saml2/SignIn\" index=\"0\" isDefault=\"true\" xmlns=\"urn:oasis:names:tc:SAML:profiles:SSO:idp-discovery-protocol\" />"
                + "</Extensions>"
                + "<KeyDescriptor><KeyInfo xmlns=\"http://www.w3.org/2000/09/xmldsig#\"><X509Data><X509Certificate>MIIDIzCCAg+gAwIBAgIQg7mOjTf994NAVxZu4jqXpzAJBgUrDgMCHQUAMCQxIjAgBgNVBAMTGUtlbnRvci5BdXRoU2VydmljZXMuVGVzdHMwHhcNMTMwOTI1MTMzNTQ0WhcNMzkxMjMxMjM1OTU5WjAkMSIwIAYDVQQDExlLZW50b3IuQXV0aFNlcnZpY2VzLlRlc3RzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwVGpfvK9N//MnA5Jo1q2liyPR24406Dp25gv7LB3HK4DWgqsb7xXM6KIV/WVOyCV2g/O1ErBlB+HLhVZ4XUJvbqBbgAJqFO+TZwcCIe8u4nTEXeU660FdtkKClA17sbtMrAGdDfOPwVBHSuavdHeD7jHNI4RUDGKnEW13/0EvnHDilIetwODRxrX/+41R24sJThFbMczByS3OAL2dcIxoAynaGeM90gXsVYow1QhJUy21+cictikb7jW4mW6dvFCBrWIceom9J295DcQIHoxJy5NoZwMir/JV00qs1wDVoN20Ve1DC5ImwcG46XPF7efQ44yLh2j5Yexw+xloA81dwIDAQABo1kwVzBVBgNVHQEETjBMgBAWIahoZhXVUogbAqkS7zwfoSYwJDEiMCAGA1UEAxMZS2VudG9yLkF1dGhTZXJ2aWNlcy5UZXN0c4IQg7mOjTf994NAVxZu4jqXpzAJBgUrDgMCHQUAA4IBAQA2aGzmuKw4AYXWMhrGj5+i8vyAoifUn1QVOFsUukEA77CrqhqqaWFoeagfJp/45vlvrfrEwtF0QcWfmO9w1VvHwm7sk1G/cdYyJ71sU+llDsdPZm7LxQvWZYkK+xELcinQpSwt4ExavS+jLcHoOYHYwIZMBn3U8wZw7Kq29oGnoFQz7HLCEl/G9i3QRyvFITNlWTjoScaqMjHTzq6HCMaRsL09DLcY3KB+cedfpC0/MBlzaxZv0DctTulyaDfM9DCYOyokGN/rQ6qkAR0DDm8fVwknbJY7kURXNGoUetulTb5ow8BvD1gncOaYHSD0kbHZG+bLsUZDFatEr2KW8jbG</X509Certificate></X509Data></KeyInfo></KeyDescriptor>"
                + "<SingleLogoutService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect\" Location=\"http://localhost/Saml2/Logout\" />"
                + "<SingleLogoutService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\" Location=\"http://localhost/Saml2/Logout\" />"
                + "<AssertionConsumerService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST\" Location=\"http://localhost/Saml2/Acs\" index=\"0\" isDefault=\"true\" />"
                + "<AssertionConsumerService Binding=\"urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact\" Location=\"http://localhost/Saml2/Acs\" index=\"1\" isDefault=\"false\" />"
                + "<AttributeConsumingService index=\"0\" isDefault=\"true\">"
                + "<ServiceName xml:lang=\"en\">attributeServiceName</ServiceName>"
                + "<RequestedAttribute Name=\"urn:attributeName\" isRequired=\"true\" NameFormat=\"urn:oasis:names:tc:SAML:2.0:attrname-format:uri\" FriendlyName=\"friendlyName\">"
                + "<saml2:AttributeValue>value1</saml2:AttributeValue>"
                + "<saml2:AttributeValue>value2</saml2:AttributeValue>"
                + "</RequestedAttribute>"
                + "<RequestedAttribute Name=\"someName\" isRequired=\"false\" />"
                + "</AttributeConsumingService>"
                + "</SPSSODescriptor>"
                + "<Organization>"
                + "<OrganizationName xml:lang=\"en\">Sustainsys.Saml2</OrganizationName>"
                + "<OrganizationDisplayName xml:lang=\"en\">Sustainsys Saml2</OrganizationDisplayName>"
                + "<OrganizationURL xml:lang=\"en\">http://github.com/SustainsysIT/Saml2</OrganizationURL>"
                + "</Organization>"
                + "<ContactPerson contactType=\"support\">"
                + "<Company>Sustainsys</Company>"
                + "<GivenName>Anders</GivenName>"
                + "<SurName>Abel</SurName>"
                + "<EmailAddress>[email protected]</EmailAddress>"
                + "<EmailAddress>[email protected]</EmailAddress>"
                + "<TelephoneNumber>+46 8 587 650 00</TelephoneNumber>"
                + "<TelephoneNumber>+46 708 96 50 63</TelephoneNumber>"
                + "</ContactPerson>"
                + "<ContactPerson contactType=\"technical\" />"
                + "</EntityDescriptor>";

            payloadXml.Should().BeEquivalentTo(XmlHelpers.XmlDocumentFromString(expectedXml));
            subject.ContentType.Should().Be("application/samlmetadata+xml");
        }
Beispiel #8
0
        public void MetadataCommand_Run_CompleteMetadata()
        {
            var options = StubFactory.CreateOptions();

            ((SPOptions)options.SPOptions).DiscoveryServiceUrl = new Uri("http://ds.example.com");

            var subject = new MetadataCommand().Run(request, options);

            XDocument payloadXml = XDocument.Parse(subject.Content);

            // Ignore the ID attribute, it is just filled with a GUID that can't be easily tested.
            payloadXml.Root.Attribute("ID").Remove();

            var expectedXml = new XDocument(new XElement(Saml2Namespaces.Saml2Metadata + "EntityDescriptor",
                                                         new XAttribute("entityID", "https://github.com/KentorIT/authservices"),
                                                         new XAttribute("cacheDuration", "PT42S"),
                                                         // Have to manually add the xmlns attribute here, as it will be present in the subject
                                                         // data and the xml tree comparison will fail if it is not present in both. Just setting the
                                                         // namespace of the elements does not inject the xmlns attribute into the node tree. It is
                                                         // only done when outputting a string.
                                                         // See http://stackoverflow.com/questions/24156689/xnode-deepequals-unexpectedly-returns-false
                                                         new XAttribute("xmlns", Saml2Namespaces.Saml2MetadataName),
                                                         new XAttribute(XNamespace.Xmlns + "saml2", Saml2Namespaces.Saml2),
                                                         new XElement(Saml2Namespaces.Saml2Metadata + "SPSSODescriptor",
                                                                      new XAttribute("protocolSupportEnumeration", "urn:oasis:names:tc:SAML:2.0:protocol"),
                                                                      new XElement(Saml2Namespaces.Saml2Metadata + "Extensions",
                                                                                   new XElement(Saml2Namespaces.Saml2IdpDiscovery + "DiscoveryResponse",
                                                                                                new XAttribute("Binding", Saml2Binding.DiscoveryResponseUri),
                                                                                                new XAttribute("Location", "http://localhost/AuthServices/SignIn"),
                                                                                                new XAttribute("index", 0),
                                                                                                new XAttribute("isDefault", true),
                                                                                                new XAttribute("xmlns", Saml2Namespaces.Saml2IdpDiscoveryName))),
                                                                      new XElement(Saml2Namespaces.Saml2Metadata + "AssertionConsumerService",
                                                                                   new XAttribute("Binding", Saml2Binding.HttpPostUri),
                                                                                   new XAttribute("Location", "http://localhost/AuthServices/Acs"),
                                                                                   new XAttribute("index", 0),
                                                                                   new XAttribute("isDefault", true)),
                                                                      new XElement(Saml2Namespaces.Saml2Metadata + "AssertionConsumerService",
                                                                                   new XAttribute("Binding", Saml2Binding.HttpArtifactUri),
                                                                                   new XAttribute("Location", "http://localhost/AuthServices/Acs"),
                                                                                   new XAttribute("index", 1),
                                                                                   new XAttribute("isDefault", false)),
                                                                      new XElement(Saml2Namespaces.Saml2Metadata + "AttributeConsumingService",
                                                                                   new XAttribute("index", 0),
                                                                                   new XAttribute("isDefault", true),
                                                                                   new XElement(Saml2Namespaces.Saml2Metadata + "ServiceName",
                                                                                                new XAttribute(XNamespace.Xml + "lang", "en"),
                                                                                                "attributeServiceName"),
                                                                                   new XElement(Saml2Namespaces.Saml2Metadata + "RequestedAttribute",
                                                                                                new XAttribute("Name", "urn:attributeName"),
                                                                                                new XAttribute("isRequired", "true"),
                                                                                                new XAttribute("NameFormat", "urn:oasis:names:tc:SAML:2.0:attrname-format:uri"),
                                                                                                new XAttribute("FriendlyName", "friendlyName"),
                                                                                                new XElement(Saml2Namespaces.Saml2 + "AttributeValue", "value1"),
                                                                                                new XElement(Saml2Namespaces.Saml2 + "AttributeValue", "value2")),
                                                                                   new XElement(Saml2Namespaces.Saml2Metadata + "RequestedAttribute",
                                                                                                new XAttribute("Name", "someName"),
                                                                                                new XAttribute("isRequired", "false")))),
                                                         new XElement(Saml2Namespaces.Saml2Metadata + "Organization",
                                                                      new XElement(Saml2Namespaces.Saml2Metadata + "OrganizationName",
                                                                                   new XAttribute(XNamespace.Xml + "lang", ""), "Kentor.AuthServices"),
                                                                      new XElement(Saml2Namespaces.Saml2Metadata + "OrganizationDisplayName",
                                                                                   new XAttribute(XNamespace.Xml + "lang", ""), "Kentor AuthServices"),
                                                                      new XElement(Saml2Namespaces.Saml2Metadata + "OrganizationURL",
                                                                                   new XAttribute(XNamespace.Xml + "lang", ""), "http://github.com/KentorIT/authservices")),
                                                         new XElement(Saml2Namespaces.Saml2Metadata + "ContactPerson",
                                                                      new XAttribute("contactType", "support"),
                                                                      new XElement(Saml2Namespaces.Saml2Metadata + "Company", "Kentor"),
                                                                      new XElement(Saml2Namespaces.Saml2Metadata + "GivenName", "Anders"),
                                                                      new XElement(Saml2Namespaces.Saml2Metadata + "SurName", "Abel"),
                                                                      new XElement(Saml2Namespaces.Saml2Metadata + "EmailAddress", "*****@*****.**"),
                                                                      new XElement(Saml2Namespaces.Saml2Metadata + "EmailAddress", "*****@*****.**"),
                                                                      new XElement(Saml2Namespaces.Saml2Metadata + "TelephoneNumber", "+46 8 587 650 00"),
                                                                      new XElement(Saml2Namespaces.Saml2Metadata + "TelephoneNumber", "+46 708 96 50 63")),
                                                         new XElement(Saml2Namespaces.Saml2Metadata + "ContactPerson",
                                                                      new XAttribute("contactType", "technical"))));

            payloadXml.Should().BeEquivalentTo(expectedXml);
            subject.ContentType.Should().Be("application/samlmetadata+xml");
        }