mirror of
https://gitea.gofwd.group/Forward_Group/ballistic-builder-spring.git
synced 2026-01-20 16:51:03 -05:00
new admin-user api
This commit is contained in:
@@ -13,4 +13,6 @@ public interface UserRepository extends JpaRepository<User, Integer> {
|
|||||||
boolean existsByEmailIgnoreCaseAndDeletedAtIsNull(String email);
|
boolean existsByEmailIgnoreCaseAndDeletedAtIsNull(String email);
|
||||||
|
|
||||||
Optional<User> findByUuid(UUID uuid);
|
Optional<User> findByUuid(UUID uuid);
|
||||||
|
|
||||||
|
boolean existsByRole(String role);
|
||||||
}
|
}
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
package group.goforward.ballistic.services;
|
package group.goforward.ballistic.services;
|
||||||
|
|
||||||
import group.goforward.ballistic.model.Brand;
|
import group.goforward.ballistic.model.Brand;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface BrandService {
|
public interface BrandService {
|
||||||
|
|
||||||
List<Brand> findAll();
|
List<Brand> findAll();
|
||||||
|
|
||||||
Optional<Brand> findById(Integer id);
|
Optional<Brand> findById(Integer id);
|
||||||
|
|
||||||
Brand save(Brand item);
|
Brand save(Brand item);
|
||||||
void deleteById(Integer id);
|
void deleteById(Integer id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,95 +1,95 @@
|
|||||||
package group.goforward.ballistic.services;
|
package group.goforward.ballistic.services;
|
||||||
|
|
||||||
import group.goforward.ballistic.model.Merchant;
|
import group.goforward.ballistic.model.Merchant;
|
||||||
import group.goforward.ballistic.model.MerchantCategoryMapping;
|
import group.goforward.ballistic.model.MerchantCategoryMapping;
|
||||||
import group.goforward.ballistic.model.ProductConfiguration;
|
import group.goforward.ballistic.model.ProductConfiguration;
|
||||||
import group.goforward.ballistic.repos.MerchantCategoryMappingRepository;
|
import group.goforward.ballistic.repos.MerchantCategoryMappingRepository;
|
||||||
import jakarta.transaction.Transactional;
|
import jakarta.transaction.Transactional;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class MerchantCategoryMappingService {
|
public class MerchantCategoryMappingService {
|
||||||
|
|
||||||
private final MerchantCategoryMappingRepository mappingRepository;
|
private final MerchantCategoryMappingRepository mappingRepository;
|
||||||
|
|
||||||
public MerchantCategoryMappingService(MerchantCategoryMappingRepository mappingRepository) {
|
public MerchantCategoryMappingService(MerchantCategoryMappingRepository mappingRepository) {
|
||||||
this.mappingRepository = mappingRepository;
|
this.mappingRepository = mappingRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<MerchantCategoryMapping> findByMerchant(Integer merchantId) {
|
public List<MerchantCategoryMapping> findByMerchant(Integer merchantId) {
|
||||||
return mappingRepository.findByMerchantIdOrderByRawCategoryAsc(merchantId);
|
return mappingRepository.findByMerchantIdOrderByRawCategoryAsc(merchantId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve (or create) a mapping row for this merchant + raw category.
|
* Resolve (or create) a mapping row for this merchant + raw category.
|
||||||
* - If it exists, returns it (with whatever mappedPartRole / mappedConfiguration are set).
|
* - If it exists, returns it (with whatever mappedPartRole / mappedConfiguration are set).
|
||||||
* - If it doesn't exist, creates a placeholder row with null mappings and returns it.
|
* - If it doesn't exist, creates a placeholder row with null mappings and returns it.
|
||||||
*
|
*
|
||||||
* The importer can then:
|
* The importer can then:
|
||||||
* - skip rows where mappedPartRole is still null
|
* - skip rows where mappedPartRole is still null
|
||||||
* - use mappedConfiguration if present
|
* - use mappedConfiguration if present
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public MerchantCategoryMapping resolveMapping(Merchant merchant, String rawCategory) {
|
public MerchantCategoryMapping resolveMapping(Merchant merchant, String rawCategory) {
|
||||||
if (rawCategory == null || rawCategory.isBlank()) {
|
if (rawCategory == null || rawCategory.isBlank()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
String trimmed = rawCategory.trim();
|
String trimmed = rawCategory.trim();
|
||||||
|
|
||||||
return mappingRepository
|
return mappingRepository
|
||||||
.findByMerchantIdAndRawCategoryIgnoreCase(merchant.getId(), trimmed)
|
.findByMerchantIdAndRawCategoryIgnoreCase(merchant.getId(), trimmed)
|
||||||
.orElseGet(() -> {
|
.orElseGet(() -> {
|
||||||
MerchantCategoryMapping mapping = new MerchantCategoryMapping();
|
MerchantCategoryMapping mapping = new MerchantCategoryMapping();
|
||||||
mapping.setMerchant(merchant);
|
mapping.setMerchant(merchant);
|
||||||
mapping.setRawCategory(trimmed);
|
mapping.setRawCategory(trimmed);
|
||||||
mapping.setMappedPartRole(null);
|
mapping.setMappedPartRole(null);
|
||||||
mapping.setMappedConfiguration(null);
|
mapping.setMappedConfiguration(null);
|
||||||
return mappingRepository.save(mapping);
|
return mappingRepository.save(mapping);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Upsert mapping (admin UI).
|
* Upsert mapping (admin UI).
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public MerchantCategoryMapping upsertMapping(
|
public MerchantCategoryMapping upsertMapping(
|
||||||
Merchant merchant,
|
Merchant merchant,
|
||||||
String rawCategory,
|
String rawCategory,
|
||||||
String mappedPartRole,
|
String mappedPartRole,
|
||||||
ProductConfiguration mappedConfiguration
|
ProductConfiguration mappedConfiguration
|
||||||
) {
|
) {
|
||||||
String trimmed = rawCategory.trim();
|
String trimmed = rawCategory.trim();
|
||||||
|
|
||||||
MerchantCategoryMapping mapping = mappingRepository
|
MerchantCategoryMapping mapping = mappingRepository
|
||||||
.findByMerchantIdAndRawCategoryIgnoreCase(merchant.getId(), trimmed)
|
.findByMerchantIdAndRawCategoryIgnoreCase(merchant.getId(), trimmed)
|
||||||
.orElseGet(() -> {
|
.orElseGet(() -> {
|
||||||
MerchantCategoryMapping m = new MerchantCategoryMapping();
|
MerchantCategoryMapping m = new MerchantCategoryMapping();
|
||||||
m.setMerchant(merchant);
|
m.setMerchant(merchant);
|
||||||
m.setRawCategory(trimmed);
|
m.setRawCategory(trimmed);
|
||||||
return m;
|
return m;
|
||||||
});
|
});
|
||||||
|
|
||||||
mapping.setMappedPartRole(
|
mapping.setMappedPartRole(
|
||||||
(mappedPartRole == null || mappedPartRole.isBlank()) ? null : mappedPartRole.trim()
|
(mappedPartRole == null || mappedPartRole.isBlank()) ? null : mappedPartRole.trim()
|
||||||
);
|
);
|
||||||
|
|
||||||
mapping.setMappedConfiguration(mappedConfiguration);
|
mapping.setMappedConfiguration(mappedConfiguration);
|
||||||
|
|
||||||
return mappingRepository.save(mapping);
|
return mappingRepository.save(mapping);
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Backwards-compatible overload for existing callers (e.g. controller)
|
* Backwards-compatible overload for existing callers (e.g. controller)
|
||||||
* that don’t care about productConfiguration yet.
|
* that don’t care about productConfiguration yet.
|
||||||
*/
|
*/
|
||||||
@Transactional
|
@Transactional
|
||||||
public MerchantCategoryMapping upsertMapping(
|
public MerchantCategoryMapping upsertMapping(
|
||||||
Merchant merchant,
|
Merchant merchant,
|
||||||
String rawCategory,
|
String rawCategory,
|
||||||
String mappedPartRole
|
String mappedPartRole
|
||||||
) {
|
) {
|
||||||
// Delegate to the new method with `null` configuration
|
// Delegate to the new method with `null` configuration
|
||||||
return upsertMapping(merchant, rawCategory, mappedPartRole, null);
|
return upsertMapping(merchant, rawCategory, mappedPartRole, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,14 +1,14 @@
|
|||||||
package group.goforward.ballistic.services;
|
package group.goforward.ballistic.services;
|
||||||
|
|
||||||
public interface MerchantFeedImportService {
|
public interface MerchantFeedImportService {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Full product + offer import for a given merchant.
|
* Full product + offer import for a given merchant.
|
||||||
*/
|
*/
|
||||||
void importMerchantFeed(Integer merchantId);
|
void importMerchantFeed(Integer merchantId);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Offers-only sync (price / stock) for a given merchant.
|
* Offers-only sync (price / stock) for a given merchant.
|
||||||
*/
|
*/
|
||||||
void syncOffersOnly(Integer merchantId);
|
void syncOffersOnly(Integer merchantId);
|
||||||
}
|
}
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
package group.goforward.ballistic.services;
|
package group.goforward.ballistic.services;
|
||||||
|
|
||||||
import group.goforward.ballistic.model.Psa;
|
import group.goforward.ballistic.model.Psa;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public interface PsaService {
|
public interface PsaService {
|
||||||
List<Psa> findAll();
|
List<Psa> findAll();
|
||||||
|
|
||||||
Optional<Psa> findById(UUID id);
|
Optional<Psa> findById(UUID id);
|
||||||
|
|
||||||
Psa save(Psa psa);
|
Psa save(Psa psa);
|
||||||
|
|
||||||
void deleteById(UUID id);
|
void deleteById(UUID id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
package group.goforward.ballistic.services;
|
package group.goforward.ballistic.services;
|
||||||
|
|
||||||
import group.goforward.ballistic.model.State;
|
import group.goforward.ballistic.model.State;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface StatesService {
|
public interface StatesService {
|
||||||
|
|
||||||
List<State> findAll();
|
List<State> findAll();
|
||||||
|
|
||||||
Optional<State> findById(Integer id);
|
Optional<State> findById(Integer id);
|
||||||
|
|
||||||
State save(State item);
|
State save(State item);
|
||||||
void deleteById(Integer id);
|
void deleteById(Integer id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
package group.goforward.ballistic.services;
|
package group.goforward.ballistic.services;
|
||||||
|
|
||||||
import group.goforward.ballistic.model.User;
|
import group.goforward.ballistic.model.User;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface UsersService {
|
public interface UsersService {
|
||||||
|
|
||||||
List<User> findAll();
|
List<User> findAll();
|
||||||
|
|
||||||
Optional<User> findById(Integer id);
|
Optional<User> findById(Integer id);
|
||||||
|
|
||||||
User save(User item);
|
User save(User item);
|
||||||
void deleteById(Integer id);
|
void deleteById(Integer id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,55 @@
|
|||||||
|
package group.goforward.ballistic.services.admin;
|
||||||
|
|
||||||
|
import group.goforward.ballistic.model.User;
|
||||||
|
import group.goforward.ballistic.repos.UserRepository;
|
||||||
|
import group.goforward.ballistic.web.dto.admin.AdminUserDto;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class AdminUserService {
|
||||||
|
|
||||||
|
private static final Set<String> ALLOWED_ROLES = Set.of("USER", "ADMIN");
|
||||||
|
|
||||||
|
private final UserRepository userRepository;
|
||||||
|
|
||||||
|
public AdminUserService(UserRepository userRepository) {
|
||||||
|
this.userRepository = userRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<AdminUserDto> getAllUsersForAdmin() {
|
||||||
|
return userRepository.findAll()
|
||||||
|
.stream()
|
||||||
|
.map(AdminUserDto::fromUser)
|
||||||
|
.toList();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Transactional
|
||||||
|
public AdminUserDto updateUserRole(UUID userUuid, String newRole, Authentication auth) {
|
||||||
|
if (newRole == null || !ALLOWED_ROLES.contains(newRole.toUpperCase())) {
|
||||||
|
throw new IllegalArgumentException("Invalid role: " + newRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
User user = userRepository.findByUuid(userUuid)
|
||||||
|
.orElseThrow(() -> new IllegalArgumentException("User not found"));
|
||||||
|
|
||||||
|
// Optional safety: do not allow demoting yourself (you can loosen this later)
|
||||||
|
String currentEmail = auth != null ? auth.getName() : null;
|
||||||
|
boolean isSelf = currentEmail != null
|
||||||
|
&& currentEmail.equalsIgnoreCase(user.getEmail());
|
||||||
|
|
||||||
|
if (isSelf && !"ADMIN".equalsIgnoreCase(newRole)) {
|
||||||
|
throw new IllegalStateException("You cannot change your own role to non-admin.");
|
||||||
|
}
|
||||||
|
|
||||||
|
user.setRole(newRole.toUpperCase());
|
||||||
|
// updatedAt will be handled by your entity / DB defaults
|
||||||
|
|
||||||
|
return AdminUserDto.fromUser(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,38 +1,38 @@
|
|||||||
package group.goforward.ballistic.services.impl;
|
package group.goforward.ballistic.services.impl;
|
||||||
|
|
||||||
|
|
||||||
import group.goforward.ballistic.model.Brand;
|
import group.goforward.ballistic.model.Brand;
|
||||||
import group.goforward.ballistic.repos.BrandRepository;
|
import group.goforward.ballistic.repos.BrandRepository;
|
||||||
import group.goforward.ballistic.services.BrandService;
|
import group.goforward.ballistic.services.BrandService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class BrandServiceImpl implements BrandService {
|
public class BrandServiceImpl implements BrandService {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private BrandRepository repo;
|
private BrandRepository repo;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Brand> findAll() {
|
public List<Brand> findAll() {
|
||||||
return repo.findAll();
|
return repo.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Brand> findById(Integer id) {
|
public Optional<Brand> findById(Integer id) {
|
||||||
return repo.findById(id);
|
return repo.findById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Brand save(Brand item) {
|
public Brand save(Brand item) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteById(Integer id) {
|
public void deleteById(Integer id) {
|
||||||
deleteById(id);
|
deleteById(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,41 +1,41 @@
|
|||||||
package group.goforward.ballistic.services.impl;
|
package group.goforward.ballistic.services.impl;
|
||||||
import group.goforward.ballistic.model.Psa;
|
import group.goforward.ballistic.model.Psa;
|
||||||
import group.goforward.ballistic.repos.PsaRepository;
|
import group.goforward.ballistic.repos.PsaRepository;
|
||||||
import group.goforward.ballistic.services.PsaService;
|
import group.goforward.ballistic.services.PsaService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class PsaServiceImpl implements PsaService {
|
public class PsaServiceImpl implements PsaService {
|
||||||
|
|
||||||
private final PsaRepository psaRepository;
|
private final PsaRepository psaRepository;
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
public PsaServiceImpl(PsaRepository psaRepository) {
|
public PsaServiceImpl(PsaRepository psaRepository) {
|
||||||
this.psaRepository = psaRepository;
|
this.psaRepository = psaRepository;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<Psa> findAll() {
|
public List<Psa> findAll() {
|
||||||
return psaRepository.findAll();
|
return psaRepository.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<Psa> findById(UUID id) {
|
public Optional<Psa> findById(UUID id) {
|
||||||
return psaRepository.findById(id);
|
return psaRepository.findById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Psa save(Psa psa) {
|
public Psa save(Psa psa) {
|
||||||
return psaRepository.save(psa);
|
return psaRepository.save(psa);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteById(UUID id) {
|
public void deleteById(UUID id) {
|
||||||
psaRepository.deleteById(id);
|
psaRepository.deleteById(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +1,38 @@
|
|||||||
package group.goforward.ballistic.services.impl;
|
package group.goforward.ballistic.services.impl;
|
||||||
|
|
||||||
|
|
||||||
import group.goforward.ballistic.model.State;
|
import group.goforward.ballistic.model.State;
|
||||||
import group.goforward.ballistic.repos.StateRepository;
|
import group.goforward.ballistic.repos.StateRepository;
|
||||||
import group.goforward.ballistic.services.StatesService;
|
import group.goforward.ballistic.services.StatesService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class StatesServiceImpl implements StatesService {
|
public class StatesServiceImpl implements StatesService {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private StateRepository repo;
|
private StateRepository repo;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<State> findAll() {
|
public List<State> findAll() {
|
||||||
return repo.findAll();
|
return repo.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<State> findById(Integer id) {
|
public Optional<State> findById(Integer id) {
|
||||||
return repo.findById(id);
|
return repo.findById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public State save(State item) {
|
public State save(State item) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteById(Integer id) {
|
public void deleteById(Integer id) {
|
||||||
deleteById(id);
|
deleteById(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,37 +1,37 @@
|
|||||||
package group.goforward.ballistic.services.impl;
|
package group.goforward.ballistic.services.impl;
|
||||||
|
|
||||||
import group.goforward.ballistic.model.User;
|
import group.goforward.ballistic.model.User;
|
||||||
import group.goforward.ballistic.repos.UserRepository;
|
import group.goforward.ballistic.repos.UserRepository;
|
||||||
import group.goforward.ballistic.services.UsersService;
|
import group.goforward.ballistic.services.UsersService;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class UsersServiceImpl implements UsersService {
|
public class UsersServiceImpl implements UsersService {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private UserRepository repo;
|
private UserRepository repo;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public List<User> findAll() {
|
public List<User> findAll() {
|
||||||
return repo.findAll();
|
return repo.findAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<User> findById(Integer id) {
|
public Optional<User> findById(Integer id) {
|
||||||
return repo.findById(id);
|
return repo.findById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public User save(User item) {
|
public User save(User item) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void deleteById(Integer id) {
|
public void deleteById(Integer id) {
|
||||||
deleteById(id);
|
deleteById(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
/**
|
/**
|
||||||
* Provides the classes necessary for the Spring Services implementations for the ballistic -Builder application.
|
* Provides the classes necessary for the Spring Services implementations for the ballistic -Builder application.
|
||||||
* This package includes Services implementations for Spring-Boot application
|
* This package includes Services implementations for Spring-Boot application
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* <p>The main entry point for managing the inventory is the
|
* <p>The main entry point for managing the inventory is the
|
||||||
* {@link group.goforward.ballistic.BattlBuilderApplication} class.</p>
|
* {@link group.goforward.ballistic.BattlBuilderApplication} class.</p>
|
||||||
*
|
*
|
||||||
* @since 1.0
|
* @since 1.0
|
||||||
* @author Don Strawsburg
|
* @author Don Strawsburg
|
||||||
* @version 1.1
|
* @version 1.1
|
||||||
*/
|
*/
|
||||||
package group.goforward.ballistic.services.impl;
|
package group.goforward.ballistic.services.impl;
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package group.goforward.ballistic.web.admin;
|
||||||
|
|
||||||
|
import group.goforward.ballistic.services.admin.AdminUserService;
|
||||||
|
import group.goforward.ballistic.web.dto.admin.AdminUserDto;
|
||||||
|
import group.goforward.ballistic.web.dto.admin.UpdateUserRoleRequest;
|
||||||
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/admin/users")
|
||||||
|
@PreAuthorize("hasRole('ADMIN')")
|
||||||
|
public class AdminUserController {
|
||||||
|
|
||||||
|
private final AdminUserService adminUserService;
|
||||||
|
|
||||||
|
public AdminUserController(AdminUserService adminUserService) {
|
||||||
|
this.adminUserService = adminUserService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping
|
||||||
|
public List<AdminUserDto> listUsers() {
|
||||||
|
return adminUserService.getAllUsersForAdmin();
|
||||||
|
}
|
||||||
|
|
||||||
|
@PatchMapping("/{uuid}/role")
|
||||||
|
public AdminUserDto updateRole(
|
||||||
|
@PathVariable("uuid") UUID uuid,
|
||||||
|
@RequestBody UpdateUserRoleRequest request,
|
||||||
|
Authentication auth
|
||||||
|
) {
|
||||||
|
return adminUserService.updateUserRole(uuid, request.getRole(), auth);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
package group.goforward.ballistic.web.dto.admin;
|
||||||
|
|
||||||
|
import group.goforward.ballistic.model.User;
|
||||||
|
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
public class AdminUserDto {
|
||||||
|
|
||||||
|
// We'll expose the UUID as the "id" used by the frontend
|
||||||
|
private UUID id;
|
||||||
|
private String email;
|
||||||
|
private String displayName;
|
||||||
|
private String role;
|
||||||
|
private OffsetDateTime createdAt;
|
||||||
|
private OffsetDateTime updatedAt;
|
||||||
|
private OffsetDateTime lastLoginAt;
|
||||||
|
|
||||||
|
public AdminUserDto(UUID id,
|
||||||
|
String email,
|
||||||
|
String displayName,
|
||||||
|
String role,
|
||||||
|
OffsetDateTime createdAt,
|
||||||
|
OffsetDateTime updatedAt,
|
||||||
|
OffsetDateTime lastLoginAt) {
|
||||||
|
this.id = id;
|
||||||
|
this.email = email;
|
||||||
|
this.displayName = displayName;
|
||||||
|
this.role = role;
|
||||||
|
this.createdAt = createdAt;
|
||||||
|
this.updatedAt = updatedAt;
|
||||||
|
this.lastLoginAt = lastLoginAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static AdminUserDto fromUser(User user) {
|
||||||
|
return new AdminUserDto(
|
||||||
|
user.getUuid(), // use UUID here (stable id)
|
||||||
|
user.getEmail(),
|
||||||
|
user.getDisplayName(),
|
||||||
|
user.getRole(), // String: "USER" / "ADMIN"
|
||||||
|
user.getCreatedAt(),
|
||||||
|
user.getUpdatedAt(),
|
||||||
|
user.getLastLoginAt()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Getters (and setters if you want Jackson to use them)
|
||||||
|
|
||||||
|
public UUID getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getEmail() {
|
||||||
|
return email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDisplayName() {
|
||||||
|
return displayName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRole() {
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OffsetDateTime getCreatedAt() {
|
||||||
|
return createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OffsetDateTime getUpdatedAt() {
|
||||||
|
return updatedAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OffsetDateTime getLastLoginAt() {
|
||||||
|
return lastLoginAt;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
package group.goforward.ballistic.web.dto.admin;
|
||||||
|
|
||||||
|
public class UpdateUserRoleRequest {
|
||||||
|
|
||||||
|
private String role;
|
||||||
|
|
||||||
|
public UpdateUserRoleRequest() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public UpdateUserRoleRequest(String role) {
|
||||||
|
this.role = role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getRole() {
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRole(String role) {
|
||||||
|
this.role = role;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -13,9 +13,10 @@ spring.datasource.driver-class-name=org.postgresql.Driver
|
|||||||
security.jwt.secret=ballistic-test-secret-key-1234567890-ABCDEFGHIJKLNMOPQRST
|
security.jwt.secret=ballistic-test-secret-key-1234567890-ABCDEFGHIJKLNMOPQRST
|
||||||
security.jwt.access-token-minutes=2880
|
security.jwt.access-token-minutes=2880
|
||||||
|
|
||||||
# Temp disabling logging to find what I fucked up
|
# Logging
|
||||||
spring.jpa.show-sql=false
|
|
||||||
logging.level.org.hibernate.SQL=warn
|
spring.jpa.show-sql=true
|
||||||
|
logging.level.org.hibernate.SQL=INFO
|
||||||
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=warn
|
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=warn
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user