Improve Security Core with lombok (#1591)

Signed-off-by: Marinov Avgustin <Avgustin.Marinov@bosch.com>
This commit is contained in:
Avgustin Marinov
2024-02-03 01:46:22 +02:00
committed by GitHub
parent 791b87b27b
commit ea885d6f61
8 changed files with 38 additions and 463 deletions

View File

@@ -21,6 +21,7 @@ import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.HexFormat;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.eclipse.hawkbit.artifact.repository.model.AbstractDbArtifact;
import org.eclipse.hawkbit.artifact.repository.model.DbArtifactHash;
@@ -32,12 +33,12 @@ import org.springframework.util.StringUtils;
* Abstract utility class for ArtifactRepository implementations with common
* functionality, e.g. computation of hashes.
*/
@Slf4j
public abstract class AbstractArtifactRepository implements ArtifactRepository {
private static final String TEMP_FILE_PREFIX = "tmp";
private static final String TEMP_FILE_SUFFIX = "artifactrepo";
private static final Logger LOG = LoggerFactory.getLogger(AbstractArtifactRepository.class);
@Override
// suppress warning, of not strong enough hashing algorithm, SHA-1 and MD5
// is not used security related
@@ -104,7 +105,7 @@ public abstract class AbstractArtifactRepository implements ArtifactRepository {
try {
Files.deleteIfExists(file.toPath());
} catch (IOException e) {
LOG.error("Could not delete temp file {} ({})", file, e.getMessage());
log.error("Could not delete temp file {} ({})", file, e.getMessage());
}
}

View File

@@ -11,6 +11,8 @@ package org.eclipse.hawkbit.im.authentication;
import java.io.Serializable;
import lombok.Getter;
import lombok.ToString;
import org.springframework.security.authentication.AbstractAuthenticationToken;
/**
@@ -19,7 +21,10 @@ import org.springframework.security.authentication.AbstractAuthenticationToken;
* spring security authentication token details to transport the principal and
* tenant in the security context session.
*/
@Getter
@ToString
public class TenantAwareAuthenticationDetails implements Serializable {
private static final long serialVersionUID = 1L;
private final String tenant;
@@ -37,24 +42,4 @@ public class TenantAwareAuthenticationDetails implements Serializable {
this.tenant = tenant;
this.controller = controller;
}
/**
* @return the tenant
*/
public String getTenant() {
return tenant;
}
/**
* @return the controller
*/
public boolean isController() {
return controller;
}
@Override
public String toString() {
return "TenantAwareAuthenticationDetails [tenant=" + tenant + ", controller=" + controller + "]";
}
}

View File

@@ -12,6 +12,8 @@ package org.eclipse.hawkbit.im.authentication;
import java.util.Collection;
import java.util.Collections;
import lombok.Getter;
import lombok.ToString;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.userdetails.User;
@@ -21,6 +23,8 @@ import org.springframework.security.core.userdetails.User;
* {@link SecurityContext} which contains the user specific attributes.
*
*/
@Getter
@ToString
public class UserPrincipal extends User {
private static final long serialVersionUID = 1L;
@@ -82,26 +86,6 @@ public class UserPrincipal extends User {
this.email = email;
}
public String getFirstname() {
return firstname;
}
public String getLastname() {
return lastname;
}
public String getLoginname() {
return loginname;
}
public String getTenant() {
return tenant;
}
public String getEmail() {
return email;
}
@Override
public boolean isAccountNonExpired() {
return true;

View File

@@ -11,11 +11,16 @@ package org.eclipse.hawkbit.security;
import java.util.List;
import lombok.Data;
import lombok.Getter;
import lombok.ToString;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* The common properties for DDI security.
*/
@Getter
@ConfigurationProperties("hawkbit.server.ddi.security")
public class DdiSecurityProperties {
@@ -36,6 +41,7 @@ public class DdiSecurityProperties {
* SSL session at the reverse proxy but adding request header which contains
* the CN of the certificate.
*/
@Data
public static class Rp {
/**
@@ -53,99 +59,33 @@ public class DdiSecurityProperties {
* client certificate authentication.
*/
private List<String> trustedIPs;
/**
* @return the cnHeader
*/
public String getCnHeader() {
return cnHeader;
}
/**
* @param cnHeader
* the cnHeader to set
*/
public void setCnHeader(final String cnHeader) {
this.cnHeader = cnHeader;
}
/**
* @return the sslIssuerHashHeader
*/
public String getSslIssuerHashHeader() {
return sslIssuerHashHeader;
}
/**
* @param sslIssuerHashHeader
* the sslIssuerHashHeader to set
*/
public void setSslIssuerHashHeader(final String sslIssuerHashHeader) {
this.sslIssuerHashHeader = sslIssuerHashHeader;
}
/**
* @return the trustedIPs
*/
public List<String> getTrustedIPs() {
return trustedIPs;
}
/**
* @param trustedIPs
* the trustedIPs to set
*/
public void setTrustedIPs(final List<String> trustedIPs) {
this.trustedIPs = trustedIPs;
}
}
/**
* DDI Authentication options.
*/
@Data
public static class Authentication {
private final Anonymous anonymous = new Anonymous();
private final Targettoken targettoken = new Targettoken();
private final Gatewaytoken gatewaytoken = new Gatewaytoken();
public Anonymous getAnonymous() {
return anonymous;
}
public Gatewaytoken getGatewaytoken() {
return gatewaytoken;
}
public Targettoken getTargettoken() {
return targettoken;
}
/**
* Target token authentication. Tokens are defined per target.
*
*/
@Data
public static class Targettoken {
/**
* Set to true to enable target token authentication.
*/
private boolean enabled = false;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(final boolean enabled) {
this.enabled = enabled;
}
}
/**
* Gateway token authentication. Tokens are defined per tenant. Use with
* care!
*
* Gateway token authentication. Tokens are defined per tenant. Use with care!
*/
@Data
public static class Gatewaytoken {
/**
@@ -161,60 +101,20 @@ public class DdiSecurityProperties {
/**
* Default gateway token itself.
*/
@ToString.Exclude
private String key = "";
public boolean isEnabled() {
return enabled;
}
public void setEnabled(final boolean enabled) {
this.enabled = enabled;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
public String getKey() {
return key;
}
public void setKey(final String key) {
this.key = key;
}
}
/**
* Anonymous authentication.
*/
@Data
public static class Anonymous {
/**
* Set to true to enable anonymous DDI client authentication.
*/
private boolean enabled = false;
/**
* @param enabled
* the enabled to set
*/
public void setEnabled(final boolean enabled) {
this.enabled = enabled;
}
/**
* @return the enabled
*/
public boolean isEnabled() {
return enabled;
}
}
}
}

View File

@@ -13,12 +13,14 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Security related hawkbit configuration.
*
*/
@Data
@ConfigurationProperties("hawkbit.server.security")
public class HawkbitSecurityProperties {
@@ -53,62 +55,10 @@ public class HawkbitSecurityProperties {
*/
private String basicRealm = "hawkBit";
public boolean isRequireSsl() {
return requireSsl;
}
public void setRequireSsl(final boolean requireSsl) {
this.requireSsl = requireSsl;
}
public List<String> getAllowedHostNames() {
return allowedHostNames;
}
public void setAllowedHostNames(final List<String> allowedHostNames) {
this.allowedHostNames = allowedHostNames;
}
public List<String> getHttpFirewallIgnoredPaths() {
return httpFirewallIgnoredPaths;
}
public void setHttpFirewallIgnoredPaths(final List<String> httpFirewallIgnoredPaths) {
this.httpFirewallIgnoredPaths = httpFirewallIgnoredPaths;
}
public String getBasicRealm() {
return basicRealm;
}
public void setBasicRealm(final String basicRealm) {
this.basicRealm = basicRealm;
}
public String getContentSecurityPolicy() {
return contentSecurityPolicy;
}
public void setContentSecurityPolicy(final String contentSecurityPolicy) {
this.contentSecurityPolicy = contentSecurityPolicy;
}
public Dos getDos() {
return dos;
}
public Clients getClients() {
return clients;
}
public Cors getCors() {
return cors;
}
/**
* Security configuration related to CORS.
*
*/
@Data
public static class Cors {
/**
@@ -135,52 +85,12 @@ public class HawkbitSecurityProperties {
* Exposed headers for CORS.
*/
private List<String> exposedHeaders = Collections.emptyList();
public boolean isEnabled() {
return enabled;
}
public void setEnabled(final boolean enabled) {
this.enabled = enabled;
}
public List<String> getAllowedOrigins() {
return allowedOrigins;
}
public void setAllowedOrigins(final List<String> allowedOrigins) {
this.allowedOrigins = allowedOrigins;
}
public List<String> getAllowedHeaders() {
return allowedHeaders;
}
public void setAllowedHeaders(final List<String> allowedHeaders) {
this.allowedHeaders = allowedHeaders;
}
public List<String> getAllowedMethods() {
return allowedMethods;
}
public void setAllowedMethods(final List<String> allowedMethods) {
this.allowedMethods = allowedMethods;
}
public List<String> getExposedHeaders() {
return exposedHeaders;
}
public void setExposedHeaders(final List<String> exposedHeaders) {
this.exposedHeaders = exposedHeaders;
}
}
/**
* Security configuration related to clients.
*
*/
@Data
public static class Clients {
public static final String X_FORWARDED_FOR = "X-Forwarded-For";
@@ -199,36 +109,12 @@ public class HawkbitSecurityProperties {
* Set to <code>true</code> if DDI clients remote IP should be stored.
*/
private boolean trackRemoteIp = true;
public String getBlacklist() {
return blacklist;
}
public void setBlacklist(final String blacklist) {
this.blacklist = blacklist;
}
public String getRemoteIpHeader() {
return remoteIpHeader;
}
public void setRemoteIpHeader(final String remoteIpHeader) {
this.remoteIpHeader = remoteIpHeader;
}
public boolean isTrackRemoteIp() {
return trackRemoteIp;
}
public void setTrackRemoteIp(final boolean trackRemoteIp) {
this.trackRemoteIp = trackRemoteIp;
}
}
/**
* Denial of service protection related properties.
*
*/
@Data
public static class Dos {
/**
@@ -322,159 +208,14 @@ public class HawkbitSecurityProperties {
private final Filter filter = new Filter();
private final Filter uiFilter = new Filter();
public Filter getUiFilter() {
return uiFilter;
}
public Filter getFilter() {
return filter;
}
public int getMaxStatusEntriesPerAction() {
return maxStatusEntriesPerAction;
}
public void setMaxStatusEntriesPerAction(final int maxStatusEntriesPerAction) {
this.maxStatusEntriesPerAction = maxStatusEntriesPerAction;
}
public int getMaxMessagesPerActionStatus() {
return maxMessagesPerActionStatus;
}
public void setMaxMessagesPerActionStatus(final int maxMessagesPerActionStatus) {
this.maxMessagesPerActionStatus = maxMessagesPerActionStatus;
}
public int getMaxAttributeEntriesPerTarget() {
return maxAttributeEntriesPerTarget;
}
public void setMaxAttributeEntriesPerTarget(final int maxAttributeEntriesPerTarget) {
this.maxAttributeEntriesPerTarget = maxAttributeEntriesPerTarget;
}
public int getMaxRolloutGroupsPerRollout() {
return maxRolloutGroupsPerRollout;
}
public void setMaxRolloutGroupsPerRollout(final int maxRolloutGroupsPerRollout) {
this.maxRolloutGroupsPerRollout = maxRolloutGroupsPerRollout;
}
public int getMaxMetaDataEntriesPerSoftwareModule() {
return maxMetaDataEntriesPerSoftwareModule;
}
public void setMaxMetaDataEntriesPerSoftwareModule(final int maxMetaDataEntriesPerSoftwareModule) {
this.maxMetaDataEntriesPerSoftwareModule = maxMetaDataEntriesPerSoftwareModule;
}
public int getMaxMetaDataEntriesPerDistributionSet() {
return maxMetaDataEntriesPerDistributionSet;
}
public void setMaxMetaDataEntriesPerDistributionSet(final int maxMetaDataEntriesPerDistributionSet) {
this.maxMetaDataEntriesPerDistributionSet = maxMetaDataEntriesPerDistributionSet;
}
public int getMaxMetaDataEntriesPerTarget() {
return maxMetaDataEntriesPerTarget;
}
public void setMaxMetaDataEntriesPerTarget(final int maxMetaDataEntriesPerTarget) {
this.maxMetaDataEntriesPerTarget = maxMetaDataEntriesPerTarget;
}
public int getMaxSoftwareModulesPerDistributionSet() {
return maxSoftwareModulesPerDistributionSet;
}
public void setMaxSoftwareModulesPerDistributionSet(final int maxSoftwareModulesPerDistributionSet) {
this.maxSoftwareModulesPerDistributionSet = maxSoftwareModulesPerDistributionSet;
}
public int getMaxSoftwareModuleTypesPerDistributionSetType() {
return maxSoftwareModuleTypesPerDistributionSetType;
}
public void setMaxSoftwareModuleTypesPerDistributionSetType(
final int maxSoftwareModuleTypesPerDistributionSetType) {
this.maxSoftwareModuleTypesPerDistributionSetType = maxSoftwareModuleTypesPerDistributionSetType;
}
public int getMaxArtifactsPerSoftwareModule() {
return maxArtifactsPerSoftwareModule;
}
public void setMaxArtifactsPerSoftwareModule(final int maxArtifactsPerSoftwareModule) {
this.maxArtifactsPerSoftwareModule = maxArtifactsPerSoftwareModule;
}
public int getMaxTargetsPerRolloutGroup() {
return maxTargetsPerRolloutGroup;
}
public void setMaxTargetsPerRolloutGroup(final int maxTargetsPerRolloutGroup) {
this.maxTargetsPerRolloutGroup = maxTargetsPerRolloutGroup;
}
public int getMaxActionsPerTarget() {
return maxActionsPerTarget;
}
public void setMaxActionsPerTarget(final int maxActionsPerTarget) {
this.maxActionsPerTarget = maxActionsPerTarget;
}
public int getMaxTargetDistributionSetAssignmentsPerManualAssignment() {
return maxTargetDistributionSetAssignmentsPerManualAssignment;
}
public void setMaxTargetDistributionSetAssignmentsPerManualAssignment(
final int maxTargetDistributionSetAssignmentsPerManualAssignment) {
this.maxTargetDistributionSetAssignmentsPerManualAssignment = maxTargetDistributionSetAssignmentsPerManualAssignment;
}
public int getMaxTargetsPerAutoAssignment() {
return maxTargetsPerAutoAssignment;
}
public void setMaxTargetsPerAutoAssignment(final int maxTargetsPerAutoAssignment) {
this.maxTargetsPerAutoAssignment = maxTargetsPerAutoAssignment;
}
public void setMaxArtifactSize(final long maxArtifactSize) {
this.maxArtifactSize = maxArtifactSize;
}
public long getMaxArtifactSize() {
return maxArtifactSize;
}
public long getMaxArtifactStorage() {
return maxArtifactStorage;
}
public void setMaxArtifactStorage(final long maxArtifactStorage) {
this.maxArtifactStorage = maxArtifactStorage;
}
public int getMaxDistributionSetTypesPerTargetType() {
return maxDistributionSetTypesPerTargetType;
}
public void setMaxDistributionSetTypesPerTargetType(final int maxDistributionSetTypesPerTargetType) {
this.maxDistributionSetTypesPerTargetType = maxDistributionSetTypesPerTargetType;
}
/**
* Configuration for hawkBits DOS prevention filter. This is usually an
* infrastructure topic (e.g. Web Application Firewall (WAF)) but might
* be useful in some cases, e.g. to prevent unintended misuse.
*
*/
@Data
public static class Filter {
/**
* True if filter is enabled.
*/
@@ -497,40 +238,6 @@ public class HawkbitSecurityProperties {
* second per client IP.
*/
private int maxWrite = 50;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(final boolean enabled) {
this.enabled = enabled;
}
public String getWhitelist() {
return whitelist;
}
public void setWhitelist(final String whitelist) {
this.whitelist = whitelist;
}
public int getMaxRead() {
return maxRead;
}
public void setMaxRead(final int maxRead) {
this.maxRead = maxRead;
}
public int getMaxWrite() {
return maxWrite;
}
public void setMaxWrite(final int maxWrite) {
this.maxWrite = maxWrite;
}
}
}
}

View File

@@ -43,5 +43,4 @@ public class InMemoryUserAuthoritiesResolver implements UserAuthoritiesResolver
}
return authorities;
}
}
}

View File

@@ -18,6 +18,7 @@ import java.util.concurrent.Callable;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
import org.eclipse.hawkbit.tenancy.TenantAware;
@@ -34,10 +35,9 @@ import org.springframework.security.core.context.SecurityContextImpl;
/**
* A Service which provide to run system code.
*/
@Slf4j
public class SystemSecurityContext {
private static final Logger LOG = LoggerFactory.getLogger(SystemSecurityContext.class);
private final TenantAware tenantAware;
/**
@@ -99,7 +99,7 @@ public class SystemSecurityContext {
public <T> T runAsSystemAsTenant(final Callable<T> callable, final String tenant) {
final SecurityContext oldContext = SecurityContextHolder.getContext();
try {
LOG.debug("entering system code execution");
log.debug("entering system code execution");
return tenantAware.runAsTenant(tenant, () -> {
try {
setSystemContext(SecurityContextHolder.getContext());
@@ -114,7 +114,7 @@ public class SystemSecurityContext {
} finally {
SecurityContextHolder.setContext(oldContext);
LOG.debug("leaving system code execution");
log.debug("leaving system code execution");
}
}

View File

@@ -22,5 +22,4 @@ public class UrlUtils {
public static String decodeUriValue(String value) {
return UriUtils.decode(value, StandardCharsets.UTF_8);
}
}
}