camp admin added
This commit is contained in:
@ -8,7 +8,7 @@ plugins {
|
||||
}
|
||||
|
||||
group = 'de.jottyfan.bico'
|
||||
version = '0.2.1'
|
||||
version = '0.2.2'
|
||||
|
||||
description = """BibleClassOrganizer"""
|
||||
|
||||
|
@ -12,6 +12,7 @@ import org.springframework.security.web.SecurityFilterChain;
|
||||
*/
|
||||
@Configuration
|
||||
public class SecurityConfig {
|
||||
|
||||
@Bean
|
||||
SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
|
||||
http.authorizeHttpRequests(
|
||||
|
@ -3,8 +3,6 @@ package de.jottyfan.bico.modules;
|
||||
import java.security.Principal;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.security.core.context.SecurityContextHolder;
|
||||
@ -12,6 +10,7 @@ import org.springframework.security.oauth2.client.authentication.OAuth2Authentic
|
||||
import org.springframework.security.oauth2.core.user.OAuth2User;
|
||||
import org.springframework.web.bind.annotation.ModelAttribute;
|
||||
|
||||
import de.jottyfan.bico.Main;
|
||||
import de.jottyfan.bico.modules.profile.ProfileService;
|
||||
|
||||
/**
|
||||
@ -20,8 +19,7 @@ import de.jottyfan.bico.modules.profile.ProfileService;
|
||||
*
|
||||
*/
|
||||
public abstract class CommonController {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(CommonController.class);
|
||||
private static final List<String> admins = List.of("andre.sieber", "tobias.kuehne", "jotty");
|
||||
|
||||
@Autowired
|
||||
private ProfileService profileService;
|
||||
@ -29,6 +27,11 @@ public abstract class CommonController {
|
||||
@Value("${spring.security.oauth2.client.provider.nextcloud.issuer-uri}")
|
||||
private String nextcloudUrl;
|
||||
|
||||
@ModelAttribute("isCampAdmin")
|
||||
public Boolean isCampAdmin(Principal principal) {
|
||||
return admins.contains(principal.getName());
|
||||
}
|
||||
|
||||
@ModelAttribute("hasBUrole")
|
||||
public Boolean hasBURole(Principal principal) {
|
||||
OAuth2AuthenticationToken token = (OAuth2AuthenticationToken) principal;
|
||||
@ -38,7 +41,7 @@ public abstract class CommonController {
|
||||
List<String> roles = (List<String>) user.getAttributes().get("roles");
|
||||
return roles.contains("Bibelunterricht");
|
||||
} else {
|
||||
LOGGER.warn("token is null, no roles can be detected");
|
||||
Main.LOGGER.warn("token is null, no roles can be detected");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -52,7 +55,7 @@ public abstract class CommonController {
|
||||
List<String> roles = (List<String>) user.getAttributes().get("roles");
|
||||
return roles.contains("Kinderstunde klein");
|
||||
} else {
|
||||
LOGGER.warn("token is null, no roles can be detected");
|
||||
Main.LOGGER.warn("token is null, no roles can be detected");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -66,7 +69,7 @@ public abstract class CommonController {
|
||||
List<String> roles = (List<String>) user.getAttributes().get("roles");
|
||||
return roles.size() > 0;
|
||||
} else {
|
||||
LOGGER.warn("token is null, no roles can be detected");
|
||||
Main.LOGGER.warn("token is null, no roles can be detected");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,51 @@
|
||||
package de.jottyfan.bico.modules.camp;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.security.Principal;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.stereotype.Controller;
|
||||
import org.springframework.ui.Model;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
|
||||
import de.jottyfan.bico.modules.CommonController;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jotty
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
@Controller
|
||||
public class AdminRegistrationController extends CommonController {
|
||||
|
||||
@Autowired
|
||||
private AdminRegistrationService service;
|
||||
|
||||
@GetMapping("/camp/registration/admin")
|
||||
public String getList(Model model, Principal principal) {
|
||||
if (isCampAdmin(principal)) {
|
||||
model.addAttribute("list", service.getAllRegistrations());
|
||||
model.addAttribute("ages", service.getAges());
|
||||
}
|
||||
return "/camp/list";
|
||||
}
|
||||
|
||||
@GetMapping("/camp/registration/admin/download")
|
||||
@ResponseBody
|
||||
public String download(HttpServletResponse response, Principal principal) throws IOException {
|
||||
if (isCampAdmin(principal)) {
|
||||
response.setHeader("Content-Disposition", String.format("attachment; filename=Gemeindefreizeit-Anmeldungen-%s.csv",
|
||||
LocalDateTime.now().format(DateTimeFormatter.ISO_DATE_TIME)));
|
||||
response.setContentType("text/csv; charset=utf-8");
|
||||
return service.getDownload();
|
||||
} else {
|
||||
return "forbidden";
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,33 @@
|
||||
package de.jottyfan.bico.modules.camp;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import de.jottyfan.bico.db.camp.tables.records.TAgeRecord;
|
||||
import de.jottyfan.bico.modules.camp.model.RegistrationBean;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author jotty
|
||||
*
|
||||
*/
|
||||
@Service
|
||||
public class AdminRegistrationService {
|
||||
|
||||
@Autowired
|
||||
private RegistrationRepository repository;
|
||||
|
||||
public List<RegistrationBean> getAllRegistrations() {
|
||||
return repository.getAllRegistrations();
|
||||
}
|
||||
|
||||
public List<TAgeRecord> getAges() {
|
||||
return repository.getAges();
|
||||
}
|
||||
|
||||
public String getDownload() {
|
||||
return repository.getDownload();
|
||||
}
|
||||
}
|
@ -3,12 +3,15 @@ package de.jottyfan.bico.modules.camp;
|
||||
import static de.jottyfan.bico.db.camp.Tables.T_AGE;
|
||||
import static de.jottyfan.bico.db.camp.Tables.T_REGISTRATION;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.List;
|
||||
|
||||
import org.jooq.DSLContext;
|
||||
import org.jooq.DeleteConditionStep;
|
||||
import org.jooq.InsertValuesStep20;
|
||||
import org.jooq.Record19;
|
||||
import org.jooq.SelectConditionStep;
|
||||
import org.jooq.SelectOnConditionStep;
|
||||
import org.jooq.SelectSeekStep1;
|
||||
import org.jooq.UpdateConditionStep;
|
||||
import org.jooq.impl.DSL;
|
||||
@ -102,6 +105,21 @@ public class RegistrationRepository {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* get all registrations (for admins only)
|
||||
*
|
||||
* @return the registrations
|
||||
*/
|
||||
public List<RegistrationBean> getAllRegistrations() {
|
||||
SelectSeekStep1<TRegistrationRecord, LocalDateTime> sql = jooq
|
||||
// @formatter:off
|
||||
.selectFrom(T_REGISTRATION)
|
||||
.orderBy(T_REGISTRATION.CREATED);
|
||||
// @formatter:on
|
||||
Main.LOGGER.trace(sql);
|
||||
return sql.fetchInto(RegistrationBean.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* get all registrations of name
|
||||
*
|
||||
@ -167,4 +185,38 @@ public class RegistrationRepository {
|
||||
Main.LOGGER.trace(sql);
|
||||
return sql.fetchInto(TAgeRecord.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* get CSV version of the list, only for admins
|
||||
*
|
||||
* @return the csv
|
||||
*/
|
||||
public String getDownload() {
|
||||
SelectOnConditionStep<Record19<LocalDateTime, String, String, EnumSex, String, Boolean, Boolean, Boolean, Boolean, Boolean, Boolean, Boolean, Boolean, Boolean, Boolean, String, String, Integer, Boolean>> sql = jooq
|
||||
// @formatter:off
|
||||
.select(T_REGISTRATION.CREATED,
|
||||
T_REGISTRATION.FORENAME,
|
||||
T_REGISTRATION.SURNAME,
|
||||
T_REGISTRATION.SEX,
|
||||
T_AGE.NAME,
|
||||
T_REGISTRATION.DAY0,
|
||||
T_REGISTRATION.DAY1,
|
||||
T_REGISTRATION.DAY2,
|
||||
T_REGISTRATION.DAY3,
|
||||
T_REGISTRATION.DAY4,
|
||||
T_REGISTRATION.BARRIER_FREE,
|
||||
T_REGISTRATION.TOWELS,
|
||||
T_REGISTRATION.BED_LINEN,
|
||||
T_REGISTRATION.COT,
|
||||
T_REGISTRATION.REQUIRE_PAYMENT,
|
||||
T_REGISTRATION.DISEASES,
|
||||
T_REGISTRATION.NUTRITION,
|
||||
T_REGISTRATION.DRIVER_PROVIDE_PLACES,
|
||||
T_REGISTRATION.WANT_PLACE_IN_CAR)
|
||||
.from(T_REGISTRATION)
|
||||
.leftJoin(T_AGE).on(T_AGE.PK_AGE.eq(T_REGISTRATION.FK_AGE));
|
||||
// @formatter:on
|
||||
Main.LOGGER.trace(sql);
|
||||
return sql.fetch().formatCSV(true);
|
||||
}
|
||||
}
|
||||
|
@ -50,4 +50,19 @@ body {
|
||||
.centeredalert {
|
||||
width: 400px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.campbadge {
|
||||
border: 1px solid #222;
|
||||
color: #222;
|
||||
}
|
||||
|
||||
[data-bs-theme=dark] .campbadge {
|
||||
border-color: silver;
|
||||
color: silver;
|
||||
}
|
||||
|
||||
.full-size {
|
||||
width: 100% !important;
|
||||
max-width: inherit !important;
|
||||
}
|
81
src/main/resources/templates/camp/list.html
Normal file
81
src/main/resources/templates/camp/list.html
Normal file
@ -0,0 +1,81 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns:th="http://www.thymeleaf.org" layout:decorate="~{template}" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:sec="http://www.thymeleaf.org/extras/spring-security">
|
||||
<body>
|
||||
<th:block layout:fragment="content">
|
||||
<div class="borderdist">
|
||||
<div class="container full-size">
|
||||
<div class="row g-2">
|
||||
<div class="col-sm-12">
|
||||
<h2>Anmeldungen zur Gemeindefreizeit 2025</h2>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert alert-danger" th:unless="${list}">Sie haben keine Berechtigung, die Anmeldungen einzusehen.</div>
|
||||
<div th:if="${list}">
|
||||
<table id="table" class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Vorname</th>
|
||||
<th>Nachname</th>
|
||||
<th>Geschlecht</th>
|
||||
<th>Alter</th>
|
||||
<th>Tage dabei</th>
|
||||
<th>Extras</th>
|
||||
<th>Unverträglichkeit</th>
|
||||
<th>Mitfahrplätze</th>
|
||||
<th>Besonderheiten</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="l : ${list}">
|
||||
<td th:text="${l.forename}"></td>
|
||||
<td th:text="${l.surname}"></td>
|
||||
<td th:text="${l.sex}"></td>
|
||||
<td>
|
||||
<th:block th:each="a : ${ages}">
|
||||
<span th:text="${a.name}" th:if="${a.pkAge == l.fkAge}"></span>
|
||||
</th:block>
|
||||
</td>
|
||||
<td>
|
||||
<span th:if="${l.day0}" class="badge campbadge">Donnerstag</span>
|
||||
<span th:if="${l.day1}" class="badge campbadge">Freitag</span>
|
||||
<span th:if="${l.day2}" class="badge campbadge">Sonnabend</span>
|
||||
<span th:if="${l.day3}" class="badge campbadge">Sonntag</span>
|
||||
<span th:if="${l.day4}" class="badge campbadge">Montag</span>
|
||||
</td>
|
||||
<td>
|
||||
<span th:if="${l.barrierFree}" class="badge campbadge">barrierefrei</span>
|
||||
<span th:if="${l.towels}" class="badge campbadge">Handtücher</span>
|
||||
<span th:if="${l.bedLinen}" class="badge campbadge">Bettwäsche</span>
|
||||
<span th:if="${l.cot}" class="badge campbadge">Kinderbett</span>
|
||||
<span th:if="${l.requirePayment}" class="badge campbadge">finanzielle Unterstützung erbeten</span>
|
||||
</td>
|
||||
<td th:text="${l.nutrition}"></td>
|
||||
<td>
|
||||
<span th:if="${l.driverProvidePlaces}">biete <span th:text="${l.driverProvidePlaces}"></span></span>
|
||||
<span th:if="${l.wantPlaceInCar}">benötige 1</span>
|
||||
</td>
|
||||
<td th:text="${l.diseases}"></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<script th:inline="javascript">
|
||||
/*<![CDATA[*/
|
||||
$(document).ready(function() {
|
||||
$("#table").DataTable({
|
||||
"language" : locale_de,
|
||||
"responsive" : true
|
||||
});
|
||||
});
|
||||
/*]]>*/
|
||||
</script>
|
||||
</div>
|
||||
<div class="row g-2" th:if="${list}">
|
||||
<div class="col-sm-12">
|
||||
<a th:href="@{/camp/registration/admin/download}" class="btn btn-outline-primary">Download</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</th:block>
|
||||
</body>
|
||||
</html>
|
@ -26,6 +26,7 @@
|
||||
<div class="collapse navbar-collapse" id="navbarSupportedContent" style="margin-right: 20px">
|
||||
<ul class="navbar-nav mb-2 mb-lg-0" th:if="${hasAnyRole}">
|
||||
<li class="nav-item"><a class="btn btn-outline-secondary" th:href="@{/camp/registration}" style="margin-left: 12px">Anmeldung Gemeindefreizeit</a></li>
|
||||
<li class="nav-item"><a class="btn btn-outline-secondary" th:href="@{/camp/registration/admin}" style="margin-left: 12px" th:if="${isCampAdmin}">Gemeindefreizeitliste</a></li>
|
||||
<li class="nav-item"><a class="btn btn-outline-secondary" th:href="@{/next}" style="margin-left: 12px" th:if="${hasDateRole || hasBUrole}">Dienstplan</a></li>
|
||||
<li class="nav-item"><a class="btn btn-outline-secondary" th:href="@{/sheet}" style="margin-left: 12px" th:if="${hasBUrole}">Einteilung</a></li>
|
||||
<li class="nav-item"><a class="btn btn-outline-secondary" th:href="@{/subject/list}" style="margin-left: 12px" th:if="${hasBUrole}">Themen</a></li>
|
||||
|
Reference in New Issue
Block a user