-
Notifications
You must be signed in to change notification settings - Fork 540
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
In-Memory Claim Management #6007
base: master
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #6007 +/- ##
============================================
+ Coverage 40.23% 40.61% +0.38%
- Complexity 14223 14748 +525
============================================
Files 1734 1743 +9
Lines 117149 122670 +5521
Branches 20155 21981 +1826
============================================
+ Hits 47134 49827 +2693
- Misses 62761 65317 +2556
- Partials 7254 7526 +272
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
78bc0c4
to
90268d2
Compare
PR builder started |
...data.mgt/src/main/java/org/wso2/carbon/identity/claim/metadata/mgt/ClaimMetadataManager.java
Outdated
Show resolved
Hide resolved
PR builder completed |
PR builder started |
PR builder completed |
...adata.mgt/src/main/java/org/wso2/carbon/identity/claim/metadata/mgt/ClaimMetadataReader.java
Show resolved
Hide resolved
|
||
import java.util.List; | ||
|
||
public interface ClaimMetadataReader { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add class comment
...adata.mgt/src/main/java/org/wso2/carbon/identity/claim/metadata/mgt/ClaimMetadataWriter.java
Show resolved
Hide resolved
...adata.mgt/src/main/java/org/wso2/carbon/identity/claim/metadata/mgt/ClaimMetadataWriter.java
Show resolved
Hide resolved
void addExternalClaim(ExternalClaim externalClaim, int tenantId) | ||
throws ClaimMetadataException; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check formatting
if (claimURI == null || StringUtils.isBlank(claimURI)) { | ||
return null; | ||
} | ||
|
||
return this.externalClaimDAO.getExternalClaims(externalClaimDialectURI, tenantId).stream() | ||
.filter(externalClaim -> claimURI.equals(externalClaim.getClaimURI())) | ||
.findFirst().orElse(null); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check the previous comment
...main/java/org/wso2/carbon/identity/claim/metadata/mgt/SystemDefaultClaimMetadataManager.java
Show resolved
Hide resolved
claims = new HashMap<>(); | ||
|
||
ClaimConfig claimConfig = IdentityClaimManagementServiceDataHolder.getInstance().getClaimConfig(); | ||
if (claimConfig != null && claimConfig.getClaimMap() != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can use MapUtils
for (Map.Entry<ClaimKey, ClaimMapping> entry : claimConfig.getClaimMap().entrySet()) { | ||
ClaimKey claimKey = entry.getKey(); | ||
ClaimMapping claimMapping = entry.getValue(); | ||
String claimDialectURI = claimKey.getDialectUri(); | ||
String claimURI = claimKey.getClaimUri(); | ||
Claim claim; | ||
|
||
boolean dialectExists = claimDialects.stream() | ||
.anyMatch(claimDialect -> claimDialect.getClaimDialectURI().equals(claimDialectURI)); | ||
if (!dialectExists) { | ||
claimDialects.add(new ClaimDialect(claimDialectURI)); | ||
} | ||
|
||
if (claimDialectURI.equals(LOCAL_CLAIM_DIALECT_URI)) { | ||
List<AttributeMapping> mappedAttributes = new ArrayList<>(); | ||
if (StringUtils.isNotBlank(claimMapping.getMappedAttribute())) { | ||
mappedAttributes | ||
.add(new AttributeMapping(primaryDomainName, claimMapping.getMappedAttribute())); | ||
} | ||
|
||
if (claimMapping.getMappedAttributes() != null) { | ||
for (Map.Entry<String, String> claimMappingEntry : claimMapping.getMappedAttributes() | ||
.entrySet()) { | ||
mappedAttributes.add(new AttributeMapping(claimMappingEntry.getKey(), | ||
claimMappingEntry.getValue())); | ||
} | ||
} | ||
|
||
Map<String, String> claimProperties = filterClaimProperties(claimConfig.getPropertyHolderMap() | ||
.get(claimKey)); | ||
claim = new LocalClaim(claimURI, mappedAttributes, claimProperties); | ||
} else { | ||
String mappedLocalClaimURI = claimConfig.getPropertyHolderMap().get(claimKey).get(ClaimConstants | ||
.MAPPED_LOCAL_CLAIM_PROPERTY); | ||
Map<String, String> claimProperties = filterClaimProperties(claimConfig.getPropertyHolderMap() | ||
.get(claimKey)); | ||
claim = new ExternalClaim(claimDialectURI, claimURI, mappedLocalClaimURI, claimProperties); | ||
} | ||
claims.computeIfAbsent(claimDialectURI, k -> new ArrayList<>()); | ||
claims.get(claimDialectURI).add(claim); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's refactor this. can simplify the nesting / extract out the finding mapped attributes part to a helper method to improve readability.
if (claimDialectURI == null || StringUtils.isBlank(claimDialectURI)) { | ||
return null; | ||
} | ||
|
||
return claimDialects.stream() | ||
.filter(claimDialect -> claimDialectURI.equals(claimDialect.getClaimDialectURI())) | ||
.findFirst() | ||
.orElse(null); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refer to previous comments about returning null
Quality Gate passedIssues Measures |
public void updateLocalClaimMappings(List<LocalClaim> localClaimList, int tenantId, String userStoreDomain) | ||
throws ClaimMetadataException { | ||
|
||
if (!localClaimList.isEmpty() && !isClaimDialectInDB(ClaimConstants.LOCAL_CLAIM_DIALECT_URI, tenantId)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
prone to NPEs. will need to check if localClaimList is not null, before calling isEmpty() on it.
|
||
List<ClaimDialect> claimDialectsInDB = this.dbBasedClaimMetadataManager.getClaimDialects(tenantId); | ||
List<ClaimDialect> claimDialectsInSystem = this.systemDefaultClaimMetadataManager.getClaimDialects(tenantId); | ||
Set<String> claimDialectURIsInDB = claimDialectsInDB.stream() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are claimDialectsInDB and claimDialectsInSystem null safe? if not get them as Optional.OfNullable before streaming
@Override | ||
public boolean isMappedLocalClaim(String localClaimURI, int tenantId) throws ClaimMetadataException { | ||
|
||
if (localClaimURI == null || StringUtils.isBlank(localClaimURI)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
explicit null check is redundant
continue; | ||
} | ||
List<Claim> externalClaims = entry.getValue().stream() | ||
.map(ExternalClaim.class::cast) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to avoid potential class cast exceptions, we can use a instanceof filter before casting
.filter(claim -> claim instanceof ExternalClaim) .map(claim -> (ExternalClaim) claim)
.map(ExternalClaim.class::cast) | ||
.filter(claim -> localClaimURI.equals(claim.getMappedLocalClaim())) | ||
.collect(Collectors.toList()); | ||
if (!externalClaims.isEmpty()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
instead of collecting and checking if it's empty, can't we use anyMatch() and terminate early?
@Override | ||
public boolean isLocalClaimMappedWithinDialect(String mappedLocalClaim, String externalClaimDialectURI, int tenantId) throws ClaimMetadataException { | ||
|
||
if (externalClaimDialectURI == null || StringUtils.isBlank(externalClaimDialectURI) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
explicit null check is redundant. StringUtils.isBlank does this
|| !claims.containsKey(externalClaimDialectURI)) { | ||
return false; | ||
} | ||
if (mappedLocalClaim == null || StringUtils.isBlank(mappedLocalClaim)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refer to previous comment
claimProperties.put(ClaimConstants.DISPLAY_NAME_PROPERTY, "0"); | ||
} | ||
|
||
if (claimProperties.containsKey(ClaimConstants.SUPPORTED_BY_DEFAULT_PROPERTY)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can use computeIfAbsent
} | ||
} | ||
|
||
if (claimProperties.containsKey(ClaimConstants.READ_ONLY_PROPERTY)) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
refer to previous comment
Proposed changes in this pull request
Class Diagram
Note: When adding updates to the database, parent entities need to be added as pre-requisites. This is intentionally handled in a non-transactional manner since it will not cause any data inconsistencies or produce stale data.
eg: When adding a claim, its dialect need to be added to the database if it is not already present. This is not handled as a single transaction.
Related Issue
When should this PR be merged
[Please describe any preconditions that need to be addressed before we
can merge this pull request.]
Follow up actions
[List any possible follow-up actions here; for instance, testing data
migrations, software that we need to install on staging and production
environments.]
Checklist (for reviewing)
General
Functionality
Code
Tests
Security
Documentation