diff --git a/pom.xml b/pom.xml
index 557e373d..c7d905e6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -152,10 +152,10 @@
ch/ethz/seb/sebserver/*
-
- ch/ethz/seb/sebserver/webservice/datalayer/batis/mapper/*
- ch/ethz/seb/sebserver/webservice/datalayer/batis/model/*
-
+
+
+
+
diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/Institution.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/Institution.java
index 157330f5..36133067 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/Institution.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/Institution.java
@@ -11,6 +11,7 @@ package ch.ethz.seb.sebserver.gbl.model.institution;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
+import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import ch.ethz.seb.sebserver.gbl.api.POSTMapper;
@@ -26,7 +27,7 @@ public final class Institution implements GrantEntity, Activatable {
public final Long id;
@JsonProperty(INSTITUTION.ATTR_NAME)
- @NotNull
+ @NotNull(message = "institution:name:notNull")
@Size(min = 3, max = 255, message = "institution:name:size:{min}:{max}:${validatedValue}")
public final String name;
@@ -40,6 +41,7 @@ public final class Institution implements GrantEntity, Activatable {
@JsonProperty(INSTITUTION.ATTR_ACTIVE)
public final Boolean active;
+ @JsonCreator
public Institution(
@JsonProperty(Domain.ATTR_ID) final Long id,
@JsonProperty(INSTITUTION.ATTR_NAME) final String name,
diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/LmsSetup.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/LmsSetup.java
index 3abd14d3..01efa743 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/LmsSetup.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/institution/LmsSetup.java
@@ -42,12 +42,12 @@ public final class LmsSetup implements GrantEntity, Activatable {
public final Long institutionId;
@JsonProperty(LMS_SETUP.ATTR_NAME)
- @NotNull
+ @NotNull(message = "lmsSetup:name:notNull")
@Size(min = 3, max = 255, message = "lmsSetup:name:size:{min}:{max}:${validatedValue}")
public final String name;
@JsonProperty(LMS_SETUP.ATTR_LMS_TYPE)
- @NotNull
+ @NotNull(message = "lmsSetup:lmsType:notNull")
public final LmsType lmsType;
@JsonProperty(LMS_SETUP.ATTR_LMS_CLIENTNAME)
@@ -59,7 +59,6 @@ public final class LmsSetup implements GrantEntity, Activatable {
public final String lmsAuthSecret;
@JsonProperty(LMS_SETUP.ATTR_LMS_URL)
- @NotNull
public final String lmsApiUrl;
@JsonProperty(LMS_SETUP.ATTR_LMS_REST_API_TOKEN)
diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserInfo.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserInfo.java
index 7573a84f..b6a83c1a 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserInfo.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserInfo.java
@@ -16,6 +16,7 @@ import org.apache.commons.lang3.BooleanUtils;
import org.joda.time.DateTimeZone;
import com.fasterxml.jackson.annotation.JsonCreator;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import ch.ethz.seb.sebserver.gbl.model.Activatable;
@@ -76,6 +77,7 @@ public final class UserInfo implements GrantEntity, Activatable, Serializable {
public final Set roles;
@JsonCreator
+ @JsonIgnoreProperties(ignoreUnknown = true)
public UserInfo(
@JsonProperty(USER.ATTR_UUID) final String uuid,
@JsonProperty(USER.ATTR_INSTITUTION_ID) final Long institutionId,
diff --git a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserMod.java b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserMod.java
index 1bcaae3e..16128e59 100644
--- a/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserMod.java
+++ b/src/main/java/ch/ethz/seb/sebserver/gbl/model/user/UserMod.java
@@ -22,9 +22,9 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
+import ch.ethz.seb.sebserver.gbl.api.POSTMapper;
import ch.ethz.seb.sebserver.gbl.model.Domain.USER;
import ch.ethz.seb.sebserver.gbl.model.Domain.USER_ROLE;
-import ch.ethz.seb.sebserver.gbl.api.POSTMapper;
import ch.ethz.seb.sebserver.gbl.model.EntityType;
import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.GrantEntity;
@@ -41,13 +41,13 @@ public final class UserMod implements GrantEntity {
public final Long institutionId;
/** Full name of the user */
- @NotNull
+ @NotNull(message = "user:name:notNull")
@Size(min = 3, max = 255, message = "user:name:size:{min}:{max}:${validatedValue}")
@JsonProperty(USER.ATTR_NAME)
public final String name;
/** The internal user name */
- @NotNull
+ @NotNull(message = "user:username:notNull")
@Size(min = 3, max = 255, message = "user:username:size:{min}:{max}:${validatedValue}")
@JsonProperty(USER.ATTR_USERNAME)
public final String username;
@@ -58,12 +58,12 @@ public final class UserMod implements GrantEntity {
public final String email;
/** The users locale */
- @NotNull
+ @NotNull(message = "user:locale:notNull")
@JsonProperty(USER.ATTR_LOCALE)
public final Locale locale;
/** The users time zone */
- @NotNull
+ @NotNull(message = "user:timeZone:notNull")
@JsonProperty(USER.ATTR_TIMEZONE)
public final DateTimeZone timeZone;
diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/InternalEncryptionService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/InternalEncryptionService.java
index a23396db..26bc9744 100644
--- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/InternalEncryptionService.java
+++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/InternalEncryptionService.java
@@ -39,7 +39,7 @@ public class InternalEncryptionService {
NO_SALT).encrypt(text);
} catch (final Exception e) {
log.error("Failed to encrypt text: ", e);
- return null;
+ return text;
}
}
@@ -50,7 +50,7 @@ public class InternalEncryptionService {
NO_SALT).decrypt(text);
} catch (final Exception e) {
log.error("Failed to decrypt text: ", e);
- return null;
+ return text;
}
}
@@ -61,7 +61,7 @@ public class InternalEncryptionService {
salt).encrypt(text);
} catch (final Exception e) {
log.error("Failed to encrypt text: ", e);
- return null;
+ return text;
}
}
@@ -72,7 +72,7 @@ public class InternalEncryptionService {
salt).decrypt(text);
} catch (final Exception e) {
log.error("Failed to decrypt text: ", e);
- return null;
+ return text;
}
}
@@ -81,7 +81,7 @@ public class InternalEncryptionService {
return Encryptors.text(secret, salt).encrypt(text);
} catch (final Exception e) {
log.error("Failed to encrypt text: ", e);
- return null;
+ return text;
}
}
@@ -90,7 +90,7 @@ public class InternalEncryptionService {
return Encryptors.text(secret, salt).decrypt(text);
} catch (final Exception e) {
log.error("Failed to decrypt text: ", e);
- return null;
+ return text;
}
}
diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/LmsSetupDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/LmsSetupDAOImpl.java
index 187e4df7..cc3de0f4 100644
--- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/LmsSetupDAOImpl.java
+++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/LmsSetupDAOImpl.java
@@ -286,37 +286,12 @@ public class LmsSetupDAOImpl implements LmsSetupDAO {
record.getName(),
LmsType.valueOf(record.getLmsType()),
record.getLmsClientname(),
- record.getLmsClientsecret(),
+ null,
record.getLmsUrl(),
record.getLmsRestApiToken(),
record.getSebClientname(),
- record.getSebClientsecret(),
+ null,
BooleanUtils.toBooleanObject(record.getActive())));
}
-// private LmsSetup handlePasswortReset(LmsSetup lmsSetup) {
-// String lmsPWDEncrypted = null;
-// String sebPWDEncrypted = null;
-// if (StringUtils.isNotBlank(lmsSetup.lmsAuthName) && StringUtils.isNotBlank(lmsSetup.lmsAuthSecret)) {
-//
-// }
-//
-// if (StringUtils.isNotBlank(lmsSetup.sebAuthName) && StringUtils.isNotBlank(lmsSetup.sebAuthSecret)) {
-//
-// }
-//
-// return new LmsSetup(
-// lmsSetup.id,
-// lmsSetup.institutionId,
-// lmsSetup.name,
-// lmsSetup.lmsType,
-// lmsSetup.lmsAuthName,
-// lmsPWDEncrypted,
-// lmsSetup.lmsApiUrl,
-// lmsSetup.lmsRestApiToken,
-// lmsSetup.sebAuthName,
-// sebPWDEncrypted,
-// lmsSetup.active);
-// }
-
}
diff --git a/src/test/java/ch/ethz/seb/sebserver/gbl/model/institution/LmsSetupTest.java b/src/test/java/ch/ethz/seb/sebserver/gbl/model/institution/LmsSetupTest.java
new file mode 100644
index 00000000..8c8e434c
--- /dev/null
+++ b/src/test/java/ch/ethz/seb/sebserver/gbl/model/institution/LmsSetupTest.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package ch.ethz.seb.sebserver.gbl.model.institution;
+
+import static org.junit.Assert.assertNotNull;
+
+import java.io.IOException;
+
+import org.junit.Test;
+
+import com.fasterxml.jackson.core.JsonParseException;
+import com.fasterxml.jackson.databind.JsonMappingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+public class LmsSetupTest {
+
+ @Test
+ public void testDeserialization() throws JsonParseException, JsonMappingException, IOException {
+ final String jsonString =
+ "{\"id\":1,\"institutionId\":1,\"name\":\"new LmsSetup 1\",\"lmsType\":\"MOCKUP\",\"lmsClientname\":\"lms1Name\",\"lmsClientsecret\":\"lms1Secret\",\"lmsUrl\":\"https://www.lms1.com\",\"lmsRestApiToken\":null,\"sebClientname\":\"seb1Name\",\"sebClientsecret\":\"seb1Secret\",\"active\":false}";
+
+ final LmsSetup lmsSetup = new ObjectMapper().readValue(jsonString, LmsSetup.class);
+ assertNotNull(lmsSetup);
+ }
+
+}
diff --git a/src/test/java/ch/ethz/seb/sebserver/webservice/integration/api/admin/LmsSetupAPITest.java b/src/test/java/ch/ethz/seb/sebserver/webservice/integration/api/admin/LmsSetupAPITest.java
new file mode 100644
index 00000000..3a1c3291
--- /dev/null
+++ b/src/test/java/ch/ethz/seb/sebserver/webservice/integration/api/admin/LmsSetupAPITest.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2019 ETH Zürich, Educational Development and Technology (LET)
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+package ch.ethz.seb.sebserver.webservice.integration.api.admin;
+
+import static org.junit.Assert.*;
+
+import java.util.List;
+
+import org.junit.Test;
+import org.springframework.http.HttpMethod;
+import org.springframework.http.HttpStatus;
+import org.springframework.test.context.jdbc.Sql;
+
+import com.fasterxml.jackson.core.type.TypeReference;
+
+import ch.ethz.seb.sebserver.gbl.api.APIMessage;
+import ch.ethz.seb.sebserver.gbl.api.SEBServerRestEndpoints;
+import ch.ethz.seb.sebserver.gbl.model.Domain;
+import ch.ethz.seb.sebserver.gbl.model.EntityProcessingReport;
+import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
+import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType;
+
+@Sql(scripts = { "classpath:schema-test.sql", "classpath:data-test.sql" })
+public class LmsSetupAPITest extends AdministrationAPIIntegrationTester {
+
+ @Test
+ public void testCreateModifyActivateDelete() throws Exception {
+ // Institutional admin 1 create a LMSSetup
+
+ // create new institution with seb-admin
+ LmsSetup lmsSetup = new RestAPITestHelper()
+ .withAccessToken(getAdminInstitution1Access())
+ .withPath(SEBServerRestEndpoints.ENDPOINT_LMS_SETUP)
+ .withMethod(HttpMethod.POST)
+ .withAttribute("name", "new LmsSetup 1")
+ .withAttribute(Domain.LMS_SETUP.ATTR_LMS_TYPE, LmsType.MOCKUP.name())
+ .withAttribute("active", "false")
+ .withExpectedStatus(HttpStatus.OK)
+ .getAsObject(new TypeReference() {
+ });
+
+ assertNotNull(lmsSetup);
+ assertNotNull(lmsSetup.id);
+ assertTrue(lmsSetup.institutionId.longValue() == 1);
+ assertEquals("new LmsSetup 1", lmsSetup.name);
+ assertTrue(LmsType.MOCKUP == lmsSetup.lmsType);
+ assertFalse(lmsSetup.active);
+
+ // set lms server and credentials
+ final LmsSetup modified = new LmsSetup(
+ lmsSetup.id,
+ lmsSetup.institutionId,
+ lmsSetup.name,
+ lmsSetup.lmsType,
+ "lms1Name",
+ "lms1Secret",
+ "https://www.lms1.com",
+ null,
+ "seb1Name",
+ "seb1Secret",
+ null);
+
+ lmsSetup = new RestAPITestHelper()
+ .withAccessToken(getAdminInstitution1Access())
+ .withPath(SEBServerRestEndpoints.ENDPOINT_LMS_SETUP + "/" + lmsSetup.id)
+ .withMethod(HttpMethod.PUT)
+ .withBodyJson(modified)
+ .withExpectedStatus(HttpStatus.OK)
+ .getAsObject(new TypeReference() {
+ });
+
+ assertNotNull(lmsSetup);
+ assertNotNull(lmsSetup.id);
+ assertTrue(lmsSetup.institutionId.longValue() == 1);
+ assertEquals("new LmsSetup 1", lmsSetup.name);
+ assertTrue(LmsType.MOCKUP == lmsSetup.lmsType);
+ assertEquals("lms1Name", lmsSetup.lmsAuthName);
+ assertEquals("seb1Name", lmsSetup.sebAuthName);
+ // secrets, once set are not exposed
+ assertEquals(null, lmsSetup.lmsAuthSecret);
+ assertEquals(null, lmsSetup.sebAuthSecret);
+ assertFalse(lmsSetup.active);
+
+ // activate
+ EntityProcessingReport report = new RestAPITestHelper()
+ .withAccessToken(getAdminInstitution1Access())
+ .withPath(SEBServerRestEndpoints.ENDPOINT_LMS_SETUP)
+ .withPath("/").withPath(String.valueOf(lmsSetup.id)).withPath("/active")
+ .withMethod(HttpMethod.POST)
+ .withExpectedStatus(HttpStatus.OK)
+ .getAsObject(new TypeReference() {
+ });
+
+ assertNotNull(report);
+ assertNotNull(report.source);
+ assertTrue(report.source.size() == 1);
+ assertEquals(String.valueOf(lmsSetup.id), report.source.iterator().next().modelId);
+ assertEquals("[]", report.dependencies.toString());
+ assertEquals("[]", report.errors.toString());
+
+ // get
+ lmsSetup = new RestAPITestHelper()
+ .withAccessToken(getAdminInstitution1Access())
+ .withPath(SEBServerRestEndpoints.ENDPOINT_LMS_SETUP).withPath("/")
+ .withPath(String.valueOf(lmsSetup.id))
+ .withMethod(HttpMethod.GET)
+ .withExpectedStatus(HttpStatus.OK)
+ .getAsObject(new TypeReference() {
+ });
+
+ assertNotNull(lmsSetup);
+ assertTrue(lmsSetup.active);
+
+ // deactivate
+ report = new RestAPITestHelper()
+ .withAccessToken(getAdminInstitution1Access())
+ .withPath(SEBServerRestEndpoints.ENDPOINT_LMS_SETUP)
+ .withPath("/").withPath(String.valueOf(lmsSetup.id)).withPath("/inactive")
+ .withMethod(HttpMethod.POST)
+ .withExpectedStatus(HttpStatus.OK)
+ .getAsObject(new TypeReference() {
+ });
+
+ assertNotNull(report);
+ assertNotNull(report.source);
+ assertTrue(report.source.size() == 1);
+ assertEquals(String.valueOf(lmsSetup.id), report.source.iterator().next().modelId);
+ assertEquals("[]", report.dependencies.toString());
+ assertEquals("[]", report.errors.toString());
+
+ lmsSetup = new RestAPITestHelper()
+ .withAccessToken(getAdminInstitution1Access())
+ .withPath(SEBServerRestEndpoints.ENDPOINT_LMS_SETUP).withPath("/")
+ .withPath(String.valueOf(lmsSetup.id))
+ .withMethod(HttpMethod.GET)
+ .withExpectedStatus(HttpStatus.OK)
+ .getAsObject(new TypeReference() {
+ });
+
+ assertNotNull(lmsSetup);
+ assertFalse(lmsSetup.active);
+
+ // delete
+ report = new RestAPITestHelper()
+ .withAccessToken(getAdminInstitution1Access())
+ .withPath(SEBServerRestEndpoints.ENDPOINT_LMS_SETUP)
+ .withPath("/").withPath(String.valueOf(lmsSetup.id))
+ .withMethod(HttpMethod.DELETE)
+ .withExpectedStatus(HttpStatus.OK)
+ .getAsObject(new TypeReference() {
+ });
+
+ assertNotNull(report);
+ assertNotNull(report.source);
+ assertTrue(report.source.size() == 1);
+ assertEquals(String.valueOf(lmsSetup.id), report.source.iterator().next().modelId);
+ assertEquals("[]", report.dependencies.toString());
+ assertEquals("[]", report.errors.toString());
+
+ // get
+ final List error = new RestAPITestHelper()
+ .withAccessToken(getAdminInstitution1Access())
+ .withPath(SEBServerRestEndpoints.ENDPOINT_LMS_SETUP).withPath("/")
+ .withPath(String.valueOf(lmsSetup.id))
+ .withMethod(HttpMethod.GET)
+ .withExpectedStatus(HttpStatus.NOT_FOUND)
+ .getAsObject(new TypeReference>() {
+ });
+
+ assertNotNull(error);
+ assertTrue(error.size() > 0);
+ assertEquals("Resource LMS_SETUP with ID: 1 not found", error.get(0).details);
+ }
+
+ @Test
+ public void testValidationOnCreate() throws Exception {
+ // create new institution with seb-admin
+ final List errors = new RestAPITestHelper()
+ .withAccessToken(getAdminInstitution1Access())
+ .withPath(SEBServerRestEndpoints.ENDPOINT_LMS_SETUP)
+ .withMethod(HttpMethod.POST)
+ .withAttribute("name", "new LmsSetup 1")
+ .withAttribute("active", "false")
+ .getAsObject(new TypeReference>() {
+ });
+
+ assertNotNull(errors);
+ assertTrue(errors.size() == 1);
+ assertEquals("Field validation error", errors.get(0).systemMessage);
+ assertEquals("[lmsSetup, lmsType, notNull]", String.valueOf(errors.get(0).attributes));
+ }
+
+}
diff --git a/src/test/resources/application-test.properties b/src/test/resources/application-test.properties
index cc85e990..7ff71ccf 100644
--- a/src/test/resources/application-test.properties
+++ b/src/test/resources/application-test.properties
@@ -16,5 +16,5 @@ sebserver.webservice.api.admin.refreshTokenValiditySeconds=-1
sebserver.webservice.api.exam.endpoint=/exam-api
sebserver.webservice.api.exam.accessTokenValiditySeconds=1800
sebserver.webservice.api.exam.refreshTokenValiditySeconds=-1
-
+sebserver.webservice.internalSecret=TO_SET
sebserver.webservice.api.redirect.unauthorized=none