diff --git a/eeg_backend/pom.xml b/eeg_backend/pom.xml
index 5f9bdde..9f11765 100644
--- a/eeg_backend/pom.xml
+++ b/eeg_backend/pom.xml
@@ -42,6 +42,16 @@
springdoc-openapi-starter-webmvc-api
3.0.3
+
+ org.mapstruct
+ mapstruct
+ 1.6.3
+
+
+ org.projectlombok
+ lombok-mapstruct-binding
+ 0.2.0
+
com.h2database
@@ -99,6 +109,31 @@
org.apache.maven.plugins
maven-compiler-plugin
+
+ ${maven.compiler.source}
+ ${maven.compiler.target}
+
+
+ org.projectlombok
+ lombok
+
+
+ org.projectlombok
+ lombok-mapstruct-binding
+ 0.2.0
+
+
+ org.mapstruct
+ mapstruct-processor
+ 1.6.3
+
+
+
+ -Amapstruct.defaultComponentModel=spring
+ -Amapstruct.defaultInjectionStrategy=constructor
+ -Amapstruct.unmappedTargetPolicy=ERROR
+
+
default-compile
diff --git a/eeg_backend/src/main/java/at/mueller/eeg/backend/common/config/event/EdaTopologyCheckEvent.java b/eeg_backend/src/main/java/at/mueller/eeg/backend/common/config/event/EdaTopologyCheckEvent.java
new file mode 100644
index 0000000..a61e6ee
--- /dev/null
+++ b/eeg_backend/src/main/java/at/mueller/eeg/backend/common/config/event/EdaTopologyCheckEvent.java
@@ -0,0 +1,8 @@
+package at.mueller.eeg.backend.common.config.event;
+
+import java.util.UUID;
+
+public record EdaTopologyCheckEvent(
+ UUID userId,
+ String atNumber
+) {}
\ No newline at end of file
diff --git a/eeg_backend/src/main/java/at/mueller/eeg/backend/common/config/event/UserRegisteredEvent.java b/eeg_backend/src/main/java/at/mueller/eeg/backend/common/config/event/UserRegisteredEvent.java
new file mode 100644
index 0000000..7e6ec6f
--- /dev/null
+++ b/eeg_backend/src/main/java/at/mueller/eeg/backend/common/config/event/UserRegisteredEvent.java
@@ -0,0 +1,8 @@
+package at.mueller.eeg.backend.common.config.event;
+
+import java.util.UUID;
+
+public record UserRegisteredEvent(
+ UUID userId,
+ String atNumber
+) {}
\ No newline at end of file
diff --git a/eeg_backend/src/main/java/at/mueller/eeg/backend/community/event/listener/MeteringPointEventListener.java b/eeg_backend/src/main/java/at/mueller/eeg/backend/community/event/listener/MeteringPointEventListener.java
new file mode 100644
index 0000000..54f5966
--- /dev/null
+++ b/eeg_backend/src/main/java/at/mueller/eeg/backend/community/event/listener/MeteringPointEventListener.java
@@ -0,0 +1,33 @@
+package at.mueller.eeg.backend.community.event.listener;
+
+import at.mueller.eeg.backend.common.config.event.EdaTopologyCheckEvent;
+import at.mueller.eeg.backend.common.config.event.UserRegisteredEvent;
+import at.mueller.eeg.backend.community.domain.MeteringPoint;
+import at.mueller.eeg.backend.community.domain.PointType;
+import at.mueller.eeg.backend.community.repository.MeteringPointRepository;
+import lombok.RequiredArgsConstructor;
+import org.springframework.context.ApplicationEventPublisher;
+import org.springframework.stereotype.Component;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.transaction.event.TransactionPhase;
+import org.springframework.transaction.event.TransactionalEventListener;
+
+@Component
+@RequiredArgsConstructor
+public class MeteringPointEventListener {
+
+ private final MeteringPointRepository meteringPointRepository;
+ private final ApplicationEventPublisher eventPublisher;
+
+ @TransactionalEventListener(phase = TransactionPhase.AFTER_COMMIT)
+ @Transactional
+ public void handleUserRegistered(UserRegisteredEvent event) {
+ MeteringPoint point = new MeteringPoint();
+ point.setUserId(event.userId());
+ point.setAtNumber(event.atNumber());
+ point.setType(PointType.CONSUMER);
+
+ meteringPointRepository.save(point);
+ eventPublisher.publishEvent(new EdaTopologyCheckEvent(point.getId(), event.atNumber()));
+ }
+}
diff --git a/eeg_backend/src/main/java/at/mueller/eeg/backend/community/repository/MeteringPointRepository.java b/eeg_backend/src/main/java/at/mueller/eeg/backend/community/repository/MeteringPointRepository.java
new file mode 100644
index 0000000..4398bcd
--- /dev/null
+++ b/eeg_backend/src/main/java/at/mueller/eeg/backend/community/repository/MeteringPointRepository.java
@@ -0,0 +1,7 @@
+package at.mueller.eeg.backend.community.repository;
+
+import at.mueller.eeg.backend.community.domain.MeteringPoint;
+import org.springframework.data.jpa.repository.JpaRepository;
+
+public interface MeteringPointRepository extends JpaRepository {
+}
diff --git a/eeg_backend/src/main/java/at/mueller/eeg/backend/iam/api/AdminIamController.java b/eeg_backend/src/main/java/at/mueller/eeg/backend/iam/api/AdminIamController.java
index 0703caf..74f441c 100644
--- a/eeg_backend/src/main/java/at/mueller/eeg/backend/iam/api/AdminIamController.java
+++ b/eeg_backend/src/main/java/at/mueller/eeg/backend/iam/api/AdminIamController.java
@@ -1,8 +1,10 @@
package at.mueller.eeg.backend.iam.api;
import at.mueller.eeg.backend.iam.api.dto.IamDtos.UserProfileResponse;
+import at.mueller.eeg.backend.iam.repository.UserRepository;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
+import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
@@ -14,16 +16,19 @@ import java.util.UUID;
@RequestMapping("/api/admin/users")
@PreAuthorize("hasRole('ADMIN')")
@Tag(name = "Admin IAM", description = "User-Verwaltung und Freigabe-Workflow")
+@RequiredArgsConstructor
public class AdminIamController {
- // private final UserManagementService userManagementService;
+ private final UserRepository userRepository;
@GetMapping("/pending")
@Operation(summary = "Lädt alle wartenden User",
description = "Zeigt User im Status PENDING inkl. der Ergebnisse des EDA-Netz-Checks.")
public ResponseEntity> getPendingUsers() {
- // Logik: Finde alle User mit status = PENDING
- return ResponseEntity.ok(List.of(/* ... */));
+
+
+ //return ResponseEntity.ok(userRepository.findAllByStatus(RegistrationStatus.PENDING));
+ return null;
}
@PostMapping("/{userId}/approve")
diff --git a/eeg_backend/src/main/java/at/mueller/eeg/backend/iam/mapper/PasswordHashMapper.java b/eeg_backend/src/main/java/at/mueller/eeg/backend/iam/mapper/PasswordHashMapper.java
new file mode 100644
index 0000000..b86d5fe
--- /dev/null
+++ b/eeg_backend/src/main/java/at/mueller/eeg/backend/iam/mapper/PasswordHashMapper.java
@@ -0,0 +1,21 @@
+package at.mueller.eeg.backend.iam.mapper;
+
+import lombok.RequiredArgsConstructor;
+import org.springframework.security.crypto.password.PasswordEncoder;
+import org.springframework.stereotype.Component;
+
+import static at.mueller.eeg.backend.iam.mapper.UserMapperAnnotations.PasswordHash;
+
+@Component
+@RequiredArgsConstructor
+public class PasswordHashMapper {
+
+ private final PasswordEncoder passwordEncoder;
+
+ @PasswordHash
+ public String hashPassword(String password) {
+ return passwordEncoder.encode(password);
+ }
+
+
+}
diff --git a/eeg_backend/src/main/java/at/mueller/eeg/backend/iam/mapper/UserMapper.java b/eeg_backend/src/main/java/at/mueller/eeg/backend/iam/mapper/UserMapper.java
new file mode 100644
index 0000000..05a0a19
--- /dev/null
+++ b/eeg_backend/src/main/java/at/mueller/eeg/backend/iam/mapper/UserMapper.java
@@ -0,0 +1,28 @@
+package at.mueller.eeg.backend.iam.mapper;
+
+import at.mueller.eeg.backend.iam.api.dto.IamDtos;
+import at.mueller.eeg.backend.iam.domain.User;
+import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
+import org.mapstruct.MappingTarget;
+
+@Mapper(
+ uses = PasswordHashMapper.class
+)
+public interface UserMapper {
+
+ @Mapping(target = "primaryAtNumber", ignore = true)
+ IamDtos.UserProfileResponse mapToDto(User user);
+
+ @Mapping(target = "status", constant = "PENDING")
+ @Mapping(target = "role", constant = "MEMBER")
+ @Mapping(target = "passwordHash", source = "password", qualifiedBy = UserMapperAnnotations.PasswordHash.class)
+ @Mapping(target = "id", ignore = true)
+ @Mapping(target = "iban", ignore = true)
+ @Mapping(target = "enabled", constant = "false")
+ @Mapping(target = "authorities", ignore = true)
+ User mapToEntity(IamDtos.RegistrationRequest request, @MappingTarget User user);
+
+
+
+}
diff --git a/eeg_backend/src/main/java/at/mueller/eeg/backend/iam/mapper/UserMapperAnnotations.java b/eeg_backend/src/main/java/at/mueller/eeg/backend/iam/mapper/UserMapperAnnotations.java
new file mode 100644
index 0000000..582c196
--- /dev/null
+++ b/eeg_backend/src/main/java/at/mueller/eeg/backend/iam/mapper/UserMapperAnnotations.java
@@ -0,0 +1,19 @@
+package at.mueller.eeg.backend.iam.mapper;
+
+import lombok.experimental.UtilityClass;
+import org.mapstruct.Qualifier;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@UtilityClass
+public class UserMapperAnnotations {
+
+ @Qualifier
+ @Target(ElementType.METHOD)
+ @Retention(RetentionPolicy.CLASS)
+ public @interface PasswordHash {
+ }
+}
diff --git a/eeg_backend/src/main/java/at/mueller/eeg/backend/iam/repository/UserRepository.java b/eeg_backend/src/main/java/at/mueller/eeg/backend/iam/repository/UserRepository.java
index b6659f3..6025aeb 100644
--- a/eeg_backend/src/main/java/at/mueller/eeg/backend/iam/repository/UserRepository.java
+++ b/eeg_backend/src/main/java/at/mueller/eeg/backend/iam/repository/UserRepository.java
@@ -1,11 +1,15 @@
package at.mueller.eeg.backend.iam.repository;
+import at.mueller.eeg.backend.iam.domain.RegistrationStatus;
import at.mueller.eeg.backend.iam.domain.User;
import org.springframework.data.jpa.repository.JpaRepository;
+import java.util.List;
import java.util.Optional;
public interface UserRepository extends JpaRepository {
Optional findByEmail(String email);
+
+ List findAllByStatus(RegistrationStatus status);
}
diff --git a/eeg_backend/src/main/java/at/mueller/eeg/backend/iam/service/AuthService.java b/eeg_backend/src/main/java/at/mueller/eeg/backend/iam/service/AuthService.java
index bb0f7d2..e83f485 100644
--- a/eeg_backend/src/main/java/at/mueller/eeg/backend/iam/service/AuthService.java
+++ b/eeg_backend/src/main/java/at/mueller/eeg/backend/iam/service/AuthService.java
@@ -1,14 +1,15 @@
package at.mueller.eeg.backend.iam.service;
-import at.mueller.eeg.backend.iam.domain.RegistrationStatus;
+import at.mueller.eeg.backend.common.config.event.UserRegisteredEvent;
import at.mueller.eeg.backend.iam.domain.User;
+import at.mueller.eeg.backend.iam.mapper.UserMapper;
import at.mueller.eeg.backend.iam.repository.UserRepository;
import lombok.RequiredArgsConstructor;
+import org.springframework.context.ApplicationEventPublisher;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
-import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.oauth2.jose.jws.MacAlgorithm;
import org.springframework.security.oauth2.jwt.JwsHeader;
import org.springframework.security.oauth2.jwt.JwtClaimsSet;
@@ -27,8 +28,9 @@ public class AuthService {
private final AuthenticationManager authenticationManager;
private final JwtEncoder jwtEncoder;
- private final PasswordEncoder passwordEncoder;
private final UserRepository userRepository;
+ private final UserMapper userMapper;
+ private final ApplicationEventPublisher eventPublisher;
/**
* Verarbeitet den Login und gibt den JWT-Token als String zurück.
@@ -57,17 +59,10 @@ public class AuthService {
throw new RuntimeException("E-Mail already exists!");
});
- String hashedPassword = passwordEncoder.encode(request.password());
-
- User newUser = new User();
- newUser.setEmail(request.email());
- newUser.setPasswordHash(hashedPassword);
- newUser.setFirstName(request.firstName());
- newUser.setLastName(request.lastName());
- newUser.setStatus(RegistrationStatus.PENDING);
- newUser.setEnabled(false);
-
+ User newUser = userMapper.mapToEntity(request, new User());
userRepository.save(newUser);
+
+ eventPublisher.publishEvent(new UserRegisteredEvent(newUser.getId(), request.atNumber()));
}
/**