From 1ab4fee6ff2fc60b1ddbf506e6af41816294adf3 Mon Sep 17 00:00:00 2001 From: omenem Date: Wed, 26 Feb 2020 18:56:47 +0100 Subject: [PATCH 1/5] Little changes to Room and dimmableLight classes --- .../controller/DimmableLightController.java | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/DimmableLightController.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/DimmableLightController.java index 0cd1144..32faf36 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/DimmableLightController.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/DimmableLightController.java @@ -2,7 +2,7 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.controller; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.DimmableLight; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.DimmableLightRepository; -import java.util.List; +import java.util.Optional; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.web.bind.annotation.DeleteMapping; @@ -22,27 +22,27 @@ public class DimmableLightController { @Autowired private DimmableLightRepository dimmableLightService; @GetMapping - public List getAll() { - return dimmableLightService.getList(); + public Iterable findAll() { + return dimmableLightService.findAll(); } @GetMapping("/{id}") - public DimmableLight getById(@PathVariable("id") long id) { - return dimmableLightService.getById(); + public Optional findById(@PathVariable("id") long id) { + return dimmableLightService.findById(id); } @PostMapping - public DimmableLight create(@RequestBody DimmableLight dl) { - return dimmableLightService.create(dl); + public DimmableLight save(@RequestBody DimmableLight dl) { + return dimmableLightService.save(dl); } - @PutMapping("/{id}") - public DimmableLight update(@PathVariable("id") long id, @RequestBody DimmableLight dl) { - return dimmableLightService.update(id, dl); + @PutMapping + public DimmableLight update(@RequestBody DimmableLight dl) { + return dimmableLightService.save(dl); } @DeleteMapping("/{id}") public void delete(@PathVariable("id") long id) { - dimmableLightService.delete(id); + dimmableLightService.deleteById(id); } } From b2353e98347f72a561167977e484a422f3e4d994 Mon Sep 17 00:00:00 2001 From: omenem Date: Wed, 26 Feb 2020 18:58:01 +0100 Subject: [PATCH 2/5] Small Changes --- .../smarthut/controller/RoomController.java | 17 +++++++++ .../sanmarinoes/smarthut/models/Device.java | 9 ++++- .../sa4/sanmarinoes/smarthut/models/Room.java | 35 +++++++++++-------- 3 files changed, 45 insertions(+), 16 deletions(-) diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/RoomController.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/RoomController.java index c60d45b..7d23922 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/RoomController.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/RoomController.java @@ -4,6 +4,8 @@ import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; import java.util.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.*; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; import org.springframework.web.bind.annotation.*; @RestController @@ -13,6 +15,8 @@ public class RoomController { @Autowired private RoomRepository roomRepository; + @Autowired private UserRepository userRepository; + @GetMapping public Iterable findAll() { return roomRepository.findAll(); @@ -25,6 +29,19 @@ public class RoomController { @PostMapping public Room save(@RequestBody Room r) { + final Object principal = + SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + + if (!(principal instanceof UserDetails)) { + throw new IllegalStateException("User is not logged in"); + } + + final String username = ((UserDetails) principal).getUsername(); + final Long userId = userRepository.findByUsername(username).getId(); + + r.setUserId(userId); + r.setUser(null); + return roomRepository.save(r); } diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Device.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Device.java index d6108e8..3ec45b9 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Device.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Device.java @@ -21,9 +21,16 @@ public abstract class Device { /** The room this device belongs in */ @ManyToOne - @JoinColumn(name = "room_id") + @JoinColumn(name = "room_id", nullable = false, updatable = false, insertable = false) private Room room; + /** + * The room this device belongs in, as a foreign key id. To use when updating and inserting from + * a REST call. + */ + @Column(name = "room_id") + private Long roomId; + /** The name of the device as assigned by the user (e.g. 'Master bedroom light') */ @Column private String name; diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Room.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Room.java index 6f36557..f297927 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Room.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Room.java @@ -18,21 +18,28 @@ public class Room { * https://www.baeldung.com/java-base64-image-string * https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html */ - @Column(name = "icon", updatable = true, nullable = false) + @Column(name = "icon", nullable = false) private byte[] icon; - @Column(name = "image", updatable = true, nullable = false) + @Column(name = "image", nullable = false) private byte[] image; /** User that owns the house this room is in */ @ManyToOne - @JoinColumn(name = "user_id") + @JoinColumn(name = "user_id", nullable = false, updatable = false, insertable = false) private User user; + /** + * User that owns the house this room is in as a foreign key id. To use when updating and + * inserting from a REST call. + */ + @Column(name = "user_id") + private Long userId; + /** The user given name of this room (e.g. 'Master bedroom') */ @Column private String name; - /** Collectiion of devices present in this room */ + /** Collection of devices present in this room */ @OneToMany(mappedBy = "room") private Set devices; @@ -44,6 +51,14 @@ public class Room { this.id = id; } + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + public User getUser() { return user; } @@ -66,16 +81,6 @@ public class Room { @Override public String toString() { - return "Room{" - + "id=" - + id - + ", user=" - + user - + ", name='" - + name - + '\'' - + ", devices=" - + devices - + '}'; + return "Room{" + "id=" + id + ", user=" + user + ", name='" + name + "\'}"; } } From 48441dfe07e2da191b0e62f785f45b95dd54029f Mon Sep 17 00:00:00 2001 From: Claudio Maggioni Date: Wed, 26 Feb 2020 21:41:54 +0100 Subject: [PATCH 3/5] Started work on input validation --- .idea/misc.xml | 2 +- ...ler.java => AuthenticationController.java} | 20 +++++++- .../controller/ButtonDimmerController.java | 5 +- .../controller/DimmableLightController.java | 5 +- .../controller/KnobDimmerController.java | 5 +- .../controller/MotionSensorController.java | 5 +- .../controller/RegularLightController.java | 5 +- .../smarthut/controller/RoomController.java | 5 +- .../smarthut/controller/SensorController.java | 5 +- .../controller/SmartPlugController.java | 5 +- .../smarthut/controller/SwitchController.java | 5 +- .../smarthut/controller/UserController.java | 40 --------------- .../smarthut/{models => dto}/JWTRequest.java | 10 +--- .../smarthut/{models => dto}/JWTResponse.java | 2 +- .../smarthut/dto/UserUpdateRequest.java | 51 +++++++++++++++++++ .../sanmarinoes/smarthut/models/Device.java | 20 +++++++- .../smarthut/models/DimmableLight.java | 13 +++-- .../sanmarinoes/smarthut/models/Light.java | 4 +- .../sa4/sanmarinoes/smarthut/models/Room.java | 40 +++++++++++---- .../sanmarinoes/smarthut/models/Sensor.java | 18 ++++++- .../smarthut/models/SmartPlug.java | 4 +- .../sa4/sanmarinoes/smarthut/models/User.java | 32 +++++++++--- 22 files changed, 206 insertions(+), 95 deletions(-) rename src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/{JWTAuthenticationController.java => AuthenticationController.java} (73%) delete mode 100644 src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/UserController.java rename src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/{models => dto}/JWTRequest.java (60%) rename src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/{models => dto}/JWTResponse.java (80%) create mode 100644 src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/dto/UserUpdateRequest.java diff --git a/.idea/misc.xml b/.idea/misc.xml index 7c6191b..241f098 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,7 +1,7 @@ - + \ No newline at end of file diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/JWTAuthenticationController.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/AuthenticationController.java similarity index 73% rename from src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/JWTAuthenticationController.java rename to src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/AuthenticationController.java index 6e3d01b..f7dee78 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/JWTAuthenticationController.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/AuthenticationController.java @@ -1,7 +1,12 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.controller; import ch.usi.inf.sa4.sanmarinoes.smarthut.config.JWTTokenUtil; +import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.JWTRequest; +import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.JWTResponse; +import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.UserUpdateRequest; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; +import java.security.Principal; +import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; @@ -14,10 +19,12 @@ import org.springframework.web.bind.annotation.*; @RestController @CrossOrigin @RequestMapping("/auth") -public class JWTAuthenticationController { +public class AuthenticationController { @Autowired private AuthenticationManager authenticationManager; + @Autowired private UserRepository userRepository; + @Autowired private JWTTokenUtil jwtTokenUtil; @Autowired private JWTUserDetailsService userDetailsService; @@ -36,12 +43,21 @@ public class JWTAuthenticationController { } @PostMapping("/register") - public User register(@RequestBody User user) { + public User register(@Valid @RequestBody User user) { user.setPassword(encoder.encode(user.getPassword())); users.save(user); return user; } + @PutMapping("/update") + public User update(@Valid @RequestBody final UserUpdateRequest u, final Principal principal) { + final User oldUser = userRepository.findByUsername(principal.getName()); + oldUser.setName(u.getName()); + oldUser.setEmail(u.getEmail()); + oldUser.setPassword(encoder.encode(u.getPassword())); + return userRepository.save(oldUser); + } + private void authenticate(String username, String password) throws Exception { try { authenticationManager.authenticate( diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/ButtonDimmerController.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/ButtonDimmerController.java index 1098824..7c2d0b7 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/ButtonDimmerController.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/ButtonDimmerController.java @@ -3,6 +3,7 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.controller; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.ButtonDimmer; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.ButtonDimmerRepository; import java.util.Optional; +import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.web.bind.annotation.DeleteMapping; @@ -31,12 +32,12 @@ public class ButtonDimmerController { } @PostMapping - public ButtonDimmer save(@RequestBody ButtonDimmer bd) { + public ButtonDimmer save(@Valid @RequestBody ButtonDimmer bd) { return buttonDimmerService.save(bd); } @PutMapping - public ButtonDimmer update(@RequestBody ButtonDimmer bd) { + public ButtonDimmer update(@Valid @RequestBody ButtonDimmer bd) { return buttonDimmerService.save(bd); } diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/DimmableLightController.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/DimmableLightController.java index 32faf36..5391e43 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/DimmableLightController.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/DimmableLightController.java @@ -3,6 +3,7 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.controller; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.DimmableLight; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.DimmableLightRepository; import java.util.Optional; +import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.web.bind.annotation.DeleteMapping; @@ -32,12 +33,12 @@ public class DimmableLightController { } @PostMapping - public DimmableLight save(@RequestBody DimmableLight dl) { + public DimmableLight save(@Valid @RequestBody DimmableLight dl) { return dimmableLightService.save(dl); } @PutMapping - public DimmableLight update(@RequestBody DimmableLight dl) { + public DimmableLight update(@Valid @RequestBody DimmableLight dl) { return dimmableLightService.save(dl); } diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/KnobDimmerController.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/KnobDimmerController.java index 0696202..3dd53d7 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/KnobDimmerController.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/KnobDimmerController.java @@ -3,6 +3,7 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.controller; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.KnobDimmer; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.KnobDimmerRepository; import java.util.Optional; +import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.web.bind.annotation.DeleteMapping; @@ -32,12 +33,12 @@ public class KnobDimmerController { } @PostMapping - public KnobDimmer save(@RequestBody KnobDimmer kd) { + public KnobDimmer save(@Valid @RequestBody KnobDimmer kd) { return knobDimmerService.save(kd); } @PutMapping - public KnobDimmer update(@RequestBody KnobDimmer kd) { + public KnobDimmer update(@Valid @RequestBody KnobDimmer kd) { return knobDimmerService.save(kd); } diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/MotionSensorController.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/MotionSensorController.java index 5ac2612..15c964f 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/MotionSensorController.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/MotionSensorController.java @@ -3,6 +3,7 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.controller; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.MotionSensor; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.MotionSensorRepository; import java.util.Optional; +import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.web.bind.annotation.DeleteMapping; @@ -32,12 +33,12 @@ public class MotionSensorController { } @PostMapping - public MotionSensor save(@RequestBody MotionSensor ms) { + public MotionSensor save(@Valid @RequestBody MotionSensor ms) { return motionSensorService.save(ms); } @PutMapping - public MotionSensor update(@RequestBody MotionSensor ms) { + public MotionSensor update(@Valid @RequestBody MotionSensor ms) { return motionSensorService.save(ms); } diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/RegularLightController.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/RegularLightController.java index 9a97abb..2ec1453 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/RegularLightController.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/RegularLightController.java @@ -3,6 +3,7 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.controller; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.RegularLight; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.RegularLightRepository; import java.util.Optional; +import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.web.bind.annotation.DeleteMapping; @@ -32,12 +33,12 @@ public class RegularLightController { } @PostMapping - public RegularLight save(@RequestBody RegularLight rl) { + public RegularLight save(@Valid @RequestBody RegularLight rl) { return regularLightService.save(rl); } @PutMapping - public RegularLight update(@RequestBody RegularLight rl) { + public RegularLight update(@Valid @RequestBody RegularLight rl) { return regularLightService.save(rl); } diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/RoomController.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/RoomController.java index 7d23922..9ff6e2e 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/RoomController.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/RoomController.java @@ -2,6 +2,7 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.controller; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; import java.util.*; +import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.*; import org.springframework.security.core.context.SecurityContextHolder; @@ -28,7 +29,7 @@ public class RoomController { } @PostMapping - public Room save(@RequestBody Room r) { + public Room save(@Valid @RequestBody Room r) { final Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); @@ -46,7 +47,7 @@ public class RoomController { } @PutMapping - public Room update(@RequestBody Room r) { + public Room update(@Valid @RequestBody Room r) { return roomRepository.save(r); } diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/SensorController.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/SensorController.java index 04fe6fb..957328e 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/SensorController.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/SensorController.java @@ -2,6 +2,7 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.controller; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; import java.util.*; +import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.*; import org.springframework.web.bind.annotation.*; @@ -24,12 +25,12 @@ public class SensorController { } @PostMapping - public Sensor save(@RequestBody Sensor s) { + public Sensor save(@Valid @RequestBody Sensor s) { return sensorRepository.save(s); } @PutMapping - public Sensor update(@RequestBody Sensor s) { + public Sensor update(@Valid @RequestBody Sensor s) { return sensorRepository.save(s); } diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/SmartPlugController.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/SmartPlugController.java index a6304b4..a0aee71 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/SmartPlugController.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/SmartPlugController.java @@ -2,6 +2,7 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.controller; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; import java.util.*; +import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.*; import org.springframework.web.bind.annotation.*; @@ -24,12 +25,12 @@ public class SmartPlugController { } @PostMapping - public SmartPlug save(@RequestBody SmartPlug sp) { + public SmartPlug save(@Valid @RequestBody SmartPlug sp) { return smartPlugRepository.save(sp); } @PutMapping - public SmartPlug update(@RequestBody SmartPlug sp) { + public SmartPlug update(@Valid @RequestBody SmartPlug sp) { return smartPlugRepository.save(sp); } diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/SwitchController.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/SwitchController.java index 4cceb34..7eb83a0 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/SwitchController.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/SwitchController.java @@ -2,6 +2,7 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.controller; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; import java.util.*; +import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.*; import org.springframework.web.bind.annotation.*; @@ -24,12 +25,12 @@ public class SwitchController { } @PostMapping - public Switch save(@RequestBody Switch s) { + public Switch save(@Valid @RequestBody Switch s) { return switchRepository.save(s); } @PutMapping - public Switch update(@RequestBody Switch s) { + public Switch update(@Valid @RequestBody Switch s) { return switchRepository.save(s); } diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/UserController.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/UserController.java deleted file mode 100644 index 941cf9b..0000000 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/UserController.java +++ /dev/null @@ -1,40 +0,0 @@ -package ch.usi.inf.sa4.sanmarinoes.smarthut.controller; - -import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; -import java.util.*; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.*; -import org.springframework.web.bind.annotation.*; - -@RestController -@EnableAutoConfiguration -@RequestMapping("/user") -public class UserController { - - @Autowired private UserRepository userRepository; - - @GetMapping - public Iterable findAll() { - return userRepository.findAll(); - } - - @GetMapping("/{id}") - public Optional findById(@PathVariable("id") long id) { - return userRepository.findById(id); - } - - @PostMapping - public User save(@RequestBody User u) { - return userRepository.save(u); - } - - @PutMapping - public User update(@RequestBody User u) { - return userRepository.save(u); - } - - @DeleteMapping("/{id}") - public void deleteById(@PathVariable("id") long id) { - userRepository.deleteById(id); - } -} diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/JWTRequest.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/dto/JWTRequest.java similarity index 60% rename from src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/JWTRequest.java rename to src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/dto/JWTRequest.java index 66d0c75..d750a50 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/JWTRequest.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/dto/JWTRequest.java @@ -1,17 +1,9 @@ -package ch.usi.inf.sa4.sanmarinoes.smarthut.models; +package ch.usi.inf.sa4.sanmarinoes.smarthut.dto; public class JWTRequest { private String username; private String password; - // need default constructor for JSON Parsing - public JWTRequest() {} - - public JWTRequest(String username, String password) { - this.setUsername(username); - this.setPassword(password); - } - public String getUsername() { return this.username; } diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/JWTResponse.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/dto/JWTResponse.java similarity index 80% rename from src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/JWTResponse.java rename to src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/dto/JWTResponse.java index 9eb1092..7bc04f2 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/JWTResponse.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/dto/JWTResponse.java @@ -1,4 +1,4 @@ -package ch.usi.inf.sa4.sanmarinoes.smarthut.models; +package ch.usi.inf.sa4.sanmarinoes.smarthut.dto; public class JWTResponse { private final String jwttoken; diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/dto/UserUpdateRequest.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/dto/UserUpdateRequest.java new file mode 100644 index 0000000..5000bb1 --- /dev/null +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/dto/UserUpdateRequest.java @@ -0,0 +1,51 @@ +package ch.usi.inf.sa4.sanmarinoes.smarthut.dto; + +import javax.validation.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; + +public class UserUpdateRequest { + /** The full name of the user */ + @NotEmpty(message = "Please provide a full name") + private String name; + + /** A non-salted password */ + @NotNull + @NotEmpty(message = "Please provide a password") + private String password; + + /** + * The user's email (validated according to criteria used in >input type="email"<> + * , technically not RFC 5322 compliant + */ + @NotNull + @NotEmpty(message = "Please provide an email") + @Pattern( + message = "Please provide a valid email", + regexp = "/^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$/") + private String email; + + public String getName() { + return name; + } + + public String getPassword() { + return password; + } + + public String getEmail() { + return email; + } + + public void setName(String name) { + this.name = name; + } + + public void setPassword(String password) { + this.password = password; + } + + public void setEmail(String email) { + this.email = email; + } +} diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Device.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Device.java index 3ec45b9..834104d 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Device.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Device.java @@ -1,6 +1,8 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models; +import com.google.gson.annotations.SerializedName; import javax.persistence.*; +import javax.validation.constraints.NotNull; /** Generic abstraction for a smart home device */ @Entity @@ -9,7 +11,10 @@ public abstract class Device { /** Ways a device can behave in the automation flow. For now only input/output */ public enum FlowType { + @SerializedName("INPUT") INPUT, + + @SerializedName("OUTPUT") OUTPUT } @@ -28,11 +33,14 @@ public abstract class Device { * The room this device belongs in, as a foreign key id. To use when updating and inserting from * a REST call. */ - @Column(name = "room_id") + @Column(name = "room_id", nullable = false) + @NotNull private Long roomId; /** The name of the device as assigned by the user (e.g. 'Master bedroom light') */ - @Column private String name; + @NotNull + @Column(nullable = false) + private String name; /** * The name for the category of this particular device (e.g 'dimmer'). Not stored in the @@ -70,6 +78,14 @@ public abstract class Device { this.name = name; } + public Long getRoomId() { + return roomId; + } + + public void setRoomId(Long roomId) { + this.roomId = roomId; + } + public Device(String kind, FlowType flowType) { this.kind = kind; this.flowType = flowType; diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/DimmableLight.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/DimmableLight.java index 666fbee..6a35248 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/DimmableLight.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/DimmableLight.java @@ -2,6 +2,9 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models; import javax.persistence.Column; import javax.persistence.Entity; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; /** Represent a dimmable light */ @Entity @@ -12,13 +15,17 @@ public class DimmableLight extends Light { } /** The light intensity value. Goes from 0 (off) to 100 (on) */ - @Column private int intensity = 0; + @NotNull + @Column(nullable = false) + @Min(1) + @Max(100) + private Integer intensity = 0; - public int getIntensity() { + public Integer getIntensity() { return intensity; } - public void setIntensity(int intensity) throws IllegalArgumentException { + public void setIntensity(Integer intensity) throws IllegalArgumentException { if (intensity < 0 || intensity > 100) { throw new IllegalArgumentException("The intensity level can't go below 0 or above 100"); } diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Light.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Light.java index bf1ed39..68a819b 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Light.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Light.java @@ -4,6 +4,7 @@ import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; +import javax.validation.constraints.NotNull; /** Represents a generic light */ @Entity @@ -11,7 +12,8 @@ import javax.persistence.InheritanceType; public abstract class Light extends OutputDevice { /** Whether the light is on or not */ - @Column(name = "light_on") + @Column(name = "light_on", nullable = false) + @NotNull boolean on; protected Light(String kind) { diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Room.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Room.java index f297927..c0fae3f 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Room.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Room.java @@ -2,6 +2,7 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models; import java.util.Set; import javax.persistence.*; +import javax.validation.constraints.NotNull; /** Represents a room in the house owned by the user */ @Entity @@ -18,31 +19,36 @@ public class Room { * https://www.baeldung.com/java-base64-image-string * https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html */ - @Column(name = "icon", nullable = false) + @Lob + @Column(name = "icon", columnDefinition = "TEXT") private byte[] icon; - @Column(name = "image", nullable = false) + @Lob + @Column(name = "image", columnDefinition = "TEXT") private byte[] image; - /** User that owns the house this room is in */ - @ManyToOne - @JoinColumn(name = "user_id", nullable = false, updatable = false, insertable = false) - private User user; - /** * User that owns the house this room is in as a foreign key id. To use when updating and * inserting from a REST call. */ - @Column(name = "user_id") + @NotNull + @Column(name = "user_id", nullable = false) private Long userId; /** The user given name of this room (e.g. 'Master bedroom') */ - @Column private String name; + @NotNull + @Column(nullable = false) + private String name; /** Collection of devices present in this room */ @OneToMany(mappedBy = "room") private Set devices; + /** User that owns the house this room is in */ + @ManyToOne + @JoinColumn(name = "user_id", nullable = false, updatable = false, insertable = false) + private User user; + public Long getId() { return id; } @@ -79,6 +85,22 @@ public class Room { return devices; } + public byte[] getIcon() { + return icon; + } + + public void setIcon(byte[] icon) { + this.icon = icon; + } + + public byte[] getImage() { + return image; + } + + public void setImage(byte[] image) { + this.image = image; + } + @Override public String toString() { return "Room{" + "id=" + id + ", user=" + user + ", name='" + name + "\'}"; diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Sensor.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Sensor.java index e5d7938..e3fbae0 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Sensor.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Sensor.java @@ -1,31 +1,45 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models; +import com.google.gson.annotations.SerializedName; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; +import javax.validation.constraints.NotNull; /** A sensor input device that measures a quantity in a continuous scale (e.g. temperature) */ @Entity public class Sensor extends InputDevice { /** Type of sensor, i.e. of the thing the sensor measures. */ - enum SensorType { + public enum SensorType { /** A sensor that measures temperature in degrees celsius */ + @SerializedName("TEMPERATURE") TEMPERATURE, /** A sensor that measures relative humidity in percentage points */ + @SerializedName("HUMIDITY") HUMIDITY, /** A sensor that measures light in degrees */ + @SerializedName("LIGHT") LIGHT } /** The type of this sensor */ - @Column + @Column(nullable = false) + @NotNull @Enumerated(value = EnumType.STRING) private SensorType sensor; + public SensorType getSensor() { + return sensor; + } + + public void setSensor(SensorType sensor) { + this.sensor = sensor; + } + public Sensor() { super("sensor"); } diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/SmartPlug.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/SmartPlug.java index e7fd36a..e0d7981 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/SmartPlug.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/SmartPlug.java @@ -2,13 +2,15 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models; import javax.persistence.Column; import javax.persistence.Entity; +import javax.validation.constraints.NotNull; /** A smart plug that can be turned either on or off */ @Entity public class SmartPlug extends OutputDevice { /** Whether the smart plug is on */ - @Column(name = "smart_plug_on") + @Column(name = "smart_plug_on", nullable = false) + @NotNull private boolean on; public boolean isOn() { diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/User.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/User.java index 7f9ec95..a8f239c 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/User.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/User.java @@ -2,7 +2,9 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models; import java.util.Set; import javax.persistence.*; +import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; /** A user of the Smarthut application */ @Entity(name = "smarthutuser") @@ -14,16 +16,34 @@ public class User { private Long id; /** The full name of the user */ - @Column @NotNull private String name; + @NotNull + @Column(nullable = false) + @NotEmpty(message = "Please provide a full name") + private String name; /** The full name of the user */ - @Column @NotNull private String username; + @NotNull + @Column(nullable = false) + @NotEmpty(message = "Please provide a username") + private String username; - /** A properly salted way to store the password TODO: define the implementation of salt */ - @Column @NotNull private String password; + /** A properly salted way to store the password */ + @NotNull + @Column(nullable = false) + @NotEmpty(message = "Please provide a password") + private String password; - /** The user's email TODO: validate email in setters */ - @Column @NotNull private String email; + /** + * The user's email (validated according to criteria used in >input type="email"<> + * , technically not RFC 5322 compliant + */ + @Column(nullable = false) + @NotNull + @NotEmpty(message = "Please provide an email") + @Pattern( + message = "Please provide a valid email", + regexp = "^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$") + private String email; /** All rooms in the user's house */ @OneToMany(mappedBy = "user") From 40785d0cf1f00c3055f9e4c77ba92fe198cf91e1 Mon Sep 17 00:00:00 2001 From: Claudio Maggioni Date: Thu, 27 Feb 2020 09:33:03 +0100 Subject: [PATCH 4/5] Better email validation for user and partial update for /auth/update --- .../smarthut/controller/AuthenticationController.java | 11 +++++++---- .../sanmarinoes/smarthut/dto/UserUpdateRequest.java | 9 +++------ .../usi/inf/sa4/sanmarinoes/smarthut/models/User.java | 6 +++--- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/AuthenticationController.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/AuthenticationController.java index f7dee78..ed82692 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/AuthenticationController.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/AuthenticationController.java @@ -49,12 +49,15 @@ public class AuthenticationController { return user; } - @PutMapping("/update") + @PatchMapping("/update") public User update(@Valid @RequestBody final UserUpdateRequest u, final Principal principal) { final User oldUser = userRepository.findByUsername(principal.getName()); - oldUser.setName(u.getName()); - oldUser.setEmail(u.getEmail()); - oldUser.setPassword(encoder.encode(u.getPassword())); + if (u.getName() != null) oldUser.setName(u.getName()); + if (u.getEmail() != null) { + oldUser.setEmail(u.getEmail()); + // TODO: handle email verification + } + if (u.getPassword() != null) oldUser.setPassword(encoder.encode(u.getPassword())); return userRepository.save(oldUser); } diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/dto/UserUpdateRequest.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/dto/UserUpdateRequest.java index 5000bb1..551b84a 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/dto/UserUpdateRequest.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/dto/UserUpdateRequest.java @@ -1,7 +1,7 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.dto; +import javax.validation.constraints.Email; import javax.validation.constraints.NotEmpty; -import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; public class UserUpdateRequest { @@ -10,7 +10,6 @@ public class UserUpdateRequest { private String name; /** A non-salted password */ - @NotNull @NotEmpty(message = "Please provide a password") private String password; @@ -18,11 +17,9 @@ public class UserUpdateRequest { * The user's email (validated according to criteria used in >input type="email"<> * , technically not RFC 5322 compliant */ - @NotNull @NotEmpty(message = "Please provide an email") - @Pattern( - message = "Please provide a valid email", - regexp = "/^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$/") + @Email(message = "Please provide a valid email address") + @Pattern(regexp = ".+@.+\\..+", message = "Please provide a valid email address") private String email; public String getName() { diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/User.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/User.java index a8f239c..62d2cd7 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/User.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/User.java @@ -2,6 +2,7 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models; import java.util.Set; import javax.persistence.*; +import javax.validation.constraints.Email; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; @@ -40,9 +41,8 @@ public class User { @Column(nullable = false) @NotNull @NotEmpty(message = "Please provide an email") - @Pattern( - message = "Please provide a valid email", - regexp = "^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\\.[a-zA-Z0-9-]+)*$") + @Email(message = "Please provide a valid email address") + @Pattern(regexp = ".+@.+\\..+", message = "Please provide a valid email address") private String email; /** All rooms in the user's house */ From f70084dd4004911844fef66c6fcf425d147b6168 Mon Sep 17 00:00:00 2001 From: omenem Date: Thu, 27 Feb 2020 09:40:44 +0100 Subject: [PATCH 5/5] Added minimum length of password --- .idea/misc.xml | 2 +- .../java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/User.java | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index 241f098..7c6191b 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,7 +1,7 @@ - + \ No newline at end of file diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/User.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/User.java index 62d2cd7..e4ce24e 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/User.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/User.java @@ -3,6 +3,7 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models; import java.util.Set; import javax.persistence.*; import javax.validation.constraints.Email; +import javax.validation.constraints.Min; import javax.validation.constraints.NotEmpty; import javax.validation.constraints.NotNull; import javax.validation.constraints.Pattern; @@ -32,6 +33,7 @@ public class User { @NotNull @Column(nullable = false) @NotEmpty(message = "Please provide a password") + @Min(value = 6, message = "Your password should be at least 6 characters long") private String password; /**