Merge branch 'cose' into 'dev'

Partial work on input validation and stronger definition of models

See merge request sa4-2020/the-sanmarinoes/backend!8
This commit is contained in:
Claudio Maggioni 2020-02-27 10:46:25 +01:00
commit e4236fa780
21 changed files with 257 additions and 115 deletions

View file

@ -1,7 +1,12 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.controller; package ch.usi.inf.sa4.sanmarinoes.smarthut.controller;
import ch.usi.inf.sa4.sanmarinoes.smarthut.config.JWTTokenUtil; 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 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.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException; import org.springframework.security.authentication.BadCredentialsException;
@ -14,10 +19,12 @@ import org.springframework.web.bind.annotation.*;
@RestController @RestController
@CrossOrigin @CrossOrigin
@RequestMapping("/auth") @RequestMapping("/auth")
public class JWTAuthenticationController { public class AuthenticationController {
@Autowired private AuthenticationManager authenticationManager; @Autowired private AuthenticationManager authenticationManager;
@Autowired private UserRepository userRepository;
@Autowired private JWTTokenUtil jwtTokenUtil; @Autowired private JWTTokenUtil jwtTokenUtil;
@Autowired private JWTUserDetailsService userDetailsService; @Autowired private JWTUserDetailsService userDetailsService;
@ -36,12 +43,24 @@ public class JWTAuthenticationController {
} }
@PostMapping("/register") @PostMapping("/register")
public User register(@RequestBody User user) { public User register(@Valid @RequestBody User user) {
user.setPassword(encoder.encode(user.getPassword())); user.setPassword(encoder.encode(user.getPassword()));
users.save(user); users.save(user);
return user; return user;
} }
@PatchMapping("/update")
public User update(@Valid @RequestBody final UserUpdateRequest u, final Principal principal) {
final User oldUser = userRepository.findByUsername(principal.getName());
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);
}
private void authenticate(String username, String password) throws Exception { private void authenticate(String username, String password) throws Exception {
try { try {
authenticationManager.authenticate( authenticationManager.authenticate(

View file

@ -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.ButtonDimmer;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.ButtonDimmerRepository; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.ButtonDimmerRepository;
import java.util.Optional; import java.util.Optional;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
@ -31,12 +32,12 @@ public class ButtonDimmerController {
} }
@PostMapping @PostMapping
public ButtonDimmer save(@RequestBody ButtonDimmer bd) { public ButtonDimmer save(@Valid @RequestBody ButtonDimmer bd) {
return buttonDimmerService.save(bd); return buttonDimmerService.save(bd);
} }
@PutMapping @PutMapping
public ButtonDimmer update(@RequestBody ButtonDimmer bd) { public ButtonDimmer update(@Valid @RequestBody ButtonDimmer bd) {
return buttonDimmerService.save(bd); return buttonDimmerService.save(bd);
} }

View file

@ -2,7 +2,8 @@ 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.DimmableLight;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.DimmableLightRepository; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.DimmableLightRepository;
import java.util.List; import java.util.Optional;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
@ -22,27 +23,27 @@ public class DimmableLightController {
@Autowired private DimmableLightRepository dimmableLightService; @Autowired private DimmableLightRepository dimmableLightService;
@GetMapping @GetMapping
public List<DimmableLight> getAll() { public Iterable<DimmableLight> findAll() {
return dimmableLightService.getList(); return dimmableLightService.findAll();
} }
@GetMapping("/{id}") @GetMapping("/{id}")
public DimmableLight getById(@PathVariable("id") long id) { public Optional<DimmableLight> findById(@PathVariable("id") long id) {
return dimmableLightService.getById(); return dimmableLightService.findById(id);
} }
@PostMapping @PostMapping
public DimmableLight create(@RequestBody DimmableLight dl) { public DimmableLight save(@Valid @RequestBody DimmableLight dl) {
return dimmableLightService.create(dl); return dimmableLightService.save(dl);
} }
@PutMapping("/{id}") @PutMapping
public DimmableLight update(@PathVariable("id") long id, @RequestBody DimmableLight dl) { public DimmableLight update(@Valid @RequestBody DimmableLight dl) {
return dimmableLightService.update(id, dl); return dimmableLightService.save(dl);
} }
@DeleteMapping("/{id}") @DeleteMapping("/{id}")
public void delete(@PathVariable("id") long id) { public void delete(@PathVariable("id") long id) {
dimmableLightService.delete(id); dimmableLightService.deleteById(id);
} }
} }

View file

@ -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.KnobDimmer;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.KnobDimmerRepository; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.KnobDimmerRepository;
import java.util.Optional; import java.util.Optional;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
@ -32,12 +33,12 @@ public class KnobDimmerController {
} }
@PostMapping @PostMapping
public KnobDimmer save(@RequestBody KnobDimmer kd) { public KnobDimmer save(@Valid @RequestBody KnobDimmer kd) {
return knobDimmerService.save(kd); return knobDimmerService.save(kd);
} }
@PutMapping @PutMapping
public KnobDimmer update(@RequestBody KnobDimmer kd) { public KnobDimmer update(@Valid @RequestBody KnobDimmer kd) {
return knobDimmerService.save(kd); return knobDimmerService.save(kd);
} }

View file

@ -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.MotionSensor;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.MotionSensorRepository; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.MotionSensorRepository;
import java.util.Optional; import java.util.Optional;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
@ -32,12 +33,12 @@ public class MotionSensorController {
} }
@PostMapping @PostMapping
public MotionSensor save(@RequestBody MotionSensor ms) { public MotionSensor save(@Valid @RequestBody MotionSensor ms) {
return motionSensorService.save(ms); return motionSensorService.save(ms);
} }
@PutMapping @PutMapping
public MotionSensor update(@RequestBody MotionSensor ms) { public MotionSensor update(@Valid @RequestBody MotionSensor ms) {
return motionSensorService.save(ms); return motionSensorService.save(ms);
} }

View file

@ -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.RegularLight;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.RegularLightRepository; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.RegularLightRepository;
import java.util.Optional; import java.util.Optional;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.DeleteMapping;
@ -32,12 +33,12 @@ public class RegularLightController {
} }
@PostMapping @PostMapping
public RegularLight save(@RequestBody RegularLight rl) { public RegularLight save(@Valid @RequestBody RegularLight rl) {
return regularLightService.save(rl); return regularLightService.save(rl);
} }
@PutMapping @PutMapping
public RegularLight update(@RequestBody RegularLight rl) { public RegularLight update(@Valid @RequestBody RegularLight rl) {
return regularLightService.save(rl); return regularLightService.save(rl);
} }

View file

@ -2,8 +2,11 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.controller;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*;
import java.util.*; import java.util.*;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.*; 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.*; import org.springframework.web.bind.annotation.*;
@RestController @RestController
@ -13,6 +16,8 @@ public class RoomController {
@Autowired private RoomRepository roomRepository; @Autowired private RoomRepository roomRepository;
@Autowired private UserRepository userRepository;
@GetMapping @GetMapping
public Iterable<Room> findAll() { public Iterable<Room> findAll() {
return roomRepository.findAll(); return roomRepository.findAll();
@ -24,12 +29,25 @@ public class RoomController {
} }
@PostMapping @PostMapping
public Room save(@RequestBody Room r) { public Room save(@Valid @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); return roomRepository.save(r);
} }
@PutMapping @PutMapping
public Room update(@RequestBody Room r) { public Room update(@Valid @RequestBody Room r) {
return roomRepository.save(r); return roomRepository.save(r);
} }

View file

@ -2,6 +2,7 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.controller;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*;
import java.util.*; import java.util.*;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.*; import org.springframework.boot.autoconfigure.*;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -24,12 +25,12 @@ public class SensorController {
} }
@PostMapping @PostMapping
public Sensor save(@RequestBody Sensor s) { public Sensor save(@Valid @RequestBody Sensor s) {
return sensorRepository.save(s); return sensorRepository.save(s);
} }
@PutMapping @PutMapping
public Sensor update(@RequestBody Sensor s) { public Sensor update(@Valid @RequestBody Sensor s) {
return sensorRepository.save(s); return sensorRepository.save(s);
} }

View file

@ -2,6 +2,7 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.controller;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*;
import java.util.*; import java.util.*;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.*; import org.springframework.boot.autoconfigure.*;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -24,12 +25,12 @@ public class SmartPlugController {
} }
@PostMapping @PostMapping
public SmartPlug save(@RequestBody SmartPlug sp) { public SmartPlug save(@Valid @RequestBody SmartPlug sp) {
return smartPlugRepository.save(sp); return smartPlugRepository.save(sp);
} }
@PutMapping @PutMapping
public SmartPlug update(@RequestBody SmartPlug sp) { public SmartPlug update(@Valid @RequestBody SmartPlug sp) {
return smartPlugRepository.save(sp); return smartPlugRepository.save(sp);
} }

View file

@ -2,6 +2,7 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.controller;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*;
import java.util.*; import java.util.*;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.*; import org.springframework.boot.autoconfigure.*;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -24,12 +25,12 @@ public class SwitchController {
} }
@PostMapping @PostMapping
public Switch save(@RequestBody Switch s) { public Switch save(@Valid @RequestBody Switch s) {
return switchRepository.save(s); return switchRepository.save(s);
} }
@PutMapping @PutMapping
public Switch update(@RequestBody Switch s) { public Switch update(@Valid @RequestBody Switch s) {
return switchRepository.save(s); return switchRepository.save(s);
} }

View file

@ -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<User> findAll() {
return userRepository.findAll();
}
@GetMapping("/{id}")
public Optional<User> 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);
}
}

View file

@ -1,17 +1,9 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.models; package ch.usi.inf.sa4.sanmarinoes.smarthut.dto;
public class JWTRequest { public class JWTRequest {
private String username; private String username;
private String password; 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() { public String getUsername() {
return this.username; return this.username;
} }

View file

@ -1,4 +1,4 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.models; package ch.usi.inf.sa4.sanmarinoes.smarthut.dto;
public class JWTResponse { public class JWTResponse {
private final String jwttoken; private final String jwttoken;

View file

@ -0,0 +1,48 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.dto;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
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 */
@NotEmpty(message = "Please provide a password")
private String password;
/**
* The user's email (validated according to criteria used in <code>&gt;input type="email"&lt;>
* </code>, technically not RFC 5322 compliant
*/
@NotEmpty(message = "Please provide an email")
@Email(message = "Please provide a valid email address")
@Pattern(regexp = ".+@.+\\..+", message = "Please provide a valid email address")
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;
}
}

View file

@ -1,6 +1,8 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.models; package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
import com.google.gson.annotations.SerializedName;
import javax.persistence.*; import javax.persistence.*;
import javax.validation.constraints.NotNull;
/** Generic abstraction for a smart home device */ /** Generic abstraction for a smart home device */
@Entity @Entity
@ -9,7 +11,10 @@ public abstract class Device {
/** Ways a device can behave in the automation flow. For now only input/output */ /** Ways a device can behave in the automation flow. For now only input/output */
public enum FlowType { public enum FlowType {
@SerializedName("INPUT")
INPUT, INPUT,
@SerializedName("OUTPUT")
OUTPUT OUTPUT
} }
@ -21,11 +26,21 @@ public abstract class Device {
/** The room this device belongs in */ /** The room this device belongs in */
@ManyToOne @ManyToOne
@JoinColumn(name = "room_id") @JoinColumn(name = "room_id", nullable = false, updatable = false, insertable = false)
private Room room; 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", nullable = false)
@NotNull
private Long roomId;
/** The name of the device as assigned by the user (e.g. 'Master bedroom light') */ /** 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 * The name for the category of this particular device (e.g 'dimmer'). Not stored in the
@ -63,6 +78,14 @@ public abstract class Device {
this.name = name; this.name = name;
} }
public Long getRoomId() {
return roomId;
}
public void setRoomId(Long roomId) {
this.roomId = roomId;
}
public Device(String kind, FlowType flowType) { public Device(String kind, FlowType flowType) {
this.kind = kind; this.kind = kind;
this.flowType = flowType; this.flowType = flowType;

View file

@ -2,6 +2,9 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
/** Represent a dimmable light */ /** Represent a dimmable light */
@Entity @Entity
@ -12,13 +15,17 @@ public class DimmableLight extends Light {
} }
/** The light intensity value. Goes from 0 (off) to 100 (on) */ /** 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; return intensity;
} }
public void setIntensity(int intensity) throws IllegalArgumentException { public void setIntensity(Integer intensity) throws IllegalArgumentException {
if (intensity < 0 || intensity > 100) { if (intensity < 0 || intensity > 100) {
throw new IllegalArgumentException("The intensity level can't go below 0 or above 100"); throw new IllegalArgumentException("The intensity level can't go below 0 or above 100");
} }

View file

@ -4,6 +4,7 @@ import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.Inheritance; import javax.persistence.Inheritance;
import javax.persistence.InheritanceType; import javax.persistence.InheritanceType;
import javax.validation.constraints.NotNull;
/** Represents a generic light */ /** Represents a generic light */
@Entity @Entity
@ -11,7 +12,8 @@ import javax.persistence.InheritanceType;
public abstract class Light extends OutputDevice { public abstract class Light extends OutputDevice {
/** Whether the light is on or not */ /** Whether the light is on or not */
@Column(name = "light_on") @Column(name = "light_on", nullable = false)
@NotNull
boolean on; boolean on;
protected Light(String kind) { protected Light(String kind) {

View file

@ -2,6 +2,7 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
import java.util.Set; import java.util.Set;
import javax.persistence.*; import javax.persistence.*;
import javax.validation.constraints.NotNull;
/** Represents a room in the house owned by the user */ /** Represents a room in the house owned by the user */
@Entity @Entity
@ -18,24 +19,36 @@ public class Room {
* https://www.baeldung.com/java-base64-image-string * https://www.baeldung.com/java-base64-image-string
* https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html * https://docs.oracle.com/javase/8/docs/api/java/util/Base64.html
*/ */
@Column(name = "icon", updatable = true, nullable = false) @Lob
@Column(name = "icon", columnDefinition = "TEXT")
private byte[] icon; private byte[] icon;
@Column(name = "image", updatable = true, nullable = false) @Lob
@Column(name = "image", columnDefinition = "TEXT")
private byte[] image; private byte[] image;
/**
* User that owns the house this room is in as a foreign key id. To use when updating and
* inserting from a REST call.
*/
@NotNull
@Column(name = "user_id", nullable = false)
private Long userId;
/** The user given name of this room (e.g. 'Master bedroom') */
@NotNull
@Column(nullable = false)
private String name;
/** Collection of devices present in this room */
@OneToMany(mappedBy = "room")
private Set<Device> devices;
/** User that owns the house this room is in */ /** User that owns the house this room is in */
@ManyToOne @ManyToOne
@JoinColumn(name = "user_id") @JoinColumn(name = "user_id", nullable = false, updatable = false, insertable = false)
private User user; private User user;
/** The user given name of this room (e.g. 'Master bedroom') */
@Column private String name;
/** Collectiion of devices present in this room */
@OneToMany(mappedBy = "room")
private Set<Device> devices;
public Long getId() { public Long getId() {
return id; return id;
} }
@ -44,6 +57,14 @@ public class Room {
this.id = id; this.id = id;
} }
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public User getUser() { public User getUser() {
return user; return user;
} }
@ -64,18 +85,24 @@ public class Room {
return devices; 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 @Override
public String toString() { public String toString() {
return "Room{" return "Room{" + "id=" + id + ", user=" + user + ", name='" + name + "\'}";
+ "id="
+ id
+ ", user="
+ user
+ ", name='"
+ name
+ '\''
+ ", devices="
+ devices
+ '}';
} }
} }

View file

@ -1,31 +1,45 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.models; package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
import com.google.gson.annotations.SerializedName;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.persistence.EnumType; import javax.persistence.EnumType;
import javax.persistence.Enumerated; import javax.persistence.Enumerated;
import javax.validation.constraints.NotNull;
/** A sensor input device that measures a quantity in a continuous scale (e.g. temperature) */ /** A sensor input device that measures a quantity in a continuous scale (e.g. temperature) */
@Entity @Entity
public class Sensor extends InputDevice { public class Sensor extends InputDevice {
/** Type of sensor, i.e. of the thing the sensor measures. */ /** Type of sensor, i.e. of the thing the sensor measures. */
enum SensorType { public enum SensorType {
/** A sensor that measures temperature in degrees celsius */ /** A sensor that measures temperature in degrees celsius */
@SerializedName("TEMPERATURE")
TEMPERATURE, TEMPERATURE,
/** A sensor that measures relative humidity in percentage points */ /** A sensor that measures relative humidity in percentage points */
@SerializedName("HUMIDITY")
HUMIDITY, HUMIDITY,
/** A sensor that measures light in degrees */ /** A sensor that measures light in degrees */
@SerializedName("LIGHT")
LIGHT LIGHT
} }
/** The type of this sensor */ /** The type of this sensor */
@Column @Column(nullable = false)
@NotNull
@Enumerated(value = EnumType.STRING) @Enumerated(value = EnumType.STRING)
private SensorType sensor; private SensorType sensor;
public SensorType getSensor() {
return sensor;
}
public void setSensor(SensorType sensor) {
this.sensor = sensor;
}
public Sensor() { public Sensor() {
super("sensor"); super("sensor");
} }

View file

@ -2,13 +2,15 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
import javax.persistence.Column; import javax.persistence.Column;
import javax.persistence.Entity; import javax.persistence.Entity;
import javax.validation.constraints.NotNull;
/** A smart plug that can be turned either on or off */ /** A smart plug that can be turned either on or off */
@Entity @Entity
public class SmartPlug extends OutputDevice { public class SmartPlug extends OutputDevice {
/** Whether the smart plug is on */ /** Whether the smart plug is on */
@Column(name = "smart_plug_on") @Column(name = "smart_plug_on", nullable = false)
@NotNull
private boolean on; private boolean on;
public boolean isOn() { public boolean isOn() {

View file

@ -2,7 +2,11 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models;
import java.util.Set; import java.util.Set;
import javax.persistence.*; 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.NotNull;
import javax.validation.constraints.Pattern;
/** A user of the Smarthut application */ /** A user of the Smarthut application */
@Entity(name = "smarthutuser") @Entity(name = "smarthutuser")
@ -14,16 +18,34 @@ public class User {
private Long id; private Long id;
/** The full name of the user */ /** 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 */ /** 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 */ /** A properly salted way to store the password */
@Column @NotNull private String password; @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;
/** The user's email TODO: validate email in setters */ /**
@Column @NotNull private String email; * The user's email (validated according to criteria used in <code>&gt;input type="email"&lt;>
* </code>, technically not RFC 5322 compliant
*/
@Column(nullable = false)
@NotNull
@NotEmpty(message = "Please provide an email")
@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 */ /** All rooms in the user's house */
@OneToMany(mappedBy = "user") @OneToMany(mappedBy = "user")