Repository: cxf Updated Branches: refs/heads/master 4a06514e3 -> 84c4048a9
Improving Jexl Utils for STS Claim Mapper Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/84c4048a Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/84c4048a Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/84c4048a Branch: refs/heads/master Commit: 84c4048a9074f30f6f618db797a9bb04b31b89e8 Parents: 4a06514 Author: Jan Bernhardt <[email protected]> Authored: Fri Sep 12 23:02:48 2014 +0200 Committer: Jan Bernhardt <[email protected]> Committed: Fri Sep 19 17:30:57 2014 +0200 ---------------------------------------------------------------------- .../cxf/sts/claims/mapper/ClaimUtils.java | 60 ++++++++++++++++++++ .../cxf/sts/claims/mapper/JexlClaimsMapper.java | 8 +++ .../sts/claims/mapper/JexlClaimsMapperTest.java | 26 ++++++++- .../jexlClaimMappingsWithFunctions.script | 7 +++ .../jexlClaimMappingsWithoutFunctions.script | 28 +++++++++ 5 files changed, 128 insertions(+), 1 deletion(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/84c4048a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/mapper/ClaimUtils.java ---------------------------------------------------------------------- diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/mapper/ClaimUtils.java b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/mapper/ClaimUtils.java index b30354f..597fb66 100644 --- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/mapper/ClaimUtils.java +++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/mapper/ClaimUtils.java @@ -24,6 +24,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Map; +import java.util.StringTokenizer; import org.apache.cxf.sts.claims.ProcessedClaim; import org.apache.cxf.sts.claims.ProcessedClaimCollection; @@ -278,4 +279,63 @@ public class ClaimUtils { return processedClaim; } + /** + * This function is especially useful if multi values from a claim are stored within a single value entry. + * + * For example multi user roles could all be stored in a single value element separated by comma: + * USER,MANAGER,ADMIN + * The result of this function will provide a claim with three distinct values: + * USER and MANAGER and ADMIN. + * + * @param processedClaim claim containing multi-values in a single value entry + * @param delimiter Delimiter to split multi-values into single values + * @return Returns a Processed Claim containing only single values per value entry + */ + public ProcessedClaim singleToMultiValue(ProcessedClaim processedClaim, String delimiter) { + if (processedClaim != null && processedClaim.getValues() != null) { + List<Object> oldValues = processedClaim.getValues(); + List<Object> newValues = new ArrayList<Object>(); + for (Object value : oldValues) { + String multivalue = value.toString(); + StringTokenizer st = new StringTokenizer(multivalue, delimiter); + while (st.hasMoreTokens()) { + newValues.add(st.nextToken()); + } + } + processedClaim.getValues().clear(); + processedClaim.getValues().addAll(newValues); + } + return processedClaim; + } + + /** + * This function is especially useful if values from multiple claim values need to be condensed into a + * single value element. + * + * For example a user has three roles: USER and MANAGER and ADMIN. If ',' is used as a delimiter, + * then this method would provide the following claim with only a single value looking like this: + * USER,MANAGER,ADMIN + * + * @param processedClaim claim containing multi-values + * @param delimiter Delimiter to concatenate multi-values into a single value + * @return Returns a Processed Claim containing only one single value + */ + public ProcessedClaim multiToSingleValue(ProcessedClaim processedClaim, String delimiter) { + if (processedClaim != null && processedClaim.getValues() != null) { + List<Object> oldValues = processedClaim.getValues(); + boolean first = true; + StringBuilder sb = new StringBuilder(); + for (Object value : oldValues) { + if (first) { + sb.append(value); + first = false; + } else { + sb.append(delimiter).append(value); + } + } + processedClaim.getValues().clear(); + processedClaim.getValues().add(sb.toString()); + } + return processedClaim; + } } http://git-wip-us.apache.org/repos/asf/cxf/blob/84c4048a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/mapper/JexlClaimsMapper.java ---------------------------------------------------------------------- diff --git a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/mapper/JexlClaimsMapper.java b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/mapper/JexlClaimsMapper.java index 8fbe59f..796e50c 100644 --- a/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/mapper/JexlClaimsMapper.java +++ b/services/sts/sts-core/src/main/java/org/apache/cxf/sts/claims/mapper/JexlClaimsMapper.java @@ -51,6 +51,14 @@ public class JexlClaimsMapper implements ClaimsMapper { functions.put("claims", new ClaimUtils()); jexl.setFunctions(functions); } + + public JexlClaimsMapper(String script) throws IOException { + this(); + + if (script != null) { + setScript(script); + } + } public ProcessedClaimCollection mapClaims(String sourceRealm, ProcessedClaimCollection sourceClaims, String targetRealm, ClaimsParameters parameters) { http://git-wip-us.apache.org/repos/asf/cxf/blob/84c4048a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/claims/mapper/JexlClaimsMapperTest.java ---------------------------------------------------------------------- diff --git a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/claims/mapper/JexlClaimsMapperTest.java b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/claims/mapper/JexlClaimsMapperTest.java index cec247a..c621806 100644 --- a/services/sts/sts-core/src/test/java/org/apache/cxf/sts/claims/mapper/JexlClaimsMapperTest.java +++ b/services/sts/sts-core/src/test/java/org/apache/cxf/sts/claims/mapper/JexlClaimsMapperTest.java @@ -165,6 +165,30 @@ public class JexlClaimsMapperTest extends org.junit.Assert { assertEquals(1, claim.getValues().size()); assertEquals("[email protected]", claim.getValues().get(0)); } + + @Test + public void testSingleToMultiValue() throws IOException { + ProcessedClaimCollection result = jcm.mapClaims("A", createClaimCollection(), "B", createProperties()); + + assertNotNull(result); + ProcessedClaim claim = findClaim(result, "http://my.schema.org/identity/claims/single2multi"); + assertNotNull(claim); + assertNotNull(claim.getValues()); + assertEquals(3, claim.getValues().size()); + assertEquals("Value2", claim.getValues().get(1)); + } + + @Test + public void testMultiToSingleValue() throws IOException { + ProcessedClaimCollection result = jcm.mapClaims("A", createClaimCollection(), "B", createProperties()); + + assertNotNull(result); + ProcessedClaim claim = findClaim(result, "http://my.schema.org/identity/claims/multi2single"); + assertNotNull(claim); + assertNotNull(claim.getValues()); + assertEquals(1, claim.getValues().size()); + assertEquals("Value1,Value2,Value3", claim.getValues().get(0)); + } @SuppressWarnings("unchecked") protected ProcessedClaimCollection createClaimCollection() { @@ -220,5 +244,5 @@ public class JexlClaimsMapperTest extends org.junit.Assert { } return null; } - + } http://git-wip-us.apache.org/repos/asf/cxf/blob/84c4048a/services/sts/sts-core/src/test/resources/jexlClaimMappingsWithFunctions.script ---------------------------------------------------------------------- diff --git a/services/sts/sts-core/src/test/resources/jexlClaimMappingsWithFunctions.script b/services/sts/sts-core/src/test/resources/jexlClaimMappingsWithFunctions.script index af5bb35..21a606b 100644 --- a/services/sts/sts-core/src/test/resources/jexlClaimMappingsWithFunctions.script +++ b/services/sts/sts-core/src/test/resources/jexlClaimMappingsWithFunctions.script @@ -48,9 +48,16 @@ var emailClaimType = 'http://schemas.xmlsoap.org/ws/2005/05/identity/claims/mail'; var emailClaim = claims:get(sourceClaims, emailClaimType); + // Claim value delimiter + var singleValue = claims:create("http://my.schema.org/identity/claims/single2multi", "Value1,Value2,Value3"); + claims:singleToMultiValue(singleValue, ","); + var multiValue = claims:create("http://my.schema.org/identity/claims/multi2single", "Value1", "Value2", "Value3"); + claims:multiToSingleValue(multiValue, ","); + // Collect claims for new token claims:add(targetClaims, mappedRoles, mergedClaim, idpClaim); claims:add(targetClaims, uppercaseClaim, lowercaseClaim, wrappedUppercaseClaim, emailClaim); + claims:add(targetClaims, singleValue, multiValue); // Set correct issuer claims:updateIssuer(targetClaims, claimsParameters.stsProperties.issuer); http://git-wip-us.apache.org/repos/asf/cxf/blob/84c4048a/services/sts/sts-core/src/test/resources/jexlClaimMappingsWithoutFunctions.script ---------------------------------------------------------------------- diff --git a/services/sts/sts-core/src/test/resources/jexlClaimMappingsWithoutFunctions.script b/services/sts/sts-core/src/test/resources/jexlClaimMappingsWithoutFunctions.script index 6b5c4f3..1eeb5ee 100644 --- a/services/sts/sts-core/src/test/resources/jexlClaimMappingsWithoutFunctions.script +++ b/services/sts/sts-core/src/test/resources/jexlClaimMappingsWithoutFunctions.script @@ -113,6 +113,34 @@ targetClaims.add(c); } } + + // Claim value delimiter + var single2multi = new("org.apache.cxf.sts.claims.ProcessedClaim"); + single2multi.claimType = new("java.net.URI", "http://my.schema.org/identity/claims/single2multi"); + single2multi.values.add("Value1,Value2,Value3"); + var newValues = new("java.util.ArrayList"); + var multiValueArray = single2multi.values[0].split(","); + for (v : multiValueArray) { + newValues.add(v); + } + single2multi.values = newValues; + targetClaims.add(single2multi); + + var multi2single = new("org.apache.cxf.sts.claims.ProcessedClaim"); + multi2single.claimType = new("java.net.URI", "http://my.schema.org/identity/claims/multi2single"); + multi2single.values.add("Value1"); + multi2single.values.add("Value2"); + multi2single.values.add("Value3"); + var newValue = ""; + var newValues = new("java.util.ArrayList"); + for (v : multi2single.values) { + newValue = newValue + "," + v; + } + newValues.add(newValue.substring(1)); + multi2single.values = newValues; + targetClaims.add(multi2single); + + // Set correct issuer for (c : targetClaims) {
