-
-
Notifications
You must be signed in to change notification settings - Fork 10.2k
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
refactor: removed some code smells from few classes #5284
base: master
Are you sure you want to change the base?
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -18,33 +18,49 @@ | |
|
||
import static com.ctrip.framework.apollo.portal.service.SystemRoleManagerService.SYSTEM_PERMISSION_TARGET_ID; | ||
|
||
import com.ctrip.framework.apollo.openapi.entity.ConsumerRole; | ||
import com.ctrip.framework.apollo.openapi.repository.ConsumerRoleRepository; | ||
import com.ctrip.framework.apollo.openapi.service.ConsumerRolePermissionService; | ||
import com.ctrip.framework.apollo.openapi.util.ConsumerAuthUtil; | ||
import com.ctrip.framework.apollo.portal.constant.PermissionType; | ||
import com.ctrip.framework.apollo.portal.entity.po.Permission; | ||
import com.ctrip.framework.apollo.portal.entity.po.RolePermission; | ||
import com.ctrip.framework.apollo.portal.repository.PermissionRepository; | ||
import com.ctrip.framework.apollo.portal.repository.RolePermissionRepository; | ||
import com.ctrip.framework.apollo.portal.util.RoleUtils; | ||
import com.nimbusds.oauth2.sdk.util.CollectionUtils; | ||
import org.springframework.stereotype.Component; | ||
import javax.servlet.http.HttpServletRequest; | ||
import java.util.List; | ||
import java.util.Set; | ||
import java.util.stream.Collectors; | ||
|
||
@Component | ||
public class ConsumerPermissionValidator { | ||
|
||
private final ConsumerRolePermissionService permissionService; | ||
private final ConsumerAuthUtil consumerAuthUtil; | ||
private final RolePermissionRepository rolePermissionRepository; | ||
private final ConsumerRoleRepository consumerRoleRepository; | ||
private final PermissionRepository permissionRepository; | ||
|
||
public ConsumerPermissionValidator(final ConsumerRolePermissionService permissionService, | ||
final ConsumerAuthUtil consumerAuthUtil) { | ||
this.permissionService = permissionService; | ||
public ConsumerPermissionValidator(final ConsumerAuthUtil consumerAuthUtil, | ||
final RolePermissionRepository rolePermissionRepository | ||
, final ConsumerRoleRepository consumerRoleRepository, | ||
final PermissionRepository permissionRepository) { | ||
this.consumerAuthUtil = consumerAuthUtil; | ||
this.rolePermissionRepository = rolePermissionRepository; | ||
this.consumerRoleRepository = consumerRoleRepository; | ||
this.permissionRepository = permissionRepository; | ||
} | ||
|
||
public boolean hasModifyNamespacePermission(HttpServletRequest request, String appId, | ||
String namespaceName, String env) { | ||
if (hasCreateNamespacePermission(request, appId)) { | ||
return true; | ||
} | ||
return permissionService.consumerHasPermission(consumerAuthUtil.retrieveConsumerId(request), | ||
return consumerHasPermission(consumerAuthUtil.retrieveConsumerId(request), | ||
PermissionType.MODIFY_NAMESPACE, RoleUtils.buildNamespaceTargetId(appId, namespaceName)) | ||
|| permissionService.consumerHasPermission(consumerAuthUtil.retrieveConsumerId(request), | ||
|| consumerHasPermission(consumerAuthUtil.retrieveConsumerId(request), | ||
PermissionType.MODIFY_NAMESPACE, | ||
RoleUtils.buildNamespaceTargetId(appId, namespaceName, env)); | ||
|
||
|
@@ -55,26 +71,54 @@ public boolean hasReleaseNamespacePermission(HttpServletRequest request, String | |
if (hasCreateNamespacePermission(request, appId)) { | ||
return true; | ||
} | ||
return permissionService.consumerHasPermission(consumerAuthUtil.retrieveConsumerId(request), | ||
return consumerHasPermission(consumerAuthUtil.retrieveConsumerId(request), | ||
PermissionType.RELEASE_NAMESPACE, RoleUtils.buildNamespaceTargetId(appId, namespaceName)) | ||
|| permissionService.consumerHasPermission(consumerAuthUtil.retrieveConsumerId(request), | ||
|| consumerHasPermission(consumerAuthUtil.retrieveConsumerId(request), | ||
PermissionType.RELEASE_NAMESPACE, | ||
RoleUtils.buildNamespaceTargetId(appId, namespaceName, env)); | ||
|
||
} | ||
|
||
public boolean hasCreateNamespacePermission(HttpServletRequest request, String appId) { | ||
return permissionService.consumerHasPermission(consumerAuthUtil.retrieveConsumerId(request), | ||
return consumerHasPermission(consumerAuthUtil.retrieveConsumerId(request), | ||
PermissionType.CREATE_NAMESPACE, appId); | ||
} | ||
|
||
public boolean hasCreateClusterPermission(HttpServletRequest request, String appId) { | ||
return permissionService.consumerHasPermission(consumerAuthUtil.retrieveConsumerId(request), | ||
return consumerHasPermission(consumerAuthUtil.retrieveConsumerId(request), | ||
PermissionType.CREATE_CLUSTER, appId); | ||
} | ||
|
||
public boolean hasCreateApplicationPermission(HttpServletRequest request) { | ||
long consumerId = consumerAuthUtil.retrieveConsumerId(request); | ||
return permissionService.consumerHasPermission(consumerId, PermissionType.CREATE_APPLICATION, SYSTEM_PERMISSION_TARGET_ID); | ||
return consumerHasPermission(consumerId, PermissionType.CREATE_APPLICATION, SYSTEM_PERMISSION_TARGET_ID); | ||
} | ||
|
||
public boolean consumerHasPermission(long consumerId, String permissionType, String targetId) { | ||
Permission permission = | ||
permissionRepository.findTopByPermissionTypeAndTargetId(permissionType, targetId); | ||
if (permission == null) { | ||
return false; | ||
} | ||
|
||
List<ConsumerRole> consumerRoles = consumerRoleRepository.findByConsumerId(consumerId); | ||
if (CollectionUtils.isEmpty(consumerRoles)) { | ||
return false; | ||
} | ||
|
||
Set<Long> roleIds = | ||
consumerRoles.stream().map(ConsumerRole::getRoleId).collect(Collectors.toSet()); | ||
List<RolePermission> rolePermissions = rolePermissionRepository.findByRoleIdIn(roleIds); | ||
if (CollectionUtils.isEmpty(rolePermissions)) { | ||
return false; | ||
} | ||
|
||
for (RolePermission rolePermission : rolePermissions) { | ||
if (rolePermission.getPermissionId() == permission.getId()) { | ||
return true; | ||
} | ||
} | ||
|
||
return false; | ||
Comment on lines
+97
to
+122
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🛠️ Refactor suggestion Optimize Database Queries in The Consider refactoring the method as follows: public boolean consumerHasPermission(long consumerId, String permissionType, String targetId) {
Permission permission = permissionRepository.findTopByPermissionTypeAndTargetId(permissionType, targetId);
if (permission == null) {
return false;
}
Set<Long> roleIds = consumerRoleRepository.findByConsumerId(consumerId)
.stream()
.map(ConsumerRole::getRoleId)
.collect(Collectors.toSet());
if (CollectionUtils.isEmpty(roleIds)) {
return false;
}
int count = rolePermissionRepository.countByRoleIdInAndPermissionId(roleIds, permission.getId());
return count > 0;
} This refactoring reduces the number of database queries by:
|
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package com.ctrip.framework.apollo.portal.component.config; | ||
|
||
import com.ctrip.framework.apollo.common.config.RefreshableConfig; | ||
import com.ctrip.framework.apollo.portal.service.PortalDBPropertySource; | ||
import com.google.common.base.Strings; | ||
import org.springframework.stereotype.Component; | ||
|
||
/** | ||
* This class handled email related configs for portalConfig class | ||
*/ | ||
@Component | ||
public class EmailConfig extends RefreshableConfig { | ||
|
||
public EmailConfig(final PortalDBPropertySource portalDBPropertySource) { | ||
super(portalDBPropertySource); | ||
} | ||
|
||
public String emailSender() { | ||
String value = getValue(PortalConfigConstants.EMAIL_SENDER, ""); | ||
return Strings.isNullOrEmpty(value) ? emailConfigUser() : value; | ||
} | ||
|
||
public String emailConfigHost() { | ||
return getValue(PortalConfigConstants.EMAIL_CONFIG_HOST, ""); | ||
} | ||
|
||
public String emailConfigPassword() { | ||
return getValue(PortalConfigConstants.EMAIL_CONFIG_PASSWORD, ""); | ||
} | ||
|
||
public String emailTemplateFramework() { | ||
return getValue(PortalConfigConstants.EMAIL_TEMPLATE_FRAMEWORK, ""); | ||
} | ||
|
||
public String emailReleaseDiffModuleTemplate() { | ||
return getValue(PortalConfigConstants.EMAIL_RELEASE_MODULE_DIFF, ""); | ||
} | ||
|
||
public String emailRollbackDiffModuleTemplate() { | ||
return getValue(PortalConfigConstants.EMAIL_ROLLBACK_MODULE_DIFF, ""); | ||
} | ||
|
||
public String emailGrayRulesModuleTemplate() { | ||
return getValue(PortalConfigConstants.EMAIL_RELEASE_MODULE_RULES, ""); | ||
} | ||
|
||
public String emailConfigUser() { | ||
return getValue(PortalConfigConstants.EMAIL_CONFIG_USER, ""); | ||
} | ||
Comment on lines
+23
to
+49
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Codebase verification Based on the gathered information, I can now provide the final response: Empty email configuration values could lead to SMTP connection failures The DefaultEmailService uses these configurations for SMTP server connection, and empty values for host, user, and password would cause email delivery failures. The email templates are used for building notification emails for release, rollback, and gray deployment events.
🔗 Analysis chainAdd documentation and consider non-empty defaults The configuration methods should:
Let me gather more information about the email configuration constants and their usage in the system. Let me check one more thing about the email service implementation to understand how it handles these configurations. 🏁 Scripts executedThe following scripts were executed for the analysis: Script: #!/bin/bash
# Search for usages of these methods to understand the impact of empty values
rg -t java "emailConfigHost|emailConfigPassword|emailTemplateFramework|emailReleaseDiffModuleTemplate|emailRollbackDiffModuleTemplate|emailGrayRulesModuleTemplate|emailConfigUser" -A 2
Length of output: 11363 Script: #!/bin/bash
# Search for the constants definitions and any validation/checks on empty values
rg -t java "EMAIL_CONFIG_HOST|EMAIL_CONFIG_PASSWORD|EMAIL_TEMPLATE_FRAMEWORK|EMAIL_RELEASE_MODULE_DIFF|EMAIL_ROLLBACK_MODULE_DIFF|EMAIL_RELEASE_MODULE_RULES|EMAIL_CONFIG_USER" -A 2
# Check DefaultEmailService implementation for empty value handling
ast-grep --pattern 'class DefaultEmailService {
$$$
}'
Length of output: 4668 Script: #!/bin/bash
# Check DefaultEmailService for SMTP configuration and error handling
rg -t java -A 10 "class DefaultEmailService"
# Check if there are any default email templates in resources
fd -t f -e html -e ftl -e vm "email"
Length of output: 1513 |
||
|
||
public boolean isEmailEnabled() { | ||
return getBooleanProperty(PortalConfigConstants.EMAIL_ENABLED, false); | ||
} | ||
} |
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.
💡 Codebase verification
Significant breaking changes detected in RefreshableConfig
The verification reveals that this is indeed a breaking change with significant impact:
The changes are breaking because:
getRefreshablePropertySources()
has been removedRefreshablePropertySource
is now mandatoryAll extending classes will need to be modified to:
getRefreshablePropertySources()
RefreshablePropertySource
🔗 Analysis chain
Verify impact of removing abstract modifier
The class has been changed from abstract to concrete, which is a breaking change. This could affect existing subclasses that previously implemented abstract methods.
Also applies to: 40-40
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
Length of output: 67
Script:
Length of output: 501
Script:
Length of output: 8017
Script:
Length of output: 2144