Merge branch 'folder_export2' into feature_license2
This commit is contained in:
commit
1e544fffab
@ -10,7 +10,7 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||
|
||||
@RestController
|
||||
@RequestMapping(name = "/",
|
||||
@RequestMapping(value = "/",
|
||||
produces = APPLICATION_JSON_VALUE)
|
||||
public class IndexRestController {
|
||||
|
||||
|
||||
@ -22,6 +22,7 @@ import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
import static org.springframework.http.MediaType.APPLICATION_JSON_VALUE;
|
||||
@ -120,13 +121,30 @@ public class UserRestController {
|
||||
@RequestParam(defaultValue = "10") int size,
|
||||
@RequestParam(required = false) UUID companyId) {
|
||||
log.info("User list request - page: {}, size: {}, companyId: {}", page, size, companyId);
|
||||
|
||||
|
||||
List<UserAccount> userAccounts;
|
||||
long totalElements;
|
||||
|
||||
if (companyId != null) {
|
||||
userAccounts = userService.findUsersByCompany(companyId, page, size);
|
||||
totalElements = userService.countUsersByCompany(companyId);
|
||||
} else {
|
||||
userAccounts = userService.findAllUsers(page, size);
|
||||
totalElements = userService.countAllUsers();
|
||||
}
|
||||
|
||||
// Convert to UserResponse DTOs
|
||||
List<UserResponse> userResponses = userAccounts.stream()
|
||||
.map(this::mapToUserResponse)
|
||||
.collect(java.util.stream.Collectors.toList());
|
||||
|
||||
// Create Page object
|
||||
Pageable pageable = PageRequest.of(page, size);
|
||||
|
||||
// TODO: Implement pagination and company filtering in service layer
|
||||
// For now, return an empty page
|
||||
Page<UserResponse> users = Page.empty(pageable);
|
||||
|
||||
Page<UserResponse> users = new org.springframework.data.domain.PageImpl<>(
|
||||
userResponses,
|
||||
pageable,
|
||||
totalElements);
|
||||
|
||||
return ResponseEntity.ok(users);
|
||||
}
|
||||
|
||||
|
||||
@ -6,30 +6,39 @@ import com.dh7789dev.xpeditis.dto.request.RegisterRequest;
|
||||
import com.dh7789dev.xpeditis.port.in.UserManagementUseCase;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
public interface UserService extends UserManagementUseCase {
|
||||
|
||||
|
||||
void changePassword(ChangePasswordRequest request, Principal connectedUser);
|
||||
|
||||
|
||||
UserAccount createUser(RegisterRequest request);
|
||||
|
||||
|
||||
UserAccount createGoogleUser(String googleToken);
|
||||
|
||||
|
||||
Optional<UserAccount> findById(UUID id);
|
||||
|
||||
|
||||
Optional<UserAccount> findByEmail(String email);
|
||||
|
||||
|
||||
Optional<UserAccount> findByUsername(String username);
|
||||
|
||||
|
||||
UserAccount updateProfile(UserAccount userAccount);
|
||||
|
||||
|
||||
void deactivateUser(UUID userId);
|
||||
|
||||
|
||||
void deleteUser(UUID userId);
|
||||
|
||||
|
||||
boolean existsByEmail(String email);
|
||||
|
||||
|
||||
boolean existsByUsername(String username);
|
||||
|
||||
List<UserAccount> findAllUsers(int page, int size);
|
||||
|
||||
List<UserAccount> findUsersByCompany(UUID companyId, int page, int size);
|
||||
|
||||
long countAllUsers();
|
||||
|
||||
long countUsersByCompany(UUID companyId);
|
||||
}
|
||||
|
||||
@ -85,4 +85,24 @@ public class UserServiceImpl implements UserService {
|
||||
public boolean existsByUsername(String username) {
|
||||
return userRepository.existsByUsername(username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.List<UserAccount> findAllUsers(int page, int size) {
|
||||
return userRepository.findAllUsers(page, size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public java.util.List<UserAccount> findUsersByCompany(UUID companyId, int page, int size) {
|
||||
return userRepository.findUsersByCompany(companyId, page, size);
|
||||
}
|
||||
|
||||
@Override
|
||||
public long countAllUsers() {
|
||||
return userRepository.countAllUsers();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long countUsersByCompany(UUID companyId) {
|
||||
return userRepository.countUsersByCompany(companyId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,6 +29,14 @@ public interface UserRepository {
|
||||
void deleteById(UUID id);
|
||||
|
||||
void deactivateUser(UUID id);
|
||||
|
||||
|
||||
List<UserAccount> findByCompanyIdAndIsActive(UUID companyId, boolean isActive);
|
||||
|
||||
List<UserAccount> findAllUsers(int page, int size);
|
||||
|
||||
List<UserAccount> findUsersByCompany(UUID companyId, int page, int size);
|
||||
|
||||
long countAllUsers();
|
||||
|
||||
long countUsersByCompany(UUID companyId);
|
||||
}
|
||||
|
||||
@ -0,0 +1,61 @@
|
||||
package com.dh7789dev.xpeditis.repository;
|
||||
|
||||
import com.dh7789dev.xpeditis.CompanyRepository;
|
||||
import com.dh7789dev.xpeditis.dao.CompanyDao;
|
||||
import com.dh7789dev.xpeditis.dto.app.Company;
|
||||
import com.dh7789dev.xpeditis.entity.CompanyEntity;
|
||||
import com.dh7789dev.xpeditis.mapper.CompanyMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Repository
|
||||
@RequiredArgsConstructor
|
||||
public class CompanyJpaRepository implements CompanyRepository {
|
||||
|
||||
private final CompanyDao companyDao;
|
||||
|
||||
@Override
|
||||
public Company save(Company company) {
|
||||
CompanyEntity entity = CompanyMapper.companyToCompanyEntity(company);
|
||||
CompanyEntity savedEntity = companyDao.save(entity);
|
||||
log.info("Company saved with ID: {}", savedEntity.getId());
|
||||
return CompanyMapper.companyEntityToCompany(savedEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Company> findById(UUID id) {
|
||||
return companyDao.findById(id)
|
||||
.map(CompanyMapper::companyEntityToCompany);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Company> findByName(String name) {
|
||||
return companyDao.findByName(name)
|
||||
.map(CompanyMapper::companyEntityToCompany);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Company> findAll() {
|
||||
return companyDao.findAll().stream()
|
||||
.map(CompanyMapper::companyEntityToCompany)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean existsByName(String name) {
|
||||
return companyDao.existsByName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteById(UUID id) {
|
||||
companyDao.deleteById(id);
|
||||
log.info("Company deleted with ID: {}", id);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,73 @@
|
||||
package com.dh7789dev.xpeditis.repository;
|
||||
|
||||
import com.dh7789dev.xpeditis.OAuth2Provider;
|
||||
import com.dh7789dev.xpeditis.dto.app.GoogleUserInfo;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.http.*;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
@Slf4j
|
||||
@Service
|
||||
public class GoogleOAuth2Provider implements OAuth2Provider {
|
||||
|
||||
@Value("${application.oauth2.google.user-info-uri:https://www.googleapis.com/oauth2/v2/userinfo}")
|
||||
private String userInfoUri;
|
||||
|
||||
private final RestTemplate restTemplate;
|
||||
|
||||
public GoogleOAuth2Provider() {
|
||||
this.restTemplate = new RestTemplate();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean validateToken(String accessToken) {
|
||||
try {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setBearerAuth(accessToken);
|
||||
HttpEntity<String> entity = new HttpEntity<>(headers);
|
||||
|
||||
ResponseEntity<GoogleUserInfo> response = restTemplate.exchange(
|
||||
userInfoUri,
|
||||
HttpMethod.GET,
|
||||
entity,
|
||||
GoogleUserInfo.class
|
||||
);
|
||||
|
||||
return response.getStatusCode() == HttpStatus.OK;
|
||||
} catch (Exception e) {
|
||||
log.error("Error validating Google token", e);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<GoogleUserInfo> getUserInfo(String accessToken) {
|
||||
try {
|
||||
HttpHeaders headers = new HttpHeaders();
|
||||
headers.setBearerAuth(accessToken);
|
||||
HttpEntity<String> entity = new HttpEntity<>(headers);
|
||||
|
||||
ResponseEntity<GoogleUserInfo> response = restTemplate.exchange(
|
||||
userInfoUri,
|
||||
HttpMethod.GET,
|
||||
entity,
|
||||
GoogleUserInfo.class
|
||||
);
|
||||
|
||||
if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
|
||||
log.info("Successfully retrieved Google user info for email: {}", response.getBody().getEmail());
|
||||
return Optional.of(response.getBody());
|
||||
}
|
||||
|
||||
log.warn("Failed to retrieve Google user info: status={}", response.getStatusCode());
|
||||
return Optional.empty();
|
||||
} catch (Exception e) {
|
||||
log.error("Error retrieving Google user info", e);
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
package com.dh7789dev.xpeditis.repository;
|
||||
|
||||
import com.dh7789dev.xpeditis.LicenseRepository;
|
||||
import com.dh7789dev.xpeditis.dao.LicenseDao;
|
||||
import com.dh7789dev.xpeditis.dto.app.License;
|
||||
import com.dh7789dev.xpeditis.entity.LicenseEntity;
|
||||
import com.dh7789dev.xpeditis.mapper.LicenseMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Repository
|
||||
@RequiredArgsConstructor
|
||||
public class LicenseJpaRepository implements LicenseRepository {
|
||||
|
||||
private final LicenseDao licenseDao;
|
||||
|
||||
@Override
|
||||
public License save(License license) {
|
||||
LicenseEntity entity = LicenseMapper.licenseToLicenseEntity(license);
|
||||
LicenseEntity savedEntity = licenseDao.save(entity);
|
||||
log.info("License saved with ID: {}", savedEntity.getId());
|
||||
return LicenseMapper.licenseEntityToLicense(savedEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<License> findById(UUID id) {
|
||||
return licenseDao.findById(id)
|
||||
.map(LicenseMapper::licenseEntityToLicense);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<License> findActiveLicenseByCompanyId(UUID companyId) {
|
||||
return licenseDao.findActiveLicenseByCompanyId(companyId)
|
||||
.map(LicenseMapper::licenseEntityToLicense);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<License> findByCompanyId(UUID companyId) {
|
||||
return licenseDao.findByCompanyId(companyId).stream()
|
||||
.map(LicenseMapper::licenseEntityToLicense)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<License> findByLicenseKey(String licenseKey) {
|
||||
return licenseDao.findByLicenseKey(licenseKey)
|
||||
.map(LicenseMapper::licenseEntityToLicense);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteById(UUID id) {
|
||||
licenseDao.deleteById(id);
|
||||
log.info("License deleted with ID: {}", id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivateLicense(UUID id) {
|
||||
licenseDao.findById(id).ifPresent(license -> {
|
||||
license.setActive(false);
|
||||
licenseDao.save(license);
|
||||
log.info("License deactivated with ID: {}", id);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,144 @@
|
||||
package com.dh7789dev.xpeditis.repository;
|
||||
|
||||
import com.dh7789dev.xpeditis.UserRepository;
|
||||
import com.dh7789dev.xpeditis.dao.UserDao;
|
||||
import com.dh7789dev.xpeditis.dto.app.UserAccount;
|
||||
import com.dh7789dev.xpeditis.dto.request.ChangePasswordRequest;
|
||||
import com.dh7789dev.xpeditis.entity.UserEntity;
|
||||
import com.dh7789dev.xpeditis.mapper.UserMapper;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageRequest;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Slf4j
|
||||
@Repository
|
||||
@RequiredArgsConstructor
|
||||
public class UserJpaRepository implements UserRepository {
|
||||
|
||||
private final UserDao userDao;
|
||||
private final PasswordEncoder passwordEncoder;
|
||||
|
||||
@Override
|
||||
public void changePassword(ChangePasswordRequest request, Principal connectedUser) {
|
||||
String username = connectedUser.getName();
|
||||
UserEntity user = userDao.findByUsername(username)
|
||||
.orElseThrow(() -> new RuntimeException("User not found"));
|
||||
|
||||
// Verify current password
|
||||
if (!passwordEncoder.matches(request.getCurrentPassword(), user.getPassword())) {
|
||||
throw new RuntimeException("Current password is incorrect");
|
||||
}
|
||||
|
||||
// Verify new password matches confirmation
|
||||
if (!request.getNewPassword().equals(request.getConfirmationPassword())) {
|
||||
throw new RuntimeException("New password and confirmation do not match");
|
||||
}
|
||||
|
||||
// Update password
|
||||
user.setPassword(passwordEncoder.encode(request.getNewPassword()));
|
||||
userDao.save(user);
|
||||
log.info("Password changed successfully for user: {}", username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public UserAccount save(UserAccount userAccount) {
|
||||
UserEntity entity = UserMapper.userAccountToUserEntity(userAccount);
|
||||
UserEntity savedEntity = userDao.save(entity);
|
||||
return UserMapper.userEntityToUserAccount(savedEntity);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<UserAccount> findById(UUID id) {
|
||||
return userDao.findById(id).map(UserMapper::userEntityToUserAccount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<UserAccount> findByEmail(String email) {
|
||||
return userDao.findByEmail(email).map(UserMapper::userEntityToUserAccount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<UserAccount> findByUsername(String username) {
|
||||
return userDao.findByUsername(username).map(UserMapper::userEntityToUserAccount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<UserAccount> findByGoogleId(String googleId) {
|
||||
return userDao.findByGoogleId(googleId).map(UserMapper::userEntityToUserAccount);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean existsByEmail(String email) {
|
||||
return userDao.existsByEmail(email);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean existsByUsername(String username) {
|
||||
return userDao.existsByUsername(username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteById(UUID id) {
|
||||
userDao.deleteById(id);
|
||||
log.info("User deleted with ID: {}", id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deactivateUser(UUID id) {
|
||||
UserEntity user = userDao.findById(id)
|
||||
.orElseThrow(() -> new RuntimeException("User not found"));
|
||||
user.setEnabled(false);
|
||||
userDao.save(user);
|
||||
log.info("User deactivated with ID: {}", id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserAccount> findByCompanyIdAndIsActive(UUID companyId, boolean isActive) {
|
||||
// This needs to be implemented in UserDao
|
||||
log.warn("findByCompanyIdAndIsActive not yet implemented in UserDao");
|
||||
return List.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserAccount> findAllUsers(int page, int size) {
|
||||
Pageable pageable = PageRequest.of(page, size);
|
||||
Page<UserEntity> userPage = userDao.findAll(pageable);
|
||||
return userPage.getContent().stream()
|
||||
.map(UserMapper::userEntityToUserAccount)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<UserAccount> findUsersByCompany(UUID companyId, int page, int size) {
|
||||
// For now, return all users filtered by company (needs DAO method)
|
||||
Pageable pageable = PageRequest.of(page, size);
|
||||
Page<UserEntity> userPage = userDao.findAll(pageable);
|
||||
return userPage.getContent().stream()
|
||||
.filter(user -> user.getCompany() != null && user.getCompany().getId().equals(companyId))
|
||||
.map(UserMapper::userEntityToUserAccount)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public long countAllUsers() {
|
||||
return userDao.count();
|
||||
}
|
||||
|
||||
@Override
|
||||
public long countUsersByCompany(UUID companyId) {
|
||||
// For now, count all and filter (needs DAO method for optimization)
|
||||
return userDao.findAll().stream()
|
||||
.filter(user -> user.getCompany() != null && user.getCompany().getId().equals(companyId))
|
||||
.count();
|
||||
}
|
||||
}
|
||||
6
pom.xml
6
pom.xml
@ -41,9 +41,9 @@
|
||||
</scm>
|
||||
|
||||
<properties>
|
||||
<java.version>23</java.version>
|
||||
<maven.compiler.source>23</maven.compiler.source>
|
||||
<maven.compiler.target>23</maven.compiler.target>
|
||||
<java.version>21</java.version>
|
||||
<maven.compiler.source>21</maven.compiler.source>
|
||||
<maven.compiler.target>21</maven.compiler.target>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<org.projectlombok.version>1.18.36</org.projectlombok.version>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user