Merge pull request #120 from bsinno/Download_server_supports_download_through_HTTP_and_HTTPs
DDI supports actifact download through http and anonyomous
This commit is contained in:
@@ -10,7 +10,6 @@ package org.eclipse.hawkbit.autoconfigure.security;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.util.Collections;
|
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.servlet.Filter;
|
import javax.servlet.Filter;
|
||||||
@@ -35,6 +34,7 @@ import org.eclipse.hawkbit.security.ControllerTenantAwareAuthenticationDetailsSo
|
|||||||
import org.eclipse.hawkbit.security.DdiSecurityProperties;
|
import org.eclipse.hawkbit.security.DdiSecurityProperties;
|
||||||
import org.eclipse.hawkbit.security.DosFilter;
|
import org.eclipse.hawkbit.security.DosFilter;
|
||||||
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
import org.eclipse.hawkbit.security.HawkbitSecurityProperties;
|
||||||
|
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticateAnonymousDownloadFilter;
|
||||||
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticateSecurityTokenFilter;
|
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticateSecurityTokenFilter;
|
||||||
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticatedGatewaySecurityTokenFilter;
|
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticatedGatewaySecurityTokenFilter;
|
||||||
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticatedSecurityHeaderFilter;
|
import org.eclipse.hawkbit.security.HttpControllerPreAuthenticatedSecurityHeaderFilter;
|
||||||
@@ -83,6 +83,8 @@ import org.vaadin.spring.security.web.VaadinRedirectStrategy;
|
|||||||
import org.vaadin.spring.security.web.authentication.VaadinAuthenticationSuccessHandler;
|
import org.vaadin.spring.security.web.authentication.VaadinAuthenticationSuccessHandler;
|
||||||
import org.vaadin.spring.security.web.authentication.VaadinUrlAuthenticationSuccessHandler;
|
import org.vaadin.spring.security.web.authentication.VaadinUrlAuthenticationSuccessHandler;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All configurations related to SP authentication and authorization layer.
|
* All configurations related to SP authentication and authorization layer.
|
||||||
*
|
*
|
||||||
@@ -147,6 +149,12 @@ public class SecurityManagedConfiguration {
|
|||||||
gatewaySecurityTokenFilter.setCheckForPrincipalChanges(true);
|
gatewaySecurityTokenFilter.setCheckForPrincipalChanges(true);
|
||||||
gatewaySecurityTokenFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
|
gatewaySecurityTokenFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
|
||||||
|
|
||||||
|
final HttpControllerPreAuthenticateAnonymousDownloadFilter controllerAnonymousDownloadFilter = new HttpControllerPreAuthenticateAnonymousDownloadFilter(
|
||||||
|
tenantConfigurationManagement, tenantAware, systemSecurityContext);
|
||||||
|
controllerAnonymousDownloadFilter.setAuthenticationManager(authenticationManager());
|
||||||
|
controllerAnonymousDownloadFilter.setCheckForPrincipalChanges(true);
|
||||||
|
controllerAnonymousDownloadFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
|
||||||
|
|
||||||
HttpSecurity httpSec = http.csrf().disable().headers()
|
HttpSecurity httpSec = http.csrf().disable().headers()
|
||||||
.addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.DENY)).contentTypeOptions()
|
.addHeaderWriter(new XFrameOptionsHeaderWriter(XFrameOptionsMode.DENY)).contentTypeOptions()
|
||||||
.xssProtection().httpStrictTransportSecurity().and();
|
.xssProtection().httpStrictTransportSecurity().and();
|
||||||
@@ -159,15 +167,17 @@ public class SecurityManagedConfiguration {
|
|||||||
LOG.info(
|
LOG.info(
|
||||||
"******************\n** Anonymous controller security enabled, should only use for developing purposes **\n******************");
|
"******************\n** Anonymous controller security enabled, should only use for developing purposes **\n******************");
|
||||||
final AnonymousAuthenticationFilter anoymousFilter = new AnonymousAuthenticationFilter(
|
final AnonymousAuthenticationFilter anoymousFilter = new AnonymousAuthenticationFilter(
|
||||||
"controllerAnonymousFilter", "anonymous", Collections.singletonList(
|
"controllerAnonymousFilter", "anonymous",
|
||||||
new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS)));
|
Lists.newArrayList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE_ANONYMOUS),
|
||||||
|
new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_DOWNLOAD_ROLE)));
|
||||||
anoymousFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
|
anoymousFilter.setAuthenticationDetailsSource(authenticationDetailsSource);
|
||||||
httpSec.requestMatchers().antMatchers("/*/controller/v1/**", "/*/controller/artifacts/v1/**").and()
|
httpSec.requestMatchers().antMatchers("/*/controller/v1/**", "/*/controller/artifacts/v1/**").and()
|
||||||
.securityContext().disable().anonymous().authenticationFilter(anoymousFilter);
|
.securityContext().disable().anonymous().authenticationFilter(anoymousFilter);
|
||||||
} else {
|
} else {
|
||||||
httpSec.addFilter(securityHeaderFilter).addFilter(securityTokenFilter)
|
httpSec.addFilter(securityHeaderFilter).addFilter(securityTokenFilter)
|
||||||
.addFilter(gatewaySecurityTokenFilter).antMatcher("/*/controller/**").anonymous().disable()
|
.addFilter(gatewaySecurityTokenFilter).addFilter(controllerAnonymousDownloadFilter)
|
||||||
.authorizeRequests().anyRequest().authenticated().and().exceptionHandling()
|
.antMatcher("/*/controller/**").anonymous().disable().authorizeRequests().anyRequest()
|
||||||
|
.authenticated().and().exceptionHandling()
|
||||||
.authenticationEntryPoint((request, response, authException) -> response
|
.authenticationEntryPoint((request, response, authException) -> response
|
||||||
.setStatus(HttpStatus.UNAUTHORIZED.value()))
|
.setStatus(HttpStatus.UNAUTHORIZED.value()))
|
||||||
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
|
.and().sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.api;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface declaration of the {@link ArtifactUrlHandler} which generates the
|
||||||
|
* URLs to specific artifacts.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@FunctionalInterface
|
||||||
|
public interface ArtifactUrlHandler {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a generated download URL for a given artifact parameters for a
|
||||||
|
* specific protocol.
|
||||||
|
*
|
||||||
|
* @param controllerId
|
||||||
|
* the authenticated controller id
|
||||||
|
* @param softwareModuleId
|
||||||
|
* the softwareModuleId belonging to the artifact
|
||||||
|
* @param filename
|
||||||
|
* the filename of the artifact
|
||||||
|
* @param sha1Hash
|
||||||
|
* the sha1Hash of the artifact
|
||||||
|
* @param protocol
|
||||||
|
* the protocol the URL should be generated
|
||||||
|
* @return an URL for the given artifact parameters in a given protocol
|
||||||
|
*/
|
||||||
|
String getUrl(String controllerId, final Long softwareModuleId, final String filename, final String sha1Hash,
|
||||||
|
final UrlProtocol protocol);
|
||||||
|
}
|
||||||
@@ -6,13 +6,13 @@
|
|||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.util;
|
package org.eclipse.hawkbit.api;
|
||||||
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Artifact handler properties class for holding all supported protocols with
|
||||||
*
|
* host, ip, port and download pattern.
|
||||||
*/
|
*/
|
||||||
@ConfigurationProperties("hawkbit.artifact.url")
|
@ConfigurationProperties("hawkbit.artifact.url")
|
||||||
public class ArtifactUrlHandlerProperties {
|
public class ArtifactUrlHandlerProperties {
|
||||||
@@ -23,23 +23,14 @@ public class ArtifactUrlHandlerProperties {
|
|||||||
private final Https https = new Https();
|
private final Https https = new Https();
|
||||||
private final Coap coap = new Coap();
|
private final Coap coap = new Coap();
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the http
|
|
||||||
*/
|
|
||||||
public Http getHttp() {
|
public Http getHttp() {
|
||||||
return http;
|
return http;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the https
|
|
||||||
*/
|
|
||||||
public Https getHttps() {
|
public Https getHttps() {
|
||||||
return https;
|
return https;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the coap
|
|
||||||
*/
|
|
||||||
public Coap getCoap() {
|
public Coap getCoap() {
|
||||||
return coap;
|
return coap;
|
||||||
}
|
}
|
||||||
@@ -66,9 +57,6 @@ public class ArtifactUrlHandlerProperties {
|
|||||||
/**
|
/**
|
||||||
* Interface for declaring common properties through all supported protocols
|
* Interface for declaring common properties through all supported protocols
|
||||||
* pattern.
|
* pattern.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public interface ProtocolProperties {
|
public interface ProtocolProperties {
|
||||||
/**
|
/**
|
||||||
@@ -94,9 +82,6 @@ public class ArtifactUrlHandlerProperties {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Object to hold the properties for the HTTP protocol.
|
* Object to hold the properties for the HTTP protocol.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static class Http implements ProtocolProperties {
|
public static class Http implements ProtocolProperties {
|
||||||
private String hostname = LOCALHOST;
|
private String hostname = LOCALHOST;
|
||||||
@@ -108,66 +93,38 @@ public class ArtifactUrlHandlerProperties {
|
|||||||
*/
|
*/
|
||||||
private String pattern = "{protocol}://{hostname}:{port}/{tenant}/controller/v1/{targetId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}";
|
private String pattern = "{protocol}://{hostname}:{port}/{tenant}/controller/v1/{targetId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}";
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the hostname
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getHostname() {
|
public String getHostname() {
|
||||||
return hostname;
|
return hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param hostname
|
|
||||||
* the hostname to set
|
|
||||||
*/
|
|
||||||
public void setHostname(final String hostname) {
|
public void setHostname(final String hostname) {
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the ip
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getIp() {
|
public String getIp() {
|
||||||
return ip;
|
return ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ip
|
|
||||||
* the ip to set
|
|
||||||
*/
|
|
||||||
public void setIp(final String ip) {
|
public void setIp(final String ip) {
|
||||||
this.ip = ip;
|
this.ip = ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the urlPattern
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getPattern() {
|
public String getPattern() {
|
||||||
return pattern;
|
return pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param urlPattern
|
|
||||||
* the urlPattern to set
|
|
||||||
*/
|
|
||||||
public void setPattern(final String urlPattern) {
|
public void setPattern(final String urlPattern) {
|
||||||
this.pattern = urlPattern;
|
this.pattern = urlPattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the port
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getPort() {
|
public String getPort() {
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param port
|
|
||||||
* the port to set
|
|
||||||
*/
|
|
||||||
public void setPort(final String port) {
|
public void setPort(final String port) {
|
||||||
this.port = port;
|
this.port = port;
|
||||||
}
|
}
|
||||||
@@ -175,9 +132,6 @@ public class ArtifactUrlHandlerProperties {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Object to hold the properties for the HTTP protocol.
|
* Object to hold the properties for the HTTP protocol.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static class Https implements ProtocolProperties {
|
public static class Https implements ProtocolProperties {
|
||||||
private String hostname = LOCALHOST;
|
private String hostname = LOCALHOST;
|
||||||
@@ -189,66 +143,38 @@ public class ArtifactUrlHandlerProperties {
|
|||||||
*/
|
*/
|
||||||
private String pattern = "{protocol}://{hostname}:{port}/{tenant}/controller/v1/{targetId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}";
|
private String pattern = "{protocol}://{hostname}:{port}/{tenant}/controller/v1/{targetId}/softwaremodules/{softwareModuleId}/artifacts/{artifactFileName}";
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the hostname
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getHostname() {
|
public String getHostname() {
|
||||||
return hostname;
|
return hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param hostname
|
|
||||||
* the hostname to set
|
|
||||||
*/
|
|
||||||
public void setHostname(final String hostname) {
|
public void setHostname(final String hostname) {
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the ip
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getIp() {
|
public String getIp() {
|
||||||
return ip;
|
return ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ip
|
|
||||||
* the ip to set
|
|
||||||
*/
|
|
||||||
public void setIp(final String ip) {
|
public void setIp(final String ip) {
|
||||||
this.ip = ip;
|
this.ip = ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the urlPattern
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getPattern() {
|
public String getPattern() {
|
||||||
return pattern;
|
return pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param urlPattern
|
|
||||||
* the urlPattern to set
|
|
||||||
*/
|
|
||||||
public void setPattern(final String urlPattern) {
|
public void setPattern(final String urlPattern) {
|
||||||
this.pattern = urlPattern;
|
this.pattern = urlPattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the port
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getPort() {
|
public String getPort() {
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param port
|
|
||||||
* the port to set
|
|
||||||
*/
|
|
||||||
public void setPort(final String port) {
|
public void setPort(final String port) {
|
||||||
this.port = port;
|
this.port = port;
|
||||||
}
|
}
|
||||||
@@ -256,9 +182,6 @@ public class ArtifactUrlHandlerProperties {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Object to hold the properties for the HTTP protocol.
|
* Object to hold the properties for the HTTP protocol.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public static class Coap implements ProtocolProperties {
|
public static class Coap implements ProtocolProperties {
|
||||||
private String hostname = LOCALHOST;
|
private String hostname = LOCALHOST;
|
||||||
@@ -270,68 +193,41 @@ public class ArtifactUrlHandlerProperties {
|
|||||||
*/
|
*/
|
||||||
private String pattern = "{protocol}://{ip}:{port}/fw/{tenant}/{targetId}/sha1/{artifactSHA1}";
|
private String pattern = "{protocol}://{ip}:{port}/fw/{tenant}/{targetId}/sha1/{artifactSHA1}";
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the hostname
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getHostname() {
|
public String getHostname() {
|
||||||
return hostname;
|
return hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param hostname
|
|
||||||
* the hostname to set
|
|
||||||
*/
|
|
||||||
public void setHostname(final String hostname) {
|
public void setHostname(final String hostname) {
|
||||||
this.hostname = hostname;
|
this.hostname = hostname;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the ip
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getIp() {
|
public String getIp() {
|
||||||
return ip;
|
return ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ip
|
|
||||||
* the ip to set
|
|
||||||
*/
|
|
||||||
public void setIp(final String ip) {
|
public void setIp(final String ip) {
|
||||||
this.ip = ip;
|
this.ip = ip;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the urlPattern
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getPattern() {
|
public String getPattern() {
|
||||||
return pattern;
|
return pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param urlPattern
|
|
||||||
* the urlPattern to set
|
|
||||||
*/
|
|
||||||
public void setPattern(final String urlPattern) {
|
public void setPattern(final String urlPattern) {
|
||||||
this.pattern = urlPattern;
|
this.pattern = urlPattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return the port
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public String getPort() {
|
public String getPort() {
|
||||||
return port;
|
return port;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @param port
|
|
||||||
* the port to set
|
|
||||||
*/
|
|
||||||
public void setPort(final String port) {
|
public void setPort(final String port) {
|
||||||
this.port = port;
|
this.port = port;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -6,17 +6,15 @@
|
|||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.util;
|
package org.eclipse.hawkbit.api;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.dmf.json.model.Artifact;
|
import org.eclipse.hawkbit.api.ArtifactUrlHandlerProperties.ProtocolProperties;
|
||||||
import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.eclipse.hawkbit.util.ArtifactUrlHandlerProperties.ProtocolProperties;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
@@ -24,8 +22,8 @@ import org.springframework.stereotype.Component;
|
|||||||
import com.google.common.base.Strings;
|
import com.google.common.base.Strings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Implementation for ArtifactUrlHandler for creating urls to download resource
|
||||||
*
|
* based on pattern.
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@EnableConfigurationProperties(ArtifactUrlHandlerProperties.class)
|
@EnableConfigurationProperties(ArtifactUrlHandlerProperties.class)
|
||||||
@@ -48,7 +46,9 @@ public class PropertyBasedArtifactUrlHandler implements ArtifactUrlHandler {
|
|||||||
private TenantAware tenantAware;
|
private TenantAware tenantAware;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUrl(final String targetId, final LocalArtifact artifact, final Artifact.UrlProtocol protocol) {
|
public String getUrl(final String targetId, final Long softwareModuleId, final String filename,
|
||||||
|
final String sha1Hash, final UrlProtocol protocol) {
|
||||||
|
|
||||||
final String protocolString = protocol.name().toLowerCase();
|
final String protocolString = protocol.name().toLowerCase();
|
||||||
final ProtocolProperties properties = urlHandlerProperties.getProperties(protocolString);
|
final ProtocolProperties properties = urlHandlerProperties.getProperties(protocolString);
|
||||||
if (properties == null || properties.getPattern() == null) {
|
if (properties == null || properties.getPattern() == null) {
|
||||||
@@ -56,8 +56,8 @@ public class PropertyBasedArtifactUrlHandler implements ArtifactUrlHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String urlPattern = properties.getPattern();
|
String urlPattern = properties.getPattern();
|
||||||
final Set<Entry<String, String>> entrySet = getReplaceMap(targetId, artifact, protocolString, properties)
|
final Set<Entry<String, String>> entrySet = getReplaceMap(targetId, softwareModuleId, filename, sha1Hash,
|
||||||
.entrySet();
|
protocolString, properties).entrySet();
|
||||||
for (final Entry<String, String> entry : entrySet) {
|
for (final Entry<String, String> entry : entrySet) {
|
||||||
if (entry.getKey().equals(PORT_PLACEHOLDER)) {
|
if (entry.getKey().equals(PORT_PLACEHOLDER)) {
|
||||||
urlPattern = urlPattern.replace(":{" + entry.getKey() + "}",
|
urlPattern = urlPattern.replace(":{" + entry.getKey() + "}",
|
||||||
@@ -69,18 +69,18 @@ public class PropertyBasedArtifactUrlHandler implements ArtifactUrlHandler {
|
|||||||
return urlPattern;
|
return urlPattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Map<String, String> getReplaceMap(final String targetId, final LocalArtifact artifact,
|
private Map<String, String> getReplaceMap(final String targetId, final Long softwareModuleId, final String filename,
|
||||||
final String protocol, final ProtocolProperties properties) {
|
final String sha1Hash, final String protocol, final ProtocolProperties properties) {
|
||||||
final Map<String, String> replaceMap = new HashMap<>();
|
final Map<String, String> replaceMap = new HashMap<>();
|
||||||
replaceMap.put(IP_PLACEHOLDER, properties.getIp());
|
replaceMap.put(IP_PLACEHOLDER, properties.getIp());
|
||||||
replaceMap.put(HOSTNAME_PLACEHOLDER, properties.getHostname());
|
replaceMap.put(HOSTNAME_PLACEHOLDER, properties.getHostname());
|
||||||
replaceMap.put(ARTIFACT_FILENAME_PLACEHOLDER, artifact.getFilename());
|
replaceMap.put(ARTIFACT_FILENAME_PLACEHOLDER, filename);
|
||||||
replaceMap.put(ARTIFACT_SHA1_PLACEHOLDER, artifact.getSha1Hash());
|
replaceMap.put(ARTIFACT_SHA1_PLACEHOLDER, sha1Hash);
|
||||||
replaceMap.put(PROTOCOL_PLACEHOLDER, protocol);
|
replaceMap.put(PROTOCOL_PLACEHOLDER, protocol);
|
||||||
replaceMap.put(PORT_PLACEHOLDER, properties.getPort());
|
replaceMap.put(PORT_PLACEHOLDER, properties.getPort());
|
||||||
replaceMap.put(TENANT_PLACEHOLDER, tenantAware.getCurrentTenant());
|
replaceMap.put(TENANT_PLACEHOLDER, tenantAware.getCurrentTenant());
|
||||||
replaceMap.put(TARGET_ID_PLACEHOLDER, targetId);
|
replaceMap.put(TARGET_ID_PLACEHOLDER, targetId);
|
||||||
replaceMap.put(SOFTWARE_MODULE_ID_PLACDEHOLDER, String.valueOf(artifact.getSoftwareModule().getId()));
|
replaceMap.put(SOFTWARE_MODULE_ID_PLACDEHOLDER, String.valueOf(softwareModuleId));
|
||||||
return replaceMap;
|
return replaceMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.api;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represented the supported protocols for artifact url's.
|
||||||
|
*/
|
||||||
|
public enum UrlProtocol {
|
||||||
|
COAP, HTTP, HTTPS
|
||||||
|
}
|
||||||
@@ -30,40 +30,60 @@ public enum TenantConfigurationKey {
|
|||||||
/**
|
/**
|
||||||
* boolean value {@code true} {@code false}.
|
* boolean value {@code true} {@code false}.
|
||||||
*/
|
*/
|
||||||
AUTHENTICATION_MODE_HEADER_ENABLED("authentication.header.enabled", "hawkbit.server.ddi.security.authentication.header.enabled", Boolean.class, Boolean.FALSE.toString(), TenantConfigurationBooleanValidator.class),
|
AUTHENTICATION_MODE_HEADER_ENABLED("authentication.header.enabled",
|
||||||
|
"hawkbit.server.ddi.security.authentication.header.enabled", Boolean.class, Boolean.FALSE.toString(),
|
||||||
|
TenantConfigurationBooleanValidator.class),
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME("authentication.header.authority", "hawkbit.server.ddi.security.authentication.header.authority", String.class, Boolean.FALSE.toString(), TenantConfigurationStringValidator.class),
|
AUTHENTICATION_MODE_HEADER_AUTHORITY_NAME("authentication.header.authority",
|
||||||
|
"hawkbit.server.ddi.security.authentication.header.authority", String.class, Boolean.FALSE.toString(),
|
||||||
|
TenantConfigurationStringValidator.class),
|
||||||
/**
|
/**
|
||||||
* boolean value {@code true} {@code false}.
|
* boolean value {@code true} {@code false}.
|
||||||
*/
|
*/
|
||||||
AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED("authentication.targettoken.enabled", "hawkbit.server.ddi.security.authentication.targettoken.enabled", Boolean.class, Boolean.FALSE.toString(), TenantConfigurationBooleanValidator.class),
|
AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED("authentication.targettoken.enabled",
|
||||||
|
"hawkbit.server.ddi.security.authentication.targettoken.enabled", Boolean.class, Boolean.FALSE.toString(),
|
||||||
|
TenantConfigurationBooleanValidator.class),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* boolean value {@code true} {@code false}.
|
* boolean value {@code true} {@code false}.
|
||||||
*/
|
*/
|
||||||
AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED("authentication.gatewaytoken.enabled", "hawkbit.server.ddi.security.authentication.gatewaytoken.enabled", Boolean.class, Boolean.FALSE.toString(), TenantConfigurationBooleanValidator.class),
|
AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_ENABLED("authentication.gatewaytoken.enabled",
|
||||||
|
"hawkbit.server.ddi.security.authentication.gatewaytoken.enabled", Boolean.class, Boolean.FALSE.toString(),
|
||||||
|
TenantConfigurationBooleanValidator.class),
|
||||||
/**
|
/**
|
||||||
* string value which holds the name of the security token key.
|
* string value which holds the name of the security token key.
|
||||||
*/
|
*/
|
||||||
AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME("authentication.gatewaytoken.name", "hawkbit.server.ddi.security.authentication.gatewaytoken.name", String.class, null, TenantConfigurationStringValidator.class),
|
AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_NAME("authentication.gatewaytoken.name",
|
||||||
|
"hawkbit.server.ddi.security.authentication.gatewaytoken.name", String.class, null,
|
||||||
|
TenantConfigurationStringValidator.class),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* string value which holds the actual security-key of the gateway security
|
* string value which holds the actual security-key of the gateway security
|
||||||
* token.
|
* token.
|
||||||
*/
|
*/
|
||||||
AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY("authentication.gatewaytoken.key", "hawkbit.server.ddi.security.authentication.gatewaytoken.key", String.class, null, TenantConfigurationStringValidator.class),
|
AUTHENTICATION_MODE_GATEWAY_SECURITY_TOKEN_KEY("authentication.gatewaytoken.key",
|
||||||
|
"hawkbit.server.ddi.security.authentication.gatewaytoken.key", String.class, null,
|
||||||
|
TenantConfigurationStringValidator.class),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* string value which holds the polling time interval in the format HH:mm:ss
|
* string value which holds the polling time interval in the format HH:mm:ss
|
||||||
*/
|
*/
|
||||||
POLLING_TIME_INTERVAL("pollingTime", "hawkbit.controller.pollingTime", String.class, null, TenantConfigurationPollingDurationValidator.class),
|
POLLING_TIME_INTERVAL("pollingTime", "hawkbit.controller.pollingTime", String.class, null,
|
||||||
|
TenantConfigurationPollingDurationValidator.class),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* string value which holds the polling time interval in the format HH:mm:ss
|
* string value which holds the polling time interval in the format HH:mm:ss
|
||||||
*/
|
*/
|
||||||
POLLING_OVERDUE_TIME_INTERVAL("pollingOverdueTime", "hawkbit.controller.pollingOverdueTime", String.class, null, TenantConfigurationPollingDurationValidator.class);
|
POLLING_OVERDUE_TIME_INTERVAL("pollingOverdueTime", "hawkbit.controller.pollingOverdueTime", String.class, null,
|
||||||
|
TenantConfigurationPollingDurationValidator.class),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* boolean value {@code true} {@code false}.
|
||||||
|
*/
|
||||||
|
ANONYMOUS_DOWNLOAD_MODE_ENABLED("anonymous.download.enabled", "hawkbit.server.download.anonymous.enabled",
|
||||||
|
Boolean.class, Boolean.FALSE.toString(), TenantConfigurationBooleanValidator.class);
|
||||||
|
|
||||||
private final String keyName;
|
private final String keyName;
|
||||||
private final String defaultKeyName;
|
private final String defaultKeyName;
|
||||||
|
|||||||
@@ -25,6 +25,11 @@
|
|||||||
<groupId>org.eclipse.hawkbit</groupId>
|
<groupId>org.eclipse.hawkbit</groupId>
|
||||||
<artifactId>hawkbit-repository</artifactId>
|
<artifactId>hawkbit-repository</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.hawkbit</groupId>
|
||||||
|
<artifactId>hawkbit-core</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.hawkbit</groupId>
|
<groupId>org.eclipse.hawkbit</groupId>
|
||||||
|
|||||||
@@ -13,12 +13,14 @@ import java.util.List;
|
|||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
|
import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
|
||||||
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
|
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
|
||||||
import org.eclipse.hawkbit.repository.ControllerManagement;
|
import org.eclipse.hawkbit.repository.ControllerManagement;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
import org.eclipse.hawkbit.security.CoapAnonymousPreAuthenticatedFilter;
|
import org.eclipse.hawkbit.security.CoapAnonymousPreAuthenticatedFilter;
|
||||||
import org.eclipse.hawkbit.security.ControllerPreAuthenticateSecurityTokenFilter;
|
import org.eclipse.hawkbit.security.ControllerPreAuthenticateSecurityTokenFilter;
|
||||||
|
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedAnonymousDownload;
|
||||||
|
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedAnonymousFilter;
|
||||||
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedGatewaySecurityTokenFilter;
|
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedGatewaySecurityTokenFilter;
|
||||||
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedSecurityHeaderFilter;
|
import org.eclipse.hawkbit.security.ControllerPreAuthenticatedSecurityHeaderFilter;
|
||||||
import org.eclipse.hawkbit.security.DdiSecurityProperties;
|
import org.eclipse.hawkbit.security.DdiSecurityProperties;
|
||||||
@@ -90,6 +92,11 @@ public class AmqpControllerAuthentfication {
|
|||||||
tenantConfigurationManagement, controllerManagement, tenantAware, systemSecurityContext);
|
tenantConfigurationManagement, controllerManagement, tenantAware, systemSecurityContext);
|
||||||
filterChain.add(securityTokenFilter);
|
filterChain.add(securityTokenFilter);
|
||||||
|
|
||||||
|
final ControllerPreAuthenticatedAnonymousDownload anonymousDownloadFilter = new ControllerPreAuthenticatedAnonymousDownload(
|
||||||
|
tenantConfigurationManagement, tenantAware, systemSecurityContext);
|
||||||
|
filterChain.add(anonymousDownloadFilter);
|
||||||
|
|
||||||
|
filterChain.add(new ControllerPreAuthenticatedAnonymousFilter(ddiSecruityProperties));
|
||||||
filterChain.add(new CoapAnonymousPreAuthenticatedFilter());
|
filterChain.add(new CoapAnonymousPreAuthenticatedFilter());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +107,7 @@ public class AmqpControllerAuthentfication {
|
|||||||
* the authentication request object
|
* the authentication request object
|
||||||
* @return the authentfication object
|
* @return the authentfication object
|
||||||
*/
|
*/
|
||||||
public Authentication doAuthenticate(final TenantSecruityToken secruityToken) {
|
public Authentication doAuthenticate(final TenantSecurityToken secruityToken) {
|
||||||
PreAuthenticatedAuthenticationToken authentication = new PreAuthenticatedAuthenticationToken(null, null);
|
PreAuthenticatedAuthenticationToken authentication = new PreAuthenticatedAuthenticationToken(null, null);
|
||||||
for (final PreAuthenficationFilter filter : filterChain) {
|
for (final PreAuthenficationFilter filter : filterChain) {
|
||||||
final PreAuthenticatedAuthenticationToken authenticationRest = createAuthentication(filter, secruityToken);
|
final PreAuthenticatedAuthenticationToken authenticationRest = createAuthentication(filter, secruityToken);
|
||||||
@@ -115,7 +122,7 @@ public class AmqpControllerAuthentfication {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static PreAuthenticatedAuthenticationToken createAuthentication(final PreAuthenficationFilter filter,
|
private static PreAuthenticatedAuthenticationToken createAuthentication(final PreAuthenficationFilter filter,
|
||||||
final TenantSecruityToken secruityToken) {
|
final TenantSecurityToken secruityToken) {
|
||||||
|
|
||||||
if (!filter.isEnable(secruityToken)) {
|
if (!filter.isEnable(secruityToken)) {
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ import java.util.Collections;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.api.ArtifactUrlHandler;
|
||||||
|
import org.eclipse.hawkbit.api.UrlProtocol;
|
||||||
import org.eclipse.hawkbit.dmf.amqp.api.EventTopic;
|
import org.eclipse.hawkbit.dmf.amqp.api.EventTopic;
|
||||||
import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey;
|
import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey;
|
||||||
import org.eclipse.hawkbit.dmf.amqp.api.MessageType;
|
import org.eclipse.hawkbit.dmf.amqp.api.MessageType;
|
||||||
@@ -25,7 +27,6 @@ import org.eclipse.hawkbit.eventbus.EventSubscriber;
|
|||||||
import org.eclipse.hawkbit.eventbus.event.CancelTargetAssignmentEvent;
|
import org.eclipse.hawkbit.eventbus.event.CancelTargetAssignmentEvent;
|
||||||
import org.eclipse.hawkbit.eventbus.event.TargetAssignDistributionSetEvent;
|
import org.eclipse.hawkbit.eventbus.event.TargetAssignDistributionSetEvent;
|
||||||
import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
||||||
import org.eclipse.hawkbit.util.ArtifactUrlHandler;
|
|
||||||
import org.eclipse.hawkbit.util.IpUtil;
|
import org.eclipse.hawkbit.util.IpUtil;
|
||||||
import org.springframework.amqp.core.Message;
|
import org.springframework.amqp.core.Message;
|
||||||
import org.springframework.amqp.core.MessageProperties;
|
import org.springframework.amqp.core.MessageProperties;
|
||||||
@@ -152,12 +153,16 @@ public class AmqpMessageDispatcherService extends BaseAmqpService {
|
|||||||
|
|
||||||
private Artifact convertArtifact(final String targetId, final LocalArtifact localArtifact) {
|
private Artifact convertArtifact(final String targetId, final LocalArtifact localArtifact) {
|
||||||
final Artifact artifact = new Artifact();
|
final Artifact artifact = new Artifact();
|
||||||
|
|
||||||
artifact.getUrls().put(Artifact.UrlProtocol.COAP,
|
artifact.getUrls().put(Artifact.UrlProtocol.COAP,
|
||||||
artifactUrlHandler.getUrl(targetId, localArtifact, Artifact.UrlProtocol.COAP));
|
artifactUrlHandler.getUrl(targetId, localArtifact.getSoftwareModule().getId(),
|
||||||
|
localArtifact.getFilename(), localArtifact.getSha1Hash(), UrlProtocol.COAP));
|
||||||
artifact.getUrls().put(Artifact.UrlProtocol.HTTP,
|
artifact.getUrls().put(Artifact.UrlProtocol.HTTP,
|
||||||
artifactUrlHandler.getUrl(targetId, localArtifact, Artifact.UrlProtocol.HTTP));
|
artifactUrlHandler.getUrl(targetId, localArtifact.getSoftwareModule().getId(),
|
||||||
|
localArtifact.getFilename(), localArtifact.getSha1Hash(), UrlProtocol.HTTP));
|
||||||
artifact.getUrls().put(Artifact.UrlProtocol.HTTPS,
|
artifact.getUrls().put(Artifact.UrlProtocol.HTTPS,
|
||||||
artifactUrlHandler.getUrl(targetId, localArtifact, Artifact.UrlProtocol.HTTPS));
|
artifactUrlHandler.getUrl(targetId, localArtifact.getSoftwareModule().getId(),
|
||||||
|
localArtifact.getFilename(), localArtifact.getSha1Hash(), UrlProtocol.HTTPS));
|
||||||
|
|
||||||
artifact.setFilename(localArtifact.getFilename());
|
artifact.setFilename(localArtifact.getFilename());
|
||||||
artifact.setHashes(new ArtifactHash(localArtifact.getSha1Hash(), null));
|
artifact.setHashes(new ArtifactHash(localArtifact.getSha1Hash(), null));
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ import org.eclipse.hawkbit.dmf.json.model.ActionUpdateStatus;
|
|||||||
import org.eclipse.hawkbit.dmf.json.model.Artifact;
|
import org.eclipse.hawkbit.dmf.json.model.Artifact;
|
||||||
import org.eclipse.hawkbit.dmf.json.model.ArtifactHash;
|
import org.eclipse.hawkbit.dmf.json.model.ArtifactHash;
|
||||||
import org.eclipse.hawkbit.dmf.json.model.DownloadResponse;
|
import org.eclipse.hawkbit.dmf.json.model.DownloadResponse;
|
||||||
import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
|
import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
|
||||||
|
import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken.FileResource;
|
||||||
import org.eclipse.hawkbit.eventbus.event.TargetAssignDistributionSetEvent;
|
import org.eclipse.hawkbit.eventbus.event.TargetAssignDistributionSetEvent;
|
||||||
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
||||||
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
|
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
|
||||||
@@ -157,25 +158,28 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
private Message handleAuthentifiactionMessage(final Message message) {
|
private Message handleAuthentifiactionMessage(final Message message) {
|
||||||
final DownloadResponse authentificationResponse = new DownloadResponse();
|
final DownloadResponse authentificationResponse = new DownloadResponse();
|
||||||
final MessageProperties messageProperties = message.getMessageProperties();
|
final MessageProperties messageProperties = message.getMessageProperties();
|
||||||
final TenantSecruityToken secruityToken = convertMessage(message, TenantSecruityToken.class);
|
final TenantSecurityToken secruityToken = convertMessage(message, TenantSecurityToken.class);
|
||||||
final String sha1 = secruityToken.getSha1();
|
final FileResource fileResource = secruityToken.getFileResource();
|
||||||
try {
|
try {
|
||||||
SecurityContextHolder.getContext().setAuthentication(authenticationManager.doAuthenticate(secruityToken));
|
SecurityContextHolder.getContext().setAuthentication(authenticationManager.doAuthenticate(secruityToken));
|
||||||
final LocalArtifact localArtifact = artifactManagement
|
|
||||||
.findFirstLocalArtifactsBySHA1(secruityToken.getSha1());
|
final LocalArtifact localArtifact = findLocalArtifactByFileResource(fileResource);
|
||||||
|
|
||||||
if (localArtifact == null) {
|
if (localArtifact == null) {
|
||||||
throw new EntityNotFoundException();
|
throw new EntityNotFoundException();
|
||||||
}
|
}
|
||||||
|
|
||||||
// check action for this download purposes, the method will throw an
|
// check action for this download purposes, the method will throw an
|
||||||
// EntityNotFoundException in case the controller is not allowed to
|
// EntityNotFoundException in case the controller is not allowed to
|
||||||
// download this file
|
// download this file because it's not assigned to an action and not
|
||||||
// because it's not assigned to an action and not assigned to this
|
// assigned to this controller. Otherwise no controllerId is set =
|
||||||
// controller.
|
// anonymous download
|
||||||
final Action action = controllerManagement.getActionForDownloadByTargetAndSoftwareModule(
|
if (secruityToken.getControllerId() != null) {
|
||||||
secruityToken.getControllerId(), localArtifact.getSoftwareModule());
|
final Action action = controllerManagement.getActionForDownloadByTargetAndSoftwareModule(
|
||||||
LOG.info("Found action for download authentication request action: {}, sha1: {}", action,
|
secruityToken.getControllerId(), localArtifact.getSoftwareModule());
|
||||||
secruityToken.getSha1());
|
LOG.info("Found action for download authentication request action: {}, resource: {}", action,
|
||||||
|
secruityToken.getFileResource());
|
||||||
|
}
|
||||||
|
|
||||||
final Artifact artifact = convertDbArtifact(artifactManagement.loadLocalArtifactBinary(localArtifact));
|
final Artifact artifact = convertDbArtifact(artifactManagement.loadLocalArtifactBinary(localArtifact));
|
||||||
if (artifact == null) {
|
if (artifact == null) {
|
||||||
@@ -183,7 +187,9 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
}
|
}
|
||||||
authentificationResponse.setArtifact(artifact);
|
authentificationResponse.setArtifact(artifact);
|
||||||
final String downloadId = UUID.randomUUID().toString();
|
final String downloadId = UUID.randomUUID().toString();
|
||||||
final DownloadArtifactCache downloadCache = new DownloadArtifactCache(DownloadType.BY_SHA1, sha1);
|
// SHA1 key is set, download by SHA1
|
||||||
|
final DownloadArtifactCache downloadCache = new DownloadArtifactCache(DownloadType.BY_SHA1,
|
||||||
|
localArtifact.getSha1Hash());
|
||||||
cache.put(downloadId, downloadCache);
|
cache.put(downloadId, downloadCache);
|
||||||
authentificationResponse
|
authentificationResponse
|
||||||
.setDownloadUrl(UriComponentsBuilder.fromUri(hostnameResolver.resolveHostname().toURI())
|
.setDownloadUrl(UriComponentsBuilder.fromUri(hostnameResolver.resolveHostname().toURI())
|
||||||
@@ -198,7 +204,7 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
authentificationResponse.setResponseCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
authentificationResponse.setResponseCode(HttpStatus.INTERNAL_SERVER_ERROR.value());
|
||||||
authentificationResponse.setMessage("Building download URI failed");
|
authentificationResponse.setMessage("Building download URI failed");
|
||||||
} catch (final EntityNotFoundException e) {
|
} catch (final EntityNotFoundException e) {
|
||||||
final String errorMessage = "Artifact with sha1 " + sha1 + "not found ";
|
final String errorMessage = "Artifact for resource " + fileResource + "not found ";
|
||||||
LOG.warn(errorMessage, e);
|
LOG.warn(errorMessage, e);
|
||||||
authentificationResponse.setResponseCode(HttpStatus.NOT_FOUND.value());
|
authentificationResponse.setResponseCode(HttpStatus.NOT_FOUND.value());
|
||||||
authentificationResponse.setMessage(errorMessage);
|
authentificationResponse.setMessage(errorMessage);
|
||||||
@@ -207,6 +213,21 @@ public class AmqpMessageHandlerService extends BaseAmqpService {
|
|||||||
return getMessageConverter().toMessage(authentificationResponse, messageProperties);
|
return getMessageConverter().toMessage(authentificationResponse, messageProperties);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private LocalArtifact findLocalArtifactByFileResource(final FileResource fileResource) {
|
||||||
|
if (fileResource.getSha1() != null) {
|
||||||
|
return artifactManagement.findFirstLocalArtifactsBySHA1(fileResource.getSha1());
|
||||||
|
} else if (fileResource.getFilename() != null) {
|
||||||
|
return artifactManagement.findLocalArtifactByFilename(fileResource.getFilename()).stream().findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
} else if (fileResource.getSoftwareModuleFilenameResource() != null) {
|
||||||
|
return artifactManagement
|
||||||
|
.findByFilenameAndSoftwareModule(fileResource.getSoftwareModuleFilenameResource().getFilename(),
|
||||||
|
fileResource.getSoftwareModuleFilenameResource().getSoftwareModuleId())
|
||||||
|
.stream().findFirst().orElse(null);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private static Artifact convertDbArtifact(final DbArtifact dbArtifact) {
|
private static Artifact convertDbArtifact(final DbArtifact dbArtifact) {
|
||||||
final Artifact artifact = new Artifact();
|
final Artifact artifact = new Artifact();
|
||||||
artifact.setSize(dbArtifact.getSize());
|
artifact.setSize(dbArtifact.getSize());
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
|
||||||
*
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
*/
|
|
||||||
package org.eclipse.hawkbit.util;
|
|
||||||
|
|
||||||
import org.eclipse.hawkbit.dmf.json.model.Artifact;
|
|
||||||
import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface declaration of the {@link ArtifactUrlHandler} which generates the
|
|
||||||
* URLs to specific artifacts.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface ArtifactUrlHandler {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a generated URL for a given artifact for a specific protocol.
|
|
||||||
*
|
|
||||||
* @param controllerId
|
|
||||||
* the authentifacted controller id
|
|
||||||
* @param localArtifact
|
|
||||||
* the artifact to retrieve a URL to
|
|
||||||
* @param protocol
|
|
||||||
* the protocol the URL should be generated
|
|
||||||
* @return an URL for the given artifact in a given protocol
|
|
||||||
*/
|
|
||||||
String getUrl(String controllerId, LocalArtifact localArtifact, final Artifact.UrlProtocol protocol);
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -19,12 +19,14 @@ import static org.mockito.Mockito.when;
|
|||||||
import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey;
|
import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey;
|
||||||
import org.eclipse.hawkbit.dmf.amqp.api.MessageType;
|
import org.eclipse.hawkbit.dmf.amqp.api.MessageType;
|
||||||
import org.eclipse.hawkbit.dmf.json.model.DownloadResponse;
|
import org.eclipse.hawkbit.dmf.json.model.DownloadResponse;
|
||||||
import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
|
import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
|
||||||
|
import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken.FileResource;
|
||||||
import org.eclipse.hawkbit.repository.ArtifactManagement;
|
import org.eclipse.hawkbit.repository.ArtifactManagement;
|
||||||
import org.eclipse.hawkbit.repository.ControllerManagement;
|
import org.eclipse.hawkbit.repository.ControllerManagement;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
||||||
import org.eclipse.hawkbit.security.DdiSecurityProperties;
|
import org.eclipse.hawkbit.security.DdiSecurityProperties;
|
||||||
|
import org.eclipse.hawkbit.security.DdiSecurityProperties.Authentication.Anonymous;
|
||||||
import org.eclipse.hawkbit.security.DdiSecurityProperties.Rp;
|
import org.eclipse.hawkbit.security.DdiSecurityProperties.Rp;
|
||||||
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
|
import org.eclipse.hawkbit.security.SecurityContextTenantAware;
|
||||||
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
import org.eclipse.hawkbit.security.SystemSecurityContext;
|
||||||
@@ -79,8 +81,14 @@ public class AmqpControllerAuthenticationTest {
|
|||||||
|
|
||||||
final DdiSecurityProperties secruityProperties = mock(DdiSecurityProperties.class);
|
final DdiSecurityProperties secruityProperties = mock(DdiSecurityProperties.class);
|
||||||
final Rp rp = mock(Rp.class);
|
final Rp rp = mock(Rp.class);
|
||||||
|
final org.eclipse.hawkbit.security.DdiSecurityProperties.Authentication ddiAuthentication = mock(
|
||||||
|
org.eclipse.hawkbit.security.DdiSecurityProperties.Authentication.class);
|
||||||
|
final Anonymous anonymous = mock(Anonymous.class);
|
||||||
when(secruityProperties.getRp()).thenReturn(rp);
|
when(secruityProperties.getRp()).thenReturn(rp);
|
||||||
when(rp.getSslIssuerHashHeader()).thenReturn("X-Ssl-Issuer-Hash-%d");
|
when(rp.getSslIssuerHashHeader()).thenReturn("X-Ssl-Issuer-Hash-%d");
|
||||||
|
when(secruityProperties.getAuthentication()).thenReturn(ddiAuthentication);
|
||||||
|
when(ddiAuthentication.getAnonymous()).thenReturn(anonymous);
|
||||||
|
when(anonymous.isEnabled()).thenReturn(false);
|
||||||
authenticationManager.setSecruityProperties(secruityProperties);
|
authenticationManager.setSecruityProperties(secruityProperties);
|
||||||
|
|
||||||
tenantConfigurationManagement = mock(TenantConfigurationManagement.class);
|
tenantConfigurationManagement = mock(TenantConfigurationManagement.class);
|
||||||
@@ -105,7 +113,8 @@ public class AmqpControllerAuthenticationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Tests authentication manager without principal")
|
@Description("Tests authentication manager without principal")
|
||||||
public void testAuthenticationeBadCredantialsWithoutPricipal() {
|
public void testAuthenticationeBadCredantialsWithoutPricipal() {
|
||||||
final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, CONTROLLLER_ID, "12345");
|
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
|
||||||
|
FileResource.sha1("12345"));
|
||||||
try {
|
try {
|
||||||
authenticationManager.doAuthenticate(securityToken);
|
authenticationManager.doAuthenticate(securityToken);
|
||||||
fail("BadCredentialsException was excepeted since principal was missing");
|
fail("BadCredentialsException was excepeted since principal was missing");
|
||||||
@@ -118,11 +127,12 @@ public class AmqpControllerAuthenticationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Tests authentication manager without wrong credential")
|
@Description("Tests authentication manager without wrong credential")
|
||||||
public void testAuthenticationBadCredantialsWithWrongCredential() {
|
public void testAuthenticationBadCredantialsWithWrongCredential() {
|
||||||
final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, CONTROLLLER_ID, "12345");
|
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
|
||||||
|
FileResource.sha1("12345"));
|
||||||
when(tenantConfigurationManagement.getConfigurationValue(
|
when(tenantConfigurationManagement.getConfigurationValue(
|
||||||
eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class)))
|
eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class)))
|
||||||
.thenReturn(CONFIG_VALUE_TRUE);
|
.thenReturn(CONFIG_VALUE_TRUE);
|
||||||
securityToken.getHeaders().put(TenantSecruityToken.AUTHORIZATION_HEADER, "TargetToken 12" + CONTROLLLER_ID);
|
securityToken.getHeaders().put(TenantSecurityToken.AUTHORIZATION_HEADER, "TargetToken 12" + CONTROLLLER_ID);
|
||||||
try {
|
try {
|
||||||
authenticationManager.doAuthenticate(securityToken);
|
authenticationManager.doAuthenticate(securityToken);
|
||||||
fail("BadCredentialsException was excepeted due to wrong credential");
|
fail("BadCredentialsException was excepeted due to wrong credential");
|
||||||
@@ -135,11 +145,12 @@ public class AmqpControllerAuthenticationTest {
|
|||||||
@Test
|
@Test
|
||||||
@Description("Tests authentication successfull")
|
@Description("Tests authentication successfull")
|
||||||
public void testSuccessfullAuthentication() {
|
public void testSuccessfullAuthentication() {
|
||||||
final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, CONTROLLLER_ID, "12345");
|
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
|
||||||
|
FileResource.sha1("12345"));
|
||||||
when(tenantConfigurationManagement.getConfigurationValue(
|
when(tenantConfigurationManagement.getConfigurationValue(
|
||||||
eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class)))
|
eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class)))
|
||||||
.thenReturn(CONFIG_VALUE_TRUE);
|
.thenReturn(CONFIG_VALUE_TRUE);
|
||||||
securityToken.getHeaders().put(TenantSecruityToken.AUTHORIZATION_HEADER, "TargetToken " + CONTROLLLER_ID);
|
securityToken.getHeaders().put(TenantSecurityToken.AUTHORIZATION_HEADER, "TargetToken " + CONTROLLLER_ID);
|
||||||
final Authentication authentication = authenticationManager.doAuthenticate(securityToken);
|
final Authentication authentication = authenticationManager.doAuthenticate(securityToken);
|
||||||
assertThat(authentication).isNotNull();
|
assertThat(authentication).isNotNull();
|
||||||
}
|
}
|
||||||
@@ -149,7 +160,8 @@ public class AmqpControllerAuthenticationTest {
|
|||||||
public void testAuthenticationMessageBadCredantialsWithoutPricipal() {
|
public void testAuthenticationMessageBadCredantialsWithoutPricipal() {
|
||||||
final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION);
|
final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION);
|
||||||
|
|
||||||
final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, CONTROLLLER_ID, "12345");
|
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
|
||||||
|
FileResource.sha1("12345"));
|
||||||
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
|
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
|
||||||
messageProperties);
|
messageProperties);
|
||||||
|
|
||||||
@@ -167,11 +179,12 @@ public class AmqpControllerAuthenticationTest {
|
|||||||
@Description("Tests authentication message without wrong credential")
|
@Description("Tests authentication message without wrong credential")
|
||||||
public void testAuthenticationMessageBadCredantialsWithWrongCredential() {
|
public void testAuthenticationMessageBadCredantialsWithWrongCredential() {
|
||||||
final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION);
|
final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION);
|
||||||
final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, CONTROLLLER_ID, "12345");
|
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
|
||||||
|
FileResource.sha1("12345"));
|
||||||
when(tenantConfigurationManagement.getConfigurationValue(
|
when(tenantConfigurationManagement.getConfigurationValue(
|
||||||
eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class)))
|
eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class)))
|
||||||
.thenReturn(CONFIG_VALUE_TRUE);
|
.thenReturn(CONFIG_VALUE_TRUE);
|
||||||
securityToken.getHeaders().put(TenantSecruityToken.AUTHORIZATION_HEADER, "TargetToken 12" + CONTROLLLER_ID);
|
securityToken.getHeaders().put(TenantSecurityToken.AUTHORIZATION_HEADER, "TargetToken 12" + CONTROLLLER_ID);
|
||||||
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
|
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
|
||||||
messageProperties);
|
messageProperties);
|
||||||
|
|
||||||
@@ -189,11 +202,12 @@ public class AmqpControllerAuthenticationTest {
|
|||||||
@Description("Tests authentication message successfull")
|
@Description("Tests authentication message successfull")
|
||||||
public void testSuccessfullMessageAuthentication() {
|
public void testSuccessfullMessageAuthentication() {
|
||||||
final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION);
|
final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION);
|
||||||
final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, CONTROLLLER_ID, "12345");
|
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, CONTROLLLER_ID,
|
||||||
|
FileResource.sha1("12345"));
|
||||||
when(tenantConfigurationManagement.getConfigurationValue(
|
when(tenantConfigurationManagement.getConfigurationValue(
|
||||||
eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class)))
|
eq(TenantConfigurationKey.AUTHENTICATION_MODE_TARGET_SECURITY_TOKEN_ENABLED), eq(Boolean.class)))
|
||||||
.thenReturn(CONFIG_VALUE_TRUE);
|
.thenReturn(CONFIG_VALUE_TRUE);
|
||||||
securityToken.getHeaders().put(TenantSecruityToken.AUTHORIZATION_HEADER, "TargetToken " + CONTROLLLER_ID);
|
securityToken.getHeaders().put(TenantSecurityToken.AUTHORIZATION_HEADER, "TargetToken " + CONTROLLLER_ID);
|
||||||
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
|
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
|
||||||
messageProperties);
|
messageProperties);
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import static org.junit.Assert.assertFalse;
|
|||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.mockito.Matchers.any;
|
import static org.mockito.Matchers.any;
|
||||||
|
import static org.mockito.Matchers.anyLong;
|
||||||
import static org.mockito.Matchers.anyObject;
|
import static org.mockito.Matchers.anyObject;
|
||||||
import static org.mockito.Matchers.anyString;
|
import static org.mockito.Matchers.anyString;
|
||||||
import static org.mockito.Matchers.eq;
|
import static org.mockito.Matchers.eq;
|
||||||
@@ -25,6 +26,7 @@ import java.util.List;
|
|||||||
|
|
||||||
import org.eclipse.hawkbit.AbstractIntegrationTestWithMongoDB;
|
import org.eclipse.hawkbit.AbstractIntegrationTestWithMongoDB;
|
||||||
import org.eclipse.hawkbit.TestDataUtil;
|
import org.eclipse.hawkbit.TestDataUtil;
|
||||||
|
import org.eclipse.hawkbit.api.ArtifactUrlHandler;
|
||||||
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
|
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
|
||||||
import org.eclipse.hawkbit.dmf.amqp.api.EventTopic;
|
import org.eclipse.hawkbit.dmf.amqp.api.EventTopic;
|
||||||
import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey;
|
import org.eclipse.hawkbit.dmf.amqp.api.MessageHeaderKey;
|
||||||
@@ -36,7 +38,6 @@ import org.eclipse.hawkbit.repository.model.Artifact;
|
|||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||||
import org.eclipse.hawkbit.util.ArtifactUrlHandler;
|
|
||||||
import org.eclipse.hawkbit.util.IpUtil;
|
import org.eclipse.hawkbit.util.IpUtil;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.mockito.ArgumentCaptor;
|
import org.mockito.ArgumentCaptor;
|
||||||
@@ -77,7 +78,8 @@ public class AmqpMessageDispatcherServiceTest extends AbstractIntegrationTestWit
|
|||||||
amqpMessageDispatcherService.setAmqpSenderService(senderService);
|
amqpMessageDispatcherService.setAmqpSenderService(senderService);
|
||||||
|
|
||||||
final ArtifactUrlHandler artifactUrlHandlerMock = Mockito.mock(ArtifactUrlHandler.class);
|
final ArtifactUrlHandler artifactUrlHandlerMock = Mockito.mock(ArtifactUrlHandler.class);
|
||||||
when(artifactUrlHandlerMock.getUrl(anyString(), any(), anyObject())).thenReturn("http://mockurl");
|
when(artifactUrlHandlerMock.getUrl(anyString(), anyLong(), anyString(), anyString(), anyObject()))
|
||||||
|
.thenReturn("http://mockurl");
|
||||||
|
|
||||||
amqpMessageDispatcherService.setArtifactUrlHandler(artifactUrlHandlerMock);
|
amqpMessageDispatcherService.setArtifactUrlHandler(artifactUrlHandlerMock);
|
||||||
|
|
||||||
|
|||||||
@@ -34,7 +34,8 @@ import org.eclipse.hawkbit.dmf.amqp.api.MessageType;
|
|||||||
import org.eclipse.hawkbit.dmf.json.model.ActionStatus;
|
import org.eclipse.hawkbit.dmf.json.model.ActionStatus;
|
||||||
import org.eclipse.hawkbit.dmf.json.model.ActionUpdateStatus;
|
import org.eclipse.hawkbit.dmf.json.model.ActionUpdateStatus;
|
||||||
import org.eclipse.hawkbit.dmf.json.model.DownloadResponse;
|
import org.eclipse.hawkbit.dmf.json.model.DownloadResponse;
|
||||||
import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
|
import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
|
||||||
|
import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken.FileResource;
|
||||||
import org.eclipse.hawkbit.eventbus.event.TargetAssignDistributionSetEvent;
|
import org.eclipse.hawkbit.eventbus.event.TargetAssignDistributionSetEvent;
|
||||||
import org.eclipse.hawkbit.repository.ArtifactManagement;
|
import org.eclipse.hawkbit.repository.ArtifactManagement;
|
||||||
import org.eclipse.hawkbit.repository.ControllerManagement;
|
import org.eclipse.hawkbit.repository.ControllerManagement;
|
||||||
@@ -263,7 +264,7 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
@Description("Tests that an download request is denied for an artifact which does not exists")
|
@Description("Tests that an download request is denied for an artifact which does not exists")
|
||||||
public void authenticationRequestDeniedForArtifactWhichDoesNotExists() {
|
public void authenticationRequestDeniedForArtifactWhichDoesNotExists() {
|
||||||
final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION);
|
final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION);
|
||||||
final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, "123", "12345");
|
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, "123", FileResource.sha1("12345"));
|
||||||
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
|
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
|
||||||
messageProperties);
|
messageProperties);
|
||||||
|
|
||||||
@@ -282,7 +283,7 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
@Description("Tests that an download request is denied for an artifact which is not assigned to the requested target")
|
@Description("Tests that an download request is denied for an artifact which is not assigned to the requested target")
|
||||||
public void authenticationRequestDeniedForArtifactWhichIsNotAssignedToTarget() {
|
public void authenticationRequestDeniedForArtifactWhichIsNotAssignedToTarget() {
|
||||||
final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION);
|
final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION);
|
||||||
final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, "123", "12345");
|
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, "123", FileResource.sha1("12345"));
|
||||||
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
|
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
|
||||||
messageProperties);
|
messageProperties);
|
||||||
|
|
||||||
@@ -306,7 +307,7 @@ public class AmqpMessageHandlerServiceTest {
|
|||||||
@Description("Tests that an download request is allowed for an artifact which exists and assigned to the requested target")
|
@Description("Tests that an download request is allowed for an artifact which exists and assigned to the requested target")
|
||||||
public void authenticationRequestAllowedForArtifactWhichExistsAndAssignedToTarget() throws MalformedURLException {
|
public void authenticationRequestAllowedForArtifactWhichExistsAndAssignedToTarget() throws MalformedURLException {
|
||||||
final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION);
|
final MessageProperties messageProperties = createMessageProperties(MessageType.AUTHENTIFICATION);
|
||||||
final TenantSecruityToken securityToken = new TenantSecruityToken(TENANT, "123", "12345");
|
final TenantSecurityToken securityToken = new TenantSecurityToken(TENANT, "123", FileResource.sha1("12345"));
|
||||||
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
|
final Message message = amqpMessageHandlerService.getMessageConverter().toMessage(securityToken,
|
||||||
messageProperties);
|
messageProperties);
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ import org.eclipse.hawkbit.AmqpTestConfiguration;
|
|||||||
import org.eclipse.hawkbit.RepositoryApplicationConfiguration;
|
import org.eclipse.hawkbit.RepositoryApplicationConfiguration;
|
||||||
import org.eclipse.hawkbit.TestConfiguration;
|
import org.eclipse.hawkbit.TestConfiguration;
|
||||||
import org.eclipse.hawkbit.TestDataUtil;
|
import org.eclipse.hawkbit.TestDataUtil;
|
||||||
import org.eclipse.hawkbit.dmf.json.model.Artifact;
|
import org.eclipse.hawkbit.api.ArtifactUrlHandler;
|
||||||
|
import org.eclipse.hawkbit.api.UrlProtocol;
|
||||||
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
import org.eclipse.hawkbit.repository.model.DistributionSet;
|
||||||
import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
||||||
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
import org.eclipse.hawkbit.repository.model.SoftwareModule;
|
||||||
@@ -30,8 +31,7 @@ import ru.yandex.qatools.allure.annotations.Features;
|
|||||||
import ru.yandex.qatools.allure.annotations.Stories;
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Tests for creating urls to download artifacts.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Features("Component Tests - Artifact URL Handler")
|
@Features("Component Tests - Artifact URL Handler")
|
||||||
@Stories("Test to generate the artifact download URL")
|
@Stories("Test to generate the artifact download URL")
|
||||||
@@ -45,6 +45,9 @@ public class PropertyBasedArtifactUrlHandlerTest extends AbstractIntegrationTest
|
|||||||
private TenantAware tenantAware;
|
private TenantAware tenantAware;
|
||||||
private LocalArtifact localArtifact;
|
private LocalArtifact localArtifact;
|
||||||
private final String controllerId = "Test";
|
private final String controllerId = "Test";
|
||||||
|
private String fileName;
|
||||||
|
private Long softwareModuleId;
|
||||||
|
private String sha1Hash;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
@@ -53,12 +56,18 @@ public class PropertyBasedArtifactUrlHandlerTest extends AbstractIntegrationTest
|
|||||||
final SoftwareModule module = dsA.getModules().iterator().next();
|
final SoftwareModule module = dsA.getModules().iterator().next();
|
||||||
localArtifact = (LocalArtifact) TestDataUtil.generateArtifacts(artifactManagement, module.getId()).stream()
|
localArtifact = (LocalArtifact) TestDataUtil.generateArtifacts(artifactManagement, module.getId()).stream()
|
||||||
.findAny().get();
|
.findAny().get();
|
||||||
|
softwareModuleId = localArtifact.getSoftwareModule().getId();
|
||||||
|
fileName = localArtifact.getFilename();
|
||||||
|
sha1Hash = localArtifact.getSha1Hash();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Description("Tests the generation of http download url.")
|
@Description("Tests the generation of http download url.")
|
||||||
public void testHttpUrl() {
|
public void testHttpUrl() {
|
||||||
final String url = urlHandlerProperties.getUrl(controllerId, localArtifact, Artifact.UrlProtocol.HTTP);
|
|
||||||
|
final String url = urlHandlerProperties.getUrl(controllerId, softwareModuleId, fileName, sha1Hash,
|
||||||
|
UrlProtocol.HTTP);
|
||||||
assertEquals("http is build incorrect",
|
assertEquals("http is build incorrect",
|
||||||
"http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId
|
"http://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId
|
||||||
+ "/softwaremodules/" + localArtifact.getSoftwareModule().getId() + "/artifacts/"
|
+ "/softwaremodules/" + localArtifact.getSoftwareModule().getId() + "/artifacts/"
|
||||||
@@ -69,7 +78,8 @@ public class PropertyBasedArtifactUrlHandlerTest extends AbstractIntegrationTest
|
|||||||
@Test
|
@Test
|
||||||
@Description("Tests the generation of https download url.")
|
@Description("Tests the generation of https download url.")
|
||||||
public void testHttpsUrl() {
|
public void testHttpsUrl() {
|
||||||
final String url = urlHandlerProperties.getUrl(controllerId, localArtifact, Artifact.UrlProtocol.HTTPS);
|
final String url = urlHandlerProperties.getUrl(controllerId, softwareModuleId, fileName, sha1Hash,
|
||||||
|
UrlProtocol.HTTPS);
|
||||||
assertEquals("https is build incorrect",
|
assertEquals("https is build incorrect",
|
||||||
"https://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId
|
"https://localhost/" + tenantAware.getCurrentTenant() + "/controller/v1/" + controllerId
|
||||||
+ "/softwaremodules/" + localArtifact.getSoftwareModule().getId() + "/artifacts/"
|
+ "/softwaremodules/" + localArtifact.getSoftwareModule().getId() + "/artifacts/"
|
||||||
@@ -80,7 +90,8 @@ public class PropertyBasedArtifactUrlHandlerTest extends AbstractIntegrationTest
|
|||||||
@Test
|
@Test
|
||||||
@Description("Tests the generation of coap download url.")
|
@Description("Tests the generation of coap download url.")
|
||||||
public void testCoapUrl() {
|
public void testCoapUrl() {
|
||||||
final String url = urlHandlerProperties.getUrl(controllerId, localArtifact, Artifact.UrlProtocol.COAP);
|
final String url = urlHandlerProperties.getUrl(controllerId, softwareModuleId, fileName, sha1Hash,
|
||||||
|
UrlProtocol.COAP);
|
||||||
|
|
||||||
assertEquals("coap is build incorrect", "coap://127.0.0.1:5683/fw/" + tenantAware.getCurrentTenant() + "/"
|
assertEquals("coap is build incorrect", "coap://127.0.0.1:5683/fw/" + tenantAware.getCurrentTenant() + "/"
|
||||||
+ controllerId + "/sha1/" + localArtifact.getSha1Hash(), url);
|
+ controllerId + "/sha1/" + localArtifact.getSha1Hash(), url);
|
||||||
|
|||||||
@@ -1,94 +0,0 @@
|
|||||||
/**
|
|
||||||
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
|
||||||
*
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
|
||||||
*/
|
|
||||||
package org.eclipse.hawkbit.dmf.json.model;
|
|
||||||
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JSON representation to authenticate a tenant.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
@JsonInclude(Include.NON_NULL)
|
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
|
||||||
public class TenantSecruityToken {
|
|
||||||
|
|
||||||
public static final String AUTHORIZATION_HEADER = "Authorization";
|
|
||||||
public static final String COAP_AUTHORIZATION_HEADER = "Coap-Authorization";
|
|
||||||
public static final String COAP_TOKEN_VALUE = "CoapToken";
|
|
||||||
|
|
||||||
@JsonProperty
|
|
||||||
private final String tenant;
|
|
||||||
@JsonProperty
|
|
||||||
private final String controllerId;
|
|
||||||
@JsonProperty(required = false)
|
|
||||||
private Map<String, String> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
|
||||||
@JsonProperty(required = false)
|
|
||||||
private final String sha1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param tenant
|
|
||||||
* the tenant for the security token
|
|
||||||
* @param controllerId
|
|
||||||
* the ID of the controller for the security token
|
|
||||||
* @param sha1
|
|
||||||
* the sha1 of authentication
|
|
||||||
*/
|
|
||||||
@JsonCreator
|
|
||||||
public TenantSecruityToken(@JsonProperty("tenant") final String tenant,
|
|
||||||
@JsonProperty("controllerId") final String controllerId, @JsonProperty("sha1") final String sha1) {
|
|
||||||
this.tenant = tenant;
|
|
||||||
this.controllerId = controllerId;
|
|
||||||
this.sha1 = sha1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTenant() {
|
|
||||||
return tenant;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getControllerId() {
|
|
||||||
return controllerId;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getHeaders() {
|
|
||||||
return headers;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getSha1() {
|
|
||||||
return sha1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a header value.
|
|
||||||
*
|
|
||||||
* @param name
|
|
||||||
* of header
|
|
||||||
* @return the value
|
|
||||||
*/
|
|
||||||
public String getHeader(final String name) {
|
|
||||||
return headers.get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setHeaders(final Map<String, String> headers) {
|
|
||||||
this.headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
|
||||||
this.headers.putAll(headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,226 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.dmf.json.model;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JSON representation to authenticate a tenant.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@JsonInclude(Include.NON_NULL)
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public class TenantSecurityToken {
|
||||||
|
|
||||||
|
public static final String AUTHORIZATION_HEADER = "Authorization";
|
||||||
|
public static final String COAP_AUTHORIZATION_HEADER = "Coap-Authorization";
|
||||||
|
public static final String COAP_TOKEN_VALUE = "CoapToken";
|
||||||
|
|
||||||
|
@JsonProperty
|
||||||
|
private final String tenant;
|
||||||
|
@JsonProperty
|
||||||
|
private final String controllerId;
|
||||||
|
@JsonProperty(required = false)
|
||||||
|
private Map<String, String> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||||
|
|
||||||
|
@JsonProperty(required = false)
|
||||||
|
private final FileResource fileResource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param tenant
|
||||||
|
* the tenant for the security token
|
||||||
|
* @param controllerId
|
||||||
|
* the ID of the controller for the security token
|
||||||
|
* @param fileResource
|
||||||
|
* the file to obtain
|
||||||
|
*/
|
||||||
|
@JsonCreator
|
||||||
|
public TenantSecurityToken(@JsonProperty("tenant") final String tenant,
|
||||||
|
@JsonProperty("controllerId") final String controllerId,
|
||||||
|
@JsonProperty("fileResource") final FileResource fileResource) {
|
||||||
|
this.tenant = tenant;
|
||||||
|
this.controllerId = controllerId;
|
||||||
|
this.fileResource = fileResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTenant() {
|
||||||
|
return tenant;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getControllerId() {
|
||||||
|
return controllerId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<String, String> getHeaders() {
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public FileResource getFileResource() {
|
||||||
|
return fileResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a header value.
|
||||||
|
*
|
||||||
|
* @param name
|
||||||
|
* of header
|
||||||
|
* @return the value
|
||||||
|
*/
|
||||||
|
public String getHeader(final String name) {
|
||||||
|
return headers.get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHeaders(final Map<String, String> headers) {
|
||||||
|
this.headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
|
||||||
|
this.headers.putAll(headers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File resource descriptor which is used to ask for the resource to
|
||||||
|
* download e.g. The lookup of the file can be different e.g. by SHA1 hash
|
||||||
|
* or by filename.
|
||||||
|
*/
|
||||||
|
@JsonInclude(Include.NON_NULL)
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public static class FileResource {
|
||||||
|
@JsonProperty(required = false)
|
||||||
|
private String sha1;
|
||||||
|
@JsonProperty(required = false)
|
||||||
|
private String filename;
|
||||||
|
@JsonProperty(required = false)
|
||||||
|
private SoftwareModuleFilenameResource softwareModuleFilenameResource;
|
||||||
|
|
||||||
|
public String getSha1() {
|
||||||
|
return sha1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSha1(final String sha1) {
|
||||||
|
this.sha1 = sha1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFilename() {
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFilename(final String filename) {
|
||||||
|
this.filename = filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SoftwareModuleFilenameResource getSoftwareModuleFilenameResource() {
|
||||||
|
return softwareModuleFilenameResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSoftwareModuleFilenameResource(
|
||||||
|
final SoftwareModuleFilenameResource softwareModuleFilenameResource) {
|
||||||
|
this.softwareModuleFilenameResource = softwareModuleFilenameResource;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* factory method to create a file resource for an SHA1 lookup.
|
||||||
|
*
|
||||||
|
* @param sha1
|
||||||
|
* the SHA1 key of the file to obtain
|
||||||
|
* @return the {@link FileResource} with SHA1 key set
|
||||||
|
*/
|
||||||
|
public static FileResource sha1(final String sha1) {
|
||||||
|
final FileResource resource = new FileResource();
|
||||||
|
resource.sha1 = sha1;
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* factory method to create a file resource for an filename lookup.
|
||||||
|
*
|
||||||
|
* @param filename
|
||||||
|
* the filename of the file to obtain
|
||||||
|
* @return the {@link FileResource} with filename set
|
||||||
|
*/
|
||||||
|
public static FileResource filename(final String filename) {
|
||||||
|
final FileResource resource = new FileResource();
|
||||||
|
resource.filename = filename;
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* factory method to create a file resource for an softwaremodule +
|
||||||
|
* filename lookup, because an filename is not globally unique but
|
||||||
|
* within a softwaremodule.
|
||||||
|
*
|
||||||
|
* @param softwareModuleId
|
||||||
|
* the ID of the software module which contains the artifact
|
||||||
|
* @param filename
|
||||||
|
* the name of file to obtain within the software module
|
||||||
|
* @return the {@link FileResource} with artifactId set
|
||||||
|
*/
|
||||||
|
public static FileResource softwareModuleFilename(final Long softwareModuleId, final String filename) {
|
||||||
|
final FileResource resource = new FileResource();
|
||||||
|
resource.softwareModuleFilenameResource = new SoftwareModuleFilenameResource(softwareModuleId, filename);
|
||||||
|
return resource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "FileResource [sha1=" + sha1 + ", filename=" + filename + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inner class which holds the pointer to an artifact based on the
|
||||||
|
* softwaremoduleId and the filename.
|
||||||
|
*/
|
||||||
|
@JsonInclude(Include.NON_NULL)
|
||||||
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
|
public static class SoftwareModuleFilenameResource {
|
||||||
|
@JsonProperty(required = false)
|
||||||
|
private Long softwareModuleId;
|
||||||
|
@JsonProperty(required = false)
|
||||||
|
private String filename;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param softwareModuleId
|
||||||
|
* the ID of the softwaremodule
|
||||||
|
* @param filename
|
||||||
|
* the name of the file of the artifact within the
|
||||||
|
* softwaremodule
|
||||||
|
*/
|
||||||
|
@JsonCreator
|
||||||
|
public SoftwareModuleFilenameResource(@JsonProperty("softwareModuleId") final Long softwareModuleId,
|
||||||
|
@JsonProperty("filename") final String filename) {
|
||||||
|
this.softwareModuleId = softwareModuleId;
|
||||||
|
this.filename = filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Long getSoftwareModuleId() {
|
||||||
|
return softwareModuleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getFilename() {
|
||||||
|
return filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSoftwareModuleId(final Long softwareModuleId) {
|
||||||
|
this.softwareModuleId = softwareModuleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFilename(final String filename) {
|
||||||
|
this.filename = filename;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -9,6 +9,8 @@
|
|||||||
package org.eclipse.hawkbit.security;
|
package org.eclipse.hawkbit.security;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import javax.servlet.FilterChain;
|
import javax.servlet.FilterChain;
|
||||||
@@ -16,14 +18,19 @@ import javax.servlet.ServletException;
|
|||||||
import javax.servlet.ServletRequest;
|
import javax.servlet.ServletRequest;
|
||||||
import javax.servlet.ServletResponse;
|
import javax.servlet.ServletResponse;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
|
import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
|
||||||
|
import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken.FileResource;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
import org.springframework.security.core.context.SecurityContextHolder;
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
|
import org.springframework.security.web.authentication.preauth.AbstractPreAuthenticatedProcessingFilter;
|
||||||
|
import org.springframework.security.web.authentication.preauth.PreAuthenticatedAuthenticationToken;
|
||||||
import org.springframework.util.AntPathMatcher;
|
import org.springframework.util.AntPathMatcher;
|
||||||
|
|
||||||
import com.google.common.collect.Iterators;
|
import com.google.common.collect.Iterators;
|
||||||
@@ -79,14 +86,6 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac
|
|||||||
pathExtractor = new AntPathMatcher();
|
pathExtractor = new AntPathMatcher();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.springframework.security.web.authentication.preauth.
|
|
||||||
* AbstractPreAuthenticatedProcessingFilter
|
|
||||||
* #doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse,
|
|
||||||
* javax.servlet.FilterChain)
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
|
public void doFilter(final ServletRequest request, final ServletResponse response, final FilterChain chain)
|
||||||
throws IOException, ServletException {
|
throws IOException, ServletException {
|
||||||
@@ -96,7 +95,7 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final TenantSecruityToken secruityToken = createTenantSecruityTokenVariables((HttpServletRequest) request);
|
final TenantSecurityToken secruityToken = createTenantSecruityTokenVariables((HttpServletRequest) request);
|
||||||
if (secruityToken == null) {
|
if (secruityToken == null) {
|
||||||
chain.doFilter(request, response);
|
chain.doFilter(request, response);
|
||||||
return;
|
return;
|
||||||
@@ -112,6 +111,18 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac
|
|||||||
|
|
||||||
protected abstract PreAuthenficationFilter createControllerAuthenticationFilter();
|
protected abstract PreAuthenficationFilter createControllerAuthenticationFilter();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void successfulAuthentication(final HttpServletRequest request, final HttpServletResponse response,
|
||||||
|
final Authentication authResult) {
|
||||||
|
final Collection<GrantedAuthority> authorities = new ArrayList<>();
|
||||||
|
authorities.addAll(authResult.getAuthorities());
|
||||||
|
authorities.addAll(abstractControllerAuthenticationFilter.getSuccessfulAuthenticationAuthorities());
|
||||||
|
final PreAuthenticatedAuthenticationToken authTokenWithGrantedAuthorities = new PreAuthenticatedAuthenticationToken(
|
||||||
|
authResult.getPrincipal(), authResult.getCredentials(), authorities);
|
||||||
|
authTokenWithGrantedAuthorities.setDetails(authResult.getDetails());
|
||||||
|
super.successfulAuthentication(request, response, authTokenWithGrantedAuthorities);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extracts tenant and controllerId from the request URI as path variables.
|
* Extracts tenant and controllerId from the request URI as path variables.
|
||||||
*
|
*
|
||||||
@@ -121,7 +132,7 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac
|
|||||||
* request does not match the pattern and no variables could be
|
* request does not match the pattern and no variables could be
|
||||||
* extracted
|
* extracted
|
||||||
*/
|
*/
|
||||||
protected TenantSecruityToken createTenantSecruityTokenVariables(final HttpServletRequest request) {
|
protected TenantSecurityToken createTenantSecruityTokenVariables(final HttpServletRequest request) {
|
||||||
final String requestURI = request.getRequestURI();
|
final String requestURI = request.getRequestURI();
|
||||||
|
|
||||||
if (pathExtractor.match(request.getContextPath() + CONTROLLER_REQUEST_ANT_PATTERN, requestURI)) {
|
if (pathExtractor.match(request.getContextPath() + CONTROLLER_REQUEST_ANT_PATTERN, requestURI)) {
|
||||||
@@ -153,9 +164,9 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private TenantSecruityToken createTenantSecruityTokenVariables(final HttpServletRequest request,
|
private TenantSecurityToken createTenantSecruityTokenVariables(final HttpServletRequest request,
|
||||||
final String tenant, final String controllerId) {
|
final String tenant, final String controllerId) {
|
||||||
final TenantSecruityToken secruityToken = new TenantSecruityToken(tenant, controllerId, "");
|
final TenantSecurityToken secruityToken = new TenantSecurityToken(tenant, controllerId, FileResource.sha1(""));
|
||||||
final UnmodifiableIterator<String> forEnumeration = Iterators.forEnumeration(request.getHeaderNames());
|
final UnmodifiableIterator<String> forEnumeration = Iterators.forEnumeration(request.getHeaderNames());
|
||||||
forEnumeration.forEachRemaining(header -> secruityToken.getHeaders().put(header, request.getHeader(header)));
|
forEnumeration.forEachRemaining(header -> secruityToken.getHeaders().put(header, request.getHeader(header)));
|
||||||
return secruityToken;
|
return secruityToken;
|
||||||
@@ -163,7 +174,7 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Object getPreAuthenticatedPrincipal(final HttpServletRequest request) {
|
protected Object getPreAuthenticatedPrincipal(final HttpServletRequest request) {
|
||||||
final TenantSecruityToken secruityToken = createTenantSecruityTokenVariables(request);
|
final TenantSecurityToken secruityToken = createTenantSecruityTokenVariables(request);
|
||||||
if (secruityToken == null) {
|
if (secruityToken == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -172,7 +183,7 @@ public abstract class AbstractHttpControllerAuthenticationFilter extends Abstrac
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Object getPreAuthenticatedCredentials(final HttpServletRequest request) {
|
protected Object getPreAuthenticatedCredentials(final HttpServletRequest request) {
|
||||||
final TenantSecruityToken secruityToken = createTenantSecruityTokenVariables(request);
|
final TenantSecurityToken secruityToken = createTenantSecruityTokenVariables(request);
|
||||||
if (secruityToken == null) {
|
if (secruityToken == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.security;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
||||||
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An pre-authenticated processing filter which add the
|
||||||
|
* {@link SpringEvalExpressions#CONTROLLER_DOWNLOAD_ROLE_ANONYMOUS} to the
|
||||||
|
* security context in case the anonymous download is allowed through
|
||||||
|
* configuration.
|
||||||
|
*/
|
||||||
|
public class HttpControllerPreAuthenticateAnonymousDownloadFilter extends AbstractHttpControllerAuthenticationFilter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param tenantConfigurationManagement
|
||||||
|
* the system management service to retrieve configuration
|
||||||
|
* properties
|
||||||
|
* @param tenantAware
|
||||||
|
* the tenant aware service to get configuration for the specific
|
||||||
|
* tenant
|
||||||
|
* @param systemSecurityContext
|
||||||
|
* the system security context
|
||||||
|
*/
|
||||||
|
public HttpControllerPreAuthenticateAnonymousDownloadFilter(
|
||||||
|
final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware,
|
||||||
|
final SystemSecurityContext systemSecurityContext) {
|
||||||
|
super(tenantConfigurationManagement, tenantAware, systemSecurityContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected PreAuthenficationFilter createControllerAuthenticationFilter() {
|
||||||
|
return new ControllerPreAuthenticatedAnonymousDownload(tenantConfigurationManagement, tenantAware,
|
||||||
|
systemSecurityContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -321,7 +321,8 @@ public class ArtifactManagement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean artifactIsOnlyUsedByOneSoftwareModule = true;
|
boolean artifactIsOnlyUsedByOneSoftwareModule = true;
|
||||||
for (LocalArtifact lArtifact : localArtifactRepository.findByGridFsFileName(existing.getGridFsFileName())) {
|
for (final LocalArtifact lArtifact : localArtifactRepository
|
||||||
|
.findByGridFsFileName(existing.getGridFsFileName())) {
|
||||||
if (!lArtifact.getSoftwareModule().isDeleted()
|
if (!lArtifact.getSoftwareModule().isDeleted()
|
||||||
&& lArtifact.getSoftwareModule().getId() != existing.getSoftwareModule().getId()) {
|
&& lArtifact.getSoftwareModule().getId() != existing.getSoftwareModule().getId()) {
|
||||||
artifactIsOnlyUsedByOneSoftwareModule = false;
|
artifactIsOnlyUsedByOneSoftwareModule = false;
|
||||||
@@ -403,7 +404,7 @@ public class ArtifactManagement {
|
|||||||
* if file could not be found in store
|
* if file could not be found in store
|
||||||
*/
|
*/
|
||||||
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_DOWNLOAD_ARTIFACT + SpringEvalExpressions.HAS_AUTH_OR
|
@PreAuthorize(SpringEvalExpressions.HAS_AUTH_DOWNLOAD_ARTIFACT + SpringEvalExpressions.HAS_AUTH_OR
|
||||||
+ SpringEvalExpressions.IS_CONTROLLER)
|
+ SpringEvalExpressions.HAS_CONTROLLER_DOWNLOAD)
|
||||||
public DbArtifact loadLocalArtifactBinary(@NotNull final LocalArtifact artifact) {
|
public DbArtifact loadLocalArtifactBinary(@NotNull final LocalArtifact artifact) {
|
||||||
final DbArtifact result = artifactRepository.getArtifactBySha1(artifact.getGridFsFileName());
|
final DbArtifact result = artifactRepository.getArtifactBySha1(artifact.getGridFsFileName());
|
||||||
if (result == null) {
|
if (result == null) {
|
||||||
|
|||||||
@@ -25,6 +25,11 @@
|
|||||||
<groupId>org.eclipse.hawkbit</groupId>
|
<groupId>org.eclipse.hawkbit</groupId>
|
||||||
<artifactId>hawkbit-repository</artifactId>
|
<artifactId>hawkbit-repository</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.eclipse.hawkbit</groupId>
|
||||||
|
<artifactId>hawkbit-core</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.hawkbit</groupId>
|
<groupId>org.eclipse.hawkbit</groupId>
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ import java.util.stream.Collectors;
|
|||||||
|
|
||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.api.ArtifactUrlHandler;
|
||||||
|
import org.eclipse.hawkbit.api.UrlProtocol;
|
||||||
import org.eclipse.hawkbit.controller.model.Artifact;
|
import org.eclipse.hawkbit.controller.model.Artifact;
|
||||||
import org.eclipse.hawkbit.controller.model.Chunk;
|
import org.eclipse.hawkbit.controller.model.Chunk;
|
||||||
import org.eclipse.hawkbit.controller.model.Config;
|
import org.eclipse.hawkbit.controller.model.Config;
|
||||||
@@ -29,27 +31,29 @@ import org.eclipse.hawkbit.repository.model.LocalArtifact;
|
|||||||
import org.eclipse.hawkbit.repository.model.Target;
|
import org.eclipse.hawkbit.repository.model.Target;
|
||||||
import org.eclipse.hawkbit.rest.resource.model.artifact.ArtifactHash;
|
import org.eclipse.hawkbit.rest.resource.model.artifact.ArtifactHash;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.hateoas.Link;
|
||||||
|
|
||||||
import com.google.common.base.Charsets;
|
import com.google.common.base.Charsets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class for the Controller API.
|
* Utility class for the Controller API.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public final class DataConversionHelper {
|
public final class DataConversionHelper {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
ArtifactUrlHandler artifactUrlHandler;
|
||||||
|
|
||||||
// utility class, private constructor.
|
// utility class, private constructor.
|
||||||
private DataConversionHelper() {
|
private DataConversionHelper() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static List<Chunk> createChunks(final String targetid, final Action uAction, final TenantAware tenantAware) {
|
static List<Chunk> createChunks(final String targetid, final Action uAction,
|
||||||
return uAction.getDistributionSet()
|
final ArtifactUrlHandler artifactUrlHandler) {
|
||||||
.getModules().stream().map(module -> new Chunk(mapChunkLegacyKeys(module.getType().getKey()),
|
return uAction.getDistributionSet().getModules().stream()
|
||||||
module.getVersion(), module.getName(), createArtifacts(targetid, module, tenantAware)))
|
.map(module -> new Chunk(mapChunkLegacyKeys(module.getType().getKey()), module.getVersion(),
|
||||||
|
module.getName(), createArtifacts(targetid, module, artifactUrlHandler)))
|
||||||
.collect(Collectors.toList());
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -72,23 +76,25 @@ public final class DataConversionHelper {
|
|||||||
* of the target
|
* of the target
|
||||||
* @param module
|
* @param module
|
||||||
* the software module
|
* the software module
|
||||||
* @param tenantAware
|
|
||||||
* of the tenant
|
|
||||||
* @return a list of artifacts or a empty list. Cannot be <null>.
|
* @return a list of artifacts or a empty list. Cannot be <null>.
|
||||||
*/
|
*/
|
||||||
public static List<Artifact> createArtifacts(final String targetid,
|
public static List<Artifact> createArtifacts(final String targetid,
|
||||||
final org.eclipse.hawkbit.repository.model.SoftwareModule module, final TenantAware tenantAware) {
|
final org.eclipse.hawkbit.repository.model.SoftwareModule module,
|
||||||
|
final ArtifactUrlHandler artifactUrlHandler) {
|
||||||
final List<Artifact> files = new ArrayList<>();
|
final List<Artifact> files = new ArrayList<>();
|
||||||
module.getLocalArtifacts().forEach(artifact -> {
|
module.getLocalArtifacts().forEach(artifact -> {
|
||||||
final Artifact file = new Artifact();
|
final Artifact file = new Artifact();
|
||||||
file.setHashes(new ArtifactHash(artifact.getSha1Hash(), artifact.getMd5Hash()));
|
file.setHashes(new ArtifactHash(artifact.getSha1Hash(), artifact.getMd5Hash()));
|
||||||
file.setFilename(artifact.getFilename());
|
file.setFilename(artifact.getFilename());
|
||||||
file.setSize(artifact.getSize());
|
file.setSize(artifact.getSize());
|
||||||
|
final String linkHttp = artifactUrlHandler.getUrl(targetid, artifact.getSoftwareModule().getId(),
|
||||||
file.add(linkTo(methodOn(RootController.class, tenantAware.getCurrentTenant()).downloadArtifact(targetid,
|
artifact.getFilename(), artifact.getSha1Hash(), UrlProtocol.HTTP);
|
||||||
artifact.getSoftwareModule().getId(), artifact.getFilename(), null, null)).withRel("download"));
|
final String linkHttps = artifactUrlHandler.getUrl(targetid, artifact.getSoftwareModule().getId(),
|
||||||
file.add(linkTo(methodOn(RootController.class, tenantAware.getCurrentTenant()).downloadArtifactMd5(targetid,
|
artifact.getFilename(), artifact.getSha1Hash(), UrlProtocol.HTTPS);
|
||||||
artifact.getSoftwareModule().getId(), artifact.getFilename(), null, null)).withRel("md5sum"));
|
file.add(new Link(linkHttps).withRel("download"));
|
||||||
|
file.add(new Link(linkHttps + ControllerConstants.ARTIFACT_MD5_DWNL_SUFFIX).withRel("md5sum"));
|
||||||
|
file.add(new Link(linkHttp).withRel("download-http"));
|
||||||
|
file.add(new Link(linkHttp + ControllerConstants.ARTIFACT_MD5_DWNL_SUFFIX).withRel("md5sum-http"));
|
||||||
|
|
||||||
files.add(file);
|
files.add(file);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import javax.servlet.http.HttpServletRequest;
|
|||||||
import javax.servlet.http.HttpServletResponse;
|
import javax.servlet.http.HttpServletResponse;
|
||||||
import javax.validation.Valid;
|
import javax.validation.Valid;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.api.ArtifactUrlHandler;
|
||||||
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
|
import org.eclipse.hawkbit.artifact.repository.model.DbArtifact;
|
||||||
import org.eclipse.hawkbit.cache.CacheWriteNotify;
|
import org.eclipse.hawkbit.cache.CacheWriteNotify;
|
||||||
import org.eclipse.hawkbit.controller.model.ActionFeedback;
|
import org.eclipse.hawkbit.controller.model.ActionFeedback;
|
||||||
@@ -84,11 +85,14 @@ public class RootController {
|
|||||||
@Autowired
|
@Autowired
|
||||||
private CacheWriteNotify cacheWriteNotify;
|
private CacheWriteNotify cacheWriteNotify;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private HawkbitSecurityProperties securityProperties;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private TenantAware tenantAware;
|
private TenantAware tenantAware;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private HawkbitSecurityProperties securityProperties;
|
private ArtifactUrlHandler artifactUrlHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns all artifacts of a given software module and target.
|
* Returns all artifacts of a given software module and target.
|
||||||
@@ -114,7 +118,7 @@ public class RootController {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ResponseEntity<>(DataConversionHelper.createArtifacts(targetid, softwareModule, tenantAware),
|
return new ResponseEntity<>(DataConversionHelper.createArtifacts(targetid, softwareModule, artifactUrlHandler),
|
||||||
HttpStatus.OK);
|
HttpStatus.OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,7 +307,7 @@ public class RootController {
|
|||||||
|
|
||||||
if (!action.isCancelingOrCanceled()) {
|
if (!action.isCancelingOrCanceled()) {
|
||||||
|
|
||||||
final List<Chunk> chunks = DataConversionHelper.createChunks(targetid, action, tenantAware);
|
final List<Chunk> chunks = DataConversionHelper.createChunks(targetid, action, artifactUrlHandler);
|
||||||
|
|
||||||
final HandlingType handlingType = action.isForce() ? HandlingType.FORCED : HandlingType.ATTEMPT;
|
final HandlingType handlingType = action.isForce() ? HandlingType.FORCED : HandlingType.ATTEMPT;
|
||||||
|
|
||||||
|
|||||||
@@ -170,15 +170,27 @@ public class DeploymentBaseTest extends AbstractIntegrationTestWithMongoDB {
|
|||||||
jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].hashes.sha1",
|
jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].hashes.sha1",
|
||||||
equalTo(artifact.getSha1Hash())))
|
equalTo(artifact.getSha1Hash())))
|
||||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.download.href",
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.download.href",
|
||||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||||
+ "/controller/v1/4712/softwaremodules/"
|
+ "/controller/v1/4712/softwaremodules/"
|
||||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||||
+ "/artifacts/test1")))
|
+ "/artifacts/test1")))
|
||||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.md5sum.href",
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.md5sum.href",
|
||||||
|
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||||
|
+ "/controller/v1/4712/softwaremodules/"
|
||||||
|
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||||
|
+ "/artifacts/test1.MD5SUM")))
|
||||||
|
|
||||||
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.download-http.href",
|
||||||
|
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||||
|
+ "/controller/v1/4712/softwaremodules/"
|
||||||
|
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||||
|
+ "/artifacts/test1")))
|
||||||
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.md5sum-http.href",
|
||||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||||
+ "/controller/v1/4712/softwaremodules/"
|
+ "/controller/v1/4712/softwaremodules/"
|
||||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||||
+ "/artifacts/test1.MD5SUM")))
|
+ "/artifacts/test1.MD5SUM")))
|
||||||
|
|
||||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].size", equalTo(5 * 1024)))
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].size", equalTo(5 * 1024)))
|
||||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].filename",
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].filename",
|
||||||
equalTo("test1.signature")))
|
equalTo("test1.signature")))
|
||||||
@@ -188,11 +200,21 @@ public class DeploymentBaseTest extends AbstractIntegrationTestWithMongoDB {
|
|||||||
jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].hashes.sha1",
|
jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].hashes.sha1",
|
||||||
equalTo(artifactSignature.getSha1Hash())))
|
equalTo(artifactSignature.getSha1Hash())))
|
||||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.download.href",
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.download.href",
|
||||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||||
+ "/controller/v1/4712/softwaremodules/"
|
+ "/controller/v1/4712/softwaremodules/"
|
||||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||||
+ "/artifacts/test1.signature")))
|
+ "/artifacts/test1.signature")))
|
||||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.md5sum.href",
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.md5sum.href",
|
||||||
|
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||||
|
+ "/controller/v1/4712/softwaremodules/"
|
||||||
|
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||||
|
+ "/artifacts/test1.signature.MD5SUM")))
|
||||||
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.download-http.href",
|
||||||
|
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||||
|
+ "/controller/v1/4712/softwaremodules/"
|
||||||
|
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||||
|
+ "/artifacts/test1.signature")))
|
||||||
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.md5sum-http.href",
|
||||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||||
+ "/controller/v1/4712/softwaremodules/"
|
+ "/controller/v1/4712/softwaremodules/"
|
||||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||||
@@ -293,12 +315,12 @@ public class DeploymentBaseTest extends AbstractIntegrationTestWithMongoDB {
|
|||||||
jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].hashes.sha1",
|
jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].hashes.sha1",
|
||||||
equalTo(artifact.getSha1Hash())))
|
equalTo(artifact.getSha1Hash())))
|
||||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.download.href",
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.download.href",
|
||||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||||
+ "/controller/v1/4712/softwaremodules/"
|
+ "/controller/v1/4712/softwaremodules/"
|
||||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||||
+ "/artifacts/test1")))
|
+ "/artifacts/test1")))
|
||||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.md5sum.href",
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.md5sum.href",
|
||||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||||
+ "/controller/v1/4712/softwaremodules/"
|
+ "/controller/v1/4712/softwaremodules/"
|
||||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||||
+ "/artifacts/test1.MD5SUM")))
|
+ "/artifacts/test1.MD5SUM")))
|
||||||
@@ -311,11 +333,21 @@ public class DeploymentBaseTest extends AbstractIntegrationTestWithMongoDB {
|
|||||||
jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].hashes.sha1",
|
jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].hashes.sha1",
|
||||||
equalTo(artifactSignature.getSha1Hash())))
|
equalTo(artifactSignature.getSha1Hash())))
|
||||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.download.href",
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.download.href",
|
||||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||||
+ "/controller/v1/4712/softwaremodules/"
|
+ "/controller/v1/4712/softwaremodules/"
|
||||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||||
+ "/artifacts/test1.signature")))
|
+ "/artifacts/test1.signature")))
|
||||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.md5sum.href",
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.md5sum.href",
|
||||||
|
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||||
|
+ "/controller/v1/4712/softwaremodules/"
|
||||||
|
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||||
|
+ "/artifacts/test1.signature.MD5SUM")))
|
||||||
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.download-http.href",
|
||||||
|
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||||
|
+ "/controller/v1/4712/softwaremodules/"
|
||||||
|
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||||
|
+ "/artifacts/test1.signature")))
|
||||||
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.md5sum-http.href",
|
||||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||||
+ "/controller/v1/4712/softwaremodules/"
|
+ "/controller/v1/4712/softwaremodules/"
|
||||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||||
@@ -409,15 +441,25 @@ public class DeploymentBaseTest extends AbstractIntegrationTestWithMongoDB {
|
|||||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].filename", equalTo("test1")))
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].filename", equalTo("test1")))
|
||||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].hashes.md5",
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].hashes.md5",
|
||||||
equalTo(artifact.getMd5Hash())))
|
equalTo(artifact.getMd5Hash())))
|
||||||
.andExpect(
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].hashes.sha1",
|
||||||
jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0].hashes.sha1",
|
equalTo(artifact.getSha1Hash())))
|
||||||
equalTo(artifact.getSha1Hash())))
|
|
||||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.download.href",
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.download.href",
|
||||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||||
+ "/controller/v1/4712/softwaremodules/"
|
+ "/controller/v1/4712/softwaremodules/"
|
||||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||||
+ "/artifacts/test1")))
|
+ "/artifacts/test1")))
|
||||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.md5sum.href",
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.md5sum.href",
|
||||||
|
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||||
|
+ "/controller/v1/4712/softwaremodules/"
|
||||||
|
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||||
|
+ "/artifacts/test1.MD5SUM")))
|
||||||
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.download-http.href",
|
||||||
|
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||||
|
+ "/controller/v1/4712/softwaremodules/"
|
||||||
|
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||||
|
+ "/artifacts/test1")))
|
||||||
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[0]._links.md5sum-http.href",
|
||||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||||
+ "/controller/v1/4712/softwaremodules/"
|
+ "/controller/v1/4712/softwaremodules/"
|
||||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||||
@@ -431,15 +473,27 @@ public class DeploymentBaseTest extends AbstractIntegrationTestWithMongoDB {
|
|||||||
jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].hashes.sha1",
|
jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1].hashes.sha1",
|
||||||
equalTo(artifactSignature.getSha1Hash())))
|
equalTo(artifactSignature.getSha1Hash())))
|
||||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.download.href",
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.download.href",
|
||||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||||
+ "/controller/v1/4712/softwaremodules/"
|
+ "/controller/v1/4712/softwaremodules/"
|
||||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||||
+ "/artifacts/test1.signature")))
|
+ "/artifacts/test1.signature")))
|
||||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.md5sum.href",
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.md5sum.href",
|
||||||
|
equalTo("https://localhost/" + tenantAware.getCurrentTenant()
|
||||||
|
+ "/controller/v1/4712/softwaremodules/"
|
||||||
|
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||||
|
+ "/artifacts/test1.signature.MD5SUM")))
|
||||||
|
|
||||||
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.download-http.href",
|
||||||
|
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||||
|
+ "/controller/v1/4712/softwaremodules/"
|
||||||
|
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||||
|
+ "/artifacts/test1.signature")))
|
||||||
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==os)][0].artifacts[1]._links.md5sum-http.href",
|
||||||
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
equalTo("http://localhost/" + tenantAware.getCurrentTenant()
|
||||||
+ "/controller/v1/4712/softwaremodules/"
|
+ "/controller/v1/4712/softwaremodules/"
|
||||||
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
+ findDistributionSetByAction.findFirstModuleByType(osType).getId()
|
||||||
+ "/artifacts/test1.signature.MD5SUM")))
|
+ "/artifacts/test1.signature.MD5SUM")))
|
||||||
|
|
||||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==bApp)][0].version",
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==bApp)][0].version",
|
||||||
equalTo(ds.findFirstModuleByType(appType).getVersion())))
|
equalTo(ds.findFirstModuleByType(appType).getVersion())))
|
||||||
.andExpect(jsonPath("$deployment.chunks[?(@.part==bApp)][0].name",
|
.andExpect(jsonPath("$deployment.chunks[?(@.part==bApp)][0].name",
|
||||||
|
|||||||
@@ -182,6 +182,12 @@ public final class SpPermission {
|
|||||||
*/
|
*/
|
||||||
public static final String CONTROLLER_ROLE_ANONYMOUS = "ROLE_CONTROLLER_ANONYMOUS";
|
public static final String CONTROLLER_ROLE_ANONYMOUS = "ROLE_CONTROLLER_ANONYMOUS";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The role which contains in the spring security context in case an
|
||||||
|
* controller is authenticated to download artifacts.
|
||||||
|
*/
|
||||||
|
public static final String CONTROLLER_DOWNLOAD_ROLE = "ROLE_CONTROLLER_DOWNLOAD";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The role which contains the spring security context in case the
|
* The role which contains the spring security context in case the
|
||||||
* system is executing code which is necessary to be privileged.
|
* system is executing code which is necessary to be privileged.
|
||||||
@@ -275,8 +281,16 @@ public final class SpPermission {
|
|||||||
* context contains the anoynmous role or the controller specific role
|
* context contains the anoynmous role or the controller specific role
|
||||||
* {@link SpPermission#CONTROLLER_ROLE}.
|
* {@link SpPermission#CONTROLLER_ROLE}.
|
||||||
*/
|
*/
|
||||||
public static final String IS_CONTROLLER = "hasAnyRole('" + CONTROLLER_ROLE_ANONYMOUS + "', '"
|
public static final String IS_CONTROLLER = "hasAnyRole('" + CONTROLLER_ROLE_ANONYMOUS + "', '" + CONTROLLER_ROLE
|
||||||
+ CONTROLLER_ROLE + "')";
|
+ "')";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Spring security eval hasAuthority expression to check if the spring
|
||||||
|
* context contains the role to allow controllers to download specific
|
||||||
|
* role {@link SpPermission#CONTROLLER_DOWNLOAD_ROLE}.
|
||||||
|
*/
|
||||||
|
public static final String HAS_CONTROLLER_DOWNLOAD = HAS_AUTH_PREFIX + CONTROLLER_DOWNLOAD_ROLE
|
||||||
|
+ HAS_AUTH_SUFFIX;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spring security eval hasAnyRole expression to check if the spring
|
* Spring security eval hasAnyRole expression to check if the spring
|
||||||
|
|||||||
@@ -35,7 +35,32 @@
|
|||||||
<groupId>org.springframework.security</groupId>
|
<groupId>org.springframework.security</groupId>
|
||||||
<artifactId>spring-security-web</artifactId>
|
<artifactId>spring-security-web</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- TEST -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.easytesting</groupId>
|
||||||
|
<artifactId>fest-assert-core</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.easytesting</groupId>
|
||||||
|
<artifactId>fest-assert</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.mockito</groupId>
|
||||||
|
<artifactId>mockito-core</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ru.yandex.qatools.allure</groupId>
|
||||||
|
<artifactId>allure-junit-adaptor</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
</project>
|
</project>
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.security;
|
package org.eclipse.hawkbit.security;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
|
import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
||||||
@@ -42,15 +42,15 @@ public abstract class AbstractControllerAuthenticationFilter implements PreAuthe
|
|||||||
protected abstract TenantConfigurationKey getTenantConfigurationKey();
|
protected abstract TenantConfigurationKey getTenantConfigurationKey();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnable(final TenantSecruityToken secruityToken) {
|
public boolean isEnable(final TenantSecurityToken secruityToken) {
|
||||||
return tenantAware.runAsTenant(secruityToken.getTenant(), configurationKeyTenantRunner);
|
return tenantAware.runAsTenant(secruityToken.getTenant(), configurationKeyTenantRunner);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract HeaderAuthentication getPreAuthenticatedPrincipal(TenantSecruityToken secruityToken);
|
public abstract HeaderAuthentication getPreAuthenticatedPrincipal(TenantSecurityToken secruityToken);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public abstract HeaderAuthentication getPreAuthenticatedCredentials(TenantSecruityToken secruityToken);
|
public abstract HeaderAuthentication getPreAuthenticatedCredentials(TenantSecurityToken secruityToken);
|
||||||
|
|
||||||
private final class SecurityConfigurationKeyTenantRunner implements TenantAware.TenantRunner<Boolean> {
|
private final class SecurityConfigurationKeyTenantRunner implements TenantAware.TenantRunner<Boolean> {
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.security;
|
package org.eclipse.hawkbit.security;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
|
import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Filter for device which download via coap.
|
* A Filter for device which download via coap.
|
||||||
@@ -19,19 +19,19 @@ import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
|
|||||||
public class CoapAnonymousPreAuthenticatedFilter implements PreAuthenficationFilter {
|
public class CoapAnonymousPreAuthenticatedFilter implements PreAuthenficationFilter {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HeaderAuthentication getPreAuthenticatedPrincipal(final TenantSecruityToken secruityToken) {
|
public HeaderAuthentication getPreAuthenticatedPrincipal(final TenantSecurityToken secruityToken) {
|
||||||
return new HeaderAuthentication(secruityToken.getControllerId(), TenantSecruityToken.COAP_TOKEN_VALUE);
|
return new HeaderAuthentication(secruityToken.getControllerId(), TenantSecurityToken.COAP_TOKEN_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HeaderAuthentication getPreAuthenticatedCredentials(final TenantSecruityToken secruityToken) {
|
public HeaderAuthentication getPreAuthenticatedCredentials(final TenantSecurityToken secruityToken) {
|
||||||
return new HeaderAuthentication(secruityToken.getControllerId(), TenantSecruityToken.COAP_TOKEN_VALUE);
|
return new HeaderAuthentication(secruityToken.getControllerId(), TenantSecurityToken.COAP_TOKEN_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isEnable(final TenantSecruityToken secruityToken) {
|
public boolean isEnable(final TenantSecurityToken secruityToken) {
|
||||||
final String authHeader = secruityToken.getHeader(TenantSecruityToken.COAP_AUTHORIZATION_HEADER);
|
final String authHeader = secruityToken.getHeader(TenantSecurityToken.COAP_AUTHORIZATION_HEADER);
|
||||||
return TenantSecruityToken.COAP_TOKEN_VALUE.equals(authHeader);
|
return TenantSecurityToken.COAP_TOKEN_VALUE.equals(authHeader);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.security;
|
package org.eclipse.hawkbit.security;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
|
import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
|
||||||
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
import org.eclipse.hawkbit.im.authentication.SpPermission;
|
||||||
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
|
import org.eclipse.hawkbit.im.authentication.TenantAwareAuthenticationDetails;
|
||||||
import org.eclipse.hawkbit.repository.ControllerManagement;
|
import org.eclipse.hawkbit.repository.ControllerManagement;
|
||||||
@@ -67,8 +67,8 @@ public class ControllerPreAuthenticateSecurityTokenFilter extends AbstractContro
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HeaderAuthentication getPreAuthenticatedPrincipal(final TenantSecruityToken secruityToken) {
|
public HeaderAuthentication getPreAuthenticatedPrincipal(final TenantSecurityToken secruityToken) {
|
||||||
final String authHeader = secruityToken.getHeader(TenantSecruityToken.AUTHORIZATION_HEADER);
|
final String authHeader = secruityToken.getHeader(TenantSecurityToken.AUTHORIZATION_HEADER);
|
||||||
if ((authHeader != null) && authHeader.startsWith(TARGET_SECURITY_TOKEN_AUTH_SCHEME)) {
|
if ((authHeader != null) && authHeader.startsWith(TARGET_SECURITY_TOKEN_AUTH_SCHEME)) {
|
||||||
LOGGER.debug("found authorization header with scheme {} using target security token for authentication",
|
LOGGER.debug("found authorization header with scheme {} using target security token for authentication",
|
||||||
TARGET_SECURITY_TOKEN_AUTH_SCHEME);
|
TARGET_SECURITY_TOKEN_AUTH_SCHEME);
|
||||||
@@ -81,7 +81,7 @@ public class ControllerPreAuthenticateSecurityTokenFilter extends AbstractContro
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HeaderAuthentication getPreAuthenticatedCredentials(final TenantSecruityToken secruityToken) {
|
public HeaderAuthentication getPreAuthenticatedCredentials(final TenantSecurityToken secruityToken) {
|
||||||
final String securityToken = tenantAware.runAsTenant(secruityToken.getTenant(),
|
final String securityToken = tenantAware.runAsTenant(secruityToken.getTenant(),
|
||||||
new GetSecurityTokenTenantRunner(secruityToken.getTenant(), secruityToken.getControllerId()));
|
new GetSecurityTokenTenantRunner(secruityToken.getTenant(), secruityToken.getControllerId()));
|
||||||
return new HeaderAuthentication(secruityToken.getControllerId(), securityToken);
|
return new HeaderAuthentication(secruityToken.getControllerId(), securityToken);
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.security;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
|
||||||
|
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
||||||
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
|
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An pre-authenticated processing filter which add the
|
||||||
|
* {@link SpringEvalExpressions#CONTROLLER_DOWNLOAD_ROLE_ANONYMOUS} to the
|
||||||
|
* security context in case the anonymous download is allowed through
|
||||||
|
* configuration.
|
||||||
|
*/
|
||||||
|
public class ControllerPreAuthenticatedAnonymousDownload extends AbstractControllerAuthenticationFilter {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*
|
||||||
|
* @param tenantConfigurationManagement
|
||||||
|
* the tenant management service to retrieve configuration
|
||||||
|
* properties
|
||||||
|
* @param tenantAware
|
||||||
|
* the tenant aware service to get configuration for the specific
|
||||||
|
* tenant
|
||||||
|
* @param systemSecurityContext
|
||||||
|
* the system security context to get access to tenant
|
||||||
|
* configuration
|
||||||
|
*/
|
||||||
|
public ControllerPreAuthenticatedAnonymousDownload(
|
||||||
|
final TenantConfigurationManagement tenantConfigurationManagement, final TenantAware tenantAware,
|
||||||
|
final SystemSecurityContext systemSecurityContext) {
|
||||||
|
super(tenantConfigurationManagement, tenantAware, systemSecurityContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HeaderAuthentication getPreAuthenticatedPrincipal(final TenantSecurityToken secruityToken) {
|
||||||
|
return new HeaderAuthentication(secruityToken.getControllerId(), secruityToken.getControllerId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HeaderAuthentication getPreAuthenticatedCredentials(final TenantSecurityToken secruityToken) {
|
||||||
|
return new HeaderAuthentication(secruityToken.getControllerId(), secruityToken.getControllerId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected TenantConfigurationKey getTenantConfigurationKey() {
|
||||||
|
return TenantConfigurationKey.ANONYMOUS_DOWNLOAD_MODE_ENABLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Collection<GrantedAuthority> getSuccessfulAuthenticationAuthorities() {
|
||||||
|
return Lists.newArrayList(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_DOWNLOAD_ROLE));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.security;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An anonymous controller filter which is only enabled in case of anonymous
|
||||||
|
* access is granted. This should only be for development purposes.
|
||||||
|
*
|
||||||
|
* @see DdiSecurityProperties
|
||||||
|
*/
|
||||||
|
public class ControllerPreAuthenticatedAnonymousFilter implements PreAuthenficationFilter {
|
||||||
|
|
||||||
|
private final DdiSecurityProperties ddiSecurityConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ddiSecurityConfiguration
|
||||||
|
* the security configuration which holds the configuration if
|
||||||
|
* anonymous is enabled or not
|
||||||
|
*/
|
||||||
|
public ControllerPreAuthenticatedAnonymousFilter(final DdiSecurityProperties ddiSecurityConfiguration) {
|
||||||
|
this.ddiSecurityConfiguration = ddiSecurityConfiguration;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HeaderAuthentication getPreAuthenticatedPrincipal(final TenantSecurityToken secruityToken) {
|
||||||
|
return new HeaderAuthentication(secruityToken.getControllerId(), secruityToken.getControllerId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public HeaderAuthentication getPreAuthenticatedCredentials(final TenantSecurityToken secruityToken) {
|
||||||
|
return new HeaderAuthentication(secruityToken.getControllerId(), secruityToken.getControllerId());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isEnable(final TenantSecurityToken secruityToken) {
|
||||||
|
return ddiSecurityConfiguration.getAuthentication().getAnonymous().isEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.security;
|
package org.eclipse.hawkbit.security;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
|
import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
||||||
@@ -56,8 +56,8 @@ public class ControllerPreAuthenticatedGatewaySecurityTokenFilter extends Abstra
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HeaderAuthentication getPreAuthenticatedPrincipal(final TenantSecruityToken secruityToken) {
|
public HeaderAuthentication getPreAuthenticatedPrincipal(final TenantSecurityToken secruityToken) {
|
||||||
final String authHeader = secruityToken.getHeader(TenantSecruityToken.AUTHORIZATION_HEADER);
|
final String authHeader = secruityToken.getHeader(TenantSecurityToken.AUTHORIZATION_HEADER);
|
||||||
if ((authHeader != null) && authHeader.startsWith(GATEWAY_SECURITY_TOKEN_AUTH_SCHEME)) {
|
if ((authHeader != null) && authHeader.startsWith(GATEWAY_SECURITY_TOKEN_AUTH_SCHEME)) {
|
||||||
LOGGER.debug("found authorization header with scheme {} using target security token for authentication",
|
LOGGER.debug("found authorization header with scheme {} using target security token for authentication",
|
||||||
GATEWAY_SECURITY_TOKEN_AUTH_SCHEME);
|
GATEWAY_SECURITY_TOKEN_AUTH_SCHEME);
|
||||||
@@ -71,7 +71,7 @@ public class ControllerPreAuthenticatedGatewaySecurityTokenFilter extends Abstra
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HeaderAuthentication getPreAuthenticatedCredentials(final TenantSecruityToken secruityToken) {
|
public HeaderAuthentication getPreAuthenticatedCredentials(final TenantSecurityToken secruityToken) {
|
||||||
final String gatewayToken = tenantAware.runAsTenant(secruityToken.getTenant(),
|
final String gatewayToken = tenantAware.runAsTenant(secruityToken.getTenant(),
|
||||||
gatewaySecurityTokenKeyConfigRunner);
|
gatewaySecurityTokenKeyConfigRunner);
|
||||||
return new HeaderAuthentication(secruityToken.getControllerId(), gatewayToken);
|
return new HeaderAuthentication(secruityToken.getControllerId(), gatewayToken);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.security;
|
package org.eclipse.hawkbit.security;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
|
import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
|
||||||
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
import org.eclipse.hawkbit.tenancy.TenantAware;
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
||||||
@@ -18,7 +18,7 @@ import org.slf4j.LoggerFactory;
|
|||||||
/**
|
/**
|
||||||
* An pre-authenticated processing filter which extracts the principal from a
|
* An pre-authenticated processing filter which extracts the principal from a
|
||||||
* request URI and the credential from a request header in a the
|
* request URI and the credential from a request header in a the
|
||||||
* {@link TenantSecruityToken}.
|
* {@link TenantSecurityToken}.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
@@ -75,7 +75,7 @@ public class ControllerPreAuthenticatedSecurityHeaderFilter extends AbstractCont
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HeaderAuthentication getPreAuthenticatedPrincipal(final TenantSecruityToken secruityToken) {
|
public HeaderAuthentication getPreAuthenticatedPrincipal(final TenantSecurityToken secruityToken) {
|
||||||
// retrieve the common name header and the authority name header from
|
// retrieve the common name header and the authority name header from
|
||||||
// the http request and
|
// the http request and
|
||||||
// combine them together
|
// combine them together
|
||||||
@@ -97,7 +97,7 @@ public class ControllerPreAuthenticatedSecurityHeaderFilter extends AbstractCont
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public HeaderAuthentication getPreAuthenticatedCredentials(final TenantSecruityToken secruityToken) {
|
public HeaderAuthentication getPreAuthenticatedCredentials(final TenantSecurityToken secruityToken) {
|
||||||
final String authorityNameConfigurationValue = tenantAware.runAsTenant(secruityToken.getTenant(),
|
final String authorityNameConfigurationValue = tenantAware.runAsTenant(secruityToken.getTenant(),
|
||||||
sslIssuerNameConfigTenantRunner);
|
sslIssuerNameConfigTenantRunner);
|
||||||
String controllerId = secruityToken.getControllerId();
|
String controllerId = secruityToken.getControllerId();
|
||||||
@@ -117,7 +117,7 @@ public class ControllerPreAuthenticatedSecurityHeaderFilter extends AbstractCont
|
|||||||
* It's ok if we find the the hash in any the trusted CA chain to accept
|
* It's ok if we find the the hash in any the trusted CA chain to accept
|
||||||
* this request for this tenant.
|
* this request for this tenant.
|
||||||
*/
|
*/
|
||||||
private String getIssuerHashHeader(final TenantSecruityToken secruityToken, final String knownIssuerHash) {
|
private String getIssuerHashHeader(final TenantSecurityToken secruityToken, final String knownIssuerHash) {
|
||||||
// iterate over the headers until we get a null header.
|
// iterate over the headers until we get a null header.
|
||||||
int iHeader = 1;
|
int iHeader = 1;
|
||||||
String foundHash;
|
String foundHash;
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ public class PreAuthTokenSourceTrustAuthenticationProvider implements Authentica
|
|||||||
if (successAuthentication) {
|
if (successAuthentication) {
|
||||||
final Collection<GrantedAuthority> controllerAuthorities = new ArrayList<>();
|
final Collection<GrantedAuthority> controllerAuthorities = new ArrayList<>();
|
||||||
controllerAuthorities.add(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE));
|
controllerAuthorities.add(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_ROLE));
|
||||||
|
controllerAuthorities.add(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_DOWNLOAD_ROLE));
|
||||||
final PreAuthenticatedAuthenticationToken successToken = new PreAuthenticatedAuthenticationToken(principal,
|
final PreAuthenticatedAuthenticationToken successToken = new PreAuthenticatedAuthenticationToken(principal,
|
||||||
credentials, controllerAuthorities);
|
credentials, controllerAuthorities);
|
||||||
successToken.setDetails(tokenDetails);
|
successToken.setDetails(tokenDetails);
|
||||||
|
|||||||
@@ -8,7 +8,12 @@
|
|||||||
*/
|
*/
|
||||||
package org.eclipse.hawkbit.security;
|
package org.eclipse.hawkbit.security;
|
||||||
|
|
||||||
import org.eclipse.hawkbit.dmf.json.model.TenantSecruityToken;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.dmf.json.model.TenantSecurityToken;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for Pre Authenfication.
|
* Interface for Pre Authenfication.
|
||||||
@@ -25,7 +30,7 @@ public interface PreAuthenficationFilter {
|
|||||||
* the secruity info
|
* the secruity info
|
||||||
* @return <true> is enabled <false> diabled
|
* @return <true> is enabled <false> diabled
|
||||||
*/
|
*/
|
||||||
boolean isEnable(TenantSecruityToken secruityToken);
|
boolean isEnable(TenantSecurityToken secruityToken);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract the principal information from the current secruityToken.
|
* Extract the principal information from the current secruityToken.
|
||||||
@@ -34,7 +39,7 @@ public interface PreAuthenficationFilter {
|
|||||||
* the secruityToken
|
* the secruityToken
|
||||||
* @return the extracted tenant and controller id
|
* @return the extracted tenant and controller id
|
||||||
*/
|
*/
|
||||||
HeaderAuthentication getPreAuthenticatedPrincipal(TenantSecruityToken secruityToken);
|
HeaderAuthentication getPreAuthenticatedPrincipal(TenantSecurityToken secruityToken);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract the principal credentials from the current secruityToken.
|
* Extract the principal credentials from the current secruityToken.
|
||||||
@@ -43,6 +48,18 @@ public interface PreAuthenficationFilter {
|
|||||||
* the secruityToken
|
* the secruityToken
|
||||||
* @return the extracted tenant and controller id
|
* @return the extracted tenant and controller id
|
||||||
*/
|
*/
|
||||||
HeaderAuthentication getPreAuthenticatedCredentials(TenantSecruityToken secruityToken);
|
HeaderAuthentication getPreAuthenticatedCredentials(TenantSecurityToken secruityToken);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allows to add additional authorities to the successful authenticated
|
||||||
|
* token.
|
||||||
|
*
|
||||||
|
* @return the authorities granted to the principal, or an empty collection
|
||||||
|
* if the token has not been authenticated. Never null.
|
||||||
|
* @see Authentication#getAuthorities()
|
||||||
|
*/
|
||||||
|
default Collection<GrantedAuthority> getSuccessfulAuthenticationAuthorities() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.security;
|
||||||
|
|
||||||
|
import static org.fest.assertions.Assertions.assertThat;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.im.authentication.SpPermission.SpringEvalExpressions;
|
||||||
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
|
import org.eclipse.hawkbit.tenancy.TenantAware;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
|
|
||||||
|
import ru.yandex.qatools.allure.annotations.Features;
|
||||||
|
import ru.yandex.qatools.allure.annotations.Stories;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Michael Hirsch
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
@Features("Unit Tests - Security")
|
||||||
|
@Stories("Exclude path aware shallow ETag filter")
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class ControllerPreAuthenticatedAnonymousDownloadTest {
|
||||||
|
|
||||||
|
private ControllerPreAuthenticatedAnonymousDownload underTest;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private TenantConfigurationManagement tenantConfigurationManagementMock;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private TenantAware tenantAwareMock;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void before() {
|
||||||
|
underTest = new ControllerPreAuthenticatedAnonymousDownload(tenantConfigurationManagementMock, tenantAwareMock,
|
||||||
|
new SystemSecurityContext(tenantAwareMock));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void useCorrectTenantConfiguationKey() {
|
||||||
|
assertThat(underTest.getTenantConfigurationKey()).as("Should be using the correct tenant configuration key")
|
||||||
|
.isEqualTo(underTest.getTenantConfigurationKey());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void successfulAuthenticationAdditionalAuthoritiesForDownload() {
|
||||||
|
assertThat(underTest.getSuccessfulAuthenticationAuthorities())
|
||||||
|
.as("Additional authorities should be containing the download anonymous role")
|
||||||
|
.contains(new SimpleGrantedAuthority(SpringEvalExpressions.CONTROLLER_DOWNLOAD_ROLE));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,9 +30,6 @@ import com.vaadin.ui.VerticalLayout;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* View to configure the authentication mode.
|
* View to configure the authentication mode.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@SpringComponent
|
@SpringComponent
|
||||||
@ViewScope
|
@ViewScope
|
||||||
|
|||||||
@@ -14,8 +14,8 @@ import java.util.List;
|
|||||||
import com.vaadin.ui.CustomComponent;
|
import com.vaadin.ui.CustomComponent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* base class for all configuration views. This class implements the logic for
|
* Base class for all configuration views. This class implements the logic for
|
||||||
* the handling of the
|
* the handling of the configurations in a consistent way.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public abstract class BaseConfigurationView extends CustomComponent implements ConfigurationGroup {
|
public abstract class BaseConfigurationView extends CustomComponent implements ConfigurationGroup {
|
||||||
|
|||||||
@@ -11,9 +11,8 @@ package org.eclipse.hawkbit.ui.tenantconfiguration;
|
|||||||
import com.vaadin.ui.Component;
|
import com.vaadin.ui.Component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Interface that all system configurations have to implement to save and undo
|
||||||
*
|
* their customized changes.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public interface ConfigurationGroup extends Component, ConfigurationItem {
|
public interface ConfigurationGroup extends Component, ConfigurationItem {
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ package org.eclipse.hawkbit.ui.tenantconfiguration;
|
|||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* represents an configurationItem, which can be modified by the user
|
* Represents an configurationItem, which can be modified by the user
|
||||||
*/
|
*/
|
||||||
public interface ConfigurationItem {
|
public interface ConfigurationItem {
|
||||||
|
|
||||||
|
|||||||
@@ -33,9 +33,6 @@ import com.vaadin.ui.VerticalLayout;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Default DistributionSet Panel.
|
* Default DistributionSet Panel.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@SpringComponent
|
@SpringComponent
|
||||||
@ViewScope
|
@ViewScope
|
||||||
|
|||||||
@@ -0,0 +1,119 @@
|
|||||||
|
/**
|
||||||
|
* Copyright (c) 2015 Bosch Software Innovations GmbH and others.
|
||||||
|
*
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*/
|
||||||
|
package org.eclipse.hawkbit.ui.tenantconfiguration;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
|
||||||
|
import org.eclipse.hawkbit.repository.TenantConfigurationManagement;
|
||||||
|
import org.eclipse.hawkbit.repository.model.TenantConfigurationValue;
|
||||||
|
import org.eclipse.hawkbit.tenancy.configuration.TenantConfigurationKey;
|
||||||
|
import org.eclipse.hawkbit.ui.components.SPUIComponentProvider;
|
||||||
|
import org.eclipse.hawkbit.ui.utils.I18N;
|
||||||
|
import org.eclipse.hawkbit.ui.utils.SPUIComponetIdProvider;
|
||||||
|
import org.eclipse.hawkbit.ui.utils.SPUILabelDefinitions;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
|
import com.vaadin.spring.annotation.SpringComponent;
|
||||||
|
import com.vaadin.spring.annotation.ViewScope;
|
||||||
|
import com.vaadin.ui.Alignment;
|
||||||
|
import com.vaadin.ui.CheckBox;
|
||||||
|
import com.vaadin.ui.GridLayout;
|
||||||
|
import com.vaadin.ui.Label;
|
||||||
|
import com.vaadin.ui.Panel;
|
||||||
|
import com.vaadin.ui.VerticalLayout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* View to enable anonymous download.
|
||||||
|
*/
|
||||||
|
@SpringComponent
|
||||||
|
@ViewScope
|
||||||
|
public class DownloadAnonymousConfigurationView extends BaseConfigurationView
|
||||||
|
implements ConfigurationItem.ConfigurationItemChangeListener {
|
||||||
|
|
||||||
|
private static final String DIST_CHECKBOX_STYLE = "dist-checkbox-style";
|
||||||
|
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private I18N i18n;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private transient TenantConfigurationManagement tenantConfigurationManagement;
|
||||||
|
|
||||||
|
boolean anonymousDownloadEnabled;
|
||||||
|
|
||||||
|
private CheckBox downloadAnonymousCheckBox;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize Default Download Anonymous layout.
|
||||||
|
*/
|
||||||
|
@PostConstruct
|
||||||
|
public void init() {
|
||||||
|
|
||||||
|
final TenantConfigurationValue<Boolean> value = tenantConfigurationManagement
|
||||||
|
.getConfigurationValue(TenantConfigurationKey.ANONYMOUS_DOWNLOAD_MODE_ENABLED, Boolean.class);
|
||||||
|
anonymousDownloadEnabled = value.getValue();
|
||||||
|
|
||||||
|
final Panel rootPanel = new Panel();
|
||||||
|
rootPanel.setSizeFull();
|
||||||
|
rootPanel.addStyleName("config-panel");
|
||||||
|
|
||||||
|
final VerticalLayout vLayout = new VerticalLayout();
|
||||||
|
vLayout.setMargin(true);
|
||||||
|
vLayout.setSizeFull();
|
||||||
|
|
||||||
|
final Label headerDisSetType = new Label(i18n.get("enonymous.download.title"));
|
||||||
|
headerDisSetType.addStyleName("config-panel-header");
|
||||||
|
vLayout.addComponent(headerDisSetType);
|
||||||
|
|
||||||
|
final GridLayout gridLayout = new GridLayout(2, 1);
|
||||||
|
gridLayout.setSpacing(true);
|
||||||
|
gridLayout.setImmediate(true);
|
||||||
|
gridLayout.setColumnExpandRatio(1, 1.0F);
|
||||||
|
gridLayout.setSizeFull();
|
||||||
|
|
||||||
|
downloadAnonymousCheckBox = SPUIComponentProvider.getCheckBox("", DIST_CHECKBOX_STYLE, null, false, "");
|
||||||
|
downloadAnonymousCheckBox.setValue(anonymousDownloadEnabled);
|
||||||
|
downloadAnonymousCheckBox.addValueChangeListener(event -> configurationHasChanged());
|
||||||
|
downloadAnonymousCheckBox.setId(SPUIComponetIdProvider.SYSTEM_CONFIGURATION_ANONYMOUS_DOWNLOAD_CHECKBOX);
|
||||||
|
|
||||||
|
gridLayout.addComponent(downloadAnonymousCheckBox);
|
||||||
|
|
||||||
|
final Label configurationLabel = SPUIComponentProvider.getLabel(i18n.get("enonymous.download.label"),
|
||||||
|
SPUILabelDefinitions.SP_LABEL_SIMPLE);
|
||||||
|
gridLayout.addComponent(configurationLabel);
|
||||||
|
gridLayout.setComponentAlignment(configurationLabel, Alignment.MIDDLE_LEFT);
|
||||||
|
|
||||||
|
vLayout.addComponent(gridLayout);
|
||||||
|
|
||||||
|
rootPanel.setContent(vLayout);
|
||||||
|
setCompositionRoot(rootPanel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configurationHasChanged() {
|
||||||
|
anonymousDownloadEnabled = downloadAnonymousCheckBox.getValue();
|
||||||
|
notifyConfigurationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void save() {
|
||||||
|
tenantConfigurationManagement.addOrUpdateConfiguration(TenantConfigurationKey.ANONYMOUS_DOWNLOAD_MODE_ENABLED,
|
||||||
|
downloadAnonymousCheckBox.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void undo() {
|
||||||
|
final TenantConfigurationValue<Boolean> value = tenantConfigurationManagement
|
||||||
|
.getConfigurationValue(TenantConfigurationKey.ANONYMOUS_DOWNLOAD_MODE_ENABLED, Boolean.class);
|
||||||
|
anonymousDownloadEnabled = value.getValue();
|
||||||
|
downloadAnonymousCheckBox.setValue(anonymousDownloadEnabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -29,8 +29,6 @@ import com.vaadin.ui.VerticalLayout;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* View to configure the polling interval and the overdue time.
|
* View to configure the polling interval and the overdue time.
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@SpringComponent
|
@SpringComponent
|
||||||
@ViewScope
|
@ViewScope
|
||||||
|
|||||||
@@ -38,9 +38,6 @@ import com.vaadin.ui.VerticalLayout;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Main UI for the system configuration view.
|
* Main UI for the system configuration view.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@SpringView(name = TenantConfigurationDashboardView.VIEW_NAME, ui = HawkbitUI.class)
|
@SpringView(name = TenantConfigurationDashboardView.VIEW_NAME, ui = HawkbitUI.class)
|
||||||
@ViewScope
|
@ViewScope
|
||||||
@@ -58,6 +55,9 @@ public class TenantConfigurationDashboardView extends CustomComponent implements
|
|||||||
@Autowired
|
@Autowired
|
||||||
private PollingConfigurationView pollingConfigurationView;
|
private PollingConfigurationView pollingConfigurationView;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DownloadAnonymousConfigurationView downloadAnonymousConfigurationView;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private I18N i18n;
|
private I18N i18n;
|
||||||
|
|
||||||
@@ -73,13 +73,14 @@ public class TenantConfigurationDashboardView extends CustomComponent implements
|
|||||||
private final List<ConfigurationGroup> configurationViews = new ArrayList<>();
|
private final List<ConfigurationGroup> configurationViews = new ArrayList<>();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* init method adds all Configuration Views to the list of Views.
|
* Init method adds all Configuration Views to the list of Views.
|
||||||
*/
|
*/
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
configurationViews.add(defaultDistributionSetTypeLayout);
|
configurationViews.add(defaultDistributionSetTypeLayout);
|
||||||
configurationViews.add(authenticationConfigurationView);
|
configurationViews.add(authenticationConfigurationView);
|
||||||
configurationViews.add(pollingConfigurationView);
|
configurationViews.add(pollingConfigurationView);
|
||||||
|
configurationViews.add(downloadAnonymousConfigurationView);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -154,13 +155,6 @@ public class TenantConfigurationDashboardView extends CustomComponent implements
|
|||||||
undoConfigurationBtn.setEnabled(false);
|
undoConfigurationBtn.setEnabled(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see
|
|
||||||
* org.eclipse.hawkbit.server.ui.tenantconfiguration.ConfigurationGroup.
|
|
||||||
* ConfigurationGroupChangeListener #configurationChanged()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void configurationHasChanged() {
|
public void configurationHasChanged() {
|
||||||
saveConfigurationBtn.setEnabled(true);
|
saveConfigurationBtn.setEnabled(true);
|
||||||
|
|||||||
@@ -21,9 +21,6 @@ import com.vaadin.server.Resource;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Menu item for system configuration view.
|
* Menu item for system configuration view.
|
||||||
*
|
|
||||||
*
|
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Component
|
@Component
|
||||||
@Order(700)
|
@Order(700)
|
||||||
|
|||||||
@@ -26,16 +26,13 @@ import com.vaadin.ui.VerticalLayout;
|
|||||||
import com.vaadin.ui.themes.ValoTheme;
|
import com.vaadin.ui.themes.ValoTheme;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* This class represents the UI item for the certificate authenticated by an
|
||||||
*
|
* reverse proxy in the authentication configuration view.
|
||||||
*/
|
*/
|
||||||
@SpringComponent
|
@SpringComponent
|
||||||
@ViewScope
|
@ViewScope
|
||||||
public class CertificateAuthenticationConfigurationItem extends AbstractAuthenticationTenantConfigurationItem {
|
public class CertificateAuthenticationConfigurationItem extends AbstractAuthenticationTenantConfigurationItem {
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -59,7 +56,7 @@ public class CertificateAuthenticationConfigurationItem extends AbstractAuthenti
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* init mehotd called by spring.
|
* Init mehotd called by spring.
|
||||||
*/
|
*/
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
@@ -94,12 +91,6 @@ public class CertificateAuthenticationConfigurationItem extends AbstractAuthenti
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.eclipse.hawkbit.server.ui.tenantconfiguration.
|
|
||||||
* TenantConfigurationItem# configEnable()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void configEnable() {
|
public void configEnable() {
|
||||||
if (!configurationEnabled) {
|
if (!configurationEnabled) {
|
||||||
@@ -110,12 +101,6 @@ public class CertificateAuthenticationConfigurationItem extends AbstractAuthenti
|
|||||||
setDetailVisible(true);
|
setDetailVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.eclipse.hawkbit.server.ui.tenantconfiguration.
|
|
||||||
* TenantConfigurationItem# configDisable()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void configDisable() {
|
public void configDisable() {
|
||||||
if (configurationEnabled) {
|
if (configurationEnabled) {
|
||||||
@@ -125,11 +110,6 @@ public class CertificateAuthenticationConfigurationItem extends AbstractAuthenti
|
|||||||
setDetailVisible(false);
|
setDetailVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see hawkbit.server.ui.tenantconfiguration.TenantConfigurationItem#save()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void save() {
|
public void save() {
|
||||||
if (configurationEnabledChange) {
|
if (configurationEnabledChange) {
|
||||||
@@ -142,11 +122,6 @@ public class CertificateAuthenticationConfigurationItem extends AbstractAuthenti
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see hawkbit.server.ui.tenantconfiguration.TenantConfigurationItem#undo()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void undo() {
|
public void undo() {
|
||||||
configurationEnabledChange = false;
|
configurationEnabledChange = false;
|
||||||
|
|||||||
@@ -30,16 +30,13 @@ import com.vaadin.ui.VerticalLayout;
|
|||||||
import com.vaadin.ui.themes.ValoTheme;
|
import com.vaadin.ui.themes.ValoTheme;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* This class represents the UI item for the gateway security token section in
|
||||||
*
|
* the authentication configuration view.
|
||||||
*/
|
*/
|
||||||
@SpringComponent
|
@SpringComponent
|
||||||
@ViewScope
|
@ViewScope
|
||||||
public class GatewaySecurityTokenAuthenticationConfigurationItem extends AbstractAuthenticationTenantConfigurationItem {
|
public class GatewaySecurityTokenAuthenticationConfigurationItem extends AbstractAuthenticationTenantConfigurationItem {
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -70,7 +67,7 @@ public class GatewaySecurityTokenAuthenticationConfigurationItem extends Abstrac
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* init mehotd called by spring.
|
* Init mehotd called by spring.
|
||||||
*/
|
*/
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
@@ -135,12 +132,6 @@ public class GatewaySecurityTokenAuthenticationConfigurationItem extends Abstrac
|
|||||||
notifyConfigurationChanged();
|
notifyConfigurationChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.eclipse.hawkbit.server.ui.tenantconfiguration.
|
|
||||||
* TenantConfigurationItem# configEnable()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void configEnable() {
|
public void configEnable() {
|
||||||
if (!configurationEnabled) {
|
if (!configurationEnabled) {
|
||||||
|
|||||||
@@ -19,17 +19,13 @@ import com.vaadin.spring.annotation.SpringComponent;
|
|||||||
import com.vaadin.spring.annotation.ViewScope;
|
import com.vaadin.spring.annotation.ViewScope;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* This class represents the UI item for the target security token section in
|
||||||
*
|
* the authentication configuration view.
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@SpringComponent
|
@SpringComponent
|
||||||
@ViewScope
|
@ViewScope
|
||||||
public class TargetSecurityTokenAuthenticationConfigurationItem extends AbstractAuthenticationTenantConfigurationItem {
|
public class TargetSecurityTokenAuthenticationConfigurationItem extends AbstractAuthenticationTenantConfigurationItem {
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
private static final long serialVersionUID = 1L;
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
@@ -49,7 +45,7 @@ public class TargetSecurityTokenAuthenticationConfigurationItem extends Abstract
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* init mehotd called by spring.
|
* Init mehotd called by spring.
|
||||||
*/
|
*/
|
||||||
@PostConstruct
|
@PostConstruct
|
||||||
public void init() {
|
public void init() {
|
||||||
@@ -57,12 +53,6 @@ public class TargetSecurityTokenAuthenticationConfigurationItem extends Abstract
|
|||||||
configurationEnabled = isConfigEnabled();
|
configurationEnabled = isConfigEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.eclipse.hawkbit.server.ui.tenantconfiguration.
|
|
||||||
* TenantConfigurationItem# configEnable()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void configEnable() {
|
public void configEnable() {
|
||||||
if (!configurationEnabled) {
|
if (!configurationEnabled) {
|
||||||
@@ -71,12 +61,6 @@ public class TargetSecurityTokenAuthenticationConfigurationItem extends Abstract
|
|||||||
configurationEnabled = true;
|
configurationEnabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* (non-Javadoc)
|
|
||||||
*
|
|
||||||
* @see org.eclipse.hawkbit.server.ui.tenantconfiguration.
|
|
||||||
* TenantConfigurationItem# configDisable()
|
|
||||||
*/
|
|
||||||
@Override
|
@Override
|
||||||
public void configDisable() {
|
public void configDisable() {
|
||||||
if (configurationEnabled) {
|
if (configurationEnabled) {
|
||||||
|
|||||||
@@ -501,6 +501,11 @@ public final class SPUIComponetIdProvider {
|
|||||||
*/
|
*/
|
||||||
public static final String SYSTEM_CONFIGURATION_CANCEL = "system.configuration.cancel";
|
public static final String SYSTEM_CONFIGURATION_CANCEL = "system.configuration.cancel";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Id of the anonymous download checkbox.
|
||||||
|
*/
|
||||||
|
public static final String SYSTEM_CONFIGURATION_ANONYMOUS_DOWNLOAD_CHECKBOX = "system.configuration.anonymous.download.checkbox";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Id of maximize/minimize icon of table - Software module table.
|
* Id of maximize/minimize icon of table - Software module table.
|
||||||
*/
|
*/
|
||||||
@@ -827,7 +832,7 @@ public final class SPUIComponetIdProvider {
|
|||||||
* Rollout status label id.
|
* Rollout status label id.
|
||||||
*/
|
*/
|
||||||
public static final String ROLLOUT_STATUS_LABEL_ID = "rollout.status.id";
|
public static final String ROLLOUT_STATUS_LABEL_ID = "rollout.status.id";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rollout group status label id.
|
* Rollout group status label id.
|
||||||
*/
|
*/
|
||||||
@@ -867,12 +872,12 @@ public final class SPUIComponetIdProvider {
|
|||||||
* Rollout group targets count message label.
|
* Rollout group targets count message label.
|
||||||
*/
|
*/
|
||||||
public static final String ROLLOUT_GROUP_TARGET_LABEL = "rollout.group.target.label";
|
public static final String ROLLOUT_GROUP_TARGET_LABEL = "rollout.group.target.label";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action confirmation popup id.
|
* Action confirmation popup id.
|
||||||
*/
|
*/
|
||||||
public static final String CONFIRMATION_POPUP_ID = "action.confirmation.popup.id";
|
public static final String CONFIRMATION_POPUP_ID = "action.confirmation.popup.id";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Validation status icon .
|
* Validation status icon .
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -401,6 +401,8 @@ configuration.polling.title=Polling Configuration
|
|||||||
configuration.polling.time=Polling Time
|
configuration.polling.time=Polling Time
|
||||||
configuration.polling.overduetime=Polling Overdue Time
|
configuration.polling.overduetime=Polling Overdue Time
|
||||||
configuration.polling.custom.value=use a custom value
|
configuration.polling.custom.value=use a custom value
|
||||||
|
enonymous.download.title=Anonymous download
|
||||||
|
enonymous.download.label=Allow anonymous download. If you enable this option the download server will accept anonymous download requests.
|
||||||
|
|
||||||
#Calendar
|
#Calendar
|
||||||
calendar.year=year
|
calendar.year=year
|
||||||
|
|||||||
@@ -389,6 +389,8 @@ configuration.defaultdistributionset.select.label=Wahl des default Distribution
|
|||||||
configuration.savebutton.tooltip=Konfigurationen speichern
|
configuration.savebutton.tooltip=Konfigurationen speichern
|
||||||
configuration.cancellbutton.tooltip=Konfigurationen zur<75>cksetzen
|
configuration.cancellbutton.tooltip=Konfigurationen zur<75>cksetzen
|
||||||
configuration.authentication.title=Authentifikationseinstellungen
|
configuration.authentication.title=Authentifikationseinstellungen
|
||||||
|
enonymous.download.title=Anonymes herunterladen
|
||||||
|
enonymous.download.label=Erlaube anonymes herunterladen. When diese option aktivert ist, wird der download server anonyme download anfragen erlauben.
|
||||||
#Calendar
|
#Calendar
|
||||||
calendar.year=Jahr
|
calendar.year=Jahr
|
||||||
calendar.years=Jahre
|
calendar.years=Jahre
|
||||||
|
|||||||
@@ -383,6 +383,8 @@ configuration.authentication.title=Authentication Configuration
|
|||||||
controller.polling.title=Polling Configuration
|
controller.polling.title=Polling Configuration
|
||||||
controller.polling.time=Polling Time
|
controller.polling.time=Polling Time
|
||||||
controller.polling.overduetime=Polling Overdue Time
|
controller.polling.overduetime=Polling Overdue Time
|
||||||
|
enonymous.download.title=Anonymous download
|
||||||
|
enonymous.download.label=Allow anonymous download. If you enable this option the download server will accept anonymous download requests.
|
||||||
|
|
||||||
#Calendar
|
#Calendar
|
||||||
calendar.year=year
|
calendar.year=year
|
||||||
|
|||||||
Reference in New Issue
Block a user