Correctly displaying no authentication warning #32

This commit is contained in:
Francesco 2023-11-07 15:09:52 +01:00
parent da8fc10414
commit 6eb572f72c
4 changed files with 40 additions and 18 deletions

View File

@ -19,11 +19,8 @@
package tech.ailef.snapadmin.external;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
import java.net.HttpURLConnection;
import java.net.URL;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -33,6 +30,8 @@ import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import tech.ailef.snapadmin.external.exceptions.DbAdminException;
/**
* Runs at startup to determine if SnapAdmin is protected with authentication.
* If this is not the case, it sets a flag that will display a warning in the
@ -49,30 +48,31 @@ public class StartupAuthCheckRunner {
@Autowired
private SnapAdminProperties properties;
@Bean
ApplicationListener<ServletWebServerInitializedEvent> serverPortListenerBean() {
return event -> {
int serverPort = event.getWebServer().getPort();
String url = "http://localhost:" + serverPort + "/" + properties.getBaseUrl();
logger.info("Checking if SnapAdmin is protected with authentication at " + url);
HttpRequest request = HttpRequest.newBuilder().uri(URI.create(url)).build();
String link = "http://localhost:" + serverPort + "/" + properties.getBaseUrl();
logger.info("Checking if SnapAdmin is protected with authentication at " + link);
try {
HttpResponse<String> response = HttpClient.newBuilder().build().send(request, BodyHandlers.ofString());
int statusCode = response.statusCode();
URL url = new URL(link);
HttpURLConnection openConnection = (HttpURLConnection)url.openConnection();
openConnection.setInstanceFollowRedirects(false);
int statusCode = openConnection.getResponseCode();
snapAdmin.setAuthenticated(statusCode != 200);
if (statusCode == 200) {
logger.warn("It seems SnapAdmin routes are not protected with authentication. The URL "
+ url + " is publicly accessible: be careful!");
snapAdmin.setAuthenticated(false);
}
} catch (IOException | InterruptedException e) {
logger.warn("Unable to connect to server at " + url);
} catch (IOException e) {
throw new DbAdminException(e);
}
};
}
}

View File

@ -126,5 +126,10 @@ public class GlobalController {
return props;
}
@ModelAttribute("snapadmin_authenticated")
public boolean isAuthenticated() {
return dbAdmin.isAuthenticated();
}
}

View File

@ -26,6 +26,7 @@ import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import tech.ailef.snapadmin.external.exceptions.DbAdminException;
import tech.ailef.snapadmin.internal.model.UserSetting;
import tech.ailef.snapadmin.internal.repository.UserSettingsRepository;
@ -47,7 +48,12 @@ public class UserConfiguration {
Optional<UserSetting> setting = repo.findById(settingName);
if (setting.isPresent())
return setting.get().getSettingValue();
return defaultValues().getOrDefault(settingName, "");
String settingDefaultValue = defaultValues().get(settingName);
if (settingDefaultValue == null)
throw new DbAdminException("Trying to access setting `" + settingName + "` but it has no default value");
return settingDefaultValue;
}
/**
@ -57,6 +63,7 @@ public class UserConfiguration {
private Map<String, String> defaultValues() {
Map<String, String> values = new HashMap<>();
values.put("brandName", "SnapAdmin");
values.put("additionalCss", "");
return values;
}
}

View File

@ -9,6 +9,16 @@
<div th:replace="~{fragments/resources :: sidebar('entities')}"></div>
<div class="main-content bg-lighter">
<h1 class="fw-bold mb-4"><i class="align-middle bi bi-database"></i><span class="align-middle"> Entities</span></h1>
<th:block th:if="${!snapadmin_authenticated}">
<div class="alert alert-danger alert-dismissible fade show" role="alert" id="auth-warning">
<h4 class="alert-heading fw-bold"><i class="bi bi-exclamation-triangle"></i> SnapAdmin is not protected</h4>
<p class="mb-0">It appears that you have not enabled security so SnapAdmin is publicly accessible. Please refer to the
documentation to learn how to <a href="https://www.snapadmin.dev/docs/#security">protect SnapAdmin with Spring Security.
</a>
</p>
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
</th:block>
<form th:action="|/${snapadmin_baseUrl}|" method="GET">
<div class="input-group">
<input type="text" th:value="${query}"