SEBSERV-459 implementation

This commit is contained in:
anhefti 2024-02-22 13:45:29 +01:00
parent 29265dd7e1
commit 979d4a6e89
7 changed files with 35 additions and 11 deletions

View file

@ -17,8 +17,12 @@ public class UserFeatures {
public enum Feature {
ADMIN_INSTITUTION("admin.institution"),
ADMIN_USER_ADMINISTRATION("admin.user.administration"),
ADMIN_USER_ACCOUNT("admin.user.account"),
ADMIN_USER_ACCOUNT_SELF_REGISTERING("admin.user.account.self.registering"),
ADMIN_USER_ACCOUNT_SELF_REGISTERING_AUTO_ACTIVATION("admin.user.account.self.registering.autoactivation"),
ADMIN_AUDIT_LOGS("admin.auditlogs"),
CONFIG_CONNECTION_CONFIGURATION("config.connection.configuration"),

View file

@ -59,14 +59,15 @@ public class LoginPage implements TemplateComposer {
public LoginPage(
final PageService pageService,
final DefaultRegisterPage defaultRegisterPage,
@Value("${sebserver.gui.registering:false}") final Boolean registeringEnabled) {
@Value("${sebserver.gui.registering:false}") final boolean guiRegEnabled,
@Value("${sebserver.feature.admin.user.account.self.registering:true}") final boolean webRegEnabled) {
this.pageService = pageService;
this.authorizationContextHolder = pageService.getAuthorizationContextHolder();
this.widgetFactory = pageService.getWidgetFactory();
this.i18nSupport = pageService.getI18nSupport();
this.defaultRegisterPage = defaultRegisterPage;
this.registeringEnabled = BooleanUtils.toBoolean(registeringEnabled);
this.registeringEnabled = webRegEnabled && guiRegEnabled;
}
@Override

View file

@ -85,6 +85,9 @@ public class RegisterPage implements TemplateComposer {
static final LocTextKey MESSAGE_SUCCESS_TEXT =
new LocTextKey("sebserver.login.register.success");
static final LocTextKey MESSAGE_SUCCESS_ACTIVATION_TEXT =
new LocTextKey("sebserver.login.register.success.activate");
private final PageService pageService;
private final ResourceService resourceService;
private final WidgetFactory widgetFactory;
@ -247,7 +250,9 @@ public class RegisterPage implements TemplateComposer {
}
pageContext.forwardToLoginPage();
pageContext.publishPageMessage(MESSAGE_SUCCESS_TILE, MESSAGE_SUCCESS_TEXT);
pageContext.publishPageMessage(
MESSAGE_SUCCESS_TILE,
(result.get().active) ? MESSAGE_SUCCESS_TEXT : MESSAGE_SUCCESS_ACTIVATION_TEXT);
});

View file

@ -178,10 +178,10 @@ public class WebserviceInfo {
}
public Map<String, Boolean> configuredFeatures() {
return Arrays.stream(UserFeatures.Feature.values()).collect(Collectors.toMap(
return new TreeMap<>( Arrays.stream(UserFeatures.Feature.values()).collect(Collectors.toMap(
f -> f.featureName,
featureService::isEnabledByConfig
));
)));
}
public boolean isMaster() {

View file

@ -10,10 +10,15 @@ package ch.ethz.seb.sebserver.webservice.weblayer.api;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import ch.ethz.seb.sebserver.gbl.model.user.*;
import ch.ethz.seb.sebserver.webservice.WebserviceInfo;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.http.MediaType;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.util.MultiValueMap;
@ -30,10 +35,6 @@ import ch.ethz.seb.sebserver.gbl.api.APIMessage.APIMessageException;
import ch.ethz.seb.sebserver.gbl.api.POSTMapper;
import ch.ethz.seb.sebserver.gbl.api.TooManyRequests;
import ch.ethz.seb.sebserver.gbl.model.Domain.USER_ROLE;
import ch.ethz.seb.sebserver.gbl.model.user.PasswordChange;
import ch.ethz.seb.sebserver.gbl.model.user.UserInfo;
import ch.ethz.seb.sebserver.gbl.model.user.UserMod;
import ch.ethz.seb.sebserver.gbl.model.user.UserRole;
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.InstitutionDAO;
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.UserActivityLogDAO;
@ -51,6 +52,8 @@ public class RegisterUserController {
private final BeanValidationService beanValidationService;
private final LocalBucket requestRateLimitBucket;
private final LocalBucket createRateLimitBucket;
private final boolean registeringEnabled;
private final boolean autoActivation;
protected RegisterUserController(
final InstitutionDAO institutionDAO,
@ -58,12 +61,15 @@ public class RegisterUserController {
final UserDAO userDAO,
final BeanValidationService beanValidationService,
final RateLimitService rateLimitService,
final WebserviceInfo webserviceInfo,
@Qualifier(WebSecurityConfig.USER_PASSWORD_ENCODER_BEAN_NAME) final PasswordEncoder userPasswordEncoder) {
final Map<String, Boolean> features = webserviceInfo.configuredFeatures();
this.userActivityLogDAO = userActivityLogDAO;
this.userDAO = userDAO;
this.beanValidationService = beanValidationService;
this. registeringEnabled = BooleanUtils.isTrue(features.get(UserFeatures.Feature.ADMIN_USER_ACCOUNT_SELF_REGISTERING.featureName));
this.autoActivation = BooleanUtils.isTrue(features.get(UserFeatures.Feature.ADMIN_USER_ACCOUNT_SELF_REGISTERING_AUTO_ACTIVATION.featureName));
this.requestRateLimitBucket = rateLimitService.createRequestLimitBucker();
this.createRateLimitBucket = rateLimitService.createCreationLimitBucker();
}
@ -76,6 +82,10 @@ public class RegisterUserController {
@RequestParam final MultiValueMap<String, String> allRequestParams,
final HttpServletRequest request) {
if (!registeringEnabled) {
throw new RuntimeException("Registering is not enabled from backend!");
}
if (!this.requestRateLimitBucket.tryConsume(1)) {
throw new TooManyRequests();
}
@ -107,7 +117,7 @@ public class RegisterUserController {
return userAccount;
})
.flatMap(this.userDAO::createNew)
.flatMap(account -> this.userDAO.setActive(account, true))
.flatMap(account -> this.userDAO.setActive(account, autoActivation))
.flatMap(this.userActivityLogDAO::logRegisterAccount)
.flatMap(account -> this.userDAO.byModelId(account.getModelId()))
.getOrThrow();

View file

@ -95,6 +95,9 @@ sebserver.webservice.configtemplate.examconfig.default.description=This has auto
# features
sebserver.feature.admin.institution.enabled=true
sebserver.feature.admin.user.account.self.registering.enabled=true
sebserver.feature.admin.user.account.self.registering.autoactivation.enabled=true
sebserver.feature.seb.liveProctoring.enabled=true
sebserver.feature.lms.type.MOCKUP.enabled=true
sebserver.feature.exam.noLMS.enabled=true

View file

@ -163,6 +163,7 @@ sebserver.login.register=Register
sebserver.login.register.form.title=Create an Account
sebserver.login.register.do=Create Account
sebserver.login.register.success=New account successfully created.<br/> Please log in with your username and password.
sebserver.login.register.success.activate=New account successfully created.<br/> Please contact your system administrator for account activation.
################################