Add setting 'Webserver.Security.Disable_registration'

- This disables /auth/register endpoint and /plan register command.
- Website will display "Registering new users has been disabled in the config." on register page

Affects issues:
- Close #2332
This commit is contained in:
Aurora Lahtela 2023-05-15 20:32:02 +03:00
parent f6af24a42a
commit f7a40fbd68
9 changed files with 43 additions and 6 deletions

View File

@ -20,6 +20,8 @@ import com.djrapitops.plan.commands.subcommands.*;
import com.djrapitops.plan.commands.use.*;
import com.djrapitops.plan.gathering.importing.ImportSystem;
import com.djrapitops.plan.settings.Permissions;
import com.djrapitops.plan.settings.config.PlanConfig;
import com.djrapitops.plan.settings.config.paths.WebserverSettings;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.lang.DeepHelpLang;
import com.djrapitops.plan.settings.locale.lang.HelpLang;
@ -51,6 +53,7 @@ public class PlanCommand {
private final DataUtilityCommands dataUtilityCommands;
private final Locale locale;
private final PlanConfig config;
private final ImportSystem importSystem;
private final ErrorLogger errorLogger;
@ -69,6 +72,7 @@ public class PlanCommand {
PluginStatusCommands statusCommands,
DatabaseCommands databaseCommands,
DataUtilityCommands dataUtilityCommands,
PlanConfig config,
ErrorLogger errorLogger
) {
this.commandName = commandName;
@ -82,6 +86,7 @@ public class PlanCommand {
this.statusCommands = statusCommands;
this.databaseCommands = databaseCommands;
this.dataUtilityCommands = dataUtilityCommands;
this.config = config;
this.errorLogger = errorLogger;
}
@ -220,6 +225,9 @@ public class PlanCommand {
}
private Subcommand registerCommand() {
if (config.isTrue(WebserverSettings.DISABLED_AUTHENTICATION) || config.isTrue(WebserverSettings.DISABLED_REGISTRATION)) {
return null;
}
return Subcommand.builder()
.aliases("register")
.requirePermission(Permissions.REGISTER_SELF)
@ -244,6 +252,9 @@ public class PlanCommand {
}
private Subcommand logoutCommand() {
if (config.isTrue(WebserverSettings.DISABLED_AUTHENTICATION)) {
return null;
}
return Subcommand.builder()
.aliases("logout")
.requirePermission(Permissions.LOGOUT_OTHER)

View File

@ -26,6 +26,7 @@ import com.djrapitops.plan.delivery.web.resolver.exception.NotFoundException;
import com.djrapitops.plan.delivery.web.resolver.request.Request;
import com.djrapitops.plan.delivery.web.resolver.request.WebUser;
import com.djrapitops.plan.delivery.webserver.auth.FailReason;
import com.djrapitops.plan.delivery.webserver.configuration.WebserverConfiguration;
import com.djrapitops.plan.delivery.webserver.http.WebServer;
import com.djrapitops.plan.delivery.webserver.resolver.*;
import com.djrapitops.plan.delivery.webserver.resolver.auth.*;
@ -86,6 +87,7 @@ public class ResponseResolver {
private final ResolverService resolverService;
private final ResponseFactory responseFactory;
private final Lazy<WebServer> webServer;
private final WebserverConfiguration webserverConfiguration;
private final PublicHtmlResolver publicHtmlResolver;
@Inject
@ -93,6 +95,7 @@ public class ResponseResolver {
ResolverSvc resolverService,
ResponseFactory responseFactory,
Lazy<WebServer> webServer,
WebserverConfiguration webserverConfiguration,
QueryPageResolver queryPageResolver,
PlayersPageResolver playersPageResolver,
@ -118,6 +121,7 @@ public class ResponseResolver {
this.resolverService = resolverService;
this.responseFactory = responseFactory;
this.webServer = webServer;
this.webserverConfiguration = webserverConfiguration;
this.queryPageResolver = queryPageResolver;
this.playersPageResolver = playersPageResolver;
this.playerPageResolver = playerPageResolver;
@ -150,12 +154,15 @@ public class ResponseResolver {
resolverService.registerResolver(plugin, "/player", playerPageResolver);
resolverService.registerResolver(plugin, "/network", serverPageResolver);
resolverService.registerResolver(plugin, "/server", serverPageResolver);
if (webserverConfiguration.isAuthenticationEnabled()) {
resolverService.registerResolver(plugin, "/login", loginPageResolver);
resolverService.registerResolver(plugin, "/register", registerPageResolver);
resolverService.registerResolver(plugin, "/auth/login", loginResolver);
resolverService.registerResolver(plugin, "/auth/logout", logoutResolver);
if (webserverConfiguration.isRegistrationEnabled()) {
resolverService.registerResolver(plugin, "/auth/register", registerResolver);
}
}
resolverService.registerResolver(plugin, "/errors", errorsPageResolver);

View File

@ -124,4 +124,8 @@ public class WebserverConfiguration {
public boolean isProxyModeHttps() {
return "proxy".equals(config.get(WebserverSettings.CERTIFICATE_PATH));
}
public boolean isRegistrationEnabled() {
return config.isFalse(WebserverSettings.DISABLED_REGISTRATION);
}
}

View File

@ -90,6 +90,7 @@ public class MetadataJSONResolver implements NoAuthResolver {
.put("networkName", serverInfo.getServer().isProxy() ? config.get(ProxySettings.NETWORK_NAME) : null)
.put("mainCommand", mainCommand)
.put("refreshBarrierMs", config.get(WebserverSettings.REDUCED_REFRESH_BARRIER))
.put("registrationDisabled", config.isTrue(WebserverSettings.DISABLED_REGISTRATION))
.build())
.build();
}

View File

@ -42,6 +42,7 @@ public class WebserverSettings {
public static final Setting<List<String>> WHITELIST = new StringListSetting("Webserver.Security.IP_whitelist.Whitelist");
public static final Setting<Boolean> DISABLED = new BooleanSetting("Webserver.Disable_Webserver");
public static final Setting<Boolean> DISABLED_AUTHENTICATION = new BooleanSetting("Webserver.Security.Disable_authentication");
public static final Setting<Boolean> DISABLED_REGISTRATION = new BooleanSetting("Webserver.Security.Disable_registration");
public static final Setting<Boolean> LOG_ACCESS_TO_CONSOLE = new BooleanSetting("Webserver.Security.Access_log.Print_to_console");
public static final Setting<String> EXTERNAL_LINK = new StringSetting("Webserver.External_Webserver_address");
public static final Setting<String> PUBLIC_HTML_PATH = new StringSetting("Webserver.Public_html_directory");

View File

@ -275,6 +275,7 @@ public enum HtmlLang implements Lang {
LOGIN_FORGOT_PASSWORD_INSTRUCTIONS_4("html.login.forgotPassword4", "After using the command, "),
LOGIN_FAILED("html.login.failed", "Login failed: "),
REGISTER("html.register.register", "Register"),
REGISTER_DISABLED("html.register.disabled", "Registering new users has been disabled in the config."),
REGISTER_CREATE_USER("html.register.createNewUser", "Create a new user"),
REGISTER_USERNAME_TIP("html.register.usernameTip", "Username can be up to 50 characters."),
REGISTER_PASSWORD_TIP("html.register.passwordTip", "Password should be more than 8 characters, but there are no limitations."),

View File

@ -62,6 +62,8 @@ Webserver:
Alias: alias
# HTTPS is required for Login.
Disable_authentication: false
# Disable /auth/register endpoint
Disable_registration: false
# Cross-Origin Resource Sharing (Requests from non-Plan web pages)
# https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
CORS:

View File

@ -63,6 +63,8 @@ Webserver:
Alias: alias
# HTTPS is required for Login.
Disable_authentication: false
# Disable /auth/register endpoint
Disable_registration: false
# Cross-Origin Resource Sharing (Requests from non-Plan web pages)
# https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS
CORS:

View File

@ -11,6 +11,7 @@ import ColorSelectorModal from "../../components/modal/ColorSelectorModal";
import {useAuth} from "../../hooks/authenticationHook";
import FinalizeRegistrationModal from "../../components/modal/FinalizeRegistrationModal";
import {fetchRegisterCheck, postRegister} from "../../service/authenticationService";
import {useMetadata} from "../../hooks/metadataHook";
const Logo = () => {
return (
@ -43,6 +44,7 @@ const RegisterCard = ({children}) => {
const RegisterForm = ({register}) => {
const {t} = useTranslation();
const {registrationDisabled} = useMetadata();
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
@ -51,6 +53,12 @@ const RegisterForm = ({register}) => {
register(username, password).then(() => setPassword(''));
}, [username, password, setPassword, register]);
if (registrationDisabled) {
return (
<p>{t('html.register.disabled')}</p>
)
}
return (
<form className="user">
<div className="mb-3">