Skip to content

Commit

Permalink
Merge pull request #249 from it-at-m/159-implementierung-urnenwahlvor…
Browse files Browse the repository at this point in the history
…bereitung-service-impl

159 implementierung urnenwahlvorbereitung service impl - Impl und Testing für Get
  • Loading branch information
MrSebastian authored May 27, 2024
2 parents f8d5fa4 + 93a1b38 commit 299eca0
Show file tree
Hide file tree
Showing 38 changed files with 1,096 additions and 6 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
id: add authorities wahlvorbereitung urnenwahlvorbereitung
author: MrSebastian
realm: ${SSO_REALM}
changes:
- addRole:
name: Wahlvorbereitung_BUSINESSACTION_GetUrnenwahlVorbereitung
clientRole: true
clientId: ${SSO_CLIENT_ID}
- assignRoleToGroup:
group: allWahlvorbereitungAuthorities
role: Wahlvorbereitung_BUSINESSACTION_GetUrnenwahlVorbereitung
clientId: ${SSO_CLIENT_ID}

- addRole:
name: Wahlvorbereitung_BUSINESSACTION_PostUrnenwahlVorbereitung
clientRole: true
clientId: ${SSO_CLIENT_ID}
- assignRoleToGroup:
group: allWahlvorbereitungAuthorities
role: Wahlvorbereitung_BUSINESSACTION_PostUrnenwahlVorbereitung
clientId: ${SSO_CLIENT_ID}

- addRole:
name: Wahlvorbereitung_WRITE_UrnenwahlVorbereitung
clientRole: true
clientId: ${SSO_CLIENT_ID}
- assignRoleToGroup:
group: allWahlvorbereitungAuthorities
role: Wahlvorbereitung_WRITE_UrnenwahlVorbereitung
clientId: ${SSO_CLIENT_ID}

- addRole:
name: Wahlvorbereitung_DELETE_UrnenwahlVorbereitung
clientRole: true
clientId: ${SSO_CLIENT_ID}
- assignRoleToGroup:
group: allWahlvorbereitungAuthorities
role: Wahlvorbereitung_DELETE_UrnenwahlVorbereitung
clientId: ${SSO_CLIENT_ID}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
id: create group allWahlvorbereitungAuthorities
author: MrSebastian
realm: ${SSO_REALM}
changes:
- addGroup:
name: allWahlvorbereitungAuthorities
- assignGroup:
user: wls_all
group: allWahlvorbereitungAuthorities
4 changes: 3 additions & 1 deletion stack/keycloak/migration/keycloak-changelog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ includes:
- path: 07_add-briefwahl-beanstandete-wahlbriefe-authorities.yml
- path: 08_create-group-all-briefwahl-and-assign.yml
- path: 09_add-briefwahl-beanstandete-wahbriefe-to-group-all-briefwahl.yml
- path: add-authorities-infomanagement-konfigurierterwahltag.yml
- path: add-authorities-infomanagement-konfigurierterwahltag.yml
- path: create-and-assign-group-all-wahlvorbereitung.yml
- path: add-authorities-wahlvorbereitung-urnenwahlvorbereitung.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
@ComponentScan(
basePackages = {
"org.springframework.data.jpa.convert.threeten",
"de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice"
"de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice",
"de.muenchen.oss.wahllokalsystem.wls.common.exception",
"de.muenchen.oss.wahllokalsystem.wls.common.security"
}
)
@EntityScan(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// allow access to /actuator/health/readiness for OpenShift Readiness Check
AntPathRequestMatcher.antMatcher("/actuator/health/readiness"),
// allow access to /actuator/metrics for Prometheus monitoring in OpenShift
AntPathRequestMatcher.antMatcher("/actuator/metrics"))
AntPathRequestMatcher.antMatcher("/actuator/metrics"),
AntPathRequestMatcher.antMatcher("/v3/api-docs/**"),
AntPathRequestMatcher.antMatcher("/swagger-ui/**"))
.permitAll())
.authorizeHttpRequests((requests) -> requests.requestMatchers("/**")
.authenticated())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.domain;

import jakarta.persistence.CollectionTable;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.Id;
import jakarta.persistence.JoinColumn;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class UrnenwahlVorbereitung {

@Id
@NotNull
@Size(max = 255)
private String wahlbezirkID;

@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "UWVorbereitung_Urnen", joinColumns = @JoinColumn(name = "vorbereitung_wahlbezirkID"))
@NotNull
@Size(min = 1)
@Builder.Default
private java.util.List<Wahlurne> urnenAnzahl = new java.util.ArrayList<>();

private long anzahlWahlkabinen;

private long anzahlWahltische;

private long anzahlNebenraeume;

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.domain;

import java.util.Optional;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.repository.CrudRepository;
import org.springframework.security.access.prepost.PreAuthorize;

public interface UrnenwahlVorbereitungRepository extends CrudRepository<UrnenwahlVorbereitung, String> {

String CACHE = "UrnenwahlVorbereitungCACHE";

@Override
Iterable<UrnenwahlVorbereitung> findAll();

@Override
@Cacheable(value = CACHE, key = "#p0")
Optional<UrnenwahlVorbereitung> findById(String wahlbezirkID);

@Override
@CachePut(value = CACHE, key = "#p0.wahlbezirkID")
@PreAuthorize("hasAuthority('Wahlvorbereitung_WRITE_UrnenwahlVorbereitung')")
<S extends UrnenwahlVorbereitung> S save(S urnenwahlVorbereitung);

@Override
@CacheEvict(value = CACHE, key = "#p0")
@PreAuthorize("hasAuthority('Wahlvorbereitung_DELETE_UrnenwahlVorbereitung')")
void deleteById(String wahlbezirkID);

@Override
@CacheEvict(value = CACHE, key = "#p0.wahlbezirkID")
@PreAuthorize("hasAuthority('Wahlvorbereitung_DELETE_UrnenwahlVorbereitung')")
void delete(UrnenwahlVorbereitung entity);

@Override
@CacheEvict(value = CACHE, allEntries = true)
@PreAuthorize("hasAuthority('Wahlvorbereitung_DELETE_UrnenwahlVorbereitung')")
void deleteAll(Iterable<? extends UrnenwahlVorbereitung> entities);

@Override
@CacheEvict(value = CACHE, allEntries = true)
@PreAuthorize("hasAuthority('Wahlvorbereitung_DELETE_UrnenwahlVorbereitung')")
void deleteAll();
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

@Embeddable
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Wahlurne {

@NotNull
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.exception;

import lombok.AccessLevel;
import lombok.NoArgsConstructor;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ExceptionConstants {

private static final String CODE_SUCHKRITERIEN_UNVOLLSTAENDIG = "901";
private static final String MSG_SUCHKRITERIEN_UNVOLLSTAENDIG = "Fehler beim Laden: Suchkriterien unvollständig.";

public static ExceptionDataWrapper SUCHKRITERIEN_UNVOLLSTAENDIG = new ExceptionDataWrapper(CODE_SUCHKRITERIEN_UNVOLLSTAENDIG,
MSG_SUCHKRITERIEN_UNVOLLSTAENDIG);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.exception;

import jakarta.validation.constraints.NotNull;

public record ExceptionDataWrapper(@NotNull String code, @NotNull String message) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.exception;

import de.muenchen.oss.wahllokalsystem.wls.common.exception.FachlicheWlsException;
import de.muenchen.oss.wahllokalsystem.wls.common.exception.util.ServiceIDFormatter;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class ExceptionFactory {

private final ServiceIDFormatter serviceIDFormatter;

public FachlicheWlsException createFachlicheWlsException(final ExceptionDataWrapper exceptionDataWrapper) {
return FachlicheWlsException.withCode(exceptionDataWrapper.code()).inService(serviceIDFormatter.getId())
.buildWithMessage(exceptionDataWrapper.message());
}
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.common;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.Builder;

@Builder
public record WahlurneDTO(String wahlID, long anzahl, Boolean urneVersiegelt) {
public record WahlurneDTO(@NotNull @Size(max = 255) String wahlID,
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) long anzahl,
Boolean urneVersiegelt) {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.urnenwahlvorbereitung;

import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung.UrnenwahlvorbereitungService;
import io.swagger.v3.oas.annotations.Operation;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/businessActions/urnenwahlVorbereitung")
@RequiredArgsConstructor
public class UrnenwahlvorbereitungController {

private final UrnenwahlvorbereitungService service;

private final UrnenwahlvorbereitungDTOMapper urnenwahlvorbereitungDTOMapper;

@Operation(description = "Laden der Wahlvorbereitungsdaten des Urnenwahllokals {wahlbezirkID}")
@GetMapping("{wahlbezirkID}")
public ResponseEntity<UrnenwahlvorbereitungDTO> getUrnenwahlVorbereitung(@PathVariable("wahlbezirkID") final String wahlbezirkID) {
val urnenwahlvorbereitungModel = service.getUrnenwahlvorbereitung(wahlbezirkID);

return withBodyOrNoContent(urnenwahlvorbereitungModel.map(urnenwahlvorbereitungDTOMapper::toDTO));
}

private <T> ResponseEntity<T> withBodyOrNoContent(final Optional<T> body) {
return body.map(ResponseEntity::ok).orElseGet(() -> ResponseEntity.noContent().build());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.urnenwahlvorbereitung;

import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.common.WahlurneDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

public record UrnenwahlvorbereitungDTO(@NotNull String wahlbezirkID,
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) long anzahlWahlkabinen,
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) long anzahlWahltische,
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) long anzahlNebenraeume,
@NotNull @Size(min = 1) List<WahlurneDTO> urnenAnzahl) {

public UrnenwahlvorbereitungDTO(final String wahlbezirkID, final long anzahlWahlkabinen, final long anzahlWahltische, final long anzahlNebenraeume,
final List<WahlurneDTO> urnenAnzahl) {
this.wahlbezirkID = wahlbezirkID;
this.anzahlWahlkabinen = anzahlWahlkabinen;
this.anzahlWahltische = anzahlWahltische;
this.anzahlNebenraeume = anzahlNebenraeume;
this.urnenAnzahl = Objects.requireNonNullElseGet(urnenAnzahl, ArrayList::new);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.urnenwahlvorbereitung;

import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.rest.common.WahlurneDTOMapper;
import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung.UrnenwahlvorbereitungModel;
import org.mapstruct.Mapper;

@Mapper(uses = WahlurneDTOMapper.class)
public interface UrnenwahlvorbereitungDTOMapper {

UrnenwahlvorbereitungDTO toDTO(UrnenwahlvorbereitungModel model);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung;

import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.common.WahlurneModel;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import lombok.Builder;

@Builder
public record UrnenwahlvorbereitungModel(String wahlbezirkID, long anzahlWahlkabinen, long anzahlWahltische, long anzahlNebenraeume,
List<WahlurneModel> urnenAnzahl) {

public UrnenwahlvorbereitungModel(final String wahlbezirkID, final long anzahlWahlkabinen, final long anzahlWahltische, final long anzahlNebenraeume,
final List<WahlurneModel> urnenAnzahl) {
this.wahlbezirkID = wahlbezirkID;
this.anzahlWahlkabinen = anzahlWahlkabinen;
this.anzahlWahltische = anzahlWahltische;
this.anzahlNebenraeume = anzahlNebenraeume;
this.urnenAnzahl = Objects.requireNonNullElseGet(urnenAnzahl, ArrayList::new);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung;

import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.domain.UrnenwahlVorbereitung;
import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.common.WahlurneModelMapper;
import org.mapstruct.Mapper;

@Mapper(uses = WahlurneModelMapper.class)
public interface UrnenwahlvorbereitungModelMapper {

UrnenwahlvorbereitungModel toModel(UrnenwahlVorbereitung entity);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.service.urnenwahlvorbereitung;

import de.muenchen.oss.wahllokalsystem.wahlvorbereitungservice.domain.UrnenwahlVorbereitungRepository;
import java.util.Optional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.parameters.P;
import org.springframework.stereotype.Service;

@Service
@RequiredArgsConstructor
@Slf4j
public class UrnenwahlvorbereitungService {

private final UrnenwahlVorbereitungRepository urnenwahlVorbereitungRepository;

private final UrnenwahlvorbereitungModelMapper urnenwahlvorbereitungModelMapper;

private final UrnenwahlvorbereitungValidator urnenwahlvorbereitungValidator;

@PreAuthorize(
"hasAuthority('Wahlvorbereitung_BUSINESSACTION_GetUrnenwahlVorbereitung')"
+ "and @bezirkIdPermisionEvaluator.tokenUserBezirkIdMatches(#wahlbezirkID, authentication)"
)
public Optional<UrnenwahlvorbereitungModel> getUrnenwahlvorbereitung(@P("wahlbezirkID") final String wahlbezirkID) {
log.debug("#getUrnenwahlVorbereitung");
log.debug("in: wahlbezirkID > {}", wahlbezirkID);

urnenwahlvorbereitungValidator.validWahlbezirkIDOrThrow(wahlbezirkID);

val dataFromRepo = urnenwahlVorbereitungRepository.findById(wahlbezirkID);
log.debug("out: urnenwahlVorbereitung > {}", dataFromRepo.orElse(null));

return dataFromRepo.map(urnenwahlvorbereitungModelMapper::toModel);
}
}
Loading

0 comments on commit 299eca0

Please sign in to comment.