diff --git a/libraries-security/pom.xml b/libraries-security/pom.xml index 0031b7bc06..46e12eb655 100644 --- a/libraries-security/pom.xml +++ b/libraries-security/pom.xml @@ -78,6 +78,29 @@ sshd-core ${apache-mina.version} + + org.xacml4j + xacml-core + ${xacml4j.version} + + + org.slf4j + slf4j-log4j12 + + + + + org.xacml4j + xacml-test + ${xacml4j.version} + test + + + org.slf4j + slf4j-log4j12 + + + @@ -90,6 +113,7 @@ 0.1.55 2.5.1 2.4.0.RELEASE + 1.4.0 \ No newline at end of file diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/ScribejavaApplication.java b/libraries-security/src/main/java/com/baeldung/scribejava/ScribejavaApplication.java index bb86c497b0..5b18567b2d 100644 --- a/libraries-security/src/main/java/com/baeldung/scribejava/ScribejavaApplication.java +++ b/libraries-security/src/main/java/com/baeldung/scribejava/ScribejavaApplication.java @@ -2,9 +2,11 @@ package com.baeldung.scribejava; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.web.servlet.ServletComponentScan; @SpringBootApplication +@ServletComponentScan public class ScribejavaApplication { public static void main(String[] args) { diff --git a/libraries-security/src/main/java/com/baeldung/scribejava/controller/RBACController.java b/libraries-security/src/main/java/com/baeldung/scribejava/controller/RBACController.java new file mode 100644 index 0000000000..785f6228e8 --- /dev/null +++ b/libraries-security/src/main/java/com/baeldung/scribejava/controller/RBACController.java @@ -0,0 +1,27 @@ +package com.baeldung.scribejava.controller; + +import java.io.IOException; + +import javax.annotation.security.DeclareRoles; +import javax.annotation.security.RolesAllowed; +import javax.servlet.ServletException; +import javax.servlet.annotation.HttpConstraint; +import javax.servlet.annotation.ServletSecurity; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +@WebServlet(name="rbac", urlPatterns = {"/protected"}) +@DeclareRoles("USER") +@ServletSecurity( + @HttpConstraint(rolesAllowed = "USER") +) +public class RBACController extends HttpServlet { + + private static final long serialVersionUID = 1L; + + protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { + resp.getWriter().println("Hello, USER"); + } +} diff --git a/libraries-security/src/test/java/com/baeldung/xacml4j/NightlyWithdrawalPolicyUnitTest.java b/libraries-security/src/test/java/com/baeldung/xacml4j/NightlyWithdrawalPolicyUnitTest.java new file mode 100644 index 0000000000..013c78370f --- /dev/null +++ b/libraries-security/src/test/java/com/baeldung/xacml4j/NightlyWithdrawalPolicyUnitTest.java @@ -0,0 +1,233 @@ +package com.baeldung.xacml4j; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; +import org.xacml4j.v20.Xacml20TestUtility; +import org.xacml4j.v30.Attribute; +import org.xacml4j.v30.Categories; +import org.xacml4j.v30.Category; +import org.xacml4j.v30.CompositeDecisionRule; +import org.xacml4j.v30.Decision; +import org.xacml4j.v30.Entity; +import org.xacml4j.v30.RequestContext; +import org.xacml4j.v30.ResponseContext; +import org.xacml4j.v30.Result; +import org.xacml4j.v30.XacmlPolicyTestSupport; +import org.xacml4j.v30.pdp.PolicyDecisionPoint; +import org.xacml4j.v30.pdp.PolicyDecisionPointBuilder; +import org.xacml4j.v30.spi.combine.DecisionCombiningAlgorithmProviderBuilder; +import org.xacml4j.v30.spi.function.FunctionProviderBuilder; +import org.xacml4j.v30.spi.pip.PolicyInformationPointBuilder; +import org.xacml4j.v30.spi.repository.InMemoryPolicyRepository; +import org.xacml4j.v30.spi.repository.PolicyRepository; +import org.xacml4j.v30.types.DoubleExp; +import org.xacml4j.v30.types.StringExp; +import org.xacml4j.v30.types.TimeExp; + +public class NightlyWithdrawalPolicyUnitTest extends XacmlPolicyTestSupport { + + private static final String POLICY_SET = "xacml4j/NightlyWithdrawalsPolicy.xml"; + + @Test + public void testWhenNightlyWithdrawalOver500_thenFail() throws Exception { + + PolicyDecisionPoint pdp = buildPDP(POLICY_SET); + + // Action category + Attribute actionAttribute = Attribute.builder("urn:oasis:names:tc:xacml:1.0:action:action-id") + .value(StringExp.of("withdrawal")) + .build(); + Entity actionEntity = Entity.builder() + .attribute(actionAttribute) + .build(); + Category actionCategory = Category.builder(Categories.ACTION) + .entity(actionEntity) + .build(); + + // Environment Category + Attribute timeAttribute = Attribute.builder("urn:oasis:names:tc:xacml:1.0:environment:current-time") + .includeInResult(false) + .value(TimeExp.of("21:00:00")) + .build(); + Entity timeEntity = Entity.builder() + .attribute(timeAttribute) + .build(); + + Category environmentCategory = Category.builder(Categories.ENVIRONMENT) + .entity(timeEntity) + .build(); + + // ATM category + Attribute amountAttribute = Attribute.builder("urn:baeldung:atm:withdrawal:amount") + .value(DoubleExp.of("1200.00")) + .build(); + Entity atmEntity = Entity.builder() + .attribute(amountAttribute) + .build(); + + Category atmCategory = Category.builder(Categories.parse("urn:baeldung:atm:withdrawal")) + .entity(atmEntity) + .build(); + + RequestContext request = RequestContext.builder() + .attributes(actionCategory, environmentCategory, atmCategory) + .build(); + + ResponseContext response = pdp.decide(request); + assertNotNull(response); + assertTrue("Shoud have at least one result", response.getResults() != null && !response.getResults() + .isEmpty()); + + Result result = response.getResults() + .iterator() + .next(); + assertTrue("Evaluation should succeed", result.getStatus() + .isSuccess()); + assertEquals("Should DENY withdrawal", Decision.DENY, result.getDecision()); + + } + + @Test + public void testWhenNightlyWithdrawalUnder500_thenSuccess() throws Exception { + + PolicyDecisionPoint pdp = buildPDP(POLICY_SET); + + // Action category + Attribute actionAttribute = Attribute.builder("urn:oasis:names:tc:xacml:1.0:action:action-id") + .includeInResult(false) + .value(StringExp.of("withdrawal")) + .build(); + Entity actionEntity = Entity.builder() + .attribute(actionAttribute) + .build(); + Category actionCategory = Category.builder(Categories.ACTION) + .entity(actionEntity) + .build(); + + // Environment Category + Attribute timeAttribute = Attribute.builder("urn:oasis:names:tc:xacml:1.0:environment:current-time") + .includeInResult(false) + .value(TimeExp.of("21:00:00")) + .build(); + Entity timeEntity = Entity.builder() + .attribute(timeAttribute) + .build(); + Category environmentCategory = Category.builder(Categories.ENVIRONMENT) + .entity(timeEntity) + .build(); + + // ATM category + Attribute amountAttribute = Attribute.builder("urn:baeldung:atm:withdrawal:amount") + .value(DoubleExp.of("499.00")) + .build(); + Entity atmEntity = Entity.builder() + .attribute(amountAttribute) + .build(); + Category atmCategory = Category.builder(Categories.parse("urn:baeldung:atm:withdrawal")) + .entity(atmEntity) + .build(); + + RequestContext request = RequestContext.builder() + .attributes(actionCategory, environmentCategory, atmCategory) + .build(); + + ResponseContext response = pdp.decide(request); + assertNotNull(response); + assertTrue("Shoud have at least one result", + response.getResults() != null && !response.getResults().isEmpty()); + + Result result = response.getResults().iterator().next(); + assertTrue("Evaluation should succeed", result.getStatus().isSuccess()); + assertEquals("Should PERMIT withdrawal", Decision.PERMIT, result.getDecision()); + + } + + @Test + public void testWhenBusinessHoursWithdrawalOver500_thenSuccess() throws Exception { + + PolicyDecisionPoint pdp = buildPDP(POLICY_SET); + + // Action category + Attribute actionAttribute = Attribute.builder("urn:oasis:names:tc:xacml:1.0:action:action-id") + .includeInResult(false) + .value(StringExp.of("withdrawal")) + .build(); + Entity actionEntity = Entity.builder() + .attribute(actionAttribute) + .build(); + Category actionCategory = Category.builder(Categories.ACTION) + .entity(actionEntity) + .build(); + + // Environment Category + Attribute timeAttribute = Attribute.builder("urn:oasis:names:tc:xacml:1.0:environment:current-time") + .includeInResult(false) + .value(TimeExp.of("12:00:00")) + .build(); + Entity timeEntity = Entity.builder() + .attribute(timeAttribute) + .build(); + Category environmentCategory = Category.builder(Categories.ENVIRONMENT) + .entity(timeEntity) + .build(); + + // ATM category + Attribute amountAttribute = Attribute.builder("urn:baeldung:atm:withdrawal:amount") + .value(DoubleExp.of("2000.00")) + .build(); + Entity atmEntity = Entity.builder() + .attribute(amountAttribute) + .build(); + + Category atmCategory = Category.builder(Categories.parse("urn:baeldung:atm:withdrawal")) + .entity(atmEntity) + .build(); + + RequestContext request = RequestContext.builder() + .attributes(actionCategory, environmentCategory, atmCategory) + .build(); + + ResponseContext response = pdp.decide(request); + assertNotNull(response); + assertTrue("Shoud have at least one result", response.getResults() != null && !response.getResults() + .isEmpty()); + + Result result = response.getResults() + .iterator() + .next(); + assertTrue("Evaluation should succeed", result.getStatus().isSuccess()); + assertEquals("Should PERMIT withdrawal", Decision.PERMIT, result.getDecision()); + + } + + private PolicyDecisionPoint buildPDP(String... policyResources) throws Exception { + PolicyRepository repository = new InMemoryPolicyRepository("tes-repository", FunctionProviderBuilder.builder() + .defaultFunctions() + .build(), + DecisionCombiningAlgorithmProviderBuilder.builder() + .withDefaultAlgorithms() + .create()); + + List policies = new ArrayList(policyResources.length); + for (String policyResource : policyResources) { + CompositeDecisionRule policy = repository.importPolicy(Xacml20TestUtility.getClasspathResource(policyResource)); + log.info("Policy: {}", policy); + policies.add(policy); + } + + return PolicyDecisionPointBuilder.builder("testPdp") + .policyRepository(repository) + .pip(PolicyInformationPointBuilder.builder("testPip") + .defaultResolvers() + .build()) + .rootPolicy(policies.get(0)) + .build(); + } + +} diff --git a/libraries-security/src/test/resources/xacml4j/NightlyWithdrawalsPolicy.xml b/libraries-security/src/test/resources/xacml4j/NightlyWithdrawalsPolicy.xml new file mode 100644 index 0000000000..163df47f36 --- /dev/null +++ b/libraries-security/src/test/resources/xacml4j/NightlyWithdrawalsPolicy.xml @@ -0,0 +1,137 @@ + + + + Withdrawal policy example + + + + +Deny withdrawals over $500 between 20:00 and 08:00 + + + + + + withdrawal + + + + + + + + + + + + + 08:00:00 + 20:00:00 + + + + + + + 500.00 + + + + + + +Permit withdrawals under $500 between 20:00 and 08:00 + + + + + + withdrawal + + + + + + + + + + + + + 08:00:00 + 20:00:00 + + + + + + + 500.00 + + + + + + +Permit withdrawals of any value between 08:00 and 20:00 + + + + + + withdrawal + + + + + + + + + + + 08:00:00 + 20:00:00 + + + + + diff --git a/libraries-security/src/test/resources/xacml4j/Request.xml b/libraries-security/src/test/resources/xacml4j/Request.xml new file mode 100644 index 0000000000..105c7ad02f --- /dev/null +++ b/libraries-security/src/test/resources/xacml4j/Request.xml @@ -0,0 +1,30 @@ + + + + + + withdrawal + + + + + 21:00:00 + + + + + 1200 + + + \ No newline at end of file diff --git a/libraries-security/src/test/resources/xacml4j/Response.xml b/libraries-security/src/test/resources/xacml4j/Response.xml new file mode 100644 index 0000000000..f82b16080d --- /dev/null +++ b/libraries-security/src/test/resources/xacml4j/Response.xml @@ -0,0 +1,9 @@ + + + + NotApplicable + + + + + diff --git a/maven-modules/maven-parent-pom-resolution/README.md b/maven-modules/maven-parent-pom-resolution/README.md new file mode 100644 index 0000000000..6f72b5e70b --- /dev/null +++ b/maven-modules/maven-parent-pom-resolution/README.md @@ -0,0 +1,3 @@ +### Relevant Articles: + +- [Understanding the "relativePath" Tag - Maven Parent POM Resolution At A Glance](https://www.baeldung.com/maven-relativepath) diff --git a/maven-modules/maven-parent-pom-resolution/pom.xml b/maven-modules/maven-parent-pom-resolution/pom.xml new file mode 100644 index 0000000000..62e3946723 --- /dev/null +++ b/maven-modules/maven-parent-pom-resolution/pom.xml @@ -0,0 +1,28 @@ + + + 4.0.0 + com.baeldung + maven-parent-pom-resolution + 1.0-SNAPSHOT + pom + + + project-a + + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.2.0 + + + + + + diff --git a/maven-modules/maven-parent-pom-resolution/project-a/pom.xml b/maven-modules/maven-parent-pom-resolution/project-a/pom.xml new file mode 100644 index 0000000000..2d53a36d84 --- /dev/null +++ b/maven-modules/maven-parent-pom-resolution/project-a/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + project-a + + com.baeldung + maven-parent-pom-resolution + 1.0-SNAPSHOT + + + pom + + + project-b + project-c + + + diff --git a/maven-modules/maven-parent-pom-resolution/project-a/project-b/pom.xml b/maven-modules/maven-parent-pom-resolution/project-a/project-b/pom.xml new file mode 100644 index 0000000000..e3f5239efe --- /dev/null +++ b/maven-modules/maven-parent-pom-resolution/project-a/project-b/pom.xml @@ -0,0 +1,15 @@ + + + 4.0.0 + project-b + + com.baeldung + project-a + 1.0-SNAPSHOT + + + pom + + diff --git a/maven-modules/maven-parent-pom-resolution/project-a/project-c/pom.xml b/maven-modules/maven-parent-pom-resolution/project-a/project-c/pom.xml new file mode 100644 index 0000000000..3c7f70ae20 --- /dev/null +++ b/maven-modules/maven-parent-pom-resolution/project-a/project-c/pom.xml @@ -0,0 +1,20 @@ + + + 4.0.0 + project-c + + com.baeldung + project-b + 1.0-SNAPSHOT + ../project-b/pom.xml + + + pom + + + project-d + + + diff --git a/maven-modules/maven-parent-pom-resolution/project-a/project-c/project-d/pom.xml b/maven-modules/maven-parent-pom-resolution/project-a/project-c/project-d/pom.xml new file mode 100644 index 0000000000..973e44eb1f --- /dev/null +++ b/maven-modules/maven-parent-pom-resolution/project-a/project-c/project-d/pom.xml @@ -0,0 +1,17 @@ + + + 4.0.0 + project-d + + com.baeldung + project-a + 1.0-SNAPSHOT + + + ../../pom.xml + + pom + + diff --git a/maven-modules/pom.xml b/maven-modules/pom.xml index a0c45234d2..fe3bbd2653 100644 --- a/maven-modules/pom.xml +++ b/maven-modules/pom.xml @@ -36,6 +36,7 @@ host-maven-repo-example plugin-management maven-surefire-plugin + maven-parent-pom-resolution