From 24fa574c63e16402c21d5d3ed9e28f41d74e3c89 Mon Sep 17 00:00:00 2001 From: Claudio Maggioni Date: Thu, 12 Mar 2020 16:57:50 +0100 Subject: [PATCH 01/29] Added email confirmation test --- build.gradle | 1 + .../models/ConfirmationTokenRepository.java | 2 + .../smarthut/AuthenticationTests.java | 36 ++++++++------- .../sanmarinoes/smarthut/SmartHutTest.java | 44 +++++++++++++++++++ src/test/resources/application.properties | 2 +- 5 files changed, 69 insertions(+), 16 deletions(-) diff --git a/build.gradle b/build.gradle index 5140ea7..303f5e7 100644 --- a/build.gradle +++ b/build.gradle @@ -32,6 +32,7 @@ dependencies { compile 'io.springfox:springfox-swagger2:2.9.2' compile 'io.springfox:springfox-swagger-ui:2.9.2' compile 'org.springframework.boot:spring-boot-configuration-processor' + testCompile 'org.springframework.boot:spring-boot-starter-webflux' implementation('org.springframework.boot:spring-boot-starter-web') { exclude group: 'org.springframework.boot', module: 'spring-boot-starter-json' diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/ConfirmationTokenRepository.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/ConfirmationTokenRepository.java index 9bf3791..40c6a17 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/ConfirmationTokenRepository.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/ConfirmationTokenRepository.java @@ -6,6 +6,8 @@ import org.springframework.data.repository.CrudRepository; public interface ConfirmationTokenRepository extends CrudRepository { ConfirmationToken findByConfirmationToken(String confirmationToken); + ConfirmationToken findByUser(User user); + @Transactional void deleteByUserAndResetPassword(User user, boolean resetPassword); } diff --git a/src/test/java/ch/usi/inf/sa4/sanmarinoes/smarthut/AuthenticationTests.java b/src/test/java/ch/usi/inf/sa4/sanmarinoes/smarthut/AuthenticationTests.java index 60761cd..d13104f 100644 --- a/src/test/java/ch/usi/inf/sa4/sanmarinoes/smarthut/AuthenticationTests.java +++ b/src/test/java/ch/usi/inf/sa4/sanmarinoes/smarthut/AuthenticationTests.java @@ -8,6 +8,8 @@ import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.OkResponse; import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.UserRegistrationRequest; import ch.usi.inf.sa4.sanmarinoes.smarthut.error.DuplicateRegistrationException; import ch.usi.inf.sa4.sanmarinoes.smarthut.error.UnauthorizedException; +import ch.usi.inf.sa4.sanmarinoes.smarthut.models.ConfirmationTokenRepository; +import ch.usi.inf.sa4.sanmarinoes.smarthut.models.UserRepository; import com.google.gson.JsonArray; import com.google.gson.JsonObject; import java.util.Map; @@ -25,6 +27,10 @@ public class AuthenticationTests extends SmartHutTest { @Autowired private TestRestTemplate restTemplate; + @Autowired private UserRepository userRepository; + + @Autowired private ConfirmationTokenRepository tokenRepository; + private UserRegistrationRequest getDisabledUser() { final UserRegistrationRequest disabledUser = new UserRegistrationRequest(); disabledUser.setName("Disabled User"); @@ -34,15 +40,6 @@ public class AuthenticationTests extends SmartHutTest { return disabledUser; } - private static final UserRegistrationRequest enabledUser = new UserRegistrationRequest(); - - static { - enabledUser.setName("Enabled User"); - enabledUser.setEmail("enabled@example.com"); - enabledUser.setUsername("enabled"); - enabledUser.setPassword("password"); - } - @Override protected void setUp() { final ResponseEntity res = @@ -50,12 +47,7 @@ public class AuthenticationTests extends SmartHutTest { this.url("/register"), getDisabledUser(), OkResponse.class); assertThat(res.getStatusCode().equals(HttpStatus.OK)); - final ResponseEntity res2 = - this.restTemplate.postForEntity( - this.url("/register"), enabledUser, OkResponse.class); - assertThat(res2.getStatusCode().equals(HttpStatus.OK)); - - // TODO: email confirmation for enabledUser + registerTestUser(restTemplate, userRepository, tokenRepository); } @Test @@ -230,4 +222,18 @@ public class AuthenticationTests extends SmartHutTest { assertThat(res.getBody() != null); assertThat(res.getBody().isUserDisabled()); } + + @Test + public void loginShouldReturnTokenWithEnabledUser() { + final JWTRequest request = new JWTRequest(); + request.setUsernameOrEmail("enabled"); + request.setPassword("password"); + + final ResponseEntity res = + this.restTemplate.postForEntity(url("/auth/login"), request, JWTResponse.class); + assertThat(res.getStatusCode().equals(HttpStatus.OK)); + assertThat(res.getBody() != null); + assertThat(res.getBody().getToken() != null); + assertThat(!res.getBody().getToken().isEmpty()); + } } diff --git a/src/test/java/ch/usi/inf/sa4/sanmarinoes/smarthut/SmartHutTest.java b/src/test/java/ch/usi/inf/sa4/sanmarinoes/smarthut/SmartHutTest.java index 5c6e097..f2b737a 100644 --- a/src/test/java/ch/usi/inf/sa4/sanmarinoes/smarthut/SmartHutTest.java +++ b/src/test/java/ch/usi/inf/sa4/sanmarinoes/smarthut/SmartHutTest.java @@ -1,6 +1,18 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut; +import static org.assertj.core.api.Assertions.assertThat; + +import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.OkResponse; +import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.UserRegistrationRequest; +import ch.usi.inf.sa4.sanmarinoes.smarthut.models.ConfirmationToken; +import ch.usi.inf.sa4.sanmarinoes.smarthut.models.ConfirmationTokenRepository; +import ch.usi.inf.sa4.sanmarinoes.smarthut.models.User; +import ch.usi.inf.sa4.sanmarinoes.smarthut.models.UserRepository; import org.junit.jupiter.api.BeforeEach; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.reactive.function.client.WebClient; public abstract class SmartHutTest { private boolean setupDone = false; @@ -15,6 +27,38 @@ public abstract class SmartHutTest { protected void setUp() {} + protected static final UserRegistrationRequest enabledUser = new UserRegistrationRequest(); + + static { + enabledUser.setName("Enabled User"); + enabledUser.setEmail("enabled@example.com"); + enabledUser.setUsername("enabled"); + enabledUser.setPassword("password"); + } + + protected void registerTestUser( + final TestRestTemplate restTemplate, + final UserRepository userRepository, + final ConfirmationTokenRepository tokenRepository) { + final ResponseEntity res2 = + restTemplate.postForEntity(this.url("/register"), enabledUser, OkResponse.class); + assertThat(res2.getStatusCode().equals(HttpStatus.OK)); + + final User persistedEnabledUser = userRepository.findByUsername("enabled"); + final ConfirmationToken token = tokenRepository.findByUser(persistedEnabledUser); + + final ResponseEntity res3 = + WebClient.create(getBaseURL()) + .get() + .uri("/register/confirm-account?token=" + token.getConfirmationToken()) + .retrieve() + .toBodilessEntity() + .block(); + + assertThat(res3.getStatusCode().is2xxSuccessful()); + assertThat(userRepository.findByUsername("enabled").getEnabled()); + } + @BeforeEach void setUpHack() { if (!setupDone) { diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index ce6fe39..673d02a 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -28,7 +28,7 @@ server.port = 2000 email.registrationSubject=Complete your SmartHut.sm registration email.registration=To confirm your registration, please click here: -email.registrationPath=http://localhost:8080/register/confirm-account?token= +email.registrationPath=http://localhost:2000/register/confirm-account?token= email.resetpasswordSubject=SmartHut.sm password reset email.resetpassword=To reset your password, please click here: From ac92344b5382b9be2642cf05b3e9f87e16dc9cb5 Mon Sep 17 00:00:00 2001 From: Jacob Salvi Date: Mon, 16 Mar 2020 14:28:35 +0100 Subject: [PATCH 02/29] added tags: dind --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 948be0a..1b4f442 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -11,6 +11,8 @@ stages: smarthut_deploy: stage: deploy image: docker:latest + tags: + - dind services: - docker:dind variables: From 23edc90b815cb896bf8adadd8674557e09d0fa80 Mon Sep 17 00:00:00 2001 From: Claudio Maggioni Date: Mon, 16 Mar 2020 14:53:07 +0100 Subject: [PATCH 03/29] Fixed @tommi27 uniqueness frenzy for rooms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I have now discovered the Schadenfreude in using git-blame. To quote an old commit message from high school: [Trascrizione domande fisica e correzione di GRAVISSIMI bug presenti nel codici di Maggioni](https://gitlab.com/staccastacca/scuolatest/-/commit/dd0933def0262ce1ca2f2b006d4f7a364fb17272) ``` La trascrizione dei test è stata fatta in modo certosino, simile a quello dei monaci emanuensi. I GRAVISSIMI buggg (3 g perchè fa faigo) potevano rendere il sito incomprensibile ``` --- .gitlab-ci.yml | 2 ++ .../usi/inf/sa4/sanmarinoes/smarthut/models/Device.java | 8 ++------ .../ch/usi/inf/sa4/sanmarinoes/smarthut/models/Room.java | 2 +- 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fc62202..2250a03 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -11,6 +11,8 @@ stages: smarthut_deploy: stage: deploy image: docker:latest + tags: + - dind services: - docker:dind variables: 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 c564914..6d0333d 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 @@ -49,17 +49,13 @@ public abstract class Device { * The name for the category of this particular device (e.g 'dimmer'). Not stored in the * database but set thanks to constructors */ - @ApiModelProperty(hidden = true) - @Transient - private final String kind; + @Transient private final String kind; /** * The way this device behaves in the automation flow. Not stored in the database but set thanks * to constructors */ - @ApiModelProperty(hidden = true) - @Transient - private final FlowType flowType; + @Transient private final FlowType flowType; public long getId() { return id; 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 68c3fc0..a30e4f8 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 @@ -139,7 +139,7 @@ public class Room { * inserting from a REST call. */ @NotNull - @Column(name = "user_id", nullable = false, unique = true) + @Column(name = "user_id", nullable = false) private Long userId; /** The user given name of this room (e.g. 'Master bedroom') */ From 2b65198df7c110d8632865da53ca226d8eb9db8b Mon Sep 17 00:00:00 2001 From: tommi27 Date: Mon, 16 Mar 2020 17:01:21 +0100 Subject: [PATCH 04/29] updated smartplug --- .../smarthut/models/SmartPlug.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) 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 fe936b3..533f394 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 @@ -1,5 +1,8 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; import javax.persistence.Column; import javax.persistence.Entity; import javax.validation.constraints.NotNull; @@ -8,11 +11,42 @@ import javax.validation.constraints.NotNull; @Entity public class SmartPlug extends Switchable { + /** The total amount of power that the smart plug has consumed represented in kW/h */ + @Column @NotNull private static double totalConsumption; + /** Whether the smart plug is on */ @Column(name = "smart_plug_on", nullable = false) @NotNull private boolean on; + public double getTotalConsumption() { + return totalConsumption; + } + + public void resetTotalConsumption() { + totalConsumption = 0; + } + + /** + * Updates the consumption of a smart plug storing it in kW/h assuming that an average smart + * plug consumes 3W and by computing the conversion from watts to kW/h + */ + private static void updateTotalConsumption() { + double averageConsumption = 3; + totalConsumption += (averageConsumption / 1000) * (1 / 3600); + } + + /** Calls updateTotalConsumption every second */ + public void updateConsumptionOverTime() { + final ScheduledExecutorService executorService = + Executors.newSingleThreadScheduledExecutor(); + + while (isOn()) { + executorService.scheduleAtFixedRate( + SmartPlug::updateTotalConsumption, 0, 1, TimeUnit.SECONDS); + } + } + @Override public boolean isOn() { return on; From e8f90c832d9bd298bc0b725e3f579b6aaf4eca29 Mon Sep 17 00:00:00 2001 From: Jacob Salvi Date: Tue, 17 Mar 2020 13:52:30 +0100 Subject: [PATCH 05/29] added tags: dind, also I am an idiot --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1b4f442..b618db2 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -53,6 +53,7 @@ test: #Runs a quality check on the code and creates a report on the codes code_quality: stage: code_quality + allow_failure: true script: - gradle cpdCheck artifacts: From 21bf76027fb399317bea1d2e1c12320ddd3cff35 Mon Sep 17 00:00:00 2001 From: Jacob Salvi Date: Tue, 17 Mar 2020 14:13:34 +0100 Subject: [PATCH 06/29] idk --- build.gradle | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/build.gradle b/build.gradle index 8ef658c..3116923 100644 --- a/build.gradle +++ b/build.gradle @@ -1,20 +1,18 @@ plugins { id 'org.springframework.boot' version '2.2.4.RELEASE' id 'io.spring.dependency-management' version '1.0.9.RELEASE' + id "de.aaschmid.cpd" version "3.1" id 'java' } - -group = 'ch.usi.inf.sa4.sanmarinoes.' +group = 'ch.usi.inf.sa4.sanmarinoes' version = '0.0.1-SNAPSHOT' -sourceCompatibility = "11" - +sourceCompatibility = '11' repositories { mavenCentral() - jcenter() } - dependencies { compile 'org.hibernate.javax.persistence:hibernate-jpa-2.1-api:1.0.0.Final' + compile "org.springframework.boot:spring-boot-starter-websocket" implementation 'org.springframework.boot:spring-boot-starter' implementation 'com.sun.mail:javax.mail:1.6.2' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' @@ -30,22 +28,17 @@ dependencies { compile 'io.springfox:springfox-swagger-ui:2.9.2' compile 'org.springframework.boot:spring-boot-configuration-processor' testCompile 'org.springframework.boot:spring-boot-starter-webflux' - implementation('org.springframework.boot:spring-boot-starter-web') { exclude group: 'org.springframework.boot', module: 'spring-boot-starter-json' } - testImplementation('org.springframework.boot:spring-boot-starter-test') { exclude group: 'org.junit.vintage', module: 'junit-vintage-engine' } - testImplementation 'org.springframework.security:spring-security-test' testImplementation 'com.h2database:h2:1.4.200' - // Fixes https://stackoverflow.com/a/60455550 testImplementation group: 'org.apache.httpcomponents', name: 'httpclient', version: '4.5.11' } - test { useJUnitPlatform() -} +} \ No newline at end of file From 835c9e047199105043d71fe44c4692802bb69024 Mon Sep 17 00:00:00 2001 From: Claudio Maggioni Date: Tue, 17 Mar 2020 16:54:35 +0100 Subject: [PATCH 07/29] Fixed smaal errors @tommi27 implementation. Fixed precision and scale values or total precision. Optimized update by using JPQL --- .../controller/SmartPlugController.java | 15 +++++++- .../sanmarinoes/smarthut/models/Device.java | 2 +- .../sanmarinoes/smarthut/models/Sensor.java | 2 +- .../smarthut/models/SmartPlug.java | 38 ++++++------------- .../smarthut/models/SmartPlugRepository.java | 23 ++++++++++- ...ensorUpdateTasks.java => UpdateTasks.java} | 25 +++++++++--- .../smarthut/socket/SensorSocketEndpoint.java | 6 +++ src/main/resources/application.properties | 2 +- 8 files changed, 76 insertions(+), 37 deletions(-) rename src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/scheduled/{SensorUpdateTasks.java => UpdateTasks.java} (74%) 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 8a57430..32bdf33 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 @@ -5,6 +5,7 @@ import static ch.usi.inf.sa4.sanmarinoes.smarthut.utils.Utils.toList; import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.SmartPlugSaveRequest; import ch.usi.inf.sa4.sanmarinoes.smarthut.error.NotFoundException; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; +import java.security.Principal; import java.util.*; import java.util.List; import javax.validation.Valid; @@ -14,7 +15,7 @@ import org.springframework.web.bind.annotation.*; @RestController @EnableAutoConfiguration -@RequestMapping("/smartplug") +@RequestMapping("/smartPlug") public class SmartPlugController { @Autowired private SmartPlugRepository smartPlugRepository; @@ -49,6 +50,18 @@ public class SmartPlugController { smartPlugRepository.findById(sp.getId()).orElseThrow(NotFoundException::new), sp); } + @DeleteMapping("/{id}/meter") + public SmartPlug resetMeter(@PathVariable("id") long id, final Principal principal) + throws NotFoundException { + final SmartPlug s = + smartPlugRepository + .findByIdAndUsername(id, principal.getName()) + .orElseThrow(NotFoundException::new); + + s.resetTotalConsumption(); + return smartPlugRepository.save(s); + } + @DeleteMapping("/{id}") public void deleteById(@PathVariable("id") long id) { smartPlugRepository.deleteById(id); 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 6d0333d..295fe37 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 @@ -36,7 +36,7 @@ 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", nullable = false, unique = true) + @Column(name = "room_id", nullable = false) @NotNull private Long roomId; 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 525ceb3..6b5e6b9 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 @@ -35,7 +35,7 @@ public class Sensor extends InputDevice { } /** The value of this sensor according to its sensor type */ - @Column(nullable = false, length = 10, precision = 1) + @Column(nullable = false, precision = 11, scale = 1) private BigDecimal value; /** The type of this 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 533f394..4411dc3 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 @@ -1,8 +1,6 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; +import java.math.BigDecimal; import javax.persistence.Column; import javax.persistence.Entity; import javax.validation.constraints.NotNull; @@ -11,40 +9,26 @@ import javax.validation.constraints.NotNull; @Entity public class SmartPlug extends Switchable { - /** The total amount of power that the smart plug has consumed represented in kW/h */ - @Column @NotNull private static double totalConsumption; + /** The average consumption of an active plug when on in Watt */ + public static final Double AVERAGE_CONSUMPTION_KW = 200.0; + + /** The total amount of power that the smart plug has consumed represented in W/h */ + @Column(precision = 13, scale = 3) + @NotNull + private BigDecimal totalConsumption = BigDecimal.ZERO; /** Whether the smart plug is on */ @Column(name = "smart_plug_on", nullable = false) @NotNull private boolean on; - public double getTotalConsumption() { + public BigDecimal getTotalConsumption() { return totalConsumption; } + /** Resets the consuption meter */ public void resetTotalConsumption() { - totalConsumption = 0; - } - - /** - * Updates the consumption of a smart plug storing it in kW/h assuming that an average smart - * plug consumes 3W and by computing the conversion from watts to kW/h - */ - private static void updateTotalConsumption() { - double averageConsumption = 3; - totalConsumption += (averageConsumption / 1000) * (1 / 3600); - } - - /** Calls updateTotalConsumption every second */ - public void updateConsumptionOverTime() { - final ScheduledExecutorService executorService = - Executors.newSingleThreadScheduledExecutor(); - - while (isOn()) { - executorService.scheduleAtFixedRate( - SmartPlug::updateTotalConsumption, 0, 1, TimeUnit.SECONDS); - } + totalConsumption = BigDecimal.ZERO; } @Override diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/SmartPlugRepository.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/SmartPlugRepository.java index 08d145d..8a02243 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/SmartPlugRepository.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/SmartPlugRepository.java @@ -1,3 +1,24 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models; -public interface SmartPlugRepository extends SwitchableRepository {} +import java.util.Collection; +import javax.transaction.Transactional; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; + +public interface SmartPlugRepository extends SwitchableRepository { + @Transactional + Collection findByOn(boolean on); + + /** + * Updates total consumption of all activated smart plugs by considering a load of + * fakeConsumption W. This query must be executed every second + * + * @see ch.usi.inf.sa4.sanmarinoes.smarthut.scheduled.UpdateTasks + * @param fakeConsumption the fake consumption in watts + */ + @Modifying(clearAutomatically = true) + @Transactional + @Query( + "UPDATE SmartPlug s SET totalConsumption = s.totalConsumption + ?1 / 3600.0 WHERE s.on = true") + void updateTotalConsumption(Double fakeConsumption); +} diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/scheduled/SensorUpdateTasks.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/scheduled/UpdateTasks.java similarity index 74% rename from src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/scheduled/SensorUpdateTasks.java rename to src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/scheduled/UpdateTasks.java index b1614aa..932db5c 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/scheduled/SensorUpdateTasks.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/scheduled/UpdateTasks.java @@ -2,10 +2,10 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.scheduled; import ch.usi.inf.sa4.sanmarinoes.smarthut.controller.MotionSensorController; import ch.usi.inf.sa4.sanmarinoes.smarthut.controller.SensorController; -import ch.usi.inf.sa4.sanmarinoes.smarthut.models.MotionSensorRepository; -import ch.usi.inf.sa4.sanmarinoes.smarthut.models.Sensor; -import ch.usi.inf.sa4.sanmarinoes.smarthut.models.SensorRepository; +import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; +import ch.usi.inf.sa4.sanmarinoes.smarthut.socket.SensorSocketEndpoint; import java.math.BigDecimal; +import java.util.Collection; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; import java.util.stream.StreamSupport; @@ -13,18 +13,25 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.stereotype.Component; -/** Generates fake sensor (and motion sensor) updates as required by milestone one */ +/** + * Generates fake sensor (and motion sensor) and smart plug consumption updates as required by + * milestone one + */ @Component -public class SensorUpdateTasks { +public class UpdateTasks { @Autowired private SensorRepository sensorRepository; @Autowired private MotionSensorRepository motionSensorRepository; + @Autowired private SmartPlugRepository smartPlugRepository; + @Autowired private SensorController sensorController; @Autowired private MotionSensorController motionSensorController; + @Autowired private SensorSocketEndpoint sensorSocketEndpoint; + /** Generates fake sensor updates every two seconds with a +/- 1.25% error */ @Scheduled(fixedRate = 2000) public void sensorFakeUpdate() { @@ -59,4 +66,12 @@ public class SensorUpdateTasks { sensor, false)); }); } + + /** Updates power consumption of all activated smart plugs every second */ + @Scheduled(fixedDelay = 1000) + public void smartPlugConsumptionFakeUpdate() { + smartPlugRepository.updateTotalConsumption(SmartPlug.AVERAGE_CONSUMPTION_KW); + final Collection c = smartPlugRepository.findByOn(true); + c.forEach(s -> sensorSocketEndpoint.broadcast(s, sensorRepository.findUser(s.getId()))); + } } diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/socket/SensorSocketEndpoint.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/socket/SensorSocketEndpoint.java index bc2f90e..f1e4808 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/socket/SensorSocketEndpoint.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/socket/SensorSocketEndpoint.java @@ -61,6 +61,12 @@ public class SensorSocketEndpoint extends Endpoint { final Collection sessions = authorizedClients.get(u); return sessions.stream() .parallel() + .filter( + s -> { + if (s.isOpen()) return true; + sessions.remove(s); + return false; + }) .filter(didThrow(s -> s.getBasicRemote().sendText(gson.toJson(message)))) .count(); } diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index f760ec8..2fb519c 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -5,7 +5,7 @@ spring.datasource.password= # Hibernate properties spring.jpa.database=POSTGRESQL -spring.jpa.show-sql=true +spring.jpa.show-sql=false spring.jpa.hibernate.ddl-auto=update spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl spring.jpa.properties.hibernate.format_sql=true From 35540fac80a85cc83cfea4753eed9d37ea323ab9 Mon Sep 17 00:00:00 2001 From: tommi27 Date: Tue, 17 Mar 2020 17:38:26 +0100 Subject: [PATCH 08/29] controllers now check if devices belong to the correct user --- .../controller/ButtonDimmerController.java | 8 ++++++-- .../smarthut/controller/DeviceController.java | 7 ++++--- .../controller/DimmableLightController.java | 9 +++++++-- .../smarthut/controller/KnobDimmerController.java | 8 ++++++-- .../controller/RegularLightController.java | 9 +++++++-- .../smarthut/controller/SmartPlugController.java | 9 +++++++-- .../smarthut/controller/SwitchController.java | 9 +++++++-- .../smarthut/models/RoomRepository.java | 15 ++++++++++++++- 8 files changed, 58 insertions(+), 16 deletions(-) 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 061c6b9..944bd8e 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 @@ -6,6 +6,7 @@ import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.ButtonDimmerDimRequest; import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.GenericDeviceSaveReguest; import ch.usi.inf.sa4.sanmarinoes.smarthut.error.NotFoundException; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; +import java.security.Principal; import java.util.List; import java.util.Set; import javax.validation.Valid; @@ -52,10 +53,13 @@ public class ButtonDimmerController } @PutMapping("/dim") - public Set dim(@Valid @RequestBody final ButtonDimmerDimRequest bd) + public Set dim( + @Valid @RequestBody final ButtonDimmerDimRequest bd, final Principal principal) throws NotFoundException { final ButtonDimmer buttonDimmer = - buttonDimmerRepository.findById(bd.getId()).orElseThrow(NotFoundException::new); + buttonDimmerRepository + .findByIdAndUsername(bd.getId(), principal.getName()) + .orElseThrow(NotFoundException::new); switch (bd.getDimType()) { case UP: diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/DeviceController.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/DeviceController.java index 2d8dd99..17bdec7 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/DeviceController.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/DeviceController.java @@ -27,16 +27,17 @@ public class DeviceController { } @PutMapping - public Device update(@Valid @RequestBody DeviceSaveRequest deviceSaveRequest) + public Device update( + @Valid @RequestBody DeviceSaveRequest deviceSaveRequest, final Principal principal) throws NotFoundException, BadDataException { final Device d = deviceRepository - .findById(deviceSaveRequest.getId()) + .findByIdAndUsername(deviceSaveRequest.getId(), principal.getName()) .orElseThrow(NotFoundException::new); // check if roomId is valid roomRepository - .findById(deviceSaveRequest.getRoomId()) + .findByIdAndUsername(deviceSaveRequest.getRoomId(), principal.getName()) .orElseThrow(() -> new BadDataException("roomId is not a valid room id")); d.setRoomId(deviceSaveRequest.getRoomId()); 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 dd2e1e3..944b6c2 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 @@ -6,6 +6,7 @@ import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.DimmableLightSaveRequest; import ch.usi.inf.sa4.sanmarinoes.smarthut.error.NotFoundException; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.DimmableLight; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.DimmableLightRepository; +import java.security.Principal; import java.util.List; import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; @@ -43,10 +44,14 @@ public class DimmableLightController { } @PutMapping - public DimmableLight update(@Valid @RequestBody DimmableLightSaveRequest sp) + public DimmableLight update( + @Valid @RequestBody DimmableLightSaveRequest sp, final Principal principal) throws NotFoundException { return save( - dimmableLightService.findById(sp.getId()).orElseThrow(NotFoundException::new), sp); + dimmableLightService + .findByIdAndUsername(sp.getId(), principal.getName()) + .orElseThrow(NotFoundException::new), + sp); } @DeleteMapping("/{id}") 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 9f59889..c15d867 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 @@ -6,6 +6,7 @@ import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.GenericDeviceSaveReguest; import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.KnobDimmerDimRequest; import ch.usi.inf.sa4.sanmarinoes.smarthut.error.NotFoundException; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; +import java.security.Principal; import java.util.List; import java.util.Set; import javax.validation.Valid; @@ -53,10 +54,13 @@ public class KnobDimmerController } @PutMapping("/dimTo") - public Set dimTo(@Valid @RequestBody final KnobDimmerDimRequest bd) + public Set dimTo( + @Valid @RequestBody final KnobDimmerDimRequest bd, final Principal principal) throws NotFoundException { final KnobDimmer dimmer = - knobDimmerRepository.findById(bd.getId()).orElseThrow(NotFoundException::new); + knobDimmerRepository + .findByIdAndUsername(bd.getId(), principal.getName()) + .orElseThrow(NotFoundException::new); dimmer.setLightIntensity(bd.getIntensity()); dimmableLightRepository.saveAll(dimmer.getOutputs()); 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 15ce2e8..e033555 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 @@ -6,6 +6,7 @@ import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.RegularLightSaveRequest; import ch.usi.inf.sa4.sanmarinoes.smarthut.error.NotFoundException; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.RegularLight; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.RegularLightRepository; +import java.security.Principal; import java.util.List; import javax.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; @@ -50,10 +51,14 @@ public class RegularLightController { } @PutMapping - public RegularLight update(@Valid @RequestBody RegularLightSaveRequest rl) + public RegularLight update( + @Valid @RequestBody RegularLightSaveRequest rl, final Principal principal) throws NotFoundException { return save( - regularLightService.findById(rl.getId()).orElseThrow(NotFoundException::new), rl); + regularLightService + .findByIdAndUsername(rl.getId(), principal.getName()) + .orElseThrow(NotFoundException::new), + rl); } @DeleteMapping("/{id}") 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 8a57430..893b85b 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 @@ -5,6 +5,7 @@ import static ch.usi.inf.sa4.sanmarinoes.smarthut.utils.Utils.toList; import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.SmartPlugSaveRequest; import ch.usi.inf.sa4.sanmarinoes.smarthut.error.NotFoundException; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; +import java.security.Principal; import java.util.*; import java.util.List; import javax.validation.Valid; @@ -44,9 +45,13 @@ public class SmartPlugController { } @PutMapping - public SmartPlug update(@Valid @RequestBody SmartPlugSaveRequest sp) throws NotFoundException { + public SmartPlug update(@Valid @RequestBody SmartPlugSaveRequest sp, final Principal principal) + throws NotFoundException { return save( - smartPlugRepository.findById(sp.getId()).orElseThrow(NotFoundException::new), sp); + smartPlugRepository + .findByIdAndUsername(sp.getId(), principal.getName()) + .orElseThrow(NotFoundException::new), + sp); } @DeleteMapping("/{id}") 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 f90108c..fc64ccb 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 @@ -6,6 +6,7 @@ import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.GenericDeviceSaveReguest; import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.SwitchOperationRequest; import ch.usi.inf.sa4.sanmarinoes.smarthut.error.NotFoundException; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; +import java.security.Principal; import java.util.*; import java.util.List; import javax.validation.Valid; @@ -55,9 +56,13 @@ public class SwitchController extends InputDeviceConnectionController operate(@Valid @RequestBody final SwitchOperationRequest sr) + public Set operate( + @Valid @RequestBody final SwitchOperationRequest sr, final Principal principal) throws NotFoundException { - final Switch s = switchRepository.findById(sr.getId()).orElseThrow(NotFoundException::new); + final Switch s = + switchRepository + .findByIdAndUsername(sr.getId(), principal.getName()) + .orElseThrow(NotFoundException::new); switch (sr.getType()) { case ON: diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/RoomRepository.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/RoomRepository.java index 08b4298..b02413d 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/RoomRepository.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/RoomRepository.java @@ -1,5 +1,18 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models; +import java.util.Optional; +import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; -public interface RoomRepository extends CrudRepository {} +public interface RoomRepository extends CrudRepository { + + /** + * Finds a room by their id and a username + * + * @param id the room id + * @param username a User's username + * @return an optional device, empty if none found + */ + @Query("SELECT r FROM Room r JOIN r.user u WHERE r.id = ?1 AND u.username = ?2") + Optional findByIdAndUsername(Long id, String username); +} From ce0edd7287fd149a6b4cadc091468e8f8c39ade3 Mon Sep 17 00:00:00 2001 From: omenem Date: Tue, 17 Mar 2020 17:45:50 +0100 Subject: [PATCH 09/29] KnobDimmer Tests --- .../sanmarinoes/smarthut/KnobDimmerTests.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/test/java/ch/usi/inf/sa4/sanmarinoes/smarthut/KnobDimmerTests.java diff --git a/src/test/java/ch/usi/inf/sa4/sanmarinoes/smarthut/KnobDimmerTests.java b/src/test/java/ch/usi/inf/sa4/sanmarinoes/smarthut/KnobDimmerTests.java new file mode 100644 index 0000000..155242d --- /dev/null +++ b/src/test/java/ch/usi/inf/sa4/sanmarinoes/smarthut/KnobDimmerTests.java @@ -0,0 +1,46 @@ +package ch.usi.inf.sa4.sanmarinoes.smarthut; + +import static org.junit.jupiter.api.Assertions.*; + +import ch.usi.inf.sa4.sanmarinoes.smarthut.models.DimmableLight; +import ch.usi.inf.sa4.sanmarinoes.smarthut.models.KnobDimmer; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; + +@DisplayName("A Knob Dimmer") +public class KnobDimmerTests { + + KnobDimmer knobDimmer; + + @BeforeEach + public void createNewKnobDimmer() { + this.knobDimmer = new KnobDimmer(); + } + + @Nested + @DisplayName(" when multiple lights are present") + class MultipleLights { + + @BeforeEach + public void setLights() { + DimmableLight dl; + for (int i = 0; i < 3; i++) { + dl = new DimmableLight(); + dl.setIntensity(10); + ; + knobDimmer.addDimmableLight(dl); + } + } + + @Test + @DisplayName(" set the intensity ") + public void increase() { + knobDimmer.setLightIntensity(30); + for (DimmableLight dl : knobDimmer.getOutputs()) { + assertEquals(30, dl.getIntensity()); + } + } + } +} From e777f29585ffc29009f8fda3ae9ba703be4c8a26 Mon Sep 17 00:00:00 2001 From: britea Date: Wed, 18 Mar 2020 13:29:21 +0100 Subject: [PATCH 10/29] Fix lob errors --- .../sa4/sanmarinoes/smarthut/models/DeviceRepository.java | 5 +++++ .../ch/usi/inf/sa4/sanmarinoes/smarthut/models/Room.java | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/DeviceRepository.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/DeviceRepository.java index f844882..ef57a88 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/DeviceRepository.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/DeviceRepository.java @@ -6,6 +6,8 @@ import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.CrudRepository; import org.springframework.data.repository.query.Param; +import javax.transaction.Transactional; + /** * DeviceRepository acts as a superclass for the other repositories so to mirror in the database the * class inheritance present among the various devices. @@ -20,6 +22,7 @@ public interface DeviceRepository extends CrudRepository findByIdAndUsername(Long id, String username); @@ -29,6 +32,7 @@ public interface DeviceRepository extends CrudRepository findAllByUsername(String username); @@ -38,6 +42,7 @@ public interface DeviceRepository extends CrudRepository Date: Wed, 18 Mar 2020 16:08:49 +0100 Subject: [PATCH 11/29] Changed docker image name on CI deploy stage --- .gitlab-ci.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 2e3639a..03683de 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -22,11 +22,13 @@ smarthut_deploy: - docker info - docker login -u smarthutsm -p $CI_DOCKER_PASS #GiovanniRoberto script: - - "docker build -t smarthutsm/smarthut:${CI_COMMIT_BRANCH} --pull ." - - "docker push smarthutsm/smarthut:${CI_COMMIT_BRANCH}" + - "docker build -t smarthutsm/smarthut-backend:${CI_COMMIT_BRANCH} --pull ." + - "docker push smarthutsm/smarthut-backend:${CI_COMMIT_BRANCH}" after_script: - docker logout - + only: + - dev + - master #base checks for the code build: From c3bcfd7e6dbcb319d1b6d8b9a229415730b0afb4 Mon Sep 17 00:00:00 2001 From: Claudio Maggioni Date: Sat, 21 Mar 2020 00:38:01 +0100 Subject: [PATCH 12/29] Fixed RoomCont... to return specific device data @tommi27 why are you not avaliable at 1am? --- .../inf/sa4/sanmarinoes/smarthut/controller/RoomController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 fb42037..8d083d9 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 @@ -79,7 +79,7 @@ public class RoomController { * id). */ @GetMapping(path = "/{roomId}/devices") - public @ResponseBody List getDevices(@PathVariable("roomId") long roomid) { + public List getDevices(@PathVariable("roomId") long roomid) { return deviceRepository.findByRoomId(roomid); } } From 600529af41fda17cd1df5c6893382ae481f10a22 Mon Sep 17 00:00:00 2001 From: tommi27 Date: Sat, 21 Mar 2020 15:08:36 +0100 Subject: [PATCH 13/29] fixed route names --- .../usi/inf/sa4/sanmarinoes/smarthut/models/ButtonDimmer.java | 2 +- .../usi/inf/sa4/sanmarinoes/smarthut/models/DimmableLight.java | 2 +- .../ch/usi/inf/sa4/sanmarinoes/smarthut/models/KnobDimmer.java | 2 +- .../usi/inf/sa4/sanmarinoes/smarthut/models/MotionSensor.java | 2 +- .../usi/inf/sa4/sanmarinoes/smarthut/models/RegularLight.java | 2 +- .../ch/usi/inf/sa4/sanmarinoes/smarthut/models/SmartPlug.java | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/ButtonDimmer.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/ButtonDimmer.java index fc91c22..da9af1c 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/ButtonDimmer.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/ButtonDimmer.java @@ -13,7 +13,7 @@ public class ButtonDimmer extends Dimmer { private static final int DIM_INCREMENT = 10; public ButtonDimmer() { - super("button-dimmer"); + super("buttonDimmer"); } /** Increases the current intensity level of the dimmable light by DIM_INCREMENT */ 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 9a75471..7a59f7b 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 @@ -21,7 +21,7 @@ public class DimmableLight extends Switchable { Connector.basic(KnobDimmer::getOutputs, DimmableLight::setDimmerId); public DimmableLight() { - super("light"); + super("dimmableLight"); } @ManyToOne diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/KnobDimmer.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/KnobDimmer.java index ce3745c..c116165 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/KnobDimmer.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/KnobDimmer.java @@ -10,7 +10,7 @@ import javax.persistence.Entity; public class KnobDimmer extends Dimmer { public KnobDimmer() { - super("knob-dimmer"); + super("knobDimmer"); } /** diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/MotionSensor.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/MotionSensor.java index 50d2206..6c5baf7 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/MotionSensor.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/MotionSensor.java @@ -19,6 +19,6 @@ public class MotionSensor extends InputDevice { } public MotionSensor() { - super("motion-sensor"); + super("motionSensor"); } } diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/RegularLight.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/RegularLight.java index de9c10a..2dcff1b 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/RegularLight.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/RegularLight.java @@ -14,7 +14,7 @@ public class RegularLight extends Switchable { boolean on; public RegularLight() { - super("regular-light"); + super("regularLight"); this.on = false; } 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 4411dc3..9b07e69 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 @@ -42,6 +42,6 @@ public class SmartPlug extends Switchable { } public SmartPlug() { - super("smart-plug"); + super("smartPlug"); } } From 8813942cc595eedcb3cee1910aeb5cb8a142c497 Mon Sep 17 00:00:00 2001 From: omenem Date: Sun, 22 Mar 2020 18:19:41 +0100 Subject: [PATCH 14/29] fixxed --- .../sa4/sanmarinoes/smarthut/dto/RoomSaveRequest.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/dto/RoomSaveRequest.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/dto/RoomSaveRequest.java index ca8fa0f..02a0e35 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/dto/RoomSaveRequest.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/dto/RoomSaveRequest.java @@ -6,6 +6,9 @@ import javax.validation.constraints.NotNull; public class RoomSaveRequest { + /** Room identifier */ + private long id; + @NotNull private Room.Icon icon; /** @@ -19,6 +22,14 @@ public class RoomSaveRequest { /** The user given name of this room (e.g. 'Master bedroom') */ @NotNull private String name; + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + public String getName() { return name; } From f4d6a3f3c777f727af8a3df6a591f9af3639199b Mon Sep 17 00:00:00 2001 From: Claudio Maggioni Date: Mon, 23 Mar 2020 16:42:33 +0100 Subject: [PATCH 15/29] RoomController PUT fixed --- .../smarthut/controller/RoomController.java | 52 +++++++++++-------- 1 file changed, 31 insertions(+), 21 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 8d083d9..6a2ded4 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 @@ -33,40 +33,50 @@ public class RoomController { return roomRepository.findById(id).orElseThrow(NotFoundException::new); } - private Room save(final RoomSaveRequest r, final Principal principal, boolean setWhenNull) { - Room newRoom = new Room(); + @PostMapping + public @ResponseBody Room create( + @Valid @RequestBody RoomSaveRequest r, final Principal principal) { final String username = principal.getName(); final Long userId = userRepository.findByUsername(username).getId(); final String img = r.getImage(); final Room.Icon icon = r.getIcon(); + final Room newRoom = new Room(); newRoom.setUserId(userId); newRoom.setName(r.getName()); - if (img != null) { - newRoom.setImage(img); - } else if (setWhenNull) { - newRoom.setImage(null); - } - if (icon != null) { - newRoom.setIcon(icon); - } else if (setWhenNull) { - newRoom.setIcon(null); - } + newRoom.setImage(img); + newRoom.setIcon(icon); return roomRepository.save(newRoom); } - @PostMapping - public @ResponseBody Room create( - @Valid @RequestBody RoomSaveRequest r, final Principal principal) { - return this.save(r, principal, true); - } - - @PutMapping + @PutMapping("/{id}") public @ResponseBody Room update( - @Valid @RequestBody RoomSaveRequest r, final Principal principal) { - return this.save(r, principal, false); + @PathVariable("id") long id, @RequestBody RoomSaveRequest r, final Principal principal) + throws NotFoundException { + final Room newRoom = + roomRepository + .findByIdAndUsername(id, principal.getName()) + .orElseThrow(NotFoundException::new); + final String img = r.getImage(); + final Room.Icon icon = r.getIcon(); + + if (r.getName() != null) { + newRoom.setName(r.getName()); + } + + if ("".equals(img)) { + newRoom.setImage(null); + } else if (img != null) { + newRoom.setImage(img); + } + + if (icon != null) { + newRoom.setIcon(icon); + } + + return roomRepository.save(newRoom); } @DeleteMapping("/{id}") From c17b6df3b5232be5fc638ffadc8a751cf7dbebd1 Mon Sep 17 00:00:00 2001 From: omenem Date: Mon, 23 Mar 2020 17:53:22 +0100 Subject: [PATCH 16/29] delete cascade no more --- .../usi/inf/sa4/sanmarinoes/smarthut/models/Dimmer.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Dimmer.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Dimmer.java index e192015..d06bece 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Dimmer.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Dimmer.java @@ -6,6 +6,7 @@ import javax.persistence.Entity; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.OneToMany; +import javax.persistence.PreRemove; /** Represents a generic dimmer input device */ @Entity @@ -32,4 +33,11 @@ public abstract class Dimmer extends InputDevice { public void addDimmableLight(DimmableLight dimmableLight) { lights.add(dimmableLight); } + + @PreRemove + private void removeLightsFromDimmer() { + for (DimmableLight dl : getOutputs()) { + dl.setDimmerId(null); + } + } } From f3680844643f11fa6403e32436798bcf32bfc95e Mon Sep 17 00:00:00 2001 From: omenem Date: Mon, 23 Mar 2020 18:31:46 +0100 Subject: [PATCH 17/29] delete cascade no more in switch --- .../usi/inf/sa4/sanmarinoes/smarthut/models/Switch.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Switch.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Switch.java index d819dfe..ed6f38d 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Switch.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Switch.java @@ -5,6 +5,7 @@ import java.util.Set; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.OneToMany; +import javax.persistence.PreRemove; /** A switch input device */ @Entity @@ -51,4 +52,11 @@ public class Switch extends InputDevice { public Set getOutputs() { return switchables; } + + @PreRemove + private void removeSwitchable() { + for (Switchable s : getOutputs()) { + s.setSwitchId(null); + } + } } From 08c4ef49a7e117dca9f2ec3f9241426aa8147b84 Mon Sep 17 00:00:00 2001 From: omenem Date: Tue, 24 Mar 2020 15:58:01 +0100 Subject: [PATCH 18/29] delete cascade in room --- .../usi/inf/sa4/sanmarinoes/smarthut/models/Room.java | 10 ++++++++++ 1 file changed, 10 insertions(+) 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 fd11d1c..34f3824 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 @@ -3,6 +3,8 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models; import ch.usi.inf.sa4.sanmarinoes.smarthut.config.GsonExclude; import com.google.gson.annotations.SerializedName; import io.swagger.annotations.ApiModelProperty; +import java.util.HashSet; +import java.util.Set; import javax.persistence.*; import javax.validation.constraints.NotNull; @@ -133,6 +135,10 @@ public class Room { @GsonExclude private User user; + @OneToMany(mappedBy = "room", orphanRemoval = true) + @GsonExclude + private Set devices = new HashSet<>(); + /** * User that owns the house this room is in as a foreign key id. To use when updating and * inserting from a REST call. @@ -186,6 +192,10 @@ public class Room { this.image = image; } + public Set getDevices() { + return devices; + } + @Override public String toString() { return "Room{" + "id=" + id + ", name='" + name + "\'}"; From 9fc0224b1ded7c42833cc818e1b1dc26fc83d8bc Mon Sep 17 00:00:00 2001 From: omenem Date: Wed, 25 Mar 2020 14:14:12 +0100 Subject: [PATCH 19/29] fix room deletion --- .../sanmarinoes/smarthut/controller/RoomController.java | 9 +++++++++ .../smarthut/models/ButtonDimmerRepository.java | 8 +++++++- .../smarthut/models/KnobDimmerRepository.java | 8 +++++++- .../usi/inf/sa4/sanmarinoes/smarthut/models/Switch.java | 2 +- .../sanmarinoes/smarthut/models/SwitchRepository.java | 8 +++++++- 5 files changed, 31 insertions(+), 4 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 6a2ded4..2bfa440 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 @@ -23,6 +23,12 @@ public class RoomController { @Autowired private DeviceRepository deviceRepository; + @Autowired private SwitchRepository switchRepository; + + @Autowired private ButtonDimmerRepository buttonDimmerRepository; + + @Autowired private KnobDimmerRepository knobDimmerRepository; + @GetMapping public List findAll() { return toList(roomRepository.findAll()); @@ -81,6 +87,9 @@ public class RoomController { @DeleteMapping("/{id}") public void deleteById(@PathVariable("id") long id) { + switchRepository.deleteAllByRoomId(id); + knobDimmerRepository.deleteAllByRoomId(id); + buttonDimmerRepository.deleteAllByRoomId(id); roomRepository.deleteById(id); } diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/ButtonDimmerRepository.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/ButtonDimmerRepository.java index 484977a..f39644a 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/ButtonDimmerRepository.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/ButtonDimmerRepository.java @@ -1,3 +1,9 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models; -public interface ButtonDimmerRepository extends DeviceRepository {} +import javax.transaction.Transactional; + +public interface ButtonDimmerRepository extends DeviceRepository { + + @Transactional + void deleteAllByRoomId(long roomId); +} diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/KnobDimmerRepository.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/KnobDimmerRepository.java index 7d7fc16..2a4558e 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/KnobDimmerRepository.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/KnobDimmerRepository.java @@ -1,3 +1,9 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models; -public interface KnobDimmerRepository extends DeviceRepository {} +import javax.transaction.Transactional; + +public interface KnobDimmerRepository extends DeviceRepository { + + @Transactional + void deleteAllByRoomId(long roomId); +} diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Switch.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Switch.java index ed6f38d..8a8057c 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Switch.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/Switch.java @@ -54,7 +54,7 @@ public class Switch extends InputDevice { } @PreRemove - private void removeSwitchable() { + public void removeSwitchable() { for (Switchable s : getOutputs()) { s.setSwitchId(null); } diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/SwitchRepository.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/SwitchRepository.java index f06f465..8650ebe 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/SwitchRepository.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/models/SwitchRepository.java @@ -1,3 +1,9 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models; -public interface SwitchRepository extends DeviceRepository {} +import javax.transaction.Transactional; + +public interface SwitchRepository extends DeviceRepository { + + @Transactional + void deleteAllByRoomId(long roomId); +} From e776b9c2e56b71bbdf6f8abe946975a0ce999274 Mon Sep 17 00:00:00 2001 From: tommi27 Date: Wed, 25 Mar 2020 14:50:05 +0100 Subject: [PATCH 20/29] socket is now sequential and not concurrent --- .../sa4/sanmarinoes/smarthut/socket/SensorSocketEndpoint.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/socket/SensorSocketEndpoint.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/socket/SensorSocketEndpoint.java index f1e4808..1735b86 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/socket/SensorSocketEndpoint.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/socket/SensorSocketEndpoint.java @@ -58,9 +58,9 @@ public class SensorSocketEndpoint extends Endpoint { * @return number of successful transfer */ public long broadcast(Object message, User u) { - final Collection sessions = authorizedClients.get(u); + final HashSet sessions = new HashSet<>(authorizedClients.get(u)); + return sessions.stream() - .parallel() .filter( s -> { if (s.isOpen()) return true; From 4281cbaf29186adf8997c4460e03990849b532c6 Mon Sep 17 00:00:00 2001 From: Claudio Maggioni Date: Wed, 25 Mar 2020 14:57:46 +0100 Subject: [PATCH 21/29] Added installation instructions and tweaked Dockerfile --- .gitignore | 4 +- .gitlab-ci.yml | 1 - Dockerfile | 7 +-- HELP.md | 13 ----- README.md | 51 +++++++++++++++++++ src/main/resources/application-dev.properties | 33 ++++++++++++ .../resources/application-prod.properties | 39 ++++++++++++++ src/main/resources/application.properties | 34 +------------ 8 files changed, 131 insertions(+), 51 deletions(-) delete mode 100644 HELP.md create mode 100644 src/main/resources/application-dev.properties create mode 100644 src/main/resources/application-prod.properties diff --git a/.gitignore b/.gitignore index ee01dda..3f7e467 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,7 @@ .idea/** +data/**/* + **/.DS_Store # Compiled class file @@ -138,4 +140,4 @@ gradle-app.setting # gradle/wrapper/gradle-wrapper.properties # IntelliJ -*.iml \ No newline at end of file +*.iml diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 03683de..309580e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -63,4 +63,3 @@ code_quality: - build/reports/cpd/cpdCheck.xml #create a report on the quality of the code expose_as: 'Code Quality Report' - allow_failure: true diff --git a/Dockerfile b/Dockerfile index 7a6dc45..c931d3a 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,8 +1,9 @@ FROM openjdk:13-jdk-alpine -ENV DB_URL "" -ENV DB_USER "" -ENV DB_PASS "" + ARG JAR_FILE=build/libs/smarthut*.jar + COPY ${JAR_FILE} app.jar + +ENV SMARTHUT_THIS_VALUE_IS_PROD_IF_THIS_IS_A_CONTAINER_PIZZOCCHERI=prod EXPOSE 8080 ENTRYPOINT ["java","-jar","/app.jar"] diff --git a/HELP.md b/HELP.md deleted file mode 100644 index 6b12689..0000000 --- a/HELP.md +++ /dev/null @@ -1,13 +0,0 @@ -# Getting Started - -### Reference Documentation -For further reference, please consider the following sections: - -* [Official Gradle documentation](https://docs.gradle.org) -* [Spring Boot Gradle Plugin Reference Guide](https://docs.spring.io/spring-boot/docs/2.2.4.RELEASE/gradle-plugin/reference/html/) - -### Additional Links -These additional references should also help you: - -* [Gradle Build Scans – insights for your project's build](https://scans.gradle.com#gradle) - diff --git a/README.md b/README.md index d483ec4..f588721 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,53 @@ # backend +## Installation guide + +In order to install a SmartHut.sm, you can use *Docker* and *Docker Compose* +in order to create che corresponding containers. + +Use the following `docker-compose.yml` example file. Change the values +of `$PASSWORD` and `$SECRET` to respectively the chosen PostgreSQL password +and the JWT secret used to run the server. `$SECRET` must be at least 64 chars long. + +```yaml +version: '3' + +services: + smarthutdb: + restart: always + image: postgres:12-alpine + container_name: smarthutdb + volumes: + - ./data:/var/lib/postgresql/data + environment: + PGDATA: /var/lib/postgresql/data/data + POSTGRES_DB: smarthut + POSTGRES_USERNAME: postgres + POSTGRES_PASSWORD: $PASSWORD + + smarthutbackend: + restart: always + image: smarthutsm/smarthut-backend:M1 + ports: + - 8080:8080 + environment: + - POSTGRES_JDBC=jdbc:postgresql://smarthutdb:5432/smarthut + - POSTGRES_USER=postgres + - POSTGRES_PASS=$PASSWORD + - SECRET=$SECRET + - MAIL_HOST=smtp.gmail.com + - MAIL_PORT=587 + - MAIL_STARTTLS=true + - MAIL_USER=smarthut.sm@gmail.com + - MAIL_PASS=dcadvbagqfkwbfts + - BACKEND_URL=http://localhost:8080 + - FRONTEND_URL=http://localhost + + smarthut: + restart: always + image: smarthutsm/smarthut:M1 + ports: + - 80:80 + environment: + - BACKEND_URL=http://localhost:8080 +``` diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties new file mode 100644 index 0000000..2fb519c --- /dev/null +++ b/src/main/resources/application-dev.properties @@ -0,0 +1,33 @@ +spring.http.converters.preferred-json-mapper=gson +spring.datasource.url=jdbc:postgresql://localhost:5432/smarthut +spring.datasource.username=postgres +spring.datasource.password= + +# Hibernate properties +spring.jpa.database=POSTGRESQL +spring.jpa.show-sql=false +spring.jpa.hibernate.ddl-auto=update +spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl +spring.jpa.properties.hibernate.format_sql=true + +jwt.secret=thiskeymustbeverylongorthethingcomplainssoiamjustgoingtowritehereabunchofgarbageciaomamma + +spring.mail.test-connection=true +spring.mail.host=smtp.gmail.com +spring.mail.port=587 +spring.mail.properties.mail.smtp.starttls.enable=true +spring.mail.username=smarthut.sm@gmail.com +spring.mail.password=dcadvbagqfkwbfts +spring.mail.properties.mail.smtp.starttls.required=true +spring.mail.properties.mail.smtp.auth=true +spring.mail.properties.mail.smtp.connectiontimeout=5000 +spring.mail.properties.mail.smtp.timeout=5000 +spring.mail.properties.mail.smtp.writetimeout=5000 + +email.registrationSubject=Complete your SmartHut.sm registration +email.registration=To confirm your registration, please click here: +email.registrationPath=http://localhost:8080/register/confirm-account?token= + +email.resetpasswordSubject=SmartHut.sm password reset +email.resetpassword=To reset your password, please click here: +email.resetpasswordPath=http://localhost:3000/password-reset?token= \ No newline at end of file diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties new file mode 100644 index 0000000..7807d21 --- /dev/null +++ b/src/main/resources/application-prod.properties @@ -0,0 +1,39 @@ +spring.http.converters.preferred-json-mapper=gson + +# Database connection properties +spring.datasource.url=${POSTGRES_JDBC} +spring.datasource.username=${POSTGRES_USER} +spring.datasource.password=${POSTGRES_PASS} + +# Hibernate properties +spring.jpa.database=POSTGRESQL +spring.jpa.show-sql=false +spring.jpa.hibernate.ddl-auto=update +spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl +spring.jpa.properties.hibernate.format_sql=true + +# JWT secret +jwt.secret=${SECRET} + +# Mail connection properties +spring.mail.test-connection=true +spring.mail.host=${MAIL_HOST} +spring.mail.port=${MAIL_PORT} +spring.mail.properties.mail.smtp.starttls.enable=${MAIL_STARTTLS} +spring.mail.username=${MAIL_USER} +spring.mail.password=${MAIL_PASS} +spring.mail.properties.mail.smtp.starttls.required=${MAIL_STARTTLS} +spring.mail.properties.mail.smtp.auth=true +spring.mail.properties.mail.smtp.connectiontimeout=5000 +spring.mail.properties.mail.smtp.timeout=5000 +spring.mail.properties.mail.smtp.writetimeout=5000 + +# Registration email properties +email.registrationSubject=Complete your SmartHut.sm registration +email.registration=To confirm your registration, please click here: +email.registrationPath=${BACKEND_URL}/register/confirm-account?token= + +# Password reset email properties +email.resetpasswordSubject=SmartHut.sm password reset +email.resetpassword=To reset your password, please click here: +email.resetpasswordPath=${FRONTEND_URL}/password-reset?token= \ No newline at end of file diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 2fb519c..2150e4d 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,33 +1 @@ -spring.http.converters.preferred-json-mapper=gson -spring.datasource.url=jdbc:postgresql://localhost:5432/smarthut -spring.datasource.username=postgres -spring.datasource.password= - -# Hibernate properties -spring.jpa.database=POSTGRESQL -spring.jpa.show-sql=false -spring.jpa.hibernate.ddl-auto=update -spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl -spring.jpa.properties.hibernate.format_sql=true - -jwt.secret=thiskeymustbeverylongorthethingcomplainssoiamjustgoingtowritehereabunchofgarbageciaomamma - -spring.mail.test-connection=true -spring.mail.host=smtp.gmail.com -spring.mail.port=587 -spring.mail.properties.mail.smtp.starttls.enable=true -spring.mail.username=smarthut.sm@gmail.com -spring.mail.password=dcadvbagqfkwbfts -spring.mail.properties.mail.smtp.starttls.required=true -spring.mail.properties.mail.smtp.auth=true -spring.mail.properties.mail.smtp.connectiontimeout=5000 -spring.mail.properties.mail.smtp.timeout=5000 -spring.mail.properties.mail.smtp.writetimeout=5000 - -email.registrationSubject=Complete your SmartHut.sm registration -email.registration=To confirm your registration, please click here: -email.registrationPath=http://localhost:8080/register/confirm-account?token= - -email.resetpasswordSubject=SmartHut.sm password reset -email.resetpassword=To reset your password, please click here: -email.resetpasswordPath=http://localhost:3000/password-reset?token= \ No newline at end of file +spring.profiles.active=${SMARTHUT_THIS_VALUE_IS_PROD_IF_THIS_IS_A_CONTAINER_PIZZOCCHERI:dev} \ No newline at end of file From 6ce44e73fff8054ab2c435bfa93ce66dc45af5dd Mon Sep 17 00:00:00 2001 From: omenem Date: Wed, 25 Mar 2020 14:58:56 +0100 Subject: [PATCH 22/29] fix min intensity of dimmabke light of 1 in Dimmable Save Request --- .../sa4/sanmarinoes/smarthut/dto/DimmableLightSaveRequest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/dto/DimmableLightSaveRequest.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/dto/DimmableLightSaveRequest.java index 01bec1a..74e911b 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/dto/DimmableLightSaveRequest.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/dto/DimmableLightSaveRequest.java @@ -11,7 +11,7 @@ public class DimmableLightSaveRequest { /** The light intensity value. Goes from 0 (off) to 100 (on) */ @NotNull - @Min(1) + @Min(0) @Max(100) private Integer intensity = 0; From 60c17b3dd8594541d2e71e3c36ae6efaae098bfb Mon Sep 17 00:00:00 2001 From: britea Date: Wed, 25 Mar 2020 17:10:27 +0100 Subject: [PATCH 23/29] Fixed @tommi27 synchronization frenzy for sensors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I have now discovered the Schadenfreude in using git-blame. To quote an old commit message from high school: [Trascrizione domande fisica e correzione di GRAVISSIMI bug presenti nel codici di Maggioni](https://gitlab.com/staccastacca/scuolatest/-/commit/dd0933def0262ce1ca2f2b006d4f7a364fb17272) ``` La trascrizione dei test è stata fatta in modo certosino, simile a quello dei monaci emanuensi. I GRAVISSIMI buggg (3 g perchè fa faigo) potevano rendere il sito incomprensibile ``` --- .../smarthut/socket/SensorSocketEndpoint.java | 20 +++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/socket/SensorSocketEndpoint.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/socket/SensorSocketEndpoint.java index 1735b86..2801a74 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/socket/SensorSocketEndpoint.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/socket/SensorSocketEndpoint.java @@ -8,6 +8,8 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; import com.google.gson.Gson; + +import java.io.IOException; import java.util.*; import javax.websocket.*; import org.springframework.beans.factory.annotation.Autowired; @@ -57,20 +59,30 @@ public class SensorSocketEndpoint extends Endpoint { * @param u the user to which to send the message * @return number of successful transfer */ - public long broadcast(Object message, User u) { + public void broadcast(Object message, User u) { final HashSet sessions = new HashSet<>(authorizedClients.get(u)); - return sessions.stream() + + + sessions.stream() .filter( s -> { if (s.isOpen()) return true; sessions.remove(s); return false; }) - .filter(didThrow(s -> s.getBasicRemote().sendText(gson.toJson(message)))) - .count(); + .forEach(s -> { + synchronized (this){ + try { + s.getBasicRemote().sendText(gson.toJson(message)); + } catch (IOException e) { + e.printStackTrace(); + } + } + }); } + /** * Handles the opening of a socket session with a client * From b283a62d0d21bb6b876fff657466bb915f680c25 Mon Sep 17 00:00:00 2001 From: Claudio Maggioni Date: Wed, 25 Mar 2020 17:31:24 +0100 Subject: [PATCH 24/29] fixed redirects --- .../config/EmailConfigurationService.java | 30 +++++++++++++++---- .../controller/AuthenticationController.java | 18 ----------- .../controller/UserAccountController.java | 19 +++++++----- src/main/resources/application-dev.properties | 4 ++- .../resources/application-prod.properties | 5 +++- 5 files changed, 44 insertions(+), 32 deletions(-) diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/config/EmailConfigurationService.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/config/EmailConfigurationService.java index 8bae55d..a26aeeb 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/config/EmailConfigurationService.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/config/EmailConfigurationService.java @@ -30,17 +30,21 @@ public class EmailConfigurationService { */ @NotNull private String registrationPath; + /** + * The URL to follow for password reset email confirmation. Has to end with the start of a query + * parameter + */ + @NotNull private String resetPasswordPath; + /** The email subject for a reset password email */ @NotNull private String resetPasswordSubject; /** The text in the email body preceding the confirmation URL for a reset password email */ @NotNull private String resetPassword; - /** - * The URL to follow for password reset email confirmation. Has to end with the start of a query - * parameter - */ - @NotNull private String resetPasswordPath; + @NotNull private String resetPasswordRedirect; + + @NotNull private String registrationRedirect; public String getRegistrationSubject() { return registrationSubject; @@ -89,4 +93,20 @@ public class EmailConfigurationService { public void setResetPasswordPath(String resetPasswordPath) { this.resetPasswordPath = resetPasswordPath; } + + public String getResetPasswordRedirect() { + return resetPasswordRedirect; + } + + public void setResetPasswordRedirect(String resetPasswordRedirect) { + this.resetPasswordRedirect = resetPasswordRedirect; + } + + public String getRegistrationRedirect() { + return registrationRedirect; + } + + public void setRegistrationRedirect(String registrationRedirect) { + this.registrationRedirect = registrationRedirect; + } } 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 3160e1c..d26eed4 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 @@ -3,12 +3,9 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.controller; import ch.usi.inf.sa4.sanmarinoes.smarthut.config.JWTTokenUtils; 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.error.UnauthorizedException; import ch.usi.inf.sa4.sanmarinoes.smarthut.error.UserNotFoundException; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; -import io.swagger.annotations.Authorization; -import java.security.Principal; import javax.validation.Valid; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; @@ -72,21 +69,6 @@ public class AuthenticationController { return new JWTResponse(token); } - @Authorization(value = "Bearer") - @PatchMapping("/update") - public User update( - @Valid @RequestBody final UserUpdateRequest userData, final Principal principal) { - final User oldUser = userRepository.findByUsername(principal.getName()); - if (userData.getName() != null) oldUser.setName(userData.getName()); - if (userData.getEmail() != null) { - oldUser.setEmail(userData.getEmail()); - // TODO: handle email verification - } - if (userData.getPassword() != null) - oldUser.setPassword(encoder.encode(userData.getPassword())); - return userRepository.save(oldUser); - } - private void authenticate(String username, String password) throws UnauthorizedException { try { authenticationManager.authenticate( diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/UserAccountController.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/UserAccountController.java index ebf354f..1957319 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/UserAccountController.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/UserAccountController.java @@ -13,6 +13,8 @@ import ch.usi.inf.sa4.sanmarinoes.smarthut.models.ConfirmationTokenRepository; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.User; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.UserRepository; import ch.usi.inf.sa4.sanmarinoes.smarthut.service.EmailSenderService; +import java.io.IOException; +import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import javax.validation.constraints.NotNull; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; @@ -158,8 +160,10 @@ public class UserAccountController { * @throws EmailTokenNotFoundException if given token is not a valid token for password reset */ @PutMapping("/reset-password") - public OkResponse resetPassword(@Valid @RequestBody PasswordResetRequest resetRequest) - throws EmailTokenNotFoundException { + public void resetPassword( + @Valid @RequestBody PasswordResetRequest resetRequest, + final HttpServletResponse response) + throws EmailTokenNotFoundException, IOException { final ConfirmationToken token = confirmationTokenRepository.findByConfirmationToken( resetRequest.getConfirmationToken()); @@ -175,7 +179,7 @@ public class UserAccountController { // Delete token to prevent further password changes confirmationTokenRepository.delete(token); - return new OkResponse(); + response.sendRedirect(emailConfig.getResetPasswordRedirect()); } /** @@ -187,16 +191,17 @@ public class UserAccountController { * confirmation */ @GetMapping(value = "/confirm-account") - public OkResponse confirmUserAccount(@RequestParam("token") @NotNull String confirmationToken) - throws EmailTokenNotFoundException { + public void confirmUserAccount( + @RequestParam("token") @NotNull String confirmationToken, + final HttpServletResponse response) + throws EmailTokenNotFoundException, IOException { final ConfirmationToken token = confirmationTokenRepository.findByConfirmationToken(confirmationToken); if (token != null && !token.getResetPassword()) { token.getUser().setEnabled(true); userRepository.save(token.getUser()); - // TODO: redirect to frontend - return new OkResponse(); + response.sendRedirect(emailConfig.getRegistrationRedirect()); } else { throw new EmailTokenNotFoundException(); } diff --git a/src/main/resources/application-dev.properties b/src/main/resources/application-dev.properties index 2fb519c..3c77362 100644 --- a/src/main/resources/application-dev.properties +++ b/src/main/resources/application-dev.properties @@ -27,7 +27,9 @@ spring.mail.properties.mail.smtp.writetimeout=5000 email.registrationSubject=Complete your SmartHut.sm registration email.registration=To confirm your registration, please click here: email.registrationPath=http://localhost:8080/register/confirm-account?token= +email.registrationRedirect=http://localhost:3000 email.resetpasswordSubject=SmartHut.sm password reset email.resetpassword=To reset your password, please click here: -email.resetpasswordPath=http://localhost:3000/password-reset?token= \ No newline at end of file +email.resetpasswordPath=http://localhost:3000/password-reset?token= +email.resetPasswordRedirect=http://localhost:3000/conf-reset-pass \ No newline at end of file diff --git a/src/main/resources/application-prod.properties b/src/main/resources/application-prod.properties index 7807d21..482fa13 100644 --- a/src/main/resources/application-prod.properties +++ b/src/main/resources/application-prod.properties @@ -32,8 +32,11 @@ spring.mail.properties.mail.smtp.writetimeout=5000 email.registrationSubject=Complete your SmartHut.sm registration email.registration=To confirm your registration, please click here: email.registrationPath=${BACKEND_URL}/register/confirm-account?token= +email.registrationSuccess=${FRONTEND_URL} + # Password reset email properties email.resetpasswordSubject=SmartHut.sm password reset email.resetpassword=To reset your password, please click here: -email.resetpasswordPath=${FRONTEND_URL}/password-reset?token= \ No newline at end of file +email.resetpasswordPath=${FRONTEND_URL}/password-reset?token= +email.resetPasswordSuccess=${FRONTEND_URL}/conf-reset-pass \ No newline at end of file From b9221cecc6cfec7d8ed264aa8956673defce85f3 Mon Sep 17 00:00:00 2001 From: Claudio Maggioni Date: Wed, 25 Mar 2020 20:21:54 +0100 Subject: [PATCH 25/29] fixed application.properties for tests --- src/test/resources/application.properties | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/test/resources/application.properties b/src/test/resources/application.properties index 673d02a..bdaafc0 100644 --- a/src/test/resources/application.properties +++ b/src/test/resources/application.properties @@ -28,8 +28,10 @@ server.port = 2000 email.registrationSubject=Complete your SmartHut.sm registration email.registration=To confirm your registration, please click here: -email.registrationPath=http://localhost:2000/register/confirm-account?token= +email.registrationPath=http://localhost:8080/register/confirm-account?token= +email.registrationRedirect=http://localhost:3000 email.resetpasswordSubject=SmartHut.sm password reset email.resetpassword=To reset your password, please click here: -email.resetpasswordPath=http://localhost:3000/password-reset?token= \ No newline at end of file +email.resetpasswordPath=http://localhost:3000/password-reset?token= +email.resetPasswordRedirect=http://localhost:3000/conf-reset-pass \ No newline at end of file From c5996608a414642e01f6a185deaf4716a348cdb5 Mon Sep 17 00:00:00 2001 From: Claudio Maggioni Date: Wed, 25 Mar 2020 22:34:15 +0100 Subject: [PATCH 26/29] fixed dimmable light --- .../sa4/sanmarinoes/smarthut/models/DimmableLight.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) 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 7a59f7b..6b537c6 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 @@ -39,6 +39,10 @@ public class DimmableLight extends Switchable { @Max(100) private Integer intensity = 0; + @NotNull + @Column(nullable = false) + private Integer oldIntensity = 100; + public Integer getIntensity() { return intensity; } @@ -55,8 +59,10 @@ public class DimmableLight extends Switchable { this.intensity = 0; } else if (intensity > 100) { this.intensity = 100; + this.oldIntensity = 100; } else { this.intensity = intensity; + this.oldIntensity = intensity; } } @@ -67,13 +73,13 @@ public class DimmableLight extends Switchable { @Override public void setOn(boolean on) { - intensity = on ? 100 : 0; + intensity = on ? oldIntensity : 0; } public void setDimmerId(Long dimmerId) { this.dimmerId = dimmerId; super.setSwitchId(null); - }; + } @Override public void setSwitchId(Long switchId) { From 27cb73292cf8124b5d7c910b4e3bf5b3c5ce3105 Mon Sep 17 00:00:00 2001 From: Claudio Maggioni Date: Wed, 25 Mar 2020 22:41:59 +0100 Subject: [PATCH 27/29] Added /auth/profile --- .../sa4/sanmarinoes/smarthut/config/SpringFoxConfig.java | 4 ++-- .../smarthut/controller/AuthenticationController.java | 6 ++++++ .../ch/usi/inf/sa4/sanmarinoes/smarthut/models/User.java | 4 +++- 3 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/config/SpringFoxConfig.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/config/SpringFoxConfig.java index 2fdab4e..971a7fb 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/config/SpringFoxConfig.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/config/SpringFoxConfig.java @@ -1,6 +1,5 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.config; - import java.util.List; import java.util.function.Predicate; import org.springframework.context.annotation.Bean; @@ -75,7 +74,8 @@ public class SpringFoxConfig { .or(PathSelectors.regex("/sensor.*")::apply) .or(PathSelectors.regex("/smartPlug.*")::apply) .or(PathSelectors.regex("/switch.*")::apply) - .or(PathSelectors.regex("/motionSensor.*")::apply); + .or(PathSelectors.regex("/motionSensor.*")::apply) + .or(PathSelectors.regex("/auth/profile.*")::apply); } /** 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 d26eed4..ad48da2 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 @@ -6,6 +6,7 @@ import ch.usi.inf.sa4.sanmarinoes.smarthut.dto.JWTResponse; import ch.usi.inf.sa4.sanmarinoes.smarthut.error.UnauthorizedException; import ch.usi.inf.sa4.sanmarinoes.smarthut.error.UserNotFoundException; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.*; +import java.security.Principal; import javax.validation.Valid; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.authentication.BadCredentialsException; @@ -69,6 +70,11 @@ public class AuthenticationController { return new JWTResponse(token); } + @GetMapping("/profile") + public User profile(final Principal principal) { + return userRepository.findByUsername(principal.getName()); + } + private void authenticate(String username, String password) throws UnauthorizedException { try { authenticationManager.authenticate( 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 dc6766d..60aad17 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 @@ -1,5 +1,6 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.models; +import ch.usi.inf.sa4.sanmarinoes.smarthut.config.GsonExclude; import io.swagger.annotations.ApiModelProperty; import java.util.Objects; import javax.persistence.*; @@ -24,6 +25,7 @@ public class User { /** A properly salted way to store the password */ @Column(nullable = false) + @GsonExclude private String password; /** @@ -34,7 +36,7 @@ public class User { private String email; @Column(nullable = false) - @ApiModelProperty(hidden = true) + @GsonExclude private Boolean isEnabled = false; public Long getId() { From 6c9e2a7d7da42fa366745538514a3c59cf51a814 Mon Sep 17 00:00:00 2001 From: Claudio Maggioni Date: Wed, 25 Mar 2020 23:13:17 +0100 Subject: [PATCH 28/29] Fixed ConcurrentModificationException on socket broadcast --- .../smarthut/socket/SensorSocketEndpoint.java | 33 +++++++------------ 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/socket/SensorSocketEndpoint.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/socket/SensorSocketEndpoint.java index 2801a74..600bdf4 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/socket/SensorSocketEndpoint.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/socket/SensorSocketEndpoint.java @@ -1,6 +1,5 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.socket; -import static ch.usi.inf.sa4.sanmarinoes.smarthut.utils.Utils.didThrow; import ch.usi.inf.sa4.sanmarinoes.smarthut.config.GsonConfig; import ch.usi.inf.sa4.sanmarinoes.smarthut.models.User; @@ -8,7 +7,6 @@ import com.google.common.collect.HashMultimap; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; import com.google.gson.Gson; - import java.io.IOException; import java.util.*; import javax.websocket.*; @@ -61,28 +59,19 @@ public class SensorSocketEndpoint extends Endpoint { */ public void broadcast(Object message, User u) { final HashSet sessions = new HashSet<>(authorizedClients.get(u)); - - - - sessions.stream() - .filter( - s -> { - if (s.isOpen()) return true; - sessions.remove(s); - return false; - }) - .forEach(s -> { - synchronized (this){ - try { - s.getBasicRemote().sendText(gson.toJson(message)); - } catch (IOException e) { - e.printStackTrace(); - } - } - }); + for (Session s : sessions) { + try { + if (s.isOpen()) { + s.getBasicRemote().sendText(gson.toJson(message)); + } else { + authorizedClients.remove(u, s); + } + } catch (IOException e) { + e.printStackTrace(); + } + } } - /** * Handles the opening of a socket session with a client * From 802cee52f8019a16e9bd79eaf2a6aa7c53754fc6 Mon Sep 17 00:00:00 2001 From: Claudio Maggioni Date: Thu, 26 Mar 2020 01:01:49 +0100 Subject: [PATCH 29/29] fixed cors on password reset --- .../smarthut/config/CORSFilter.java | 23 +++++-------------- .../controller/UserAccountController.java | 4 ++-- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/config/CORSFilter.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/config/CORSFilter.java index 7df826d..d5e19ae 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/config/CORSFilter.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/config/CORSFilter.java @@ -1,7 +1,6 @@ package ch.usi.inf.sa4.sanmarinoes.smarthut.config; import java.io.IOException; -import java.util.List; import javax.servlet.*; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; @@ -14,23 +13,13 @@ import org.springframework.stereotype.Component; @Component public class CORSFilter implements Filter { - static void setCORSHeaders(HttpServletResponse response) { + public static void setCORSHeaders(HttpServletResponse response) { response.setHeader("Access-Control-Allow-Origin", "*"); - response.setHeader("Access-Control-Allow-Methods", "HEAD, PUT, POST, GET, OPTIONS, DELETE"); - response.setHeader("Access-Control-Max-Age", "3600"); - response.setHeader( - "Access-Control-Allow-Headers", - String.join( - ",", - List.of( - "Access-Control-Allow-Headers", - "Origin", - "Accept", - "X-Requested-With", - "Authorization", - "Content-Type", - "Access-Control-Request-Method", - "Access-Control-Request-Headers"))); + response.setHeader("Access-Control-Allow-Methods", "*"); + response.setHeader("Access-Control-Allow-Headers", "*"); + response.setHeader("Access-Control-Allow-Credentials", "true"); + response.setHeader("Access-Control-Expose-Headers", "*"); + response.setHeader("Access-Control-Max-Age", "6".repeat(99)); } @Override diff --git a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/UserAccountController.java b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/UserAccountController.java index 1957319..950fb1a 100644 --- a/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/UserAccountController.java +++ b/src/main/java/ch/usi/inf/sa4/sanmarinoes/smarthut/controller/UserAccountController.java @@ -160,7 +160,7 @@ public class UserAccountController { * @throws EmailTokenNotFoundException if given token is not a valid token for password reset */ @PutMapping("/reset-password") - public void resetPassword( + public OkResponse resetPassword( @Valid @RequestBody PasswordResetRequest resetRequest, final HttpServletResponse response) throws EmailTokenNotFoundException, IOException { @@ -179,7 +179,7 @@ public class UserAccountController { // Delete token to prevent further password changes confirmationTokenRepository.delete(token); - response.sendRedirect(emailConfig.getResetPasswordRedirect()); + return new OkResponse(); } /**