Merge branch '69-7-fixes-to-guest-user-story' into 'dev'
Resolve "7: fixes to guest user story" Closes #69 See merge request sa4-2020/the-sanmarinoes/backend!112
This commit is contained in:
commit
38c703e521
4 changed files with 83 additions and 40 deletions
|
@ -6,20 +6,13 @@ import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.SceneSaveRequest;
|
|||
import ch.usi.inf.sa4.sanmarinoes.smarthut.error.NotFoundException;
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*;
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.service.SceneService;
|
||||
import ch.usi.inf.sa4.sanmarinoes.smarthut.utils.Utils;
|
||||
import java.security.Principal;
|
||||
import java.util.List;
|
||||
import javax.validation.Valid;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.ResponseBody;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
@RestController
|
||||
@EnableAutoConfiguration
|
||||
|
@ -27,21 +20,20 @@ import org.springframework.web.bind.annotation.RestController;
|
|||
public class SceneController {
|
||||
|
||||
@Autowired private SceneRepository sceneRepository;
|
||||
@Autowired private UserRepository userRepository;
|
||||
@Autowired private SceneService sceneService;
|
||||
@Autowired private UserRepository userService;
|
||||
@Autowired private StateRepository<State<?>> stateService;
|
||||
@Autowired private StateRepository<State<?>> stateRepository;
|
||||
|
||||
@GetMapping
|
||||
public List<Scene> findAll(Principal principal) {
|
||||
return toList(sceneRepository.findByUsername(principal.getName()));
|
||||
}
|
||||
|
||||
@GetMapping("/{id}")
|
||||
public @ResponseBody Scene findById(@PathVariable("id") long id, Principal principal)
|
||||
public List<Scene> findAll(
|
||||
Principal principal, @RequestParam(value = "hostId", required = false) Long hostId)
|
||||
throws NotFoundException {
|
||||
return sceneRepository
|
||||
.findByIdAndUsername(id, principal.getName())
|
||||
.orElseThrow(NotFoundException::new);
|
||||
if (hostId == null) {
|
||||
return toList(sceneRepository.findByUsername(principal.getName()));
|
||||
} else {
|
||||
Utils.returnIfGuest(userRepository, null, hostId, principal);
|
||||
return sceneRepository.findByHostId(hostId);
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping
|
||||
|
@ -49,7 +41,7 @@ public class SceneController {
|
|||
@Valid @RequestBody SceneSaveRequest s, final Principal principal) {
|
||||
|
||||
final String username = principal.getName();
|
||||
final Long userId = userService.findByUsername(username).getId();
|
||||
final Long userId = userRepository.findByUsername(username).getId();
|
||||
|
||||
final Scene newScene = new Scene();
|
||||
|
||||
|
@ -62,14 +54,27 @@ public class SceneController {
|
|||
}
|
||||
|
||||
@PostMapping("/{id}/apply")
|
||||
public @ResponseBody List<Device> apply(@PathVariable("id") long id, final Principal principal)
|
||||
public @ResponseBody List<Device> apply(
|
||||
@PathVariable("id") long id,
|
||||
final Principal principal,
|
||||
@RequestParam(value = "hostId", required = false) Long hostId)
|
||||
throws NotFoundException {
|
||||
final Scene newScene =
|
||||
sceneRepository
|
||||
.findByIdAndUsername(id, principal.getName())
|
||||
.orElseThrow(NotFoundException::new);
|
||||
|
||||
return sceneService.apply(newScene, principal.getName(), false);
|
||||
if (hostId == null) {
|
||||
return sceneService.apply(
|
||||
sceneRepository
|
||||
.findByIdAndUsername(id, principal.getName())
|
||||
.orElseThrow(NotFoundException::new),
|
||||
principal.getName(),
|
||||
false);
|
||||
} else {
|
||||
Utils.returnIfGuest(userRepository, null, hostId, principal);
|
||||
return sceneService.applyAsGuest(
|
||||
sceneRepository
|
||||
.findByIdAndUserId(id, hostId)
|
||||
.orElseThrow(NotFoundException::new),
|
||||
principal.getName(),
|
||||
hostId);
|
||||
}
|
||||
}
|
||||
|
||||
@PostMapping("/{id}/copyFrom/{copyId}")
|
||||
|
@ -112,7 +117,7 @@ public class SceneController {
|
|||
|
||||
@DeleteMapping("/{id}")
|
||||
public void deleteById(@PathVariable("id") long id) {
|
||||
stateService.deleteAllBySceneId(id);
|
||||
stateRepository.deleteAllBySceneId(id);
|
||||
sceneRepository.deleteById(id);
|
||||
}
|
||||
|
||||
|
@ -122,7 +127,7 @@ public class SceneController {
|
|||
*/
|
||||
@GetMapping(path = "/{sceneId}/states")
|
||||
public List<State<?>> getDevices(@PathVariable("sceneId") long sceneId) {
|
||||
Iterable<State<?>> states = stateService.findBySceneId(sceneId);
|
||||
Iterable<State<?>> states = stateRepository.findBySceneId(sceneId);
|
||||
return toList(states);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,4 +19,9 @@ public interface SceneRepository extends CrudRepository<Scene, Long> {
|
|||
|
||||
@Query("SELECT s FROM Scene s JOIN s.user u WHERE u.username = ?1")
|
||||
List<Scene> findByUsername(String username);
|
||||
|
||||
@Query("SELECT s FROM Scene s JOIN s.user u WHERE u.id = ?1 AND s.guestAccessEnabled = true")
|
||||
List<Scene> findByHostId(Long hostId);
|
||||
|
||||
Optional<Scene> findByIdAndUserId(Long id, Long userId);
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ import java.util.Collection;
|
|||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.StreamSupport;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
|
@ -68,6 +70,7 @@ public class DeviceService {
|
|||
throws NotFoundException {
|
||||
try {
|
||||
Iterable<Device> devices;
|
||||
User host = null;
|
||||
if (hostId == null) {
|
||||
if (roomId != null) {
|
||||
roomRepository
|
||||
|
@ -79,8 +82,7 @@ public class DeviceService {
|
|||
}
|
||||
} else {
|
||||
final User guest = userRepository.findByUsername(username);
|
||||
final User host =
|
||||
userRepository.findById(hostId).orElseThrow(NotFoundException::new);
|
||||
host = userRepository.findById(hostId).orElseThrow(NotFoundException::new);
|
||||
|
||||
if (!guest.getHosts().contains(host)) {
|
||||
throw new NotFoundException();
|
||||
|
@ -99,7 +101,13 @@ public class DeviceService {
|
|||
|
||||
populateComputedFields(devices);
|
||||
|
||||
return toList(devices);
|
||||
if (host != null && !host.isCameraEnabled()) {
|
||||
return StreamSupport.stream(devices.spliterator(), true)
|
||||
.filter(d -> !(d instanceof SecurityCamera))
|
||||
.collect(Collectors.toList());
|
||||
} else {
|
||||
return toList(devices);
|
||||
}
|
||||
} catch (NotFoundException e) {
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
|
@ -120,7 +128,13 @@ public class DeviceService {
|
|||
final User host = userRepository.findById(hostId).orElseThrow(NotFoundException::new);
|
||||
if (!host.getGuests().contains(currentUser)) throw new NotFoundException();
|
||||
renameIfDuplicate(device, host.getUsername());
|
||||
|
||||
device = deviceRepository.save(device);
|
||||
propagateUpdateAsGuest(device, host, currentUser);
|
||||
return device;
|
||||
}
|
||||
|
||||
private void propagateUpdateAsGuest(Device device, User host, User guest) {
|
||||
final Set<User> guests = Set.copyOf(host.getGuests());
|
||||
|
||||
// We're telling the host that a guest has modified a device. Therefore, fromGuest becomes
|
||||
|
@ -130,15 +144,22 @@ public class DeviceService {
|
|||
|
||||
// We're telling all guests that a higher entity has issued a device update. Therefore,
|
||||
// fromHost becomes true.
|
||||
for (final User guest : guests) {
|
||||
if (guest.equals(currentUser)) {
|
||||
for (final User aGuest : guests) {
|
||||
if (aGuest.equals(guest)) {
|
||||
continue;
|
||||
}
|
||||
// enqueue all device updates for all other guests
|
||||
endpoint.queueDeviceUpdate(device, guest, false, host.getId(), false);
|
||||
endpoint.queueDeviceUpdate(device, aGuest, false, host.getId(), false);
|
||||
}
|
||||
}
|
||||
|
||||
return device;
|
||||
List<Device> saveAllAsGuestSceneApplication(
|
||||
List<Device> devices, String guestUsername, Long hostId) {
|
||||
final User guest = userRepository.findByUsername(guestUsername);
|
||||
final User host = userRepository.findById(hostId).orElseThrow(IllegalStateException::new);
|
||||
deviceRepository.saveAll(devices);
|
||||
devices.forEach(d -> this.propagateUpdateAsGuest(d, host, guest));
|
||||
return devices;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -13,18 +13,30 @@ public class SceneService {
|
|||
@Autowired private DeviceService deviceService;
|
||||
@Autowired private StateRepository<State<?>> stateRepository;
|
||||
|
||||
public List<Device> apply(Scene newScene, String username, boolean fromTrigger) {
|
||||
private List<Device> copyStatesToDevices(Scene fromScene) {
|
||||
final List<Device> updated = new ArrayList<>();
|
||||
|
||||
for (final State<?> s : newScene.getStates()) {
|
||||
for (final State<?> s : fromScene.getStates()) {
|
||||
s.apply();
|
||||
updated.add(s.getDevice());
|
||||
}
|
||||
deviceService.saveAllAsOwner(updated, username, true, fromTrigger);
|
||||
|
||||
deviceService.populateComputedFields(updated);
|
||||
return updated;
|
||||
}
|
||||
|
||||
public List<Device> apply(Scene newScene, String username, boolean fromTrigger) {
|
||||
List<Device> updated = copyStatesToDevices(newScene);
|
||||
deviceService.saveAllAsOwner(updated, username, true, fromTrigger);
|
||||
return updated;
|
||||
}
|
||||
|
||||
public List<Device> applyAsGuest(Scene newScene, String username, Long hostId) {
|
||||
List<Device> updated = copyStatesToDevices(newScene);
|
||||
deviceService.saveAllAsGuestSceneApplication(updated, username, hostId);
|
||||
return updated;
|
||||
}
|
||||
|
||||
public List<State<?>> copyStates(Scene to, Scene from) {
|
||||
final ArrayList<State<?>> states = new ArrayList<>();
|
||||
for (final State<?> s : from.getStates()) {
|
||||
|
|
Loading…
Reference in a new issue