Neutralized id value from client in device routes for creation.

Reconfigured Springfox for authentication in device and room routes.
This commit is contained in:
Claudio Maggioni 2020-03-13 15:48:03 +01:00
parent f1fc5a83c1
commit 7bb05b705f
22 changed files with 174 additions and 38 deletions

View file

@ -1,6 +1,5 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.config; package ch.usi.inf.sa4.sanmarinoes.smarthut.config;
import static springfox.documentation.builders.PathSelectors.regex;
import java.util.List; import java.util.List;
import java.util.function.Predicate; import java.util.function.Predicate;
@ -10,10 +9,9 @@ import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder; import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors; import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors; import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo; import springfox.documentation.service.*;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.SecurityScheme;
import springfox.documentation.spi.DocumentationType; import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket; import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2; import springfox.documentation.swagger2.annotations.EnableSwagger2;
@ -39,7 +37,8 @@ public class SpringFoxConfig {
.paths(paths()::test) .paths(paths()::test)
.build() .build()
.apiInfo(apiInfo()) .apiInfo(apiInfo())
.securitySchemes(securitySchemes()); .securitySchemes(securitySchemes())
.securityContexts(List.of(securityContext()));
} }
/** /**
@ -51,14 +50,32 @@ public class SpringFoxConfig {
return List.of(new ApiKey("Bearer", "Authorization", "header")); return List.of(new ApiKey("Bearer", "Authorization", "header"));
} }
/** private SecurityContext securityContext() {
* Return a Java functional API predicate for regex matches return SecurityContext.builder()
* .securityReferences(defaultAuth())
* @param regex the regex to match on .forPaths(authenticatedPaths()::test)
* @return a Java functional API predicate .build();
*/ }
private Predicate<String> regexPredicate(final String regex) {
return regex(regex)::apply; private List<SecurityReference> defaultAuth() {
final AuthorizationScope authorizationScope =
new AuthorizationScope("global", "accessEverything");
return List.of(
new SecurityReference("Bearer", new AuthorizationScope[] {authorizationScope}));
}
private Predicate<String> authenticatedPaths() {
return ((Predicate<String>) PathSelectors.regex("/auth/update")::apply)
.or(PathSelectors.regex("/room.*")::apply)
.or(PathSelectors.regex("/device.*")::apply)
.or(PathSelectors.regex("/buttonDimmer.*")::apply)
.or(PathSelectors.regex("/dimmableLight.*")::apply)
.or(PathSelectors.regex("/knobDimmer.*")::apply)
.or(PathSelectors.regex("/regularLight.*")::apply)
.or(PathSelectors.regex("/sensor.*")::apply)
.or(PathSelectors.regex("/smartPlug.*")::apply)
.or(PathSelectors.regex("/switch.*")::apply)
.or(PathSelectors.regex("/motionSensor.*")::apply);
} }
/** /**

View file

@ -0,0 +1,44 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.controller;
import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.DeviceSaveRequest;
import ch.usi.inf.sa4.sanmarinoes.smarthut.error.BadDataException;
import ch.usi.inf.sa4.sanmarinoes.smarthut.error.NotFoundException;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.Device;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.DeviceRepository;
import ch.usi.inf.sa4.sanmarinoes.smarthut.models.RoomRepository;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
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.RestController;
@RestController
@EnableAutoConfiguration
@RequestMapping("/device")
public class DeviceController {
@Autowired private DeviceRepository<Device> deviceRepository;
@Autowired private RoomRepository roomRepository;
@PutMapping
public Device update(@Valid @RequestBody DeviceSaveRequest deviceSaveRequest)
throws NotFoundException, BadDataException {
final Device d =
deviceRepository
.findById(deviceSaveRequest.getId())
.orElseThrow(NotFoundException::new);
// check if roomId is valid
roomRepository
.findById(deviceSaveRequest.getRoomId())
.orElseThrow(() -> new BadDataException("roomId is not a valid room id"));
d.setRoomId(deviceSaveRequest.getRoomId());
d.setName(deviceSaveRequest.getName());
deviceRepository.save(d);
return d;
}
}

View file

@ -42,6 +42,7 @@ public class DimmableLightController {
@PutMapping @PutMapping
public DimmableLight update(@Valid @RequestBody DimmableLightSaveRequest dl) { public DimmableLight update(@Valid @RequestBody DimmableLightSaveRequest dl) {
dl.setId(0);
return this.create(dl); return this.create(dl);
} }

View file

@ -42,6 +42,7 @@ public class KnobDimmerController {
@PutMapping @PutMapping
public KnobDimmer update(@Valid @RequestBody KnobDimmerSaveRequest kd) { public KnobDimmer update(@Valid @RequestBody KnobDimmerSaveRequest kd) {
kd.setId(0);
return this.create(kd); return this.create(kd);
} }

View file

@ -42,6 +42,7 @@ public class MotionSensorController {
@PutMapping @PutMapping
public MotionSensor update(@Valid @RequestBody MotionSensorSaveRequest ms) { public MotionSensor update(@Valid @RequestBody MotionSensorSaveRequest ms) {
ms.setId(0);
return this.create(ms); return this.create(ms);
} }

View file

@ -49,6 +49,7 @@ public class RegularLightController {
@PutMapping @PutMapping
public RegularLight update(@Valid @RequestBody RegularLightSaveRequest rl) { public RegularLight update(@Valid @RequestBody RegularLightSaveRequest rl) {
rl.setId(0);
return this.create(rl); return this.create(rl);
} }

View file

@ -44,12 +44,12 @@ public class RoomController {
newRoom.setUserId(userId); newRoom.setUserId(userId);
newRoom.setName(r.getName()); newRoom.setName(r.getName());
if (img != null) { if (img != null) {
newRoom.setImage(img.getBytes()); newRoom.setImage(img);
} else if (setWhenNull) { } else if (setWhenNull) {
newRoom.setImage(null); newRoom.setImage(null);
} }
if (icon != null) { if (icon != null) {
newRoom.setIcon(icon.getBytes()); newRoom.setIcon(icon);
} else if (setWhenNull) { } else if (setWhenNull) {
newRoom.setIcon(null); newRoom.setIcon(null);
} }

View file

@ -43,6 +43,7 @@ public class SensorController {
@PutMapping @PutMapping
public Sensor update(@Valid @RequestBody SensorSaveRequest s) { public Sensor update(@Valid @RequestBody SensorSaveRequest s) {
s.setId(0);
return this.create(s); return this.create(s);
} }

View file

@ -42,6 +42,7 @@ public class SmartPlugController {
@PutMapping @PutMapping
public SmartPlug update(@Valid @RequestBody SmartPlugSaveRequest sp) { public SmartPlug update(@Valid @RequestBody SmartPlugSaveRequest sp) {
sp.setId(0);
return this.create(sp); return this.create(sp);
} }

View file

@ -42,6 +42,7 @@ public class SwitchController {
@PutMapping @PutMapping
public Switch update(@Valid @RequestBody SwitchSaveRequest s) { public Switch update(@Valid @RequestBody SwitchSaveRequest s) {
s.setId(0);
return this.create(s); return this.create(s);
} }

View file

@ -1,15 +0,0 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.controller;
import org.springframework.boot.autoconfigure.*;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
@EnableAutoConfiguration
public class WelcomeController {
@GetMapping
ResponseEntity<Void> testConnection() {
return ResponseEntity.ok(null);
}
}

View file

@ -60,4 +60,8 @@ public class ButtonDimmerSaveRequest {
public String getName() { public String getName() {
return name; return name;
} }
public void setId(long id) {
this.id = id;
}
} }

View file

@ -0,0 +1,42 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.dto;
import javax.validation.constraints.NotEmpty;
import javax.validation.constraints.NotNull;
public class DeviceSaveRequest {
/** Device identifier */
private long id;
/**
* The room this device belongs in, as a foreign key id. To use when updating and inserting from
* a REST call.
*/
@NotNull private Long roomId;
/** The name of the device as assigned by the user (e.g. 'Master bedroom light') */
@NotNull @NotEmpty private String name;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public Long getRoomId() {
return roomId;
}
public void setRoomId(Long roomId) {
this.roomId = roomId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

View file

@ -66,4 +66,8 @@ public class DimmableLightSaveRequest {
} }
this.intensity = intensity; this.intensity = intensity;
} }
public void setId(long id) {
this.id = id;
}
} }

View file

@ -48,4 +48,8 @@ public class KnobDimmerSaveRequest {
public Set<DimmableLight> getLights() { public Set<DimmableLight> getLights() {
return lights; return lights;
} }
public void setId(long id) {
this.id = id;
}
} }

View file

@ -44,4 +44,8 @@ public class MotionSensorSaveRequest {
public void setDetected(boolean detected) { public void setDetected(boolean detected) {
this.detected = detected; this.detected = detected;
} }
public void setId(long id) {
this.id = id;
}
} }

View file

@ -45,4 +45,8 @@ public class RegularLightSaveRequest {
public void setOn(boolean on) { public void setOn(boolean on) {
this.on = on; this.on = on;
} }
public void setId(long id) {
this.id = id;
}
} }

View file

@ -78,4 +78,8 @@ public class SensorSaveRequest {
public void setValue(int newValue) { public void setValue(int newValue) {
this.value = newValue; this.value = newValue;
} }
public void setId(long id) {
this.id = id;
}
} }

View file

@ -45,4 +45,8 @@ public class SmartPlugSaveRequest {
public void setOn(boolean on) { public void setOn(boolean on) {
this.on = on; this.on = on;
} }
public void setId(long id) {
this.id = id;
}
} }

View file

@ -45,4 +45,8 @@ public class SwitchSaveRequest {
public void setOn(boolean on) { public void setOn(boolean on) {
this.on = on; this.on = on;
} }
public void setId(long id) {
this.id = id;
}
} }

View file

@ -0,0 +1,11 @@
package ch.usi.inf.sa4.sanmarinoes.smarthut.error;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
@ResponseStatus(code = HttpStatus.BAD_REQUEST)
public class BadDataException extends Exception {
public BadDataException(String message) {
super(message);
}
}

View file

@ -20,13 +20,11 @@ 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
*/ */
@Lob @Column private String icon;
@Column(name = "icon", columnDefinition = "TEXT")
private byte[] icon;
@Lob @Lob
@Column(name = "image", columnDefinition = "TEXT") @Column(name = "image", columnDefinition = "TEXT")
private byte[] image; private String image;
/** /**
* User that owns the house this room is in as a foreign key id. To use when updating and * User that owns the house this room is in as a foreign key id. To use when updating and
@ -65,19 +63,19 @@ public class Room {
this.name = name; this.name = name;
} }
public byte[] getIcon() { public String getIcon() {
return icon; return icon;
} }
public void setIcon(byte[] icon) { public void setIcon(String icon) {
this.icon = icon; this.icon = icon;
} }
public byte[] getImage() { public String getImage() {
return image; return image;
} }
public void setImage(byte[] image) { public void setImage(String image) {
this.image = image; this.image = image;
} }