Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

168 implementierung wahlkonfiguration #231

Merged
merged 85 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
0a9951a
add authorities for informanagement Konfiguration
MrSebastian May 7, 2024
c5e1e6d
link new keyloak migration file
MrSebastian May 7, 2024
b065396
create database model
MrSebastian May 7, 2024
92773f6
use localhost for keycloak and fix path
MrSebastian May 7, 2024
8c50351
init and work in progress on service get konfiguration by key
MrSebastian May 7, 2024
0fa6986
init and work in progress for konfiguration controller
MrSebastian May 7, 2024
f4414f2
some sample requests for konfiguration in infomanagement
MrSebastian May 7, 2024
26b260b
move security relevant actions to new service
MrSebastian May 8, 2024
c0a21d1
assign attribute wahlbezirksArt and create users
MrSebastian May 8, 2024
b6a9cfa
update request to have bwb and uwb user
MrSebastian May 8, 2024
2afa1e6
move http-request to test-resources
MrSebastian May 10, 2024
935375c
finish draft for getKonfigurationByKey implementation
MrSebastian May 10, 2024
cf497ee
remove unused method
MrSebastian May 10, 2024
c516ce6
@Value injection via constructor
MrSebastian May 10, 2024
22a9250
add lombok builder
MrSebastian May 10, 2024
a9c9c3d
creating tests
MrSebastian May 10, 2024
82a092b
add lombok builder
MrSebastian May 10, 2024
cce953d
add controller unit test
MrSebastian May 10, 2024
c380139
add dto mapper unit test
MrSebastian May 10, 2024
03e3597
move preauthorize from class to method
MrSebastian May 10, 2024
762b264
add service oid
MrSebastian May 10, 2024
09136ee
add security test utils
MrSebastian May 10, 2024
268cdcb
add service security test
MrSebastian May 10, 2024
9486a0d
add default konfig values
MrSebastian May 13, 2024
2d9e908
add test request which respones depends on wahlbezirkart
MrSebastian May 13, 2024
c581bee
redesign get user detail concept
MrSebastian May 13, 2024
2aec6dd
removed useless mocked bean
MrSebastian May 13, 2024
03639ab
create annotation to run with mocked user and jwt token
MrSebastian May 13, 2024
e975961
add more constants for authorities
MrSebastian May 13, 2024
1ee363a
create controller integration test
MrSebastian May 13, 2024
1fc1aab
spotless:apply
MrSebastian May 13, 2024
c863512
Merge branch 'refs/heads/dev' into 168-implementierung-wahlkonfiguration
MrSebastian May 14, 2024
1f542cd
add security tests for konfiguration controller
MrSebastian May 14, 2024
8a9ed15
added flyway migration files for oracle
MrSebastian May 14, 2024
a3b976c
add global exception handler
MrSebastian May 14, 2024
fb0180c
implementing post konfiguration
MrSebastian May 14, 2024
bb47128
implementing tests for post konfiguration
MrSebastian May 14, 2024
32f2482
add http example request for post konfiguration
MrSebastian May 14, 2024
2e525db
implemented get all konfigurations
MrSebastian May 14, 2024
0695894
implemented tests for get all konfigurations
MrSebastian May 14, 2024
6653209
fix missing no content on get all konfigurations
MrSebastian May 14, 2024
1b0d2e4
add authorities for kennbuchstaben in informanagement
MrSebastian May 14, 2024
68e5513
implemented kennbuchstabenlisten
MrSebastian May 14, 2024
0f0fd15
implemented and updated tests for kennbuchstabenlisten
MrSebastian May 14, 2024
20717df
add example request for get kennbuchstabenlisten
MrSebastian May 14, 2024
ca7cad9
implemted unauthorized access to some konfigurations
MrSebastian May 14, 2024
3e1044c
added test for unathorized konfiguration access
MrSebastian May 14, 2024
88dae83
added example request for unauthorized access for konfiguration
MrSebastian May 14, 2024
59ac615
spotless:apply
MrSebastian May 14, 2024
855676a
fixing tests
MrSebastian May 14, 2024
020060d
improve code coverage with additional test
MrSebastian May 14, 2024
27c7051
exclude generated sources from codestyle
MrSebastian May 14, 2024
9d6f261
refactor dto into their own package
MrSebastian May 14, 2024
041735a
refactor model into their own package
MrSebastian May 14, 2024
1a73b6d
fix typos in validator
MrSebastian May 14, 2024
615a75c
remove unused method
MrSebastian May 14, 2024
6eb8ed7
add super @NonNull
MrSebastian May 14, 2024
a7c6c34
remove unnecessary ;
MrSebastian May 14, 2024
201a75e
replace variables that are always null
MrSebastian May 14, 2024
5a105c0
spotless:apply
MrSebastian May 14, 2024
d8e2c48
remove empty lines
MrSebastian May 15, 2024
96b409b
move jwtHandler into security package
MrSebastian May 15, 2024
af2e01f
move tests to matching package
MrSebastian May 15, 2024
734566d
add new created users to doku
MrSebastian May 15, 2024
0883108
add tests to verify existence of bean in specific states
MrSebastian May 15, 2024
0a42b14
fix classnames to match pattern
MrSebastian May 15, 2024
0e43e21
add security util with default username and password
MrSebastian May 15, 2024
1322de2
remove empty line
MrSebastian May 15, 2024
ecb1318
spotless:apply
MrSebastian May 15, 2024
b77cb70
move method for authority variations into separate method
MrSebastian May 15, 2024
5143e89
Merge branch 'refs/heads/dev' into 168-implementierung-wahlkonfiguration
MrSebastian May 15, 2024
53fa731
Merge branch 'refs/heads/dev' into 168-implementierung-wahlkonfiguration
MrSebastian May 22, 2024
a6069aa
reorder flyway files after dev-merge
MrSebastian May 22, 2024
7bc21b4
unify use of ExceptionDataWrapper
MrSebastian May 22, 2024
d3a26a9
combines classes into one package
MrSebastian May 22, 2024
6246ea7
use authority-setup-only security method
MrSebastian May 22, 2024
e941152
Merge branch 'refs/heads/dev' into 168-implementierung-wahlkonfiguration
MrSebastian May 28, 2024
f57806c
fix comment
MrSebastian May 28, 2024
afac4ae
feedback: fixing typos
MrSebastian May 28, 2024
fe6e376
Merge remote-tracking branch 'origin/168-implementierung-wahlkonfigur…
MrSebastian May 28, 2024
27f3ef7
fix missing refactored method names
MrSebastian May 28, 2024
7be4b59
update tests for new spring version
MrSebastian May 28, 2024
8523da6
update test after typo fix
MrSebastian May 28, 2024
e762f69
Merge branch 'refs/heads/dev' into 168-implementierung-wahlkonfiguration
MrSebastian May 29, 2024
380166a
revert to keycloak 20 cause trouble with user attributes
MrSebastian May 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions docs/src/technik/development/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ flowchart LR

### Benutzer

| Name | Passwort | Beschreibung |
| --- | --- | --- |
| keycloak_test | test | Ein Benutzer ohne weitere Rechte |
| wls_all | test | Ein Benutzer mit allen Rechten |
| Name | Passwort | Beschreibung |
| --- | --- |-----------------------------------------------------------------------|
| keycloak_test | test | Ein Benutzer ohne weitere Rechte |
| wls_all | test | Ein Benutzer mit allen Rechten |
| wls_all_bwb | test | Ein Benutzer mit allen Rechten mit der WahlbezirksArt BWB (Briefwahl) |
| wls_all_uwb | test | Ein Benutzer mit allen Rechten mit der WahlbezirksArt UWB (Urnenwahl) |

### Beispiel-Requests

Expand Down
5 changes: 2 additions & 3 deletions stack/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ services:
## Keycloak
wls-keycloak:
container_name: wls-keycloak
image: quay.io/keycloak/keycloak:24.0.4
image: quay.io/keycloak/keycloak:20.0.5
command:
- start-dev
- start-dev --http-relative-path /auth
depends_on:
- wls-db-postgres-keycloak
environment:
Expand All @@ -36,7 +36,6 @@ services:
- KC_DB_URL=jdbc:postgresql://wls-db-postgres-keycloak:5432/${KEYCLOAK_DB}
- KC_DB_USERNAME=${KEYCLOAK_DB_USER}
- KC_DB_PASSWORD=${KEYCLOAK_DB_PASSWORD}
- KC_HTTP_RELATIVE_PATH=auth
ports:
- 8100:8080
networks:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
id: add authorities infomanagement konfiguration
author: MrSebastian
realm: ${SSO_REALM}
changes:
- addRole:
name: Infomanagement_READ_Konfiguration
clientRole: true
clientId: ${SSO_CLIENT_ID}
- addRole:
name: Infomanagement_WRITE_Konfiguration
clientRole: true
clientId: ${SSO_CLIENT_ID}
- addRole:
name: Infomanagement_DELETE_Konfiguration
clientRole: true
clientId: ${SSO_CLIENT_ID}
- addRole:
name: Infomanagement_BUSINESSACTION_GetKonfiguration
clientRole: true
clientId: ${SSO_CLIENT_ID}
- addRole:
name: Infomanagement_BUSINESSACTION_GetKonfigurationen
clientRole: true
clientId: ${SSO_CLIENT_ID}
- addRole:
name: Infomanagement_BUSINESSACTION_PostKonfiguration
clientRole: true
clientId: ${SSO_CLIENT_ID}

- assignRoleToGroup:
group: allInfomanagementAuthorities
role: Infomanagement_READ_Konfiguration
clientId: ${SSO_CLIENT_ID}
- assignRoleToGroup:
group: allInfomanagementAuthorities
role: Infomanagement_WRITE_Konfiguration
clientId: ${SSO_CLIENT_ID}
- assignRoleToGroup:
group: allInfomanagementAuthorities
role: Infomanagement_DELETE_Konfiguration
clientId: ${SSO_CLIENT_ID}
- assignRoleToGroup:
group: allInfomanagementAuthorities
role: Infomanagement_BUSINESSACTION_GetKonfiguration
clientId: ${SSO_CLIENT_ID}
- assignRoleToGroup:
group: allInfomanagementAuthorities
role: Infomanagement_BUSINESSACTION_GetKonfigurationen
clientId: ${SSO_CLIENT_ID}
- assignRoleToGroup:
group: allInfomanagementAuthorities
role: Infomanagement_BUSINESSACTION_PostKonfiguration
clientId: ${SSO_CLIENT_ID}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
id: add authorities infomanagement kennbuchstaben
author: MrSebastian
realm: ${SSO_REALM}
changes:
- addRole:
name: Infomanagement_BUSINESSACTION_GetKennbuchstabenListen
clientRole: true
clientId: ${SSO_CLIENT_ID}

- assignRoleToGroup:
group: allInfomanagementAuthorities
role: Infomanagement_BUSINESSACTION_GetKennbuchstabenListen
clientId: ${SSO_CLIENT_ID}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
id: add user attribute mapper wahlbezirksart
author: MrSebastian
realm: ${SSO_REALM}
changes:
# maps user attribute wahlbezirksArt to a claim wahlbezirksArt
- addClientUserAttributeMapper:
clientId: ${SSO_CLIENT_ID}
name: wahlbezirksArt
userAttribute: wahlbezirksArt
claimName: wahlbezirksArt
addToUserInfo: true
addToAccessToken: true
47 changes: 47 additions & 0 deletions stack/keycloak/migration/add-wahlbezirksart-to-user.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
id: add wahlbezirksart to user
author: MrSebastian
realm: ${SSO_REALM}
changes:
- addUserAttribute:
name: wls_all
attributeName: wahlbezirksArt
attributeValues:
- UWB
MrSebastian marked this conversation as resolved.
Show resolved Hide resolved

- addUser:
MrSebastian marked this conversation as resolved.
Show resolved Hide resolved
name: wls_all_uwb
lastName: all
firstName: wls_uwb
enabled: true
emailVerified: true
email: wls_all_uwb@example.com
attributes:
user_name:
- wls_all_uwb
wahlbezirksArt:
- UWB
groups:
- allBroadcastAuthorities
- allInfomanagementAuthorities
- updateUserPassword:
name: wls_all_uwb
password: "test"

- addUser:
name: wls_all_bwb
lastName: all
firstName: wls_bwb
enabled: true
emailVerified: true
email: wls_all_bwb@example.com
attributes:
user_name:
- wls_all_bwb
wahlbezirksArt:
- BWB
groups:
- allBroadcastAuthorities
- allInfomanagementAuthorities
- updateUserPassword:
name: wls_all_bwb
password: "test"
6 changes: 5 additions & 1 deletion stack/keycloak/migration/keycloak-changelog.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,8 @@ includes:
- path: create-and-assign-group-all-wahlvorbereitung.yml
- path: add-authorities-wahlvorbereitung-urnenwahlvorbereitung.yml
- path: add_authorities-briefwahl-wahlbriefdaten.yml
- path: add-authorities-wahlvorbereitung-waehlerverzeichnis.yml
- path: add-authorities-wahlvorbereitung-waehlerverzeichnis.yml
- path: add-authorities-infomanagement-konfiguration.yml
- path: add-user-attribute-mapper-wahlbezirks-art.yml
- path: add-wahlbezirksart-to-user.yml
- path: add-authority-infomanagement-kennbuchstaben.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package de.muenchen.oss.wahllokalsystem.infomanagementservice.common.security;

import java.util.Optional;
import org.springframework.context.annotation.Profile;
import org.springframework.security.authentication.AnonymousAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;

@Component
@Profile("no-security")
MrSebastian marked this conversation as resolved.
Show resolved Hide resolved
public class AnonymousHandler implements AuthenticationHandler {
@Override
public boolean canHandle(Authentication authentication) {
return authentication instanceof AnonymousAuthenticationToken;
}

@Override
public Optional<String> getDetail(String detailKey, Authentication authentication) {
return Optional.empty();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package de.muenchen.oss.wahllokalsystem.infomanagementservice.common.security;

import java.util.Optional;
import org.springframework.security.core.Authentication;

public interface AuthenticationHandler {

boolean canHandle(Authentication authentication);

Optional<String> getDetail(String detailKey, Authentication authentication);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package de.muenchen.oss.wahllokalsystem.infomanagementservice.common.security;

import java.util.Optional;
import org.springframework.security.core.Authentication;
import org.springframework.security.oauth2.server.resource.authentication.JwtAuthenticationToken;
import org.springframework.stereotype.Component;

@Component
public class JWTHandler implements AuthenticationHandler {

@Override
public boolean canHandle(final Authentication authentication) {
return authentication instanceof JwtAuthenticationToken;
}

public Optional<String> getDetail(final String detailKey, final Authentication authentication) {
if (authentication instanceof JwtAuthenticationToken jwtToken) {
return Optional.ofNullable(jwtToken.getToken().getClaimAsString(detailKey));
} else {
return Optional.empty();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
AntPathRequestMatcher.antMatcher("/actuator/metrics"),
AntPathRequestMatcher.antMatcher("/v3/api-docs/**"),
AntPathRequestMatcher.antMatcher("/swagger-ui/**"),
AntPathRequestMatcher.antMatcher("/businessActions/loginCheck/**"))
AntPathRequestMatcher.antMatcher("/businessActions/loginCheck/**"),
AntPathRequestMatcher.antMatcher("/businessActions/konfigurationUnauthorized/**"))
.permitAll())
.authorizeHttpRequests((requests) -> requests.requestMatchers("/**")
.authenticated())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package de.muenchen.oss.wahllokalsystem.infomanagementservice.domain.konfiguration;

import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Indexed;

@Entity
@Indexed
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Konfiguration {

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

@Size(max = 1024)
private String wert;

@Size(max = 1024)
private String beschreibung;

@Size(max = 1024)
private String standardwert;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package de.muenchen.oss.wahllokalsystem.infomanagementservice.domain.konfiguration;

import java.util.List;
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.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.lang.NonNull;
import org.springframework.security.access.prepost.PreAuthorize;

public interface KonfigurationRepository extends CrudRepository<Konfiguration, String> {

String CACHE = "KonfigurationCACHE";

@Override
@PreAuthorize("hasAuthority('Infomanagement_READ_Konfiguration')")
@NonNull
List<Konfiguration> findAll();

@Override
@Cacheable(value = CACHE, key = "#p0")
@PreAuthorize("hasAuthority('Infomanagement_READ_Konfiguration')")
@NonNull
Optional<Konfiguration> findById(@NonNull String key);

@Override
@CachePut(value = CACHE, key = "#p0.schluessel")
@PreAuthorize("hasAuthority('Infomanagement_WRITE_Konfiguration')")
@NonNull
<S extends Konfiguration> S save(@NonNull S konfiguration);

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

@Override
@CacheEvict(value = CACHE, key = "#p0.schluessel")
@PreAuthorize("hasAuthority('Infomanagement_DELETE_Konfiguration')")
void delete(@NonNull Konfiguration entity);

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

@Override
@CacheEvict(value = CACHE, allEntries = true)
@PreAuthorize("hasAuthority('Infomanagement_DELETE_Konfiguration')")
void deleteAll();

@Query("SELECT k FROM Konfiguration k WHERE k.schluessel = 'FRUEHESTE_LOGIN_UHRZEIT'")
Optional<Konfiguration> getFruehesteLoginUhrzeit();

@Query("SELECT k FROM Konfiguration k WHERE k.schluessel = 'SPAETESTE_LOGIN_UHRZEIT'")
Optional<Konfiguration> getSpaetesteLoginUhrzeit();

@Query("SELECT k FROM Konfiguration k WHERE k.schluessel = 'WILLKOMMENSTEXT'")
Optional<Konfiguration> getWillkommenstext();

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

import lombok.AccessLevel;
import lombok.NoArgsConstructor;

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ExceptionConstants {
public static final ExceptionDataWrapper DELETE_KONFIGURIERTERWAHLTAG_NOT_DELETEABLE = new ExceptionDataWrapper("105",
"deleteKonfigurierterWahltag: Der konfigurierte Wahltag konnte nicht gelöscht werden.");
public static final ExceptionDataWrapper POST_KONFIGURIERTERWAHLTAG_PARAMETER_UNVOLLSTAENDIG = new ExceptionDataWrapper("100",
"postKonfigurierterWahltag: Suchkriterien unvollständig.");
public static final ExceptionDataWrapper DELETE_KONFIGURIERTERWAHLTAG_PARAMETER_UNVOLLSTAENDIG = new ExceptionDataWrapper("104",
"deleteKonfigurierterWahltag: Suchkriterien unvollständig.");
public static final ExceptionDataWrapper POSTKONFIGURATION_NOT_SAVEABLE = new ExceptionDataWrapper("101",
"postKonfiguration: Die Konfiguration konnte nicht gespeichert werden.");
public static final ExceptionDataWrapper GETKENNBUCHSTABENLISTEN_KONFIGURATION_NOT_FOUND = new ExceptionDataWrapper("103",
"getKennbuchstabenListen: Es wurden keine Kennbuchstaben gefunden.");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package de.muenchen.oss.wahllokalsystem.infomanagementservice.exception;

import de.muenchen.oss.wahllokalsystem.wls.common.exception.errorhandler.AbstractExceptionHandler;
import de.muenchen.oss.wahllokalsystem.wls.common.exception.rest.model.DTOMapper;
import de.muenchen.oss.wahllokalsystem.wls.common.exception.rest.model.WlsExceptionDTO;
import de.muenchen.oss.wahllokalsystem.wls.common.exception.util.ServiceIDFormatter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;

@ControllerAdvice
@Slf4j
public class GlobalExceptionHandler extends AbstractExceptionHandler {

private final ServiceIDFormatter serviceIDFormatter;

public GlobalExceptionHandler(final ServiceIDFormatter serviceIDFormatter, final DTOMapper dtoMapper) {
super(dtoMapper);
this.serviceIDFormatter = serviceIDFormatter;
}

@ExceptionHandler
public ResponseEntity<WlsExceptionDTO> handleThrowables(final Throwable throwable) {
log.info("handling throwable", throwable);
return createResponse(getWahlExceptionDTO(throwable));
}

@Override
protected String getService() {
return serviceIDFormatter.getId();
}
}
Loading