feat: impl automatic User creation

This commit is contained in:
filippo-ferrari 2024-09-09 19:10:19 +02:00
parent 6b7aef13d5
commit d9142c7492
12 changed files with 106 additions and 49 deletions

View file

@ -10,6 +10,12 @@ services:
SPRING_DATASOURCE_URL: ${DB_ADDRESS}/${DB_NAME} SPRING_DATASOURCE_URL: ${DB_ADDRESS}/${DB_NAME}
SPRING_DATASOURCE_USERNAME: ${DB_USER} SPRING_DATASOURCE_USERNAME: ${DB_USER}
SPRING_DATASOURCE_PASSWORD: ${DB_PASSWORD} SPRING_DATASOURCE_PASSWORD: ${DB_PASSWORD}
ADMIN_USERNAME: ${ADMIN_USERNAME}
ADMIN_PASSWORD: ${ADMIN_PASSWORD}
ADMIN_FIRST_NAME: ${ADMIN_FIRST_NAME}
ADMIN_LAST_NAME: ${ADMIN_LAST_NAME}
ADMIN_ROLES: ${ADMIN_ROLES}
ADMIN_EMAIL: ${ADMIN_EMAIL}
depends_on: depends_on:
- db - db

View file

@ -1,41 +0,0 @@
package com.application.munera;
import com.application.munera.data.Person;
import com.application.munera.repositories.PersonRepository;
import com.application.munera.repositories.UserRepository;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class StartupInitializer {
private final UserRepository userRepository;
private final PersonRepository personRepository;
@Autowired
public StartupInitializer(UserRepository userRepository, PersonRepository personRepository) {
this.userRepository = userRepository;
this.personRepository = personRepository;
}
/**
* Initializes Person entities for all existing users.
*/
@PostConstruct
public void initializePersonEntities() {
userRepository.findAll().forEach(user -> {
// Check if Person entity exists for the user by userId
if (personRepository.findByUserId(user.getId()).isEmpty()) {
// Create and save the Person entity
Person newPerson = new Person();
newPerson.setFirstName(user.getFirstName());
newPerson.setLastName(user.getLastName());
newPerson.setUsername(user.getUsername());
newPerson.setUserId(user.getId());
personRepository.save(newPerson);
}
});
}
}

View file

@ -40,7 +40,6 @@ public class Person extends AbstractEntity {
@Column(name = "credit") @Column(name = "credit")
private BigDecimal credit; private BigDecimal credit;
// Updated to match the new field names in Expense
@OneToMany(mappedBy = "payer") @OneToMany(mappedBy = "payer")
private Set<Expense> expensesAsPayer; private Set<Expense> expensesAsPayer;

View file

@ -4,8 +4,13 @@ import com.application.munera.data.User;
import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository; import org.springframework.stereotype.Repository;
import java.util.Optional;
@Repository @Repository
public interface UserRepository extends JpaRepository<User, Long> { public interface UserRepository extends JpaRepository<User, Long> {
User findByUsername(final String username); User findByUsername(final String username);
//TODO: join these two methods
Optional<User> findOptionalByUsername(final String username);
} }

View file

@ -0,0 +1,19 @@
package com.application.munera.security;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
@Getter
@Setter
@Configuration
@ConfigurationProperties(prefix = "admin")
public class AdminProperties {
private String username;
private String password;
private String firstName;
private String lastName;
private String roles;
private String email;
}

View file

@ -1,4 +1,4 @@
package com.application.munera; package com.application.munera.security;
import com.application.munera.repositories.UserRepository; import com.application.munera.repositories.UserRepository;
import com.application.munera.views.login.LoginView; import com.application.munera.views.login.LoginView;

View file

@ -1,4 +1,4 @@
package com.application.munera; package com.application.munera.security;
import org.springframework.security.core.Authentication; import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;

View file

@ -0,0 +1,31 @@
package com.application.munera.security;
import com.application.munera.data.User;
import com.application.munera.services.UserService;
import jakarta.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserInitializer {
@Autowired
private UserService userService;
@Autowired
private AdminProperties adminProperties;
@PostConstruct
public void init() {
if (userService.count() == 0) {
User adminUser = new User();
adminUser.setUsername(adminProperties.getUsername());
adminUser.setPassword(adminProperties.getPassword());
adminUser.setFirstName(adminProperties.getFirstName());
adminUser.setLastName(adminProperties.getLastName());
adminUser.setRoles(adminProperties.getRoles());
adminUser.setEmail(adminProperties.getEmail());
userService.saveUserAndConnectedPerson(adminUser);
}
}
}

View file

@ -1,6 +1,6 @@
package com.application.munera.services; package com.application.munera.services;
import com.application.munera.SecurityUtils; import com.application.munera.security.SecurityUtils;
import com.application.munera.data.Expense; import com.application.munera.data.Expense;
import com.application.munera.data.ExpenseType; import com.application.munera.data.ExpenseType;
import com.application.munera.data.Person; import com.application.munera.data.Person;

View file

@ -7,7 +7,7 @@ import com.application.munera.repositories.UserRepository;
import org.springframework.security.core.userdetails.UserDetails; import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import static com.application.munera.SecurityUtils.getLoggedInUserDetails; import static com.application.munera.security.SecurityUtils.getLoggedInUserDetails;
@Service @Service
public class UserService { public class UserService {
@ -39,9 +39,38 @@ public class UserService {
public void updateUser(User user) { public void updateUser(User user) {
userRepository.save(user); userRepository.save(user);
Person person = personRepository.findByUserId(user.getId()) final var person = personRepository.findByUserId(user.getId())
.orElseThrow(() -> new IllegalStateException("Associated Person not found")); .orElseThrow(() -> new IllegalStateException("Associated Person not found"));
person.setFirstName(user.getFirstName()); person.setFirstName(user.getFirstName());
person.setLastName(user.getLastName()); person.setLastName(user.getLastName());
personRepository.save(person); personRepository.save(person);
}} }
public void saveUserAndConnectedPerson(User user) {
// Check if the user already exists in the database
final var existingUserOptional = userRepository.findOptionalByUsername(user.getUsername());
User existingUser;
// Save the new user entity if he doesn't exist yet
existingUser = existingUserOptional.orElseGet(() -> userRepository.save(user));
// Check if the associated person exists for the user
final var existingPerson = personRepository.findByUserId(existingUser.getId());
if (existingPerson.isEmpty()) {
// If no person is associated with the user, create a new Person entity and link it to the User
Person person = new Person();
person.setUsername(existingUser.getUsername());
person.setFirstName(existingUser.getFirstName());
person.setLastName(existingUser.getLastName());
person.setEmail(existingUser.getEmail());
person.setUserId(existingUser.getId());
personRepository.save(person);
}
}
public Long count() {
return this.userRepository.count();
}
}

View file

@ -1,6 +1,6 @@
package com.application.munera.views.expenses; package com.application.munera.views.expenses;
import com.application.munera.SecurityUtils; import com.application.munera.security.SecurityUtils;
import com.application.munera.data.*; import com.application.munera.data.*;
import com.application.munera.services.*; import com.application.munera.services.*;
import com.application.munera.views.MainLayout; import com.application.munera.views.MainLayout;

View file

@ -11,6 +11,15 @@ spring.profiles.active=dev
spring.datasource.url = ${DB_ADDRESS}/${DB_NAME} spring.datasource.url = ${DB_ADDRESS}/${DB_NAME}
spring.datasource.username = ${DB_USER} spring.datasource.username = ${DB_USER}
spring.datasource.password = ${DB_PASSWORD} spring.datasource.password = ${DB_PASSWORD}
# Default user
admin.username=${ADMIN_USERNAME}
admin.password=${ADMIN_PASSWORD}
admin.first_name=${ADMIN_FIRST_NAME}
admin.last_name=${ADMIN_LAST_NAME}
admin.roles=${ADMIN_ROLES}
#admin.email=${ADMIN_EMAIL}
spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect spring.jpa.database-platform=org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto = update spring.jpa.hibernate.ddl-auto = update
# To improve the performance during development. # To improve the performance during development.