diff --git a/smp-angular/src/app/app.module.ts b/smp-angular/src/app/app.module.ts index 578ad75842104c565a9d1efaecfb97c2e2ee2eef..df8bfff5a5e0eac1e6c2bb93fa246812b43cddc2 100644 --- a/smp-angular/src/app/app.module.ts +++ b/smp-angular/src/app/app.module.ts @@ -1,7 +1,7 @@ import {BrowserModule} from '@angular/platform-browser'; import {NgModule} from '@angular/core'; import {FormsModule, ReactiveFormsModule} from '@angular/forms'; -import {HttpClient, HttpClientModule} from '@angular/common/http'; +import {HttpClient, HttpClientModule, HttpClientXsrfModule} from '@angular/common/http'; import {FlexLayoutModule} from '@angular/flex-layout'; import { MatButtonModule, @@ -153,6 +153,10 @@ import {SmlIntegrationService} from "./domain/sml-integration.service"; BrowserModule, FlexLayoutModule, HttpClientModule, + HttpClientXsrfModule.withOptions({ + cookieName: 'XSRF-TOKEN', + headerName: 'X-XSRF-TOKEN' + }), BrowserAnimationsModule, FormsModule, NgxDatatableModule, @@ -200,7 +204,7 @@ import {SmlIntegrationService} from "./domain/sml-integration.service"; provide: ExtendedHttpClient, useFactory: extendedHttpClientCreator, deps: [HttpClient, HttpEventService, SecurityService] - }, + } ], bootstrap: [AppComponent] }) diff --git a/smp-api/pom.xml b/smp-api/pom.xml index c692047d09de7eb3794edf9111f68ea9eda9e0da..644a8b9269d7442f23037023a1445d6cf2ffa175 100644 --- a/smp-api/pom.xml +++ b/smp-api/pom.xml @@ -34,6 +34,10 @@ <groupId>org.apache.cxf.xjc-utils</groupId> <artifactId>cxf-xjc-runtime</artifactId> </dependency> + <dependency> + <groupId>org.springframework</groupId> + <artifactId>spring-web</artifactId> + </dependency> <dependency> <groupId>pl.pragmatists</groupId> <artifactId>JUnitParams</artifactId> diff --git a/smp-api/src/main/java/eu/europa/ec/smp/api/Identifiers.java b/smp-api/src/main/java/eu/europa/ec/smp/api/Identifiers.java index e223e5b02746420c3934c0837370a35ff4cac823..9086b4f6847945b37ea9205e3ab079c1a64a5a26 100644 --- a/smp-api/src/main/java/eu/europa/ec/smp/api/Identifiers.java +++ b/smp-api/src/main/java/eu/europa/ec/smp/api/Identifiers.java @@ -18,11 +18,7 @@ import org.apache.commons.lang3.StringUtils; import org.oasis_open.docs.bdxr.ns.smp._2016._05.DocumentIdentifier; import org.oasis_open.docs.bdxr.ns.smp._2016._05.ParticipantIdentifierType; import org.oasis_open.docs.bdxr.ns.smp._2016._05.ProcessIdentifier; - -import java.io.UnsupportedEncodingException; -import java.net.URLEncoder; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import org.springframework.web.util.UriUtils; import static java.nio.charset.StandardCharsets.UTF_8; @@ -34,12 +30,11 @@ import static java.nio.charset.StandardCharsets.UTF_8; public class Identifiers { public static final String EBCORE_IDENTIFIER_PREFIX = "urn:oasis:names:tc:ebcore:partyid-type:"; - public static final String EBCORE_IDENTIFIER_FORMAT="%s:%s"; - public static final String EBCORE_IDENTIFIER_ISO6523_SCHEME="iso6523"; - public static final String DOUBLE_COLON_IDENTIFIER_FORMAT="%s::%s"; - - private static final String EMPTY_IDENTIFIER="Null/Empty"; + public static final String EBCORE_IDENTIFIER_FORMAT = "%s:%s"; + public static final String EBCORE_IDENTIFIER_ISO6523_SCHEME = "iso6523"; + public static final String DOUBLE_COLON_IDENTIFIER_FORMAT = "%s::%s"; + private static final String EMPTY_IDENTIFIER = "Null/Empty"; public static ParticipantIdentifierType asParticipantId(String participantIDentifier) { @@ -58,20 +53,20 @@ public class Identifiers { } public static String asString(ParticipantIdentifierType participantId) { - if(StringUtils.isBlank(participantId.getScheme())) { + if (StringUtils.isBlank(participantId.getScheme())) { // if scheme is empty just return value (for OASIS SMP 1.0 must start with :: ) - return (StringUtils.startsWithIgnoreCase(participantId.getScheme(), EBCORE_IDENTIFIER_PREFIX)? - "":"::") + participantId.getValue(); + return (StringUtils.startsWithIgnoreCase(participantId.getScheme(), EBCORE_IDENTIFIER_PREFIX) ? + "" : "::") + participantId.getValue(); } String format = - StringUtils.startsWithIgnoreCase(participantId.getScheme(), EBCORE_IDENTIFIER_PREFIX)? - EBCORE_IDENTIFIER_FORMAT:DOUBLE_COLON_IDENTIFIER_FORMAT; + StringUtils.startsWithIgnoreCase(participantId.getScheme(), EBCORE_IDENTIFIER_PREFIX) ? + EBCORE_IDENTIFIER_FORMAT : DOUBLE_COLON_IDENTIFIER_FORMAT; - return String.format(format, participantId.getScheme(), participantId.getValue()); + return String.format(format, participantId.getScheme(), participantId.getValue()); } public static String asString(DocumentIdentifier docId) { - return String.format(DOUBLE_COLON_IDENTIFIER_FORMAT, docId.getScheme()!=null?docId.getScheme():"", docId.getValue()); + return String.format(DOUBLE_COLON_IDENTIFIER_FORMAT, docId.getScheme() != null ? docId.getScheme() : "", docId.getValue()); } public static String asUrlEncodedString(ParticipantIdentifierType participantId) { @@ -83,20 +78,17 @@ public class Identifiers { } private static String urlEncode(String s) { - try { - return URLEncoder.encode(s, UTF_8.name()); - } catch (UnsupportedEncodingException e) { - throw new IllegalStateException(e); - } + return UriUtils.encode(s, UTF_8.name()); } + private static String[] splitParticipantIdentifier(String participantIdentifier) { String[] idResult; - if (StringUtils.isBlank(participantIdentifier)){ + if (StringUtils.isBlank(participantIdentifier)) { throw new MalformedIdentifierException(EMPTY_IDENTIFIER, null); } String identifier = participantIdentifier.trim(); - if(identifier.startsWith(EBCORE_IDENTIFIER_PREFIX) + if (identifier.startsWith(EBCORE_IDENTIFIER_PREFIX) || identifier.startsWith("::" + EBCORE_IDENTIFIER_PREFIX)) { idResult = splitEbCoreIdentifier(identifier); } else { @@ -110,25 +102,26 @@ public class Identifiers { /** * Method splits identifier at first occurrence of double colon :: and returns array size of 2. The first value is * schema and the second is identifier. If identifier is blank or with missing :: MalformedIdentifierException is thrown + * * @param doubleColonDelimitedId * @return array with two elements. First is schema and second is id */ private static String[] splitDoubleColonIdentifier(String doubleColonDelimitedId) { - if (StringUtils.isBlank(doubleColonDelimitedId)){ + if (StringUtils.isBlank(doubleColonDelimitedId)) { throw new MalformedIdentifierException(EMPTY_IDENTIFIER, null); } String[] idResult = new String[2]; int delimiterIndex = doubleColonDelimitedId.indexOf("::"); - if (delimiterIndex<0){ + if (delimiterIndex < 0) { throw new MalformedIdentifierException(doubleColonDelimitedId, null); } - idResult[0] = delimiterIndex==0?null:doubleColonDelimitedId.substring(0,delimiterIndex); - idResult[1] = doubleColonDelimitedId.substring(delimiterIndex+2); + idResult[0] = delimiterIndex == 0 ? null : doubleColonDelimitedId.substring(0, delimiterIndex); + idResult[1] = doubleColonDelimitedId.substring(delimiterIndex + 2); - if (StringUtils.isBlank(idResult[1])){ + if (StringUtils.isBlank(idResult[1])) { throw new MalformedIdentifierException(doubleColonDelimitedId, null); } @@ -136,26 +129,26 @@ public class Identifiers { } - public static String[] splitEbCoreIdentifier(final String partyId) { + public static String[] splitEbCoreIdentifier(final String partyId) { String partyIdPrivate = partyId.trim(); if (partyIdPrivate.startsWith("::")) { partyIdPrivate = StringUtils.removeStart(partyIdPrivate, "::"); } - if (!partyIdPrivate.startsWith(EBCORE_IDENTIFIER_PREFIX)){ + if (!partyIdPrivate.startsWith(EBCORE_IDENTIFIER_PREFIX)) { throw new MalformedIdentifierException(partyId, null); } - boolean isIso6523 = partyIdPrivate.startsWith(EBCORE_IDENTIFIER_PREFIX+EBCORE_IDENTIFIER_ISO6523_SCHEME +":"); + boolean isIso6523 = partyIdPrivate.startsWith(EBCORE_IDENTIFIER_PREFIX + EBCORE_IDENTIFIER_ISO6523_SCHEME + ":"); - int isSchemeDelimiter = partyIdPrivate.indexOf(':',EBCORE_IDENTIFIER_PREFIX.length()); - if (isSchemeDelimiter < 0){ + int isSchemeDelimiter = partyIdPrivate.indexOf(':', EBCORE_IDENTIFIER_PREFIX.length()); + if (isSchemeDelimiter < 0) { // invalid scheme - throw new IllegalArgumentException(String.format("Invalid ebCore id [%s] ebcoreId must have prefix 'urn:oasis:names:tc:ebcore:partyid-type', "+ + throw new IllegalArgumentException(String.format("Invalid ebCore id [%s] ebcoreId must have prefix 'urn:oasis:names:tc:ebcore:partyid-type', " + "and parts <catalog-identifier>, <scheme-in-catalog>, <scheme-specific-identifier> separated by colon. " + "Example: urn:oasis:names:tc:ebcore:partyid-type:<catalog-identifier>:(<scheme-in-catalog>)?:<scheme-specific-identifier>.", partyIdPrivate)); } - int isPartDelimiter = partyIdPrivate.indexOf(':',isSchemeDelimiter+1); + int isPartDelimiter = partyIdPrivate.indexOf(':', isSchemeDelimiter + 1); String[] result = new String[2]; if (isPartDelimiter < 0 && isIso6523) { // for iso scheme-in-catalog is mandatory @@ -163,10 +156,10 @@ public class Identifiers { throw new IllegalArgumentException(String.format("Invalid ebCore id [%s] ebcoreId must have prefix 'urn:oasis:names:tc:ebcore:partyid-type', " + "and parts <catalog-identifier>, <scheme-in-catalog>, <scheme-specific-identifier> separated by colon. " + "Example: urn:oasis:names:tc:ebcore:partyid-type:<catalog-identifier>:(<scheme-in-catalog>)?:<scheme-specific-identifier>.", partyIdPrivate)); - } else if (isPartDelimiter < 0){ + } else if (isPartDelimiter < 0) { result[0] = partyIdPrivate.substring(0, isSchemeDelimiter).trim(); result[1] = partyIdPrivate.substring(isSchemeDelimiter + 1).trim(); - }else { + } else { result[0] = partyIdPrivate.substring(0, isPartDelimiter).trim(); result[1] = partyIdPrivate.substring(isPartDelimiter + 1).trim(); } @@ -177,11 +170,8 @@ public class Identifiers { } //check if double colon was used for identifier separator in ebecoreid if (result[0].endsWith(":")) { - result[0] = StringUtils.removeEnd(result[0] , ":"); + result[0] = StringUtils.removeEnd(result[0], ":"); } return result; - } - - } diff --git a/smp-api/src/test/java/eu/europa/ec/smp/api/IdentifiersTest.java b/smp-api/src/test/java/eu/europa/ec/smp/api/IdentifiersTest.java index f353ad87226f7e1902e83dd9020e44b1fe32c893..58a2135e850faf7be3f45ab267328b3f1bc84168 100644 --- a/smp-api/src/test/java/eu/europa/ec/smp/api/IdentifiersTest.java +++ b/smp-api/src/test/java/eu/europa/ec/smp/api/IdentifiersTest.java @@ -174,7 +174,6 @@ public class IdentifiersTest { return res; } - @Test @Parameters(method = "participantIdentifierPositiveCases") @TestCaseName("{0}") @@ -248,7 +247,6 @@ public class IdentifiersTest { assertEquals(value, processId.getValue()); } - @Test @Parameters(method = "negativeCases") public void testProcessIdNegative(String negativeInput) { @@ -277,7 +275,6 @@ public class IdentifiersTest { fail(); } - private void negativeAssertions(String negativeInput, Exception e) { assertTrue(e instanceof MalformedIdentifierException); assertEquals(MALFORMED_INPUT_MSG + (StringUtils.isBlank(negativeInput) ? "Null/Empty" : negativeInput), e.getMessage()); @@ -292,6 +289,16 @@ public class IdentifiersTest { assertEquals("ehealth%3Aactorid%3Aqns%3A%3A0088%3Aconformance%3Asg01%23", Identifiers.asUrlEncodedString(participantId)); } + @Test + public void testUrlEncodingParticipantIdWithSpace() { + //given + ParticipantIdentifierType participantId = new ParticipantIdentifierType("GPR: 0088:conformance:sg01#", "ehealth:actorid:qns"); + + //when-then + //Because this is path segment spaces must be percent encoded (not with +)! + assertEquals("ehealth%3Aactorid%3Aqns%3A%3AGPR%3A%200088%3Aconformance%3Asg01%23", Identifiers.asUrlEncodedString(participantId)); + } + @Test public void testUrlEncodingDocumentId() { //given @@ -301,5 +308,14 @@ public class IdentifiersTest { assertEquals("busdox%3Adocid%3Aqns%3A%3Aurn%3A%3Aehealth%23%23services%3Aextended%3Aepsos01%3A%3A101", Identifiers.asUrlEncodedString(docId)); } + @Test + public void testUrlEncodingDocumentIdWithSpace() { + //given + DocumentIdentifier docId = new DocumentIdentifier("urn::ehealth##services:extended:epsos01:: 101", "busdox:docid:qns"); + + //when-then + //Because this is path segment spaces must be percent encoded (not with +)! + assertEquals("busdox%3Adocid%3Aqns%3A%3Aurn%3A%3Aehealth%23%23services%3Aextended%3Aepsos01%3A%3A%20101", Identifiers.asUrlEncodedString(docId)); + } } diff --git a/smp-api/src/test/java/eu/europa/ec/smp/api/validators/BdxSmpOasisValidatorTest.java b/smp-api/src/test/java/eu/europa/ec/smp/api/validators/BdxSmpOasisValidatorTest.java index fd2ec90745b91f5c2db6034af823352b99e46beb..d8ade4ed84ec838ffdbc125714ad6a55342554a1 100644 --- a/smp-api/src/test/java/eu/europa/ec/smp/api/validators/BdxSmpOasisValidatorTest.java +++ b/smp-api/src/test/java/eu/europa/ec/smp/api/validators/BdxSmpOasisValidatorTest.java @@ -35,7 +35,7 @@ public class BdxSmpOasisValidatorTest { private static final String UTF_8 = "UTF-8"; @Test - @Parameters({"ServiceMetadata_OK.xml","ServiceGroup_OK.xml"}) + @Parameters({"ServiceMetadata_OK.xml", "ServiceGroup_OK.xml"}) public void testValidatePositive(String xmlFilename) throws IOException, XmlInvalidAgainstSchemaException { // given byte[] xmlBody = loadXMLFileAsByteArray(xmlFilename); @@ -48,12 +48,12 @@ public class BdxSmpOasisValidatorTest { } private static Object[] negativeCases() { - return new Object[][] { - {"ServiceMetadata_ElementAdded.xml", "cvc-complex-type.2.4.a: Invalid content was found starting with element 'ElementAdded'. One of '{\"http://docs.oasis-open.org/bdxr/ns/SMP/2016/05\":ServiceInformation, \"http://docs.oasis-open.org/bdxr/ns/SMP/2016/05\":Redirect}' is expected."}, - {"ServiceMetadata_ElementMissing.xml", "cvc-complex-type.2.4.b: The content of element 'Redirect' is not complete. One of '{\"http://docs.oasis-open.org/bdxr/ns/SMP/2016/05\":CertificateUID}' is expected."}, - {"ServiceGroup_MissingAssignment.xml", "Attribute name \"missingAssignment\" associated with an element type \"ServiceMetadataReferenceCollection\" must be followed by the ' = ' character."}, - {"ServiceGroup_UnexpectedAttribute.xml","cvc-complex-type.3.2.2: Attribute 'unexpectedAttribute' is not allowed to appear in element 'ServiceMetadataReferenceCollection'."}, - {"ServiceGroup_externalDTD.xml", "External DTD: Failed to read external DTD 'any_external_file_address.dtd', because 'file' access is not allowed due to restriction set by the accessExternalDTD property."} + return new Object[][]{ + {"ServiceMetadata_ElementAdded.xml", "cvc-complex-type.2.4.a: Invalid content was found starting with element '{\"http://docs.oasis-open.org/bdxr/ns/SMP/2016/05\":ElementAdded}'. One of '{\"http://docs.oasis-open.org/bdxr/ns/SMP/2016/05\":ServiceInformation, \"http://docs.oasis-open.org/bdxr/ns/SMP/2016/05\":Redirect}' is expected."}, + {"ServiceMetadata_ElementMissing.xml", "cvc-complex-type.2.4.b: The content of element 'Redirect' is not complete. One of '{\"http://docs.oasis-open.org/bdxr/ns/SMP/2016/05\":CertificateUID}' is expected."}, + {"ServiceGroup_MissingAssignment.xml", "Attribute name \"missingAssignment\" associated with an element type \"ServiceMetadataReferenceCollection\" must be followed by the ' = ' character."}, + {"ServiceGroup_UnexpectedAttribute.xml", "cvc-complex-type.3.2.2: Attribute 'unexpectedAttribute' is not allowed to appear in element 'ServiceMetadataReferenceCollection'."}, + {"ServiceGroup_externalDTD.xml", "External DTD: Failed to read external DTD 'any_external_file_address.dtd', because 'file' access is not allowed due to restriction set by the accessExternalDTD property."} }; } @@ -75,12 +75,12 @@ public class BdxSmpOasisValidatorTest { } public String loadXMLFile(String path) throws IOException { - URL fileUrl = BdxSmpOasisValidatorTest.class.getResource("/XMLValidation/"+path); + URL fileUrl = BdxSmpOasisValidatorTest.class.getResource("/XMLValidation/" + path); return IOUtils.toString(fileUrl.openStream(), UTF_8); } public byte[] loadXMLFileAsByteArray(String path) throws IOException { - URL fileUrl = BdxSmpOasisValidatorTest.class.getResource("/XMLValidation/"+path); + URL fileUrl = BdxSmpOasisValidatorTest.class.getResource("/XMLValidation/" + path); return IOUtils.toByteArray(fileUrl.openStream()); } } diff --git a/smp-server-library/pom.xml b/smp-server-library/pom.xml index 04babd6b5179026209ede45c443786ae1efa2e04..ffd58acb6b9a87c53922bc2098544a1b34e62b2d 100644 --- a/smp-server-library/pom.xml +++ b/smp-server-library/pom.xml @@ -216,6 +216,11 @@ <artifactId>h2</artifactId> <scope>test</scope> </dependency> + <dependency> + <groupId>org.hamcrest</groupId> + <artifactId>hamcrest-junit</artifactId> + <scope>test</scope> + </dependency> </dependencies> <build> diff --git a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupServiceIntegrationTest.java b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupServiceIntegrationTest.java index 4711274f4fe3a4feb37367f33fbb73597b5fddec..819c85b2e672a8903976bee128dc974166cae202 100644 --- a/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupServiceIntegrationTest.java +++ b/smp-server-library/src/test/java/eu/europa/ec/edelivery/smp/services/ui/UIServiceGroupServiceIntegrationTest.java @@ -14,6 +14,7 @@ import eu.europa.ec.edelivery.smp.services.AbstractServiceIntegrationTest; import eu.europa.ec.edelivery.smp.testutil.TestConstants; import eu.europa.ec.edelivery.smp.testutil.TestDBUtils; import eu.europa.ec.edelivery.smp.testutil.TestROUtils; +import org.hamcrest.text.MatchesPattern; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; @@ -24,6 +25,7 @@ import java.io.IOException; import java.util.Collections; import static org.hamcrest.core.StringContains.containsString; +import static org.hamcrest.text.MatchesPattern.matchesPattern; import static org.junit.Assert.*; @@ -283,7 +285,7 @@ public class UIServiceGroupServiceIntegrationTest extends AbstractServiceIntegra @Test - public void validateExtensionVaild() throws IOException { + public void validateExtensionValid() throws IOException { // given ServiceGroupValidationRO sg = TestROUtils.getValidExtension(); @@ -296,7 +298,7 @@ public class UIServiceGroupServiceIntegrationTest extends AbstractServiceIntegra } @Test - public void validateExtensionMultipleVaild() throws IOException { + public void validateExtensionMultipleValid() throws IOException { // given ServiceGroupValidationRO sg = TestROUtils.getValidMultipleExtension(); @@ -309,7 +311,7 @@ public class UIServiceGroupServiceIntegrationTest extends AbstractServiceIntegra } @Test - public void validateExtensionCustomTextInvaldValid() throws IOException { + public void validateExtensionCustomTextInvalid() throws IOException { // given ServiceGroupValidationRO sg = TestROUtils.getValidCustomText(); @@ -331,7 +333,8 @@ public class UIServiceGroupServiceIntegrationTest extends AbstractServiceIntegra // then assertNotNull(sg.getErrorMessage()); - assertThat(sg.getErrorMessage(), containsString(" Invalid content was found starting with element 'ExtensionID'.")); + + assertThat(sg.getErrorMessage(), matchesPattern(".*cvc-complex-type.2.4.a: Invalid content was found starting with element \\'\\{?(\"http://docs.oasis-open.org/bdxr/ns/SMP/2016/05\")?:ExtensionID\\}?\\'.*")); assertNotNull(sg.getExtension()); } diff --git a/smp-server-library/src/test/resources/examples/services/SignedServiceMetadataPoland.xml b/smp-server-library/src/test/resources/examples/services/SignedServiceMetadataPoland.xml index 1843e834d051daf5c327c3ae742bdd4c1f4d71d8..b75548b315dce6a61fa0950bba830caef8fade27 100644 --- a/smp-server-library/src/test/resources/examples/services/SignedServiceMetadataPoland.xml +++ b/smp-server-library/src/test/resources/examples/services/SignedServiceMetadataPoland.xml @@ -31,15 +31,15 @@ <ExtensionAgencyName>Agency name 2</ExtensionAgencyName> </Extension> </ServiceInformation> -</ServiceMetadata><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/><SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><DigestValue>bX6lTuxT21gbMILjxDoWzPYIZ4aQYu3iflyhpuLawys=</DigestValue></Reference></SignedInfo><SignatureValue>NQkzaoSBu9/Y7AilnxgX6/LM3A0g5WrDyxMEih9BbgnowPk24bNixc0A6kAI2Sp2MNojZUBRFue6 -uADhnQapRK4dRcAtHe2+Ao/SBHRP6233mghPosd4Y9Sw6hQ0wwziio5koa8bO5qtP5TjaVU8Yggo -MsTCeW2rFgFFzPtZ4ac=</SignatureValue><KeyInfo><X509Data><X509SubjectName>CN=SMP Mock Services,OU=DIGIT,O=European Commision,C=BE</X509SubjectName><X509Certificate>MIICIzCCAYygAwIBAgIEWCRzfjANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJCRTEbMBkGA1UE -CgwSRXVyb3BlYW4gQ29tbWlzaW9uMQ4wDAYDVQQLDAVESUdJVDEaMBgGA1UEAwwRU01QIE1vY2sg -U2VydmljZXMwHhcNMTYxMTEwMTMxODE4WhcNMjYxMTEwMTMxODE4WjBWMQswCQYDVQQGEwJCRTEb -MBkGA1UECgwSRXVyb3BlYW4gQ29tbWlzaW9uMQ4wDAYDVQQLDAVESUdJVDEaMBgGA1UEAwwRU01Q -IE1vY2sgU2VydmljZXMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALrpN2GGqctPTP27g+zA -DCmQxdOZgDQg5AeF/N5w0knZYy1GnqvAoXgLGHeS1l+2DKx4/E6SlcU6SLIGhVtpF+Gitdp+3to2 -6FfV5qcCy4XKz1xm19r84ykXPWD835DbGB7o1HSlKx4+GmAr5eL2VH/zgINcJojam3gimvedoNWj -AgMBAAEwDQYJKoZIhvcNAQELBQADgYEAXoh7T9eYOdjasnzPfsTeQ1ptEorj4pIZMRFjn2BWl+mZ -K4XRn2+doLjN2dHremGyeKBgLb0Ulp9E9I5P8kxuIs7TjroxZofK9ixhfBv5rJhLcHy8XdrUYqAS +</ServiceMetadata><Signature xmlns="http://www.w3.org/2000/09/xmldsig#"><SignedInfo><CanonicalizationMethod Algorithm="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"/><SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><Reference URI=""><Transforms><Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/></Transforms><DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><DigestValue>bX6lTuxT21gbMILjxDoWzPYIZ4aQYu3iflyhpuLawys=</DigestValue></Reference></SignedInfo><SignatureValue>NQkzaoSBu9/Y7AilnxgX6/LM3A0g5WrDyxMEih9BbgnowPk24bNixc0A6kAI2Sp2MNojZUBRFue6 +uADhnQapRK4dRcAtHe2+Ao/SBHRP6233mghPosd4Y9Sw6hQ0wwziio5koa8bO5qtP5TjaVU8Yggo +MsTCeW2rFgFFzPtZ4ac=</SignatureValue><KeyInfo><X509Data><X509SubjectName>CN=SMP Mock Services,OU=DIGIT,O=European Commision,C=BE</X509SubjectName><X509Certificate>MIICIzCCAYygAwIBAgIEWCRzfjANBgkqhkiG9w0BAQsFADBWMQswCQYDVQQGEwJCRTEbMBkGA1UE +CgwSRXVyb3BlYW4gQ29tbWlzaW9uMQ4wDAYDVQQLDAVESUdJVDEaMBgGA1UEAwwRU01QIE1vY2sg +U2VydmljZXMwHhcNMTYxMTEwMTMxODE4WhcNMjYxMTEwMTMxODE4WjBWMQswCQYDVQQGEwJCRTEb +MBkGA1UECgwSRXVyb3BlYW4gQ29tbWlzaW9uMQ4wDAYDVQQLDAVESUdJVDEaMBgGA1UEAwwRU01Q +IE1vY2sgU2VydmljZXMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALrpN2GGqctPTP27g+zA +DCmQxdOZgDQg5AeF/N5w0knZYy1GnqvAoXgLGHeS1l+2DKx4/E6SlcU6SLIGhVtpF+Gitdp+3to2 +6FfV5qcCy4XKz1xm19r84ykXPWD835DbGB7o1HSlKx4+GmAr5eL2VH/zgINcJojam3gimvedoNWj +AgMBAAEwDQYJKoZIhvcNAQELBQADgYEAXoh7T9eYOdjasnzPfsTeQ1ptEorj4pIZMRFjn2BWl+mZ +K4XRn2+doLjN2dHremGyeKBgLb0Ulp9E9I5P8kxuIs7TjroxZofK9ixhfBv5rJhLcHy8XdrUYqAS awc3c5bM9fNxRWCMkNYNoSYVxPBdlS4zEeLNNzRY+wjrMNYIJR4=</X509Certificate></X509Data></KeyInfo></Signature></SignedServiceMetadata> \ No newline at end of file diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/URLCsrfMatcher.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/URLCsrfMatcher.java index 260294500cebd3ff69c97ee9889bb95a8ed5bbf5..3b68855f96780bd7e4be09d88c441ffc11570178 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/URLCsrfMatcher.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/auth/URLCsrfMatcher.java @@ -2,44 +2,49 @@ package eu.europa.ec.edelivery.smp.auth; import eu.europa.ec.edelivery.smp.logging.SMPLoggerFactory; import org.slf4j.Logger; +import org.springframework.http.HttpMethod; import org.springframework.security.web.util.matcher.RegexRequestMatcher; import org.springframework.security.web.util.matcher.RequestMatcher; import javax.annotation.PostConstruct; import javax.servlet.http.HttpServletRequest; -import java.util.Arrays; -import java.util.HashSet; - +import java.util.*; +import java.util.regex.Matcher; + +/** + * URLCsrfMatcher matches the request and validates if request can be ignored for CSRF. + * As example the non session requests (as SMP REST API) should now have the CSRF tokens. + * + * @author Joze Rihtarsic + * @since 4.2 + */ public class URLCsrfMatcher implements RequestMatcher { - private static final Logger LOGGER = SMPLoggerFactory.getLogger(URLCsrfMatcher.class); - - protected String ignoreUrl; + private static final Logger LOG = SMPLoggerFactory.getLogger(URLCsrfMatcher.class); + private List<RequestMatcher> unprotectedMatcherList = new ArrayList<>(); - private RegexRequestMatcher unprotectedMatcher = null; - private final HashSet<String> allowedMethods = new HashSet<String>( Arrays.asList("GET", "HEAD", "TRACE", "OPTIONS")); - - @PostConstruct - public void init() { - LOGGER.debug("Initializing the matcher with [{}]", ignoreUrl); - unprotectedMatcher = new RegexRequestMatcher(ignoreUrl, null); - } @Override public boolean matches(HttpServletRequest request) { - if(this.allowedMethods.contains(request.getMethod())) { - LOGGER.trace("Matched method [{}]", request.getMethod()); - return false; - } - return !unprotectedMatcher.matches(request); + Optional<RequestMatcher> unprotectedMatcher = unprotectedMatcherList.stream().filter(requestMatcher -> requestMatcher.matches(request)).findFirst(); + return !unprotectedMatcher.isPresent(); } - public String getIgnoreUrl() { - return ignoreUrl; - } - public void setIgnoreUrl(String ignoreUrl) { - this.ignoreUrl = ignoreUrl; + /** + * Creates a case-sensitive {@code Pattern} instance to match against the request for http method(s). + * @param ignoreUrlPattern the regular expression to match ignore URLs. + * @param httpMethods the HTTP method(s) to match. May be null to match all methods. + */ + public void addIgnoreUrl(String ignoreUrlPattern, HttpMethod ... httpMethods) { + if (httpMethods==null || httpMethods.length ==0) { + unprotectedMatcherList.add(new RegexRequestMatcher(ignoreUrlPattern, null)); + } else { + Arrays.stream(httpMethods).forEach(httpMethod -> { + unprotectedMatcherList.add(new RegexRequestMatcher(ignoreUrlPattern, httpMethod.name())); + }); + } + } } \ No newline at end of file diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SpringSecurityConfig.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SpringSecurityConfig.java index 627db4d95d4b7b4b2c732e72c1e5bc3f6947d4af..6bbfd7f9dd17c7fd52b73844429d1c02bee5cbfe 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SpringSecurityConfig.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/config/SpringSecurityConfig.java @@ -17,6 +17,7 @@ import eu.europa.ec.edelivery.security.BlueCoatAuthenticationFilter; import eu.europa.ec.edelivery.security.EDeliveryX509AuthenticationFilter; import eu.europa.ec.edelivery.smp.auth.SMPAuthenticationProvider; import eu.europa.ec.edelivery.smp.auth.SMPAuthority; +import eu.europa.ec.edelivery.smp.auth.URLCsrfMatcher; import eu.europa.ec.edelivery.smp.error.SpringSecurityExceptionHandler; import eu.europa.ec.edelivery.smp.utils.SMPCookieWriter; import org.slf4j.Logger; @@ -36,9 +37,11 @@ import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.builders.WebSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.web.csrf.CookieCsrfTokenRepository; +import org.springframework.security.web.csrf.CsrfTokenRepository; import org.springframework.security.web.firewall.DefaultHttpFirewall; import org.springframework.security.web.firewall.HttpFirewall; +import org.springframework.security.web.util.matcher.RequestMatcher; /** * Created by gutowpa on 12/07/2017. @@ -54,6 +57,8 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { SMPAuthenticationProvider smpAuthenticationProvider; BlueCoatAuthenticationFilter blueCoatAuthenticationFilter; EDeliveryX509AuthenticationFilter x509AuthenticationFilter; + CsrfTokenRepository csrfTokenRepository; + RequestMatcher csrfURLMatcher; @Value("${authentication.blueCoat.enabled:false}") boolean clientCertEnabled; @@ -70,49 +75,48 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { @Autowired public SpringSecurityConfig(SMPAuthenticationProvider smpAuthenticationProvider, @Lazy BlueCoatAuthenticationFilter blueCoatAuthenticationFilter, - @Lazy EDeliveryX509AuthenticationFilter x509AuthenticationFilter) { + @Lazy EDeliveryX509AuthenticationFilter x509AuthenticationFilter, + @Lazy CsrfTokenRepository csrfTokenRepository, + @Lazy RequestMatcher csrfURLMatcher) { super(false); this.smpAuthenticationProvider = smpAuthenticationProvider; this.blueCoatAuthenticationFilter = blueCoatAuthenticationFilter; this.x509AuthenticationFilter = x509AuthenticationFilter; + this.csrfTokenRepository = csrfTokenRepository; + this.csrfURLMatcher = csrfURLMatcher; } @Override protected void configure(HttpSecurity httpSecurity) throws Exception { - - // prepare filters - blueCoatAuthenticationFilter.setBlueCoatEnabled(clientCertEnabled); - - httpSecurity.csrf().disable() - .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.ALWAYS).and() - .exceptionHandling().authenticationEntryPoint(new SpringSecurityExceptionHandler()).and() + httpSecurity + .csrf().csrfTokenRepository(csrfTokenRepository).requireCsrfProtectionMatcher(csrfURLMatcher).and() + .exceptionHandling() + .authenticationEntryPoint(new SpringSecurityExceptionHandler()) + .accessDeniedHandler(new SpringSecurityExceptionHandler()) + .and() .headers().frameOptions().deny().contentTypeOptions().and().xssProtection().xssProtectionEnabled(true).and().and() - .addFilter(blueCoatAuthenticationFilter) .addFilter(x509AuthenticationFilter) - .httpBasic() - .and() // username + .httpBasic().authenticationEntryPoint(new SpringSecurityExceptionHandler()).and() // username .anonymous().authorities(SMPAuthority.S_AUTHORITY_ANONYMOUS.getAuthority()).and() - .authorizeRequests().antMatchers(HttpMethod.DELETE, "/ui/rest/security/authentication").permitAll() - .antMatchers(HttpMethod.POST, "/ui/rest/security/authentication").permitAll() - .and() .authorizeRequests() - .antMatchers(HttpMethod.DELETE).hasAnyAuthority( + .antMatchers(HttpMethod.DELETE, "/ui/rest/security/authentication").permitAll() + .antMatchers(HttpMethod.POST, "/ui/rest/security/authentication").permitAll().and() + .authorizeRequests() + .antMatchers(HttpMethod.DELETE).hasAnyAuthority( SMPAuthority.S_AUTHORITY_SMP_ADMIN.getAuthority(), SMPAuthority.S_AUTHORITY_SERVICE_GROUP.getAuthority(), SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN.getAuthority()) - .antMatchers(HttpMethod.PUT).hasAnyAuthority( + .antMatchers(HttpMethod.PUT).hasAnyAuthority( SMPAuthority.S_AUTHORITY_SMP_ADMIN.getAuthority(), SMPAuthority.S_AUTHORITY_SERVICE_GROUP.getAuthority(), SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN.getAuthority()) .antMatchers(HttpMethod.GET).permitAll().and() - .authorizeRequests().antMatchers(HttpMethod.GET, "/ui/").hasAnyAuthority( + .authorizeRequests() + .antMatchers(HttpMethod.GET, "/ui/").hasAnyAuthority( SMPAuthority.S_AUTHORITY_SMP_ADMIN.getAuthority(), SMPAuthority.S_AUTHORITY_SERVICE_GROUP.getAuthority(), - SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN.getAuthority()).and() - ; - - + SMPAuthority.S_AUTHORITY_SYSTEM_ADMIN.getAuthority()); } @Override @@ -145,6 +149,7 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { public BlueCoatAuthenticationFilter getClientCertAuthenticationFilter(@Qualifier("smpAuthenticationManager") AuthenticationManager authenticationManager) { BlueCoatAuthenticationFilter blueCoatAuthenticationFilter = new BlueCoatAuthenticationFilter(); blueCoatAuthenticationFilter.setAuthenticationManager(authenticationManager); + blueCoatAuthenticationFilter.setBlueCoatEnabled(clientCertEnabled); return blueCoatAuthenticationFilter; } @@ -156,7 +161,31 @@ public class SpringSecurityConfig extends WebSecurityConfigurerAdapter { } @Bean - public SMPCookieWriter getSMPCookieWriter() { + public CsrfTokenRepository tokenRepository() { + CookieCsrfTokenRepository repository = CookieCsrfTokenRepository.withHttpOnlyFalse(); + return repository; + } + + @Bean + public RequestMatcher csrfURLMatcher() { + URLCsrfMatcher requestMatcher = new URLCsrfMatcher(); + // init pages + requestMatcher.addIgnoreUrl("^/$", HttpMethod.GET); + requestMatcher.addIgnoreUrl("favicon.ico$", HttpMethod.GET); + requestMatcher.addIgnoreUrl("^/(index.html|ui/(#/)?|)$", HttpMethod.GET); + // Csrf ignore "SMP API 'stateless' calls! (each call is authenticated and session is not used!)" + requestMatcher.addIgnoreUrl("/.*::.*(/services/?.*)?", HttpMethod.GET, HttpMethod.DELETE, HttpMethod.POST, HttpMethod.PUT); + // ignore for login and logout + requestMatcher.addIgnoreUrl("/ui/rest/security/authentication", HttpMethod.DELETE, HttpMethod.POST); + // allow all gets + requestMatcher.addIgnoreUrl("/ui/.*", HttpMethod.GET); + // monitor + requestMatcher.addIgnoreUrl("/monitor/is-alive", HttpMethod.GET); + return requestMatcher; + } + + @Bean + public SMPCookieWriter smpCookieWriter() { return new SMPCookieWriter(); } } diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/error/SpringSecurityExceptionHandler.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/error/SpringSecurityExceptionHandler.java index fb3fb8c41500f44b62f671696c79f7f2bf524356..e5d2d5bac523427a6d050bbebc0704be71b10cc2 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/error/SpringSecurityExceptionHandler.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/error/SpringSecurityExceptionHandler.java @@ -45,7 +45,7 @@ public class SpringSecurityExceptionHandler extends BasicAuthenticationEntryPoin private static final Logger log = LoggerFactory.getLogger(SpringSecurityExceptionHandler.class); public SpringSecurityExceptionHandler() { - this.setRealmName("any realm name"); + this.setRealmName("SMPSecurityRealm"); } @Override @@ -79,8 +79,8 @@ public class SpringSecurityExceptionHandler extends BasicAuthenticationEntryPoin String errorUniqueId = ((ErrorResponse) response.getBody()).getErrorUniqueId(); String logMsg = format("Error unique ID: %s", errorUniqueId); - - log.warn(logMsg, exception); + log.warn("Security error:[{}] with [{}].", errorMsg, logMsg); + log.debug(logMsg, exception); return response; } diff --git a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResource.java b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResource.java index 24da759ac5dfddb5c53b7c7748fefd5e5c2158ae..74f25609822f3e3488d4b283a2604f56250bf95e 100644 --- a/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResource.java +++ b/smp-webapp/src/main/java/eu/europa/ec/edelivery/smp/ui/AuthenticationResource.java @@ -3,7 +3,6 @@ package eu.europa.ec.edelivery.smp.ui; import eu.europa.ec.edelivery.smp.auth.SMPAuthenticationService; import eu.europa.ec.edelivery.smp.auth.SMPAuthenticationToken; -import eu.europa.ec.edelivery.smp.auth.SMPAuthority; import eu.europa.ec.edelivery.smp.auth.SMPAuthorizationService; import eu.europa.ec.edelivery.smp.data.ui.ErrorRO; import eu.europa.ec.edelivery.smp.data.ui.LoginRO; @@ -22,6 +21,8 @@ import org.springframework.security.core.AuthenticationException; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.web.authentication.logout.CookieClearingLogoutHandler; import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler; +import org.springframework.security.web.csrf.CsrfToken; +import org.springframework.security.web.csrf.CsrfTokenRepository; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*; @@ -50,15 +51,23 @@ public class AuthenticationResource { private ConfigurationService configurationService; + public CsrfTokenRepository csrfTokenRepository; + SMPCookieWriter smpCookieWriter; @Autowired - public AuthenticationResource(SMPAuthenticationService authenticationService, SMPAuthorizationService authorizationService, ConversionService conversionService, ConfigurationService configurationService, SMPCookieWriter smpCookieWriter) { + public AuthenticationResource(SMPAuthenticationService authenticationService + , SMPAuthorizationService authorizationService + , ConversionService conversionService + , ConfigurationService configurationService + , SMPCookieWriter smpCookieWriter + , CsrfTokenRepository csrfTokenRepository) { this.authenticationService = authenticationService; this.authorizationService = authorizationService; this.conversionService = conversionService; this.configurationService = configurationService; this.smpCookieWriter = smpCookieWriter; + this.csrfTokenRepository = csrfTokenRepository; } @ResponseStatus(value = HttpStatus.FORBIDDEN) @@ -72,9 +81,10 @@ public class AuthenticationResource { @Transactional(noRollbackFor = BadCredentialsException.class) public UserRO authenticate(@RequestBody LoginRO loginRO, HttpServletRequest request, HttpServletResponse response) { LOG.debug("Authenticating user [{}]", loginRO.getUsername()); - // reset session id with login - + // reset session id token and the Csrf Token at login recreatedSessionCookie(request, response); + CsrfToken csfrToken = csrfTokenRepository.generateToken(request); + csrfTokenRepository.saveToken(csfrToken, request, response); SMPAuthenticationToken authentication = (SMPAuthenticationToken) authenticationService.authenticate(loginRO.getUsername(), loginRO.getPassword()); UserRO userRO = conversionService.convert(authentication.getUser(), UserRO.class); @@ -115,6 +125,8 @@ public class AuthenticationResource { * @param response */ public void recreatedSessionCookie(HttpServletRequest request, HttpServletResponse response) { + // recreate session id (first make sure it exists) + request.getSession(true).getId(); String sessionId = request.changeSessionId(); smpCookieWriter.writeCookieToResponse(SESSION_COOKIE_NAME, sessionId, diff --git a/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SecurityConfigurationClientCertTest.java b/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SecurityConfigurationClientCertTest.java index ce84508031a572bdf6f46ff2542f3360ba1bf462..974548b0934baa5a5f59f0e845c772b5579bbcff 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SecurityConfigurationClientCertTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SecurityConfigurationClientCertTest.java @@ -38,6 +38,7 @@ import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Arrays; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -183,7 +184,7 @@ public class SecurityConfigurationClientCertTest { HttpHeaders headers = new HttpHeaders(); headers.add("Client-Cert", clientCert); mvc.perform(MockMvcRequestBuilders.put(RETURN_LOGGED_USER_PATH) - .headers(headers)) + .headers(headers).with(csrf())) .andExpect(status().isOk()) .andExpect(content().string(expectedCertificateId)) .andReturn().getResponse().getContentAsString(); diff --git a/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SecurityConfigurationTest.java b/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SecurityConfigurationTest.java index 27877ddfde1c070f53e9249a78aabd1016c1a8d6..c334114c27fd5c2e52bc86aa2acbb696f6966533 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SecurityConfigurationTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/cipa/smp/server/security/SecurityConfigurationTest.java @@ -31,6 +31,7 @@ import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -81,27 +82,31 @@ public class SecurityConfigurationTest { @Test public void getMethodAccessiblePubliclyTest() throws Exception { - mvc.perform(MockMvcRequestBuilders.get(RETURN_LOGGED_USER_PATH)) + mvc.perform(MockMvcRequestBuilders.get(RETURN_LOGGED_USER_PATH) + .with(csrf())) .andExpect(status().isOk()) .andExpect(content().string("anonymousUser")); } @Test public void notAuthenticatedUserCannotCallPutTest() throws Exception { - mvc.perform(MockMvcRequestBuilders.put(RETURN_LOGGED_USER_PATH)) + mvc.perform(MockMvcRequestBuilders.put(RETURN_LOGGED_USER_PATH) + .with(csrf())) .andExpect(status().isUnauthorized()); } @Test public void notAuthenticatedUserCannotCallDeleteTest() throws Exception { - mvc.perform(MockMvcRequestBuilders.delete(RETURN_LOGGED_USER_PATH)) + mvc.perform(MockMvcRequestBuilders.delete(RETURN_LOGGED_USER_PATH) + .with(csrf())) .andExpect(status().isUnauthorized()); } @Test public void userStoredWithHashedPassIsAuthorizedForPutTest() throws Exception { mvc.perform(MockMvcRequestBuilders.put(RETURN_LOGGED_USER_PATH) - .with(httpBasic(TEST_USERNAME_DB_HASHED_PASS, PASSWORD))) + .with(httpBasic(TEST_USERNAME_DB_HASHED_PASS, PASSWORD)) + .with(csrf())) .andExpect(status().isOk()) .andExpect(content().string(TEST_USERNAME_DB_HASHED_PASS)); } @@ -113,7 +118,8 @@ public class SecurityConfigurationTest { Assert.assertNotEquals(upperCaseUsername, TEST_USERNAME_DB_HASHED_PASS); mvc.perform(MockMvcRequestBuilders.put(RETURN_LOGGED_USER_PATH) - .with(httpBasic(upperCaseUsername, PASSWORD))) + .with(httpBasic(upperCaseUsername, PASSWORD)) + .with(csrf())) .andExpect(status().isOk()) .andExpect(content().string(upperCaseUsername)); } @@ -124,7 +130,7 @@ public class SecurityConfigurationTest { @Test public void userStoredWithClearPassIsNotAuthorizedForPutTest() throws Exception { mvc.perform(MockMvcRequestBuilders.put(RETURN_LOGGED_USER_PATH) - .with(httpBasic(TEST_USERNAME_DB_CLEAR_PASS, PASSWORD))) + .with(httpBasic(TEST_USERNAME_DB_CLEAR_PASS, PASSWORD)).with(csrf())) .andExpect(status().isUnauthorized()); } @@ -134,7 +140,7 @@ public class SecurityConfigurationTest { HttpHeaders headers = new HttpHeaders(); headers.add("Client-Cert", "malformed header value"); mvc.perform(MockMvcRequestBuilders.put(RETURN_LOGGED_USER_PATH) - .headers(headers)) + .headers(headers).with(csrf())) .andExpect(status().isUnauthorized()); } @@ -143,7 +149,8 @@ public class SecurityConfigurationTest { HttpHeaders headers = new HttpHeaders(); headers.add("Client-Cert", BLUE_COAT_VALID_HEADER); mvc.perform(MockMvcRequestBuilders.put(RETURN_LOGGED_USER_PATH) - .headers(headers)) + .headers(headers) + .with(csrf())) .andExpect(status().isOk()) .andExpect(content().string(TEST_USERNAME_BLUE_COAT)) .andReturn().getResponse().getContentAsString(); @@ -154,7 +161,7 @@ public class SecurityConfigurationTest { headers.add("Client-Cert", BLUE_COAT_NOT_AUTHORIZED_HEADER); mvc.perform(MockMvcRequestBuilders.put(RETURN_LOGGED_USER_PATH) - .headers(headers)) + .headers(headers).with(csrf())) .andExpect(status().isUnauthorized()); } @@ -164,7 +171,8 @@ public class SecurityConfigurationTest { headers.add("Client-Cert", BLUE_COAT_VALID_HEADER); mvc.perform(MockMvcRequestBuilders.put(RETURN_LOGGED_USER_PATH) .headers(headers) - .with(httpBasic(TEST_USERNAME_DB_HASHED_PASS, PASSWORD))) + .with(httpBasic(TEST_USERNAME_DB_HASHED_PASS, PASSWORD)) + .with(csrf())) .andExpect(status().isOk()) .andExpect(content().string(TEST_USERNAME_BLUE_COAT)); } @@ -175,7 +183,8 @@ public class SecurityConfigurationTest { headers.add("Client-Cert", BLUE_COAT_VALID_HEADER_UPPER_SN); mvc.perform(MockMvcRequestBuilders.put(RETURN_LOGGED_USER_PATH) .headers(headers) - .with(httpBasic(TEST_USERNAME_DB_HASHED_PASS, PASSWORD))) + .with(httpBasic(TEST_USERNAME_DB_HASHED_PASS, PASSWORD)) + .with(csrf())) .andExpect(status().isOk()) .andExpect(content().string(TEST_USERNAME_BLUE_COAT)); } @@ -187,7 +196,8 @@ public class SecurityConfigurationTest { headers.add("Client-Cert", BLUE_COAT_VALID_HEADER_DB_UPPER_SN); mvc.perform(MockMvcRequestBuilders.put(RETURN_LOGGED_USER_PATH) .headers(headers) - .with(httpBasic(TEST_USERNAME_DB_HASHED_PASS, PASSWORD))) + .with(httpBasic(TEST_USERNAME_DB_HASHED_PASS, PASSWORD)) + .with(csrf())) .andExpect(status().isOk()) .andExpect(content().string(TEST_USERNAME_BLUE_COAT__DB_UPPER_SN)); } @@ -198,7 +208,8 @@ public class SecurityConfigurationTest { headers.add("Client-Cert", BLUE_COAT_VALID_HEADER_DB_UPPER_SN); mvc.perform(MockMvcRequestBuilders.put(RETURN_LOGGED_USER_PATH) .headers(headers) - .with(httpBasic(TEST_USERNAME_DB_HASHED_PASS, PASSWORD))) + .with(httpBasic(TEST_USERNAME_DB_HASHED_PASS, PASSWORD)) + .with(csrf())) .andExpect(status().isOk()) .andExpect(content().string(TEST_USERNAME_BLUE_COAT__DB_UPPER_SN)); } diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/ApplicationResourceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/ApplicationResourceTest.java index 029b738fadfec67c747c6918baa00ac25695048c..3d4f71d27c6db37b01ba7facfb0e36a7d5df0a6a 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/ApplicationResourceTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/ApplicationResourceTest.java @@ -29,6 +29,7 @@ import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; import static org.junit.Assert.*; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -110,7 +111,8 @@ public class ApplicationResourceTest { @Test public void testGetApplicationConfigNotAuthorized() throws Exception { // when - mvc.perform(get(PATH + "/config")) + mvc.perform(get(PATH + "/config") + .with(csrf())) .andExpect(status().isUnauthorized()) .andReturn() .getResponse(); @@ -118,21 +120,26 @@ public class ApplicationResourceTest { @Test public void testGetApplicationConfigAuthorized() throws Exception { // SMP admin - String val = mvc.perform(get(PATH + "/config").with(SMP_ADMIN_CREDENTIALS)) + String val = mvc.perform(get(PATH + "/config") + .with(SMP_ADMIN_CREDENTIALS) + .with(csrf())) .andExpect(status().isOk()) .andReturn() .getResponse() .getContentAsString(); assertNotNull(val); // service group - val = mvc.perform(get(PATH + "/config").with(SG_ADMIN_CREDENTIALS)) + val = mvc.perform(get(PATH + "/config").with(SG_ADMIN_CREDENTIALS) + .with(csrf())) .andExpect(status().isOk()) .andReturn() .getResponse() .getContentAsString(); assertNotNull(val); // system admin - val = mvc.perform(get(PATH + "/config").with(SYSTEM_CREDENTIALS)) + val = mvc.perform(get(PATH + "/config") + .with(SYSTEM_CREDENTIALS) + .with(csrf())) .andExpect(status().isOk()) .andReturn() .getResponse() @@ -143,8 +150,9 @@ public class ApplicationResourceTest { @Test public void testGetApplicationConfigSMPAdmin() throws Exception { // when - String value = mvc.perform(get(PATH + "/config").with(SMP_ADMIN_CREDENTIALS)) - + String value = mvc.perform(get(PATH + "/config") + .with(SMP_ADMIN_CREDENTIALS) + .with(csrf())) .andExpect(status().isOk()) .andReturn() .getResponse() diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/DomainResourceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/DomainResourceTest.java index 6011dc3778fc355454ee9496455ceb12671e771d..12b12d7c60f7bd6a9c95ec0a96b6e6493118e37e 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/DomainResourceTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/DomainResourceTest.java @@ -30,6 +30,7 @@ import javax.servlet.ServletContextListener; import static org.hamcrest.Matchers.stringContainsInOrder; import static org.junit.Assert.*; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; @@ -86,8 +87,10 @@ public class DomainResourceTest { public void geDomainList() throws Exception { // given when - MvcResult result = mvc.perform(get(PATH).with(SYSTEM_CREDENTIALS)). - andExpect(status().isOk()).andReturn(); + MvcResult result = mvc.perform(get(PATH) + .with(SYSTEM_CREDENTIALS) + .with(csrf())) + .andExpect(status().isOk()).andReturn(); //them ObjectMapper mapper = new ObjectMapper(); @@ -111,6 +114,7 @@ public class DomainResourceTest { MvcResult result = mvc.perform(put(PATH ) .with(SYSTEM_CREDENTIALS) + .with(csrf()) .header("Content-Type", " application/json") .content("[{\"status\":3,\"index\":9,\"id\":2,\"domainCode\":\"domainTwo\",\"smlSubdomain\":\"newdomain\",\"smlSmpId\":\"CEF-SMP-010\",\"smlParticipantIdentifierRegExp\":null,\"smlClientCertHeader\":null,\"smlClientKeyAlias\":null,\"signatureKeyAlias\":\"sig-key\",\"smlBlueCoatAuth\":true,\"smlRegistered\":false,\"deleted\":true}]")) // delete domain with id 2 .andExpect(status().isOk()).andReturn(); @@ -125,6 +129,7 @@ public class DomainResourceTest { // given when MvcResult result = mvc.perform(put(PATH ) .with(SYSTEM_CREDENTIALS) + .with(csrf()) .header("Content-Type", " application/json") .content("[{\"status\":3,\"index\":9,\"id\":10,\"domainCode\":\"domainTwoNotExist\",\"smlSubdomain\":\"newdomain\",\"smlSmpId\":\"CEF-SMP-010\",\"smlParticipantIdentifierRegExp\":null,\"smlClientCertHeader\":null,\"smlClientKeyAlias\":null,\"signatureKeyAlias\":\"sig-key\",\"smlBlueCoatAuth\":true,\"smlRegistered\":false,\"deleted\":true}]")) // delete domain with id 2 .andExpect(status().isOk()).andReturn(); @@ -135,6 +140,7 @@ public class DomainResourceTest { // given when MvcResult result = mvc.perform(post(PATH + "/validateDelete") .with(SYSTEM_CREDENTIALS) + .with(csrf()) .header("Content-Type", " application/json") .content("[2]")) // delete domain with id 2 .andExpect(status().isOk()).andReturn(); @@ -157,6 +163,7 @@ public class DomainResourceTest { MvcResult result = mvc.perform(put(PATH ) .with(SYSTEM_CREDENTIALS) + .with(csrf()) .header("Content-Type", " application/json") .content("[{\"status\":1,\"index\":9,\"id\":2,\"domainCode\":\"domainTwo\",\"smlSubdomain\":\"newdomain\",\"smlSmpId\":\"CEF-SMP-010\",\"smlParticipantIdentifierRegExp\":null,\"smlClientCertHeader\":null,\"smlClientKeyAlias\":null,\"signatureKeyAlias\":\"sig-key\",\"smlBlueCoatAuth\":true,\"smlRegistered\":false,\"deleted\":true}]")) // delete domain with id 2 .andExpect(status().isOk()).andReturn(); @@ -170,6 +177,7 @@ public class DomainResourceTest { // given when MvcResult result = mvc.perform(post(PATH + "/validateDelete") .with(SYSTEM_CREDENTIALS) + .with(csrf()) .header("Content-Type", " application/json") .content("[1]")) // delete domain with id 2 .andExpect(status().isOk()).andReturn(); @@ -192,6 +200,7 @@ public class DomainResourceTest { // domainTwo - domain code mvc.perform(post(PATH + "/3/smlregister/domainTwo") .with(SYSTEM_CREDENTIALS) + .with(csrf()) .header("Content-Type", " application/json")) .andExpect(status().isOk()) .andExpect(content().string(stringContainsInOrder("Configuration error: SML integration is not enabled!!"))); @@ -204,6 +213,7 @@ public class DomainResourceTest { // domainTwo - domain code mvc.perform(post(PATH + "/3/smlunregister/domainTwo") .with(SYSTEM_CREDENTIALS) + .with(csrf()) .header("Content-Type", " application/json")) .andExpect(status().isOk()) .andExpect(content().string(stringContainsInOrder("Configuration error: SML integration is not enabled!!"))); diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/KeystoreResourceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/KeystoreResourceTest.java index 2aaa79520d54b61218106017eb076a683dcb2ec2..e157dd6bbdb5aeeab4b1f3e49676804157dd9654 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/KeystoreResourceTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/KeystoreResourceTest.java @@ -42,6 +42,7 @@ import java.util.Arrays; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; @@ -98,8 +99,10 @@ public class KeystoreResourceTest { public void getKeyCertificateList() throws Exception { // given when int countStart = uiKeystoreService.getKeystoreEntriesList().size(); - MvcResult result = mvc.perform(get(PATH).with(SYSTEM_CREDENTIALS)). - andExpect(status().isOk()).andReturn(); + MvcResult result = mvc.perform(get(PATH) + .with(SYSTEM_CREDENTIALS) + .with(csrf())) + .andExpect(status().isOk()).andReturn(); //them ObjectMapper mapper = new ObjectMapper(); @@ -122,6 +125,7 @@ public class KeystoreResourceTest { // given when MvcResult result = mvc.perform(post(PATH+"/3/upload/JKS/test123") .with(SYSTEM_CREDENTIALS) + .with(csrf()) .content("invalid keystore")). andExpect(status().isOk()).andReturn(); @@ -139,6 +143,7 @@ public class KeystoreResourceTest { // given when MvcResult result = mvc.perform(post(PATH+"/3/upload/JKS/NewPassword1234") .with(SYSTEM_CREDENTIALS) + .with(csrf()) .content(Files.readAllBytes(keystore)) ) .andExpect(status().isOk()).andReturn(); @@ -157,6 +162,7 @@ public class KeystoreResourceTest { // given when MvcResult result = mvc.perform(post(PATH+"/3/upload/JKS/test123") .with(SYSTEM_CREDENTIALS) + .with(csrf()) .content(Files.readAllBytes(keystore)) ) .andExpect(status().isOk()).andReturn(); @@ -176,6 +182,7 @@ public class KeystoreResourceTest { // given when MvcResult result = mvc.perform(delete(PATH+"/3/delete/second_domain_alias") .with(SYSTEM_CREDENTIALS) + .with(csrf()) .content(Files.readAllBytes(keystore)) ) .andExpect(status().isOk()).andReturn(); diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/ServiceGroupResourceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/ServiceGroupResourceTest.java index 954657a403fb483eb6280fba55b72f6dda40d8fa..eb764c375a184f775831c25a915b78fb80954a1c 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/ServiceGroupResourceTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/ServiceGroupResourceTest.java @@ -37,6 +37,7 @@ import javax.xml.ws.spi.WebServiceFeatureAnnotation; import java.io.IOException; import static org.junit.Assert.*; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post; @@ -95,7 +96,7 @@ public class ServiceGroupResourceTest { public void getServiceGroupListForSMPAdmin() throws Exception { // given when MvcResult result = mvc.perform(get(PATH) - .with(SMP_ADMIN_CREDENTIALS) + .with(SMP_ADMIN_CREDENTIALS).with(csrf()) ).andExpect(status().isOk()).andReturn(); //them @@ -119,7 +120,7 @@ public class ServiceGroupResourceTest { public void getServiceGroupListForServiceGroupAdmin() throws Exception { // given when MvcResult result = mvc.perform(get(PATH) - .with(SG_ADMIN_CREDENTIALS) + .with(SG_ADMIN_CREDENTIALS).with(csrf()) ).andExpect(status().isOk()).andReturn(); //them @@ -143,7 +144,7 @@ public class ServiceGroupResourceTest { // given when MvcResult result = mvc.perform(get(PATH + "/100000") - .with(SMP_ADMIN_CREDENTIALS)). + .with(SMP_ADMIN_CREDENTIALS).with(csrf())). andExpect(status().isOk()).andReturn(); //them @@ -172,8 +173,8 @@ public class ServiceGroupResourceTest { // given when MvcResult result = mvc.perform(get(PATH + "/extension/100000") - .with(SMP_ADMIN_CREDENTIALS)). - andExpect(status().isOk()).andReturn(); + .with(SMP_ADMIN_CREDENTIALS).with(csrf())) + .andExpect(status().isOk()).andReturn(); //them ObjectMapper mapper = new ObjectMapper(); @@ -187,7 +188,7 @@ public class ServiceGroupResourceTest { } @Test - public void testValidateInvald() throws Exception { + public void testValidateInvalid() throws Exception { ObjectMapper mapper = new ObjectMapper(); ServiceGroupValidationRO validate = new ServiceGroupValidationRO(); validate.setExtension(validExtension + "<ADFA>sdfadsf"); @@ -196,7 +197,8 @@ public class ServiceGroupResourceTest { MvcResult result = mvc.perform(post(PATH + "/extension/validate") .with(SMP_ADMIN_CREDENTIALS) .header("Content-Type","application/json") - .content(mapper.writeValueAsString(validate))) + .content(mapper.writeValueAsString(validate)) + .with(csrf())) .andExpect(status().isOk()).andReturn(); //then diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/TruststoreResourceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/TruststoreResourceTest.java index 8b9ac9344fac36003bd42c2e30473b8cff981fcf..dd8f0c1c48156be4eacd1727f3cb034ccc6abc4a 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/TruststoreResourceTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/TruststoreResourceTest.java @@ -40,6 +40,7 @@ import java.util.ArrayList; import java.util.List; import static org.junit.Assert.*; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; @@ -94,8 +95,10 @@ public class TruststoreResourceTest { public void getCertificateList() throws Exception { // given when int countStart = uiTruststoreService.getCertificateROEntriesList().size(); - MvcResult result = mvc.perform(get(PATH).with(SYSTEM_CREDENTIALS)). - andExpect(status().isOk()).andReturn(); + MvcResult result = mvc.perform(get(PATH) + .with(SYSTEM_CREDENTIALS) + .with(csrf())) + .andExpect(status().isOk()).andReturn(); //them ObjectMapper mapper = new ObjectMapper(); @@ -123,6 +126,7 @@ public class TruststoreResourceTest { // given when MvcResult result = mvc.perform(post(PATH+"/3/certdata") .with(SYSTEM_CREDENTIALS) + .with(csrf()) .content(buff)) .andExpect(status().isOk()).andReturn(); @@ -145,6 +149,7 @@ public class TruststoreResourceTest { int countStart = uiTruststoreService.getNormalizedTrustedList().size(); MvcResult prepRes = mvc.perform(post(PATH+"/3/certdata") .with(SYSTEM_CREDENTIALS) + .with(csrf()) .content(buff)) .andExpect(status().isOk()).andReturn(); @@ -158,6 +163,7 @@ public class TruststoreResourceTest { // then MvcResult result = mvc.perform(delete(PATH+"/3/delete/"+res.getAlias()) .with(SYSTEM_CREDENTIALS) + .with(csrf()) .content(buff)) .andExpect(status().isOk()).andReturn(); uiTruststoreService.refreshData(); diff --git a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/UserResourceTest.java b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/UserResourceTest.java index eab1870de97d5192b3b990ef5984d1d0d52f314d..f739b076a76165a9b7405827704e9603f95e203f 100644 --- a/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/UserResourceTest.java +++ b/smp-webapp/src/test/java/eu/europa/ec/edelivery/smp/ui/UserResourceTest.java @@ -40,6 +40,7 @@ import java.util.Optional; import java.util.UUID; import static org.junit.Assert.*; +import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf; import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.httpBasic; import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content; @@ -88,8 +89,10 @@ public class UserResourceTest { @Test public void getUserList() throws Exception { // given when - MvcResult result = mvc.perform(get(PATH).with(ADMIN_CREDENTIALS)). - andExpect(status().isOk()).andReturn(); + MvcResult result = mvc.perform(get(PATH) + .with(ADMIN_CREDENTIALS) + .with(csrf())) + .andExpect(status().isOk()).andReturn(); //them ObjectMapper mapper = new ObjectMapper(); @@ -127,7 +130,9 @@ public class UserResourceTest { } userRO.getCertificate().setCertificateId(UUID.randomUUID().toString()); - mvc.perform(put(PATH+"/"+userRO.getId()).with(ADMIN_CREDENTIALS) + mvc.perform(put(PATH+"/"+userRO.getId()) + .with(ADMIN_CREDENTIALS) + .with(csrf()) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(userRO)) ).andExpect(status().isOk()).andReturn(); @@ -155,7 +160,9 @@ public class UserResourceTest { } userRO.getCertificate().setCertificateId(UUID.randomUUID().toString()); - mvc.perform(put(PATH+"/"+userRO.getId()).with(SYSTEM_CREDENTIALS) + mvc.perform(put(PATH+"/"+userRO.getId()) + .with(SYSTEM_CREDENTIALS) + .with(csrf()) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(userRO)) ).andExpect(status().isUnauthorized()); @@ -164,8 +171,10 @@ public class UserResourceTest { @Test public void testUpdateUserList() throws Exception { // given when - MvcResult result = mvc.perform(get(PATH).with(SYSTEM_CREDENTIALS)). - andExpect(status().isOk()).andReturn(); + MvcResult result = mvc.perform(get(PATH) + .with(SYSTEM_CREDENTIALS) + .with(csrf())) + .andExpect(status().isOk()).andReturn(); ObjectMapper mapper = new ObjectMapper(); ServiceResult res = mapper.readValue(result.getResponse().getContentAsString(), ServiceResult.class); assertNotNull(res); @@ -181,7 +190,9 @@ public class UserResourceTest { userRO.getCertificate().setCertificateId(UUID.randomUUID().toString()); mvc.perform(put(PATH) - .with(SYSTEM_CREDENTIALS).contentType(MediaType.APPLICATION_JSON) + .with(SYSTEM_CREDENTIALS) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(Arrays.asList(userRO))) ).andExpect(status().isOk()); } @@ -189,8 +200,10 @@ public class UserResourceTest { @Test public void testUpdateUserListWrongAuthentication() throws Exception { // given when - MvcResult result = mvc.perform(get(PATH).with(SYSTEM_CREDENTIALS)). - andExpect(status().isOk()).andReturn(); + MvcResult result = mvc.perform(get(PATH) + .with(SYSTEM_CREDENTIALS) + .with(csrf())) + .andExpect(status().isOk()).andReturn(); ObjectMapper mapper = new ObjectMapper(); ServiceResult res = mapper.readValue(result.getResponse().getContentAsString(), ServiceResult.class); assertNotNull(res); @@ -206,17 +219,22 @@ public class UserResourceTest { userRO.getCertificate().setCertificateId(UUID.randomUUID().toString()); // anonymous mvc.perform(put(PATH) + .with(csrf()) .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(Arrays.asList(userRO))) ).andExpect(status().isUnauthorized()); mvc.perform(put(PATH) - .with(ADMIN_CREDENTIALS).contentType(MediaType.APPLICATION_JSON) + .with(ADMIN_CREDENTIALS) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(Arrays.asList(userRO))) ).andExpect(status().isUnauthorized()); mvc.perform(put(PATH) - .with(SG_ADMIN_CREDENTIALS).contentType(MediaType.APPLICATION_JSON) + .with(SG_ADMIN_CREDENTIALS) + .with(csrf()) + .contentType(MediaType.APPLICATION_JSON) .content(mapper.writeValueAsString(Arrays.asList(userRO))) ).andExpect(status().isUnauthorized()); } @@ -228,6 +246,7 @@ public class UserResourceTest { // given when MvcResult result = mvc.perform(post(PATH+"/1098765430/certdata") .with(SYSTEM_CREDENTIALS) + .with(csrf()) .content(buff)) .andExpect(status().isOk()).andReturn(); @@ -250,6 +269,7 @@ public class UserResourceTest { // given when mvc.perform(post(PATH+"/1098765430/certdata") .with(SYSTEM_CREDENTIALS) + .with(csrf()) .content(buff)) .andExpect(status().is5xxServerError()) .andExpect(content().string(CoreMatchers.containsString(" The certificate is not valid"))); @@ -265,6 +285,7 @@ public class UserResourceTest { // given when MvcResult result = mvc.perform(post(PATH+"/1098765430/certdata") .with(SYSTEM_CREDENTIALS) + .with(csrf()) .content(buff)) .andExpect(status().isOk()).andReturn(); @@ -283,6 +304,7 @@ public class UserResourceTest { // given when mvc.perform(post(PATH+"/34556655/certdata") .with(ADMIN_CREDENTIALS) + .with(csrf()) .content(buff)) .andExpect(status().isUnauthorized()).andReturn(); } @@ -292,6 +314,7 @@ public class UserResourceTest { // 1 is id for smp_admin MvcResult result = mvc.perform(post(PATH+"/1/samePreviousPasswordUsed") .with(ADMIN_CREDENTIALS) + .with(csrf()) .content("test123")) .andExpect(status().isOk()).andReturn(); @@ -304,6 +327,7 @@ public class UserResourceTest { // 1 is id for smp_admin MvcResult result = mvc.perform(post(PATH+"/1/samePreviousPasswordUsed") .with(ADMIN_CREDENTIALS) + .with(csrf()) .content("7777")) .andExpect(status().isOk()).andReturn(); @@ -316,16 +340,16 @@ public class UserResourceTest { // 1 is id for smp_admin so for 3 should be Unauthorized MvcResult result = mvc.perform(post(PATH+"/3/samePreviousPasswordUsed") .with(ADMIN_CREDENTIALS) + .with(csrf()) .content("test123")) .andExpect(status().isUnauthorized()).andReturn(); - - } @Test public void testValidateDeleteUserOK() throws Exception { MvcResult result = mvc.perform(post(PATH+"/validateDelete") .with(SYSTEM_CREDENTIALS) + .with(csrf()) .contentType(org.springframework.http.MediaType.APPLICATION_JSON) .content("[5]")) .andExpect(status().isOk()).andReturn(); @@ -343,6 +367,7 @@ public class UserResourceTest { // note system credential has id 3! MvcResult result = mvc.perform(post(PATH+"/validateDelete") .with(SYSTEM_CREDENTIALS) + .with(csrf()) .contentType(org.springframework.http.MediaType.APPLICATION_JSON) .content("[3]")) .andExpect(status().isOk())