basic validation

This commit is contained in:
Jottyfan
2022-12-08 23:03:50 +01:00
parent df7e4e7f0e
commit 2e376291c5
12 changed files with 174 additions and 35 deletions

View File

@@ -34,10 +34,10 @@ public class KeycloakRepository {
@Value("${keycloak.realm:ow}")
private String keycloakRealm;
@Value("${keycloak.admin.name:admin")
@Value("${ow.keycloak.admin.name:admin")
private String keycloakAdminName;
@Value("${keycloak.admin.password:password")
@Value("${ow.keycloak.admin.password:password")
private String keycloakAdminPassword;
/**

View File

@@ -3,32 +3,50 @@ package de.jottyfan.camporganizer.module.registration;
import java.io.Serializable;
import java.time.LocalDate;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
import org.springframework.format.annotation.DateTimeFormat;
import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole;
import de.jottyfan.camporganizer.db.jooq.enums.EnumSex;
import de.jottyfan.camporganizer.module.registration.validate.UnusedUsername;
/**
*
*
* @author jotty
*
*/
@UnusedUsername(field = "login", message = "Dieses Login ist leider bereits vergeben. Bitte wähle ein anderes.")
public class RegistrationBean implements Serializable {
private static final long serialVersionUID = 1L;
@NotBlank(message = "Bitte gib deinen Vornamen an.")
private String forename;
@NotBlank(message = "Bitte gib deinen Nachnamen an.")
private String surname;
@NotNull(message = "Bitte gib dein Geschlecht an. Wir benötigen das, um zu wissen, ob du in einem Jungs- oder Mädchenzimmer übernachten kannst.")
private EnumSex sex;
@NotNull(message = "Bitte gib dein Geburtsdatum an. Damit errechnen wir, ob die Freizeit für dich geeignet ist.")
@DateTimeFormat(pattern="yyyy-MM-dd")
private LocalDate birthDate;
@NotBlank(message = "Bitte gib die Strasse deines Wohnsitzes an.")
private String street;
@NotBlank(message = "Bitte gib die Postleitzahl deines Wohnsitzes an.")
private String zip;
@NotBlank(message = "Bitte gib den Ort deines Wohnsitzes an.")
private String city;
@Email(message = "Bitte gib eine gültige E-Mail-Adresse an (oder gar keine).")
private String email;
private String phone;
private String comment;
@NotNull(message = "Bitte gib an, zu welcher Freizeit du dich anmelden möchtest.")
private Integer fkCamp;
@NotNull(message = "Bitte gib an, in welcher Rolle du dich anmelden möchtest.")
private EnumCamprole campRole;
@NotNull(message = "Bitte gib an, ob du dir für spätere Anmeldungen einen Zugang einrichten willst.")
private Boolean registerInKeycloak;
private String login;
private String password;

View File

@@ -1,10 +1,12 @@
package de.jottyfan.camporganizer.module.registration;
import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
@@ -39,7 +41,14 @@ public class RegistrationController extends CommonController {
}
@PostMapping("/registration/register")
public String register(@ModelAttribute RegistrationBean bean, Model model) {
public String register(@Valid @ModelAttribute RegistrationBean bean, Model model, final BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
super.setupSession(model, request);
CampBean campBean = service.getCamp(bean.getFkCamp());
model.addAttribute("camp", campBean);
model.addAttribute("bean", bean);
return "/registration";
}
Boolean result = service.register(bean);
// TODO: give the user a message about success or error and, if registered in keycloak, a note about how to login
return index(bean.getFkCamp(), model);

View File

@@ -65,10 +65,26 @@ public class RegistrationGateway {
}
}
/**
* test if the login is available (not yet in use)
*
* @param login the login
* @return true or false
*/
public Boolean isLoginAvailable(String login) {
SelectConditionStep<TProfileRecord> sql = jooq
// @formatter:off
.selectFrom(T_PROFILE)
.where(T_PROFILE.USERNAME.eq(login));
// @formatter:on
LOGGER.debug(sql);
return sql.fetch().size() < 1;
}
/**
* save the content in t_person; also, create a profile for the user if
* registerInKeycloak is true
*
*
* @param bean the bean
* @return true or false
*/
@@ -76,10 +92,7 @@ public class RegistrationGateway {
LambdaResultWrapper lrw = new LambdaResultWrapper();
jooq.transaction(t -> {
if (bean.getRegisterInKeycloak()) {
SelectConditionStep<TProfileRecord> sql0 = DSL.using(t).selectFrom(T_PROFILE)
.where(T_PROFILE.USERNAME.eq(bean.getLogin()));
LOGGER.debug(sql0);
if (sql0.fetch().size() > 0) {
if (!isLoginAvailable(bean.getLogin())) {
throw new DataAccessException("login already in use: " + bean.getLogin());
}
// TODO: check if teacher is at least 2 years older than the camp participants

View File

@@ -0,0 +1,29 @@
package de.jottyfan.camporganizer.module.registration.validate;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import javax.validation.Constraint;
import javax.validation.Payload;
/**
*
* @author jotty
*
*/
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = UnusedUsernameValidator.class)
@Documented
public @interface UnusedUsername {
String message() default "username is already in use";
String field();
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}

View File

@@ -0,0 +1,40 @@
package de.jottyfan.camporganizer.module.registration.validate;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.factory.annotation.Autowired;
import de.jottyfan.camporganizer.module.registration.RegistrationGateway;
/**
*
* @author jotty
*
*/
public class UnusedUsernameValidator implements ConstraintValidator<UnusedUsername, Object> {
private String field;
private String message;
@Autowired
private RegistrationGateway gateway;
public void initialize(UnusedUsername uu) {
this.field = uu.field();
this.message = uu.message();
}
@Override
public boolean isValid(Object value, ConstraintValidatorContext context) {
Object login = new BeanWrapperImpl(value).getPropertyValue(field);
Boolean result = gateway.isLoginAvailable((String) login);
if (!result) {
context.buildConstraintViolationWithTemplate(message).addPropertyNode(field).addConstraintViolation()
.disableDefaultConstraintViolation();
}
return result;
}
}