basic registration functionality, still missing keycloak
This commit is contained in:
		| @@ -0,0 +1,22 @@ | ||||
| package de.jottyfan.camporganizer.module.common; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| public class LambdaResultWrapper { | ||||
| 	private Integer counter; | ||||
| 	 | ||||
| 	public LambdaResultWrapper() { | ||||
| 		counter = 0; | ||||
| 	} | ||||
|  | ||||
| 	public Integer getCounter() { | ||||
| 		return counter; | ||||
| 	} | ||||
|  | ||||
| 	public void add(Integer i) { | ||||
| 		counter += i; | ||||
| 	} | ||||
| } | ||||
| @@ -0,0 +1,27 @@ | ||||
| package de.jottyfan.camporganizer.module.registration; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.springframework.stereotype.Repository; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author henkej | ||||
|  * | ||||
|  */ | ||||
| @Repository | ||||
| public class KeycloakRepository { | ||||
| 	private final static Logger LOGGER = LogManager.getLogger(KeycloakRepository.class); | ||||
|  | ||||
| 	/** | ||||
| 	 * register the login in keycloak | ||||
| 	 *  | ||||
| 	 * @param login | ||||
| 	 * @param password | ||||
| 	 */ | ||||
| 	public void register(String login, String password) { | ||||
| 		// TODO Auto-generated method stub | ||||
| 		LOGGER.error("not yet implemented registration of user {} in keycloak", login); | ||||
| 	} | ||||
|  | ||||
| } | ||||
| @@ -0,0 +1,245 @@ | ||||
| package de.jottyfan.camporganizer.module.registration; | ||||
|  | ||||
| import java.io.Serializable; | ||||
| import java.time.LocalDate; | ||||
|  | ||||
| import org.springframework.format.annotation.DateTimeFormat; | ||||
|  | ||||
| import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole; | ||||
| import de.jottyfan.camporganizer.db.jooq.enums.EnumSex; | ||||
|  | ||||
| /** | ||||
|  *  | ||||
|  * @author jotty | ||||
|  * | ||||
|  */ | ||||
| public class RegistrationBean implements Serializable { | ||||
| 	private static final long serialVersionUID = 1L; | ||||
|  | ||||
| 	private String forename; | ||||
| 	private String surname; | ||||
| 	private EnumSex sex; | ||||
| 	@DateTimeFormat(pattern="yyyy-MM-dd") | ||||
| 	private LocalDate birthDate; | ||||
| 	private String street; | ||||
| 	private String zip; | ||||
| 	private String city; | ||||
| 	private String email; | ||||
| 	private String phone; | ||||
| 	private String comment; | ||||
| 	private Integer fkCamp; | ||||
| 	private EnumCamprole campRole; | ||||
| 	private Boolean registerInKeycloak; | ||||
| 	private String login; | ||||
| 	private String password; | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the forename | ||||
| 	 */ | ||||
| 	public String getForename() { | ||||
| 		return forename; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param forename the forename to set | ||||
| 	 */ | ||||
| 	public void setForename(String forename) { | ||||
| 		this.forename = forename; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the surname | ||||
| 	 */ | ||||
| 	public String getSurname() { | ||||
| 		return surname; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param surname the surname to set | ||||
| 	 */ | ||||
| 	public void setSurname(String surname) { | ||||
| 		this.surname = surname; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the sex | ||||
| 	 */ | ||||
| 	public EnumSex getSex() { | ||||
| 		return sex; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param sex the sex to set | ||||
| 	 */ | ||||
| 	public void setSex(EnumSex sex) { | ||||
| 		this.sex = sex; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the birthDate | ||||
| 	 */ | ||||
| 	public LocalDate getBirthDate() { | ||||
| 		return birthDate; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param birthDate the birthDate to set | ||||
| 	 */ | ||||
| 	public void setBirthDate(LocalDate birthDate) { | ||||
| 		this.birthDate = birthDate; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the street | ||||
| 	 */ | ||||
| 	public String getStreet() { | ||||
| 		return street; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param street the street to set | ||||
| 	 */ | ||||
| 	public void setStreet(String street) { | ||||
| 		this.street = street; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the zip | ||||
| 	 */ | ||||
| 	public String getZip() { | ||||
| 		return zip; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param zip the zip to set | ||||
| 	 */ | ||||
| 	public void setZip(String zip) { | ||||
| 		this.zip = zip; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the city | ||||
| 	 */ | ||||
| 	public String getCity() { | ||||
| 		return city; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param city the city to set | ||||
| 	 */ | ||||
| 	public void setCity(String city) { | ||||
| 		this.city = city; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the email | ||||
| 	 */ | ||||
| 	public String getEmail() { | ||||
| 		return email; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param email the email to set | ||||
| 	 */ | ||||
| 	public void setEmail(String email) { | ||||
| 		this.email = email; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the phone | ||||
| 	 */ | ||||
| 	public String getPhone() { | ||||
| 		return phone; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param phone the phone to set | ||||
| 	 */ | ||||
| 	public void setPhone(String phone) { | ||||
| 		this.phone = phone; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the comment | ||||
| 	 */ | ||||
| 	public String getComment() { | ||||
| 		return comment; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param comment the comment to set | ||||
| 	 */ | ||||
| 	public void setComment(String comment) { | ||||
| 		this.comment = comment; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the registerInKeycloak | ||||
| 	 */ | ||||
| 	public Boolean getRegisterInKeycloak() { | ||||
| 		return registerInKeycloak; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param registerInKeycloak the registerInKeycloak to set | ||||
| 	 */ | ||||
| 	public void setRegisterInKeycloak(Boolean registerInKeycloak) { | ||||
| 		this.registerInKeycloak = registerInKeycloak; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the login | ||||
| 	 */ | ||||
| 	public String getLogin() { | ||||
| 		return login; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param login the login to set | ||||
| 	 */ | ||||
| 	public void setLogin(String login) { | ||||
| 		this.login = login; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the password | ||||
| 	 */ | ||||
| 	public String getPassword() { | ||||
| 		return password; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param password the password to set | ||||
| 	 */ | ||||
| 	public void setPassword(String password) { | ||||
| 		this.password = password; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the fkCamp | ||||
| 	 */ | ||||
| 	public Integer getFkCamp() { | ||||
| 		return fkCamp; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param fkCamp the fkCamp to set | ||||
| 	 */ | ||||
| 	public void setFkCamp(Integer fkCamp) { | ||||
| 		this.fkCamp = fkCamp; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @return the campRole | ||||
| 	 */ | ||||
| 	public EnumCamprole getCampRole() { | ||||
| 		return campRole; | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * @param campRole the campRole to set | ||||
| 	 */ | ||||
| 	public void setCampRole(EnumCamprole campRole) { | ||||
| 		this.campRole = campRole; | ||||
| 	} | ||||
| } | ||||
| @@ -6,7 +6,9 @@ import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.stereotype.Controller; | ||||
| import org.springframework.ui.Model; | ||||
| import org.springframework.web.bind.annotation.GetMapping; | ||||
| import org.springframework.web.bind.annotation.ModelAttribute; | ||||
| import org.springframework.web.bind.annotation.PathVariable; | ||||
| import org.springframework.web.bind.annotation.PostMapping; | ||||
|  | ||||
| import de.jottyfan.camporganizer.module.common.CommonController; | ||||
|  | ||||
| @@ -27,9 +29,19 @@ public class RegistrationController extends CommonController { | ||||
| 	@GetMapping("/registration/{fkCamp}") | ||||
| 	public String index(@PathVariable(name = "fkCamp", required = true) Integer fkCamp, Model model) { | ||||
| 		super.setupSession(model, request); | ||||
| 		model.addAttribute("camp", service.getCamp(fkCamp)); | ||||
| 		// TODO: prepare a bean for the form variables; use model.getAttribute("camp").getPk() for the fk_camp | ||||
| 		CampBean campBean = service.getCamp(fkCamp); | ||||
| 		model.addAttribute("camp", campBean); | ||||
| 		RegistrationBean bean = new RegistrationBean(); | ||||
| 		bean.setFkCamp(fkCamp); | ||||
| 		bean.setRegisterInKeycloak(true); // we want people to register generally | ||||
| 		model.addAttribute("bean", bean); | ||||
| 		return "/registration"; | ||||
| 	} | ||||
|  | ||||
| 	@PostMapping("/registration/register") | ||||
| 	public String register(@ModelAttribute RegistrationBean bean, Model model) { | ||||
| 		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); | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -1,18 +1,34 @@ | ||||
| package de.jottyfan.camporganizer.module.registration; | ||||
|  | ||||
| import static de.jottyfan.camporganizer.db.jooq.Tables.T_CAMP; | ||||
| import static de.jottyfan.camporganizer.db.jooq.Tables.T_PERSON; | ||||
| import static de.jottyfan.camporganizer.db.jooq.Tables.T_PROFILE; | ||||
|  | ||||
| import java.time.LocalDate; | ||||
| import java.time.LocalDateTime; | ||||
| import java.time.temporal.ChronoUnit; | ||||
| import java.util.UUID; | ||||
|  | ||||
| import org.apache.logging.log4j.LogManager; | ||||
| import org.apache.logging.log4j.Logger; | ||||
| import org.jasypt.util.password.StrongPasswordEncryptor; | ||||
| import org.jooq.DSLContext; | ||||
| import org.jooq.InsertResultStep; | ||||
| import org.jooq.InsertValuesStep12; | ||||
| import org.jooq.InsertValuesStep13; | ||||
| import org.jooq.SelectConditionStep; | ||||
| import org.jooq.exception.DataAccessException; | ||||
| import org.jooq.impl.DSL; | ||||
| import org.springframework.beans.factory.annotation.Autowired; | ||||
| import org.springframework.stereotype.Repository; | ||||
| import org.springframework.transaction.annotation.Transactional; | ||||
|  | ||||
| import de.jottyfan.camporganizer.db.jooq.enums.EnumCamprole; | ||||
| import de.jottyfan.camporganizer.db.jooq.enums.EnumSex; | ||||
| import de.jottyfan.camporganizer.db.jooq.tables.records.TCampRecord; | ||||
| import de.jottyfan.camporganizer.db.jooq.tables.records.TPersonRecord; | ||||
| import de.jottyfan.camporganizer.db.jooq.tables.records.TProfileRecord; | ||||
| import de.jottyfan.camporganizer.module.common.LambdaResultWrapper; | ||||
|  | ||||
| /** | ||||
|  * | ||||
| @@ -49,4 +65,89 @@ public class RegistrationGateway { | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * 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 | ||||
| 	 */ | ||||
| 	public Boolean register(RegistrationBean bean) { | ||||
| 		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) { | ||||
| 					throw new DataAccessException("login already in use: " + bean.getLogin()); | ||||
| 				} | ||||
| 				// TODO: check if teacher is at least 2 years older than the camp participants | ||||
| 				String oldPassword = new StrongPasswordEncryptor().encryptPassword(bean.getPassword()); | ||||
| 				InsertResultStep<TProfileRecord> sql1 = DSL.using(t) | ||||
| 				// @formatter:off | ||||
| 					.insertInto(T_PROFILE, | ||||
| 							        T_PROFILE.FORENAME, | ||||
| 							        T_PROFILE.SURNAME, | ||||
| 							        T_PROFILE.USERNAME, | ||||
| 							        T_PROFILE.PASSWORD, | ||||
| 							        T_PROFILE.DUEDATE, | ||||
| 							        T_PROFILE.UUID) | ||||
| 					.values(bean.getForename(), bean.getSurname(), bean.getLogin(), oldPassword, LocalDateTime.now().plus(356, ChronoUnit.DAYS), UUID.nameUUIDFromBytes(bean.getLogin().getBytes()).toString()) | ||||
| 					.returning(T_PROFILE.PK); | ||||
| 				// @formatter:on | ||||
| 				LOGGER.debug(sql1.toString()); | ||||
| 				Integer fkProfile = sql1.fetchOne().getPk(); | ||||
| 				// register the person for camp participation | ||||
| 				InsertValuesStep13<TPersonRecord, String, String, EnumSex, LocalDate, String, String, String, String, String, EnumCamprole, Integer, String, Integer> sql2 = DSL | ||||
| 						.using(t) | ||||
| 						// @formatter:off | ||||
| 				.insertInto(T_PERSON, | ||||
| 						       T_PERSON.FORENAME, | ||||
| 						       T_PERSON.SURNAME, | ||||
| 						       T_PERSON.SEX, | ||||
| 						       T_PERSON.BIRTHDATE, | ||||
| 						       T_PERSON.STREET, | ||||
| 						       T_PERSON.ZIP, | ||||
| 						       T_PERSON.CITY, | ||||
| 						       T_PERSON.EMAIL, | ||||
| 						       T_PERSON.PHONE, | ||||
| 						       T_PERSON.CAMPROLE, | ||||
| 						       T_PERSON.FK_CAMP, | ||||
| 						       T_PERSON.COMMENT, | ||||
| 						       T_PERSON.FK_PROFILE) | ||||
| 				.values(bean.getForename(), bean.getSurname(), bean.getSex(), | ||||
| 						bean.getBirthDate(), bean.getStreet(), bean.getZip(), bean.getCity(), bean.getEmail(), | ||||
| 						bean.getPhone(), bean.getCampRole(), bean.getFkCamp(), bean.getComment(), fkProfile); | ||||
| 			// @formatter:on | ||||
| 				LOGGER.debug(sql2.toString()); | ||||
| 				lrw.add(sql2.execute()); | ||||
| 				// register the login for the portal | ||||
| 			} else { | ||||
| 				InsertValuesStep12<TPersonRecord, String, String, EnumSex, LocalDate, String, String, String, String, String, EnumCamprole, Integer, String> sql = DSL | ||||
| 						.using(t) | ||||
| 						// @formatter:off | ||||
| 					.insertInto(T_PERSON, | ||||
| 							       T_PERSON.FORENAME, | ||||
| 							       T_PERSON.SURNAME, | ||||
| 							       T_PERSON.SEX, | ||||
| 							       T_PERSON.BIRTHDATE, | ||||
| 							       T_PERSON.STREET, | ||||
| 							       T_PERSON.ZIP, | ||||
| 							       T_PERSON.CITY, | ||||
| 							       T_PERSON.EMAIL, | ||||
| 							       T_PERSON.PHONE, | ||||
| 							       T_PERSON.CAMPROLE, | ||||
| 							       T_PERSON.FK_CAMP, | ||||
| 							       T_PERSON.COMMENT) | ||||
| 					.values(bean.getForename(), bean.getSurname(), bean.getSex(), | ||||
| 							bean.getBirthDate(), bean.getStreet(), bean.getZip(), bean.getCity(), bean.getEmail(), | ||||
| 							bean.getPhone(), bean.getCampRole(), bean.getFkCamp(), bean.getComment()); | ||||
| 				// @formatter:on | ||||
| 				LOGGER.debug(sql.toString()); | ||||
| 				lrw.add(sql.execute()); | ||||
| 			} | ||||
| 		}); | ||||
| 		return lrw.getCounter() > 0; | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -13,6 +13,9 @@ public class RegistrationService { | ||||
|  | ||||
| 	@Autowired | ||||
| 	private RegistrationGateway gateway; | ||||
| 	 | ||||
| 	@Autowired | ||||
| 	private KeycloakRepository keycloak; | ||||
|  | ||||
| 	/** | ||||
| 	 * get the camp | ||||
| @@ -24,4 +27,17 @@ public class RegistrationService { | ||||
| 		return gateway.getCamp(fkCamp); | ||||
| 	} | ||||
|  | ||||
| 	/** | ||||
| 	 * register the person for a camp; if registerInKeycloak, do so also | ||||
| 	 *  | ||||
| 	 * @param bean the bean | ||||
| 	 * @return true if successful, false otherwise  | ||||
| 	 */ | ||||
| 	public Boolean register(RegistrationBean bean) { | ||||
| 		Boolean result = gateway.register(bean); | ||||
| 		if (result && bean.getRegisterInKeycloak()) { | ||||
| 			keycloak.register(bean.getLogin(), bean.getPassword()); | ||||
| 		} | ||||
| 		return result; | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -15,66 +15,80 @@ | ||||
| 		<h3 class="centered cabin" th:text="'zur ' + ${camp.name} + ' ' + ${camp.year}"></h3> | ||||
| 		<div class="card centered-card" style="max-width: 48rem"> | ||||
| 			<div class="card-body"> | ||||
| 				<form action="#" method="post"> | ||||
| 				<form th:action="@{/registration/register}" th:object="${bean}" method="post"> | ||||
| 					<input type="hidden" th:field="*{fkCamp}" /> | ||||
| 					<div class="container"> | ||||
| 						<div class="row"> | ||||
| 							<div class="col-sm-6 rowdist"> | ||||
| 								<input type="text" class="form-control" placeholder="Vorname" /> | ||||
| 								<input type="text" class="form-control" placeholder="Vorname" th:field="*{forename}" /> | ||||
| 							</div> | ||||
| 							<div class="col-sm-6 rowdist"> | ||||
| 								<input type="text" class="form-control" placeholder="Nachname" /> | ||||
| 								<input type="text" class="form-control" placeholder="Nachname" th:field="*{surname}" /> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 						<div class="row"> | ||||
| 							<div class="col-sm-6 rowdist"> | ||||
| 								<select class="form-select"> | ||||
| 								<select class="form-select" th:field="*{sex}"> | ||||
| 									<option value="">Geschlecht</option> | ||||
| 									<option value="female">weiblich</option> | ||||
| 									<option value="male">männlich</option> | ||||
| 								</select> | ||||
| 							</div> | ||||
| 							<div class="col-sm-6 rowdist"> | ||||
| 								<input type="date" class="form-control" placeholder="Geburtsdatum" /> | ||||
| 								<input type="date" class="form-control" placeholder="Geburtsdatum"  th:field="*{birthDate}" /> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 						<div class="row"> | ||||
| 							<div class="col-sm-6 rowdist"> | ||||
| 								<input type="text" class="form-control" placeholder="Straße und Hausnummer" /> | ||||
| 								<input type="text" class="form-control" placeholder="Straße und Hausnummer" th:field="*{street}" /> | ||||
| 							</div> | ||||
| 							<div class="col-sm-2 rowdist"> | ||||
| 								<input type="text" class="form-control" placeholder="PLZ" /> | ||||
| 								<input type="text" class="form-control" placeholder="PLZ" th:field="*{zip}" /> | ||||
| 							</div> | ||||
| 							<div class="col-sm-4 rowdist"> | ||||
| 								<input type="text" class="form-control" placeholder="Ort" /> | ||||
| 								<input type="text" class="form-control" placeholder="Ort" th:field="*{city}" /> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 						<div class="row"> | ||||
| 							<div class="col-sm-6 rowdist"> | ||||
| 								<input type="text" class="form-control" placeholder="E-Mail" /> | ||||
| 								<input type="text" class="form-control" placeholder="E-Mail" th:field="*{email}" /> | ||||
| 							</div> | ||||
| 							<div class="col-sm-6 rowdist"> | ||||
| 								<input type="text" class="form-control" placeholder="Telefonnummer" /> | ||||
| 								<input type="text" class="form-control" placeholder="Telefonnummer" th:field="*{phone}" /> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 						<div class="row"> | ||||
| 							<div class="col-sm-6 rowdist"> | ||||
| 								<span>mitkommen als</span> | ||||
| 							</div> | ||||
| 							<div class="col-sm-6 rowdist"> | ||||
| 								<select class="form-select" th:field="*{campRole}"> | ||||
| 									<option value="student">Teilnehmer</option> | ||||
| 									<option value="teacher">Mitarbeiter</option> | ||||
| 									<option value="feeder">Küchenteam</option> | ||||
| 									<option value="director">Leiter</option> | ||||
| 								</select> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 						<div class="row"> | ||||
| 							<div class="col-sm-12 rowdist"> | ||||
| 								<textarea class="form-control" placeholder="Sonstiges"></textarea> | ||||
| 								<textarea class="form-control" placeholder="Sonstiges" th:field="*{comment}"></textarea> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 						<div class="row"> | ||||
| 							<div class="col-sm-12 rowdist"> | ||||
| 								<div class="form-check" title="Die Anmeldedaten können in den Kontoeinstellungen bearbeitet und für die nächsten Freizeitanmeldungen verwendet werden."> | ||||
| 									<input id="save" type="checkbox" class="form-check-input" checked="checked" onchange="$('#createlogin').toggle();" /> | ||||
| 									<input id="save" type="checkbox" class="form-check-input" th:field="*{registerInKeycloak}" onchange="$('#createlogin').toggle();" /> | ||||
| 									<label class="form-check-label" for="save">Anmeldedaten speichern</label> | ||||
| 								</div> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 						<div id="createlogin" class="row"> | ||||
| 							<div class="col-sm-6 rowdist"> | ||||
| 								<input type="text" class="form-control" placeholder="Login" /> | ||||
| 								<input type="text" class="form-control" placeholder="Login" th:field="*{login}" /> | ||||
| 							</div> | ||||
| 							<div class="col-sm-6 rowdist"> | ||||
| 								<input type="password" class="form-control" placeholder="Passwort" /> | ||||
| 								<input type="password" class="form-control" placeholder="Passwort" th:field="*{password}" /> | ||||
| 							</div> | ||||
| 						</div> | ||||
| 						<div class="row"> | ||||
| @@ -89,4 +103,4 @@ | ||||
| 	</div> | ||||
| 	</content> | ||||
| </body> | ||||
| </html> | ||||
| </html> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user