PhoneService.java 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. package it.bgates.remotebe.service;
  2. import it.bgates.remotebe.entities.Device;
  3. import it.bgates.remotebe.entities.Phone;
  4. import it.bgates.remotebe.entities.User;
  5. import it.bgates.remotebe.exception.*;
  6. import it.bgates.remotebe.repository.PhoneRepository;
  7. import it.bgates.remotebe.repository.UserRepository;
  8. import jakarta.persistence.EntityManager;
  9. import jakarta.persistence.TypedQuery;
  10. import jakarta.validation.Valid;
  11. import lombok.RequiredArgsConstructor;
  12. import org.springframework.stereotype.Service;
  13. import org.springframework.transaction.annotation.Transactional;
  14. import java.security.Principal;
  15. import java.time.LocalDateTime;
  16. import java.util.List;
  17. import java.util.Optional;
  18. @Service
  19. @RequiredArgsConstructor
  20. public class PhoneService extends BaseService {
  21. private final PhoneRepository phoneRepository;
  22. private final UserRepository userRepository;
  23. private final EntityManager entityManager;
  24. // private final DeviceService deviceService;
  25. // private final BillingService billingService;
  26. //private final ConfigService configService;
  27. public List<Phone> getPhonesByDeviceId(Integer deviceId, Principal principal) throws UserNotFoundException, NotFoundException {
  28. /*
  29. Device device = deviceService.getDevice(deviceId, principal);
  30. if (device == null) {
  31. throw new NotFoundException("Device not found");
  32. }
  33. */
  34. return phoneRepository.findByDeviceId(deviceId);
  35. }
  36. @Transactional
  37. public Phone addPhone(@Valid Phone phone, Principal principal)
  38. throws UserNotFoundException,
  39. InvalidBillingTypeException,
  40. InsufficientCreditException,
  41. AlreadyPresentException, NullValueNotAllowed {
  42. if (phone.getDevice() == null) {
  43. throw new NullValueNotAllowed("Dispositivo non specificato");
  44. }
  45. // del numero di telefono tieni solo le cifre e il carattere +
  46. phone.setPhoneNumber(phone.getPhoneNumber().replaceAll("[^0-9+]", ""));
  47. if (phone.getId() == null) {
  48. /*
  49. if (!billingService.sufficientBalance(principal, configService.getBillingTypeCost(BillingType.USER_ADD))) {
  50. throw new InsufficientCreditException("Saldo GT-Coins insufficiente per effettuare l'operazione");
  51. }
  52. */
  53. // check if the same phone number is already present in the device
  54. int cnt = phoneRepository.countPhones(phone.getDevice().getId(), phone.getPhoneNumber());
  55. if (cnt > 9) {
  56. throw new AlreadyPresentException("Numero di telefono già presente nel dispositivo");
  57. }
  58. phone.setCreateDate(LocalDateTime.now());
  59. }
  60. if (phone.getDeleted() == null) {
  61. phone.setDeleted(false);
  62. }
  63. phone.setModified(true);
  64. phone.setSynched(false);
  65. Phone addedPhone = phoneRepository.save(phone);
  66. /*
  67. billingService.addBilling(principal, phone.getDevice(), BillingType.USER_ADD,
  68. String.format(
  69. "Aggiunto numero %s", phone.getPhoneNumber()
  70. )
  71. );
  72. */
  73. return addedPhone;
  74. }
  75. public List<Phone> filter(Integer deviceId, String filter, Principal principal) throws UserNotFoundException {
  76. getUserDetails(principal);
  77. Optional<User> user = userRepository.findByUsername(userDetails.getUsername());
  78. if (user.isEmpty()) {
  79. return List.of();
  80. }
  81. StringBuilder filterBuilder = new StringBuilder();
  82. String join = "";
  83. if (isSuperUser()) {
  84. filterBuilder.append("WHERE true ");
  85. } else if (isDistributor()) {
  86. filterBuilder.append("join device d on d.id = p.device.id ");
  87. filterBuilder.append("WHERE d.distributor = :distributor");
  88. } else if (isUser()) {
  89. filterBuilder.append("join device d on d.id = p.device.id ");
  90. filterBuilder.append("join p.device.owner o on o.id = p.device.owner.id ");
  91. filterBuilder.append("WHERE o.id=:ownerId ");
  92. } else {
  93. filterBuilder.append("WHERE false ");
  94. }
  95. if (deviceId != null) {
  96. filterBuilder.append(join).append("and p.device.id=:deviceId ");
  97. }
  98. List<String> params = buildFilter(filterBuilder, filter, new String[]{
  99. "p.phoneNumber",
  100. "p.description"
  101. });
  102. String sql = "SELECT p FROM Phone p " + System.lineSeparator() +
  103. filterBuilder + System.lineSeparator() +
  104. " ORDER BY p.description";
  105. TypedQuery<Phone> query = entityManager.createQuery(sql, Phone.class);
  106. for (int i = 0; i < params.size(); i++) {
  107. query.setParameter("param_" + i, params.get(i));
  108. }
  109. if (isDistributor()) {
  110. query.setParameter("distributor", user.get().getDistributor());
  111. } else if (isUser()) {
  112. query.setParameter("ownerId", user.get().getId());
  113. }
  114. if (deviceId != null) {
  115. query.setParameter("deviceId", deviceId);
  116. }
  117. List<Phone> phones = query.getResultList();
  118. return phones;
  119. }
  120. public Boolean deactivatePhone(Integer phoneId, Principal principal) throws NotFoundException, UserNotFoundException, PermissionDeniedException {
  121. getUserDetails(principal);
  122. Optional<User> user = userRepository.findByUsername(userDetails.getUsername());
  123. if (user.isEmpty()) {
  124. throw new UserNotFoundException("Utente non trovato");
  125. }
  126. Phone phoneToDeactivate = checkDeviceAccessibleToUser(phoneId, user.get());
  127. Optional<Phone> phone = phoneRepository.findById(phoneId);
  128. if (phone.isPresent()) {
  129. phone.get().setActive(false);
  130. phone.get().setSynched(false);
  131. phone.get().setModified(true);
  132. phoneRepository.save(phone.get());
  133. return true;
  134. }
  135. throw new NotFoundException("Telefono non trovato");
  136. }
  137. /**
  138. * Marks the phone for deletion after verifying user access and permissions.
  139. *
  140. * @param id The ID of the phone to be deleted.
  141. * @param principal The security principal of the currently authenticated user.
  142. * @return A boolean value indicating whether the phone was successfully marked as deleted.
  143. * @throws UserNotFoundException If the authenticated user could not be found.
  144. * @throws PermissionDeniedException If the user does not have permission to access the phone.
  145. * @throws NotFoundException If the phone with the specified ID does not exist.
  146. */
  147. public boolean deletePhones(Integer id, Principal principal) throws UserNotFoundException, PermissionDeniedException, NotFoundException {
  148. getUserDetails(principal);
  149. Optional<User> user = userRepository.findByUsername(userDetails.getUsername());
  150. if (user.isEmpty()) {
  151. throw new UserNotFoundException("Utente non trovato");
  152. }
  153. if (phoneRepository.findById(id).isEmpty()) {
  154. throw new NotFoundException("Telefono non trovato");
  155. }
  156. Phone phoneToDelete = checkDeviceAccessibleToUser(id, user.get());
  157. phoneToDelete.setDeleted(true);
  158. phoneToDelete.setSynched(false);
  159. phoneToDelete.setDeletionTime(LocalDateTime.now());
  160. phoneRepository.save(phoneToDelete);
  161. return true;
  162. }
  163. /**
  164. * Checks if the device that has the phone is accessible to the given user based on their role and permissions.
  165. * This method executes a query to retrieve a phone entity based on the user's access level
  166. * and the provided ID. If the user does not have permission to access the device,
  167. * a {@link PermissionDeniedException} is thrown.
  168. *
  169. * @param id the ID of the phone to be checked.
  170. * @param user an {@code Optional<User>} representing the current logged-in user requesting access.
  171. * The user parameter is required to determine the level of permissions.
  172. * @return the {@code Phone} entity that the user has access to if permitted.
  173. * @throws PermissionDeniedException if the user is not allowed to manage the specified phone.
  174. */
  175. private Phone checkDeviceAccessibleToUser(Integer id, User user) throws PermissionDeniedException {
  176. // Check if user has access to phone
  177. StringBuilder filterBuilder = new StringBuilder();
  178. String join = "";
  179. if (isSuperUser()) {
  180. filterBuilder.append("WHERE phone.id = :id ");
  181. } else if (isDistributor()) {
  182. filterBuilder.append("join device d on d.id = phone.device.id ");
  183. filterBuilder.append("WHERE d.distributor = :distributor and phone.id = :id");
  184. } else if (isUser()) {
  185. filterBuilder.append("join device d on d.id = phone.device.id ");
  186. filterBuilder.append("join phone.device.owner o on o.id = phone.device.owner.id ");
  187. filterBuilder.append("WHERE o.id=:ownerId and phone.id=:id ");
  188. } else {
  189. filterBuilder.append("WHERE false ");
  190. }
  191. String sql = "SELECT phone FROM Phone phone " + System.lineSeparator() +
  192. filterBuilder + System.lineSeparator();
  193. TypedQuery<Phone> query = entityManager.createQuery(sql, Phone.class);
  194. query.setParameter("id", id);
  195. if (isDistributor()) {
  196. query.setParameter("distributor", user.getDistributor());
  197. } else if (isUser()) {
  198. query.setParameter("ownerId", user.getId());
  199. }
  200. List<Phone> phones = query.getResultList();
  201. if (phones.isEmpty()) {
  202. throw new PermissionDeniedException("Utente non autorizzato a gestire il telefono specificato");
  203. }
  204. return phones.getFirst();
  205. }
  206. public Boolean activatePhone(Integer phoneId, Principal principal) throws NotFoundException, UserNotFoundException, PermissionDeniedException {
  207. getUserDetails(principal);
  208. Optional<User> user = userRepository.findByUsername(userDetails.getUsername());
  209. if (user.isEmpty()) {
  210. throw new UserNotFoundException("Utente non trovato");
  211. }
  212. if (phoneRepository.findById(phoneId).isEmpty()) {
  213. throw new NotFoundException("Telefono non trovato");
  214. }
  215. Phone phone = checkDeviceAccessibleToUser(phoneId, user.get());
  216. phone.setActive(true);
  217. phoneRepository.save(phone);
  218. return true;
  219. }
  220. public List<Phone> getDeletedPhones(Device device) {
  221. return phoneRepository.findDeletedPhoneByDevice(device.getId());
  222. }
  223. public List<Phone> getModifiedPhones(Device device) {
  224. return phoneRepository.findModifiedPhoneByDevice(device.getId());
  225. }
  226. public void delete(Integer id) {
  227. phoneRepository.deleteById(id);
  228. }
  229. public void clearUserModifiedFlags(Integer id) {
  230. phoneRepository.clearUserModifiedFlags(id);
  231. }
  232. }