SEBSERV-372 finished testing with user account
This commit is contained in:
parent
a5bab8fc9f
commit
b9553c93ba
15 changed files with 66 additions and 45 deletions
|
@ -170,7 +170,12 @@ public interface ClientConnectionDAO extends
|
|||
* @return Result refer to a collection of client connection records or to an error when happened */
|
||||
Result<Collection<ClientConnectionRecord>> getsecurityKeyConnectionRecords(Long examId);
|
||||
|
||||
Result<Collection<ClientConnectionRecord>> getAllActiveNotGranted();
|
||||
/** Get all client connection records that don't have an security access grant yet
|
||||
* and for specific exam.
|
||||
*
|
||||
* @param examId The exam identifier
|
||||
* @return Result refer to client connection records to the an error when happened */
|
||||
Result<Collection<ClientConnectionRecord>> getAllActiveNotGranted(Long examId);
|
||||
|
||||
Result<Long> countSignatureHashes(Long examId, String signatureHash);
|
||||
|
||||
|
|
|
@ -783,12 +783,15 @@ public class ClientConnectionDAOImpl implements ClientConnectionDAO {
|
|||
|
||||
@Override
|
||||
@Transactional(readOnly = true)
|
||||
public Result<Collection<ClientConnectionRecord>> getAllActiveNotGranted() {
|
||||
public Result<Collection<ClientConnectionRecord>> getAllActiveNotGranted(final Long examId) {
|
||||
return Result.tryCatch(() -> this.clientConnectionRecordMapper
|
||||
.selectByExample()
|
||||
.where(
|
||||
ClientConnectionRecordDynamicSqlSupport.status,
|
||||
SqlBuilder.isIn(ClientConnection.SECURE_CHECK_STATES))
|
||||
.and(
|
||||
ClientConnectionRecordDynamicSqlSupport.examId,
|
||||
SqlBuilder.isEqualTo(examId))
|
||||
.and(
|
||||
ClientConnectionRecordDynamicSqlSupport.securityCheckGranted,
|
||||
SqlBuilder.isEqualTo(Constants.BYTE_FALSE),
|
||||
|
|
|
@ -31,8 +31,6 @@ public interface MoodleAPIRestTemplate {
|
|||
|
||||
String getService();
|
||||
|
||||
void setService(String service);
|
||||
|
||||
CharSequence getAccessToken();
|
||||
|
||||
void testAPIConnection(String... functions);
|
||||
|
|
|
@ -34,14 +34,16 @@ public interface MoodleRestTemplateFactory {
|
|||
|
||||
/** Creates a MoodleAPIRestTemplate for the bundled LMSSetup of this factory.
|
||||
*
|
||||
* @param service The moodle web service name to within requesting an access token for
|
||||
* @return Result refer to the MoodleAPIRestTemplate or to an error when happened */
|
||||
Result<MoodleAPIRestTemplate> createRestTemplate();
|
||||
Result<MoodleAPIRestTemplate> createRestTemplate(String service);
|
||||
|
||||
/** Creates a MoodleAPIRestTemplate for the bundled LMSSetup of this factory.
|
||||
* Uses specified access token request path to request an access token.
|
||||
*
|
||||
* @param service The moodle web service name to within requesting an access token for
|
||||
* @param accessTokenPath access token request path to request an access token
|
||||
* @return Result refer to the MoodleAPIRestTemplate or to an error when happened */
|
||||
Result<MoodleAPIRestTemplate> createRestTemplate(final String accessTokenPath);
|
||||
Result<MoodleAPIRestTemplate> createRestTemplate(String service, String accessTokenPath);
|
||||
|
||||
}
|
||||
|
|
|
@ -136,13 +136,13 @@ public class MoodleRestTemplateFactoryImpl implements MoodleRestTemplateFactory
|
|||
}
|
||||
|
||||
@Override
|
||||
public Result<MoodleAPIRestTemplate> createRestTemplate() {
|
||||
public Result<MoodleAPIRestTemplate> createRestTemplate(final String service) {
|
||||
|
||||
final LmsSetup lmsSetup = this.apiTemplateDataSupplier.getLmsSetup();
|
||||
|
||||
return this.knownTokenAccessPaths
|
||||
.stream()
|
||||
.map(this::createRestTemplate)
|
||||
.map(path -> this.createRestTemplate(service, path))
|
||||
.map(result -> {
|
||||
if (result.hasError()) {
|
||||
log.warn("Failed to get access token for LMS: {}({})",
|
||||
|
@ -161,7 +161,7 @@ public class MoodleRestTemplateFactoryImpl implements MoodleRestTemplateFactory
|
|||
}
|
||||
|
||||
@Override
|
||||
public Result<MoodleAPIRestTemplate> createRestTemplate(final String accessTokenPath) {
|
||||
public Result<MoodleAPIRestTemplate> createRestTemplate(final String service, final String accessTokenPath) {
|
||||
|
||||
final LmsSetup lmsSetup = this.apiTemplateDataSupplier.getLmsSetup();
|
||||
|
||||
|
@ -182,6 +182,7 @@ public class MoodleRestTemplateFactoryImpl implements MoodleRestTemplateFactory
|
|||
this.apiTemplateDataSupplier,
|
||||
lmsSetup.lmsApiUrl,
|
||||
accessTokenPath,
|
||||
service,
|
||||
plainAPIToken,
|
||||
plainClientId,
|
||||
plainClientSecret);
|
||||
|
@ -205,7 +206,6 @@ public class MoodleRestTemplateFactoryImpl implements MoodleRestTemplateFactory
|
|||
|
||||
public static class MoodleAPIRestTemplateImpl extends RestTemplate implements MoodleAPIRestTemplate {
|
||||
|
||||
private static final String MOODLE_MOBILE_APP_SERVICE = "moodle_mobile_app";
|
||||
private static final String REST_API_TEST_FUNCTION = "core_webservice_get_site_info";
|
||||
|
||||
final JSONMapper jsonMapper;
|
||||
|
@ -225,6 +225,7 @@ public class MoodleRestTemplateFactoryImpl implements MoodleRestTemplateFactory
|
|||
final APITemplateDataSupplier apiTemplateDataSupplier,
|
||||
final String serverURL,
|
||||
final String tokenPath,
|
||||
final String service,
|
||||
final CharSequence apiToken,
|
||||
final CharSequence username,
|
||||
final CharSequence password) {
|
||||
|
@ -240,8 +241,7 @@ public class MoodleRestTemplateFactoryImpl implements MoodleRestTemplateFactory
|
|||
this.tokenReqURIVars = new HashMap<>();
|
||||
this.tokenReqURIVars.put(URI_VAR_USER_NAME, String.valueOf(username));
|
||||
this.tokenReqURIVars.put(URI_VAR_PASSWORD, String.valueOf(password));
|
||||
this.tokenReqURIVars.put(URI_VAR_SERVICE, MOODLE_MOBILE_APP_SERVICE);
|
||||
|
||||
this.tokenReqURIVars.put(URI_VAR_SERVICE, service);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -249,11 +249,6 @@ public class MoodleRestTemplateFactoryImpl implements MoodleRestTemplateFactory
|
|||
return this.tokenReqURIVars.get(URI_VAR_SERVICE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setService(final String service) {
|
||||
this.tokenReqURIVars.put(URI_VAR_SERVICE, service);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getAccessToken() {
|
||||
if (this.accessToken == null) {
|
||||
|
|
|
@ -722,7 +722,7 @@ public class MoodleCourseAccess implements CourseAccessAPI {
|
|||
private Result<MoodleAPIRestTemplate> getRestTemplate() {
|
||||
if (this.restTemplate == null) {
|
||||
final Result<MoodleAPIRestTemplate> templateRequest = this.restTemplateFactory
|
||||
.createRestTemplate();
|
||||
.createRestTemplate(MoodleLmsAPITemplateFactory.MOODLE_MOBILE_APP_SERVICE);
|
||||
if (templateRequest.hasError()) {
|
||||
return templateRequest;
|
||||
} else {
|
||||
|
|
|
@ -36,6 +36,8 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleRestT
|
|||
@WebServiceProfile
|
||||
public class MoodleLmsAPITemplateFactory implements LmsAPITemplateFactory {
|
||||
|
||||
static final String MOODLE_MOBILE_APP_SERVICE = "moodle_mobile_app";
|
||||
|
||||
private final JSONMapper jsonMapper;
|
||||
private final AsyncService asyncService;
|
||||
private final Environment environment;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle;
|
||||
package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.plugin;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
@ -15,7 +15,8 @@ import org.springframework.stereotype.Service;
|
|||
|
||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult;
|
||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.plugin.MoodlePluginCourseAccess;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleAPIRestTemplate;
|
||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleRestTemplateFactory;
|
||||
|
||||
@Lazy
|
||||
@Service
|
||||
|
@ -41,7 +42,7 @@ public class MoodlePluginCheck {
|
|||
}
|
||||
|
||||
final MoodleAPIRestTemplate restTemplate = restTemplateFactory
|
||||
.createRestTemplate()
|
||||
.createRestTemplate(MooldePluginLmsAPITemplateFactory.SEB_SERVER_SERVICE_NAME)
|
||||
.getOrThrow();
|
||||
|
||||
try {
|
|
@ -575,12 +575,11 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme
|
|||
private Result<MoodleAPIRestTemplate> getRestTemplate() {
|
||||
if (this.restTemplate == null) {
|
||||
final Result<MoodleAPIRestTemplate> templateRequest = this.restTemplateFactory
|
||||
.createRestTemplate();
|
||||
.createRestTemplate(MooldePluginLmsAPITemplateFactory.SEB_SERVER_SERVICE_NAME);
|
||||
if (templateRequest.hasError()) {
|
||||
return templateRequest;
|
||||
} else {
|
||||
final MoodleAPIRestTemplate moodleAPIRestTemplate = templateRequest.get();
|
||||
moodleAPIRestTemplate.setService(MooldePluginLmsAPITemplateFactory.SEB_SERVER_SERVICE_NAME);
|
||||
this.restTemplate = moodleAPIRestTemplate;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -265,12 +265,11 @@ public class MoodlePluginCourseRestriction implements SEBRestrictionAPI {
|
|||
private Result<MoodleAPIRestTemplate> getRestTemplate() {
|
||||
if (this.restTemplate == null) {
|
||||
final Result<MoodleAPIRestTemplate> templateRequest = this.restTemplateFactory
|
||||
.createRestTemplate();
|
||||
.createRestTemplate(MooldePluginLmsAPITemplateFactory.SEB_SERVER_SERVICE_NAME);
|
||||
if (templateRequest.hasError()) {
|
||||
return templateRequest;
|
||||
} else {
|
||||
final MoodleAPIRestTemplate moodleAPIRestTemplate = templateRequest.get();
|
||||
moodleAPIRestTemplate.setService(MooldePluginLmsAPITemplateFactory.SEB_SERVER_SERVICE_NAME);
|
||||
this.restTemplate = moodleAPIRestTemplate;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleRestT
|
|||
@WebServiceProfile
|
||||
public class MooldePluginLmsAPITemplateFactory implements LmsAPITemplateFactory {
|
||||
|
||||
public static final String SEB_SERVER_SERVICE_NAME = "seb-server-service";
|
||||
public static final String SEB_SERVER_SERVICE_NAME = "SEB-Server-Webservice";
|
||||
|
||||
private final JSONMapper jsonMapper;
|
||||
private final CacheManager cacheManager;
|
||||
|
|
|
@ -12,11 +12,13 @@ import java.math.BigDecimal;
|
|||
import java.util.Collections;
|
||||
import java.util.Objects;
|
||||
|
||||
import org.apache.commons.lang3.BooleanUtils;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnection;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientConnectionData;
|
||||
import ch.ethz.seb.sebserver.gbl.model.session.ClientEvent;
|
||||
|
@ -92,14 +94,11 @@ public class SEBClientSessionServiceImpl implements SEBClientSessionService {
|
|||
|
||||
@Override
|
||||
public void updateASKGrants() {
|
||||
|
||||
// TODO check only for exams with enabled ASK check!!!
|
||||
|
||||
this.clientConnectionDAO
|
||||
.getAllActiveNotGranted()
|
||||
.onError(error -> log.error("Failed to get none granted active client connections: ", error))
|
||||
.getOr(Collections.emptyList())
|
||||
.forEach(this.securityKeyService::updateAppSignatureKeyGrant);
|
||||
this.examSessionService
|
||||
.getExamDAO()
|
||||
.allRunningExamIds()
|
||||
.onSuccess(ids -> ids.stream().forEach(examId -> updateASKGrant(examId)))
|
||||
.onError(error -> log.error("Unexpected error while trying to updateASKGrants: ", error));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -202,4 +201,21 @@ public class SEBClientSessionServiceImpl implements SEBClientSessionService {
|
|||
}
|
||||
}
|
||||
|
||||
private void updateASKGrant(final Long examId) {
|
||||
if (this.examSessionService
|
||||
.getRunningExam(examId)
|
||||
.map(exam -> exam.getAdditionalAttribute(Exam.ADDITIONAL_ATTR_SIGNATURE_KEY_CHECK_ENABLED))
|
||||
.map(BooleanUtils::toBoolean)
|
||||
.getOr(true)) {
|
||||
|
||||
this.clientConnectionDAO
|
||||
.getAllActiveNotGranted(examId)
|
||||
.onError(error -> log.error(
|
||||
"Failed to get none granted active client connections: ",
|
||||
error))
|
||||
.getOr(Collections.emptyList())
|
||||
.forEach(this.securityKeyService::updateAppSignatureKeyGrant);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -328,7 +328,7 @@ sebserver.useraccount.delete.confirm.message.noDeps=The User Account ({0}) was s
|
|||
|
||||
sebserver.lmssetup.type.MOCKUP=Testing
|
||||
sebserver.lmssetup.type.MOODLE=Moodle
|
||||
sebserver.lmssetup.type.MOODLE_PLUGIN=Moodle Plugin
|
||||
sebserver.lmssetup.type.MOODLE_PLUGIN=Moodle with SEB Server Plugin
|
||||
sebserver.lmssetup.type.MOODLE_PLUGIN.tooltip=Moodle with SEB Server integration plugin installed
|
||||
sebserver.lmssetup.type.OPEN_EDX=Open edX
|
||||
sebserver.lmssetup.type.ANS_DELFT=Ans Delft
|
||||
|
|
|
@ -68,12 +68,12 @@ public class MoodleMockupRestTemplateFactory implements MoodleRestTemplateFactor
|
|||
}
|
||||
|
||||
@Override
|
||||
public Result<MoodleAPIRestTemplate> createRestTemplate() {
|
||||
public Result<MoodleAPIRestTemplate> createRestTemplate(final String service) {
|
||||
return Result.of(new MockupMoodleRestTemplate(this.apiTemplateDataSupplier.getLmsSetup().lmsApiUrl));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Result<MoodleAPIRestTemplate> createRestTemplate(final String accessTokenPath) {
|
||||
public Result<MoodleAPIRestTemplate> createRestTemplate(final String service, final String accessTokenPath) {
|
||||
return Result.of(new MockupMoodleRestTemplate(this.apiTemplateDataSupplier.getLmsSetup().lmsApiUrl));
|
||||
}
|
||||
|
||||
|
@ -101,10 +101,6 @@ public class MoodleMockupRestTemplateFactory implements MoodleRestTemplateFactor
|
|||
return "mockup-service";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setService(final String service) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getAccessToken() {
|
||||
return this.accessToken;
|
||||
|
|
|
@ -16,6 +16,7 @@ import java.util.TreeMap;
|
|||
|
||||
import org.junit.Test;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
|
@ -44,7 +45,8 @@ public class MoodleCourseAccessTest {
|
|||
|
||||
final MoodleRestTemplateFactoryImpl moodleRestTemplateFactory = mock(MoodleRestTemplateFactoryImpl.class);
|
||||
final MoodleAPIRestTemplateImpl moodleAPIRestTemplate = mock(MoodleAPIRestTemplateImpl.class);
|
||||
when(moodleRestTemplateFactory.createRestTemplate()).thenReturn(Result.of(moodleAPIRestTemplate));
|
||||
when(moodleRestTemplateFactory.createRestTemplate(Mockito.anyString()))
|
||||
.thenReturn(Result.of(moodleAPIRestTemplate));
|
||||
when(moodleAPIRestTemplate.callMoodleAPIFunction(
|
||||
anyString(),
|
||||
any())).thenReturn("[\r\n" +
|
||||
|
@ -119,7 +121,8 @@ public class MoodleCourseAccessTest {
|
|||
@Test
|
||||
public void testInitAPIAccessError1() {
|
||||
final MoodleRestTemplateFactoryImpl moodleRestTemplateFactory = mock(MoodleRestTemplateFactoryImpl.class);
|
||||
when(moodleRestTemplateFactory.createRestTemplate()).thenReturn(Result.ofRuntimeError("Error1"));
|
||||
when(moodleRestTemplateFactory.createRestTemplate(Mockito.anyString()))
|
||||
.thenReturn(Result.ofRuntimeError("Error1"));
|
||||
when(moodleRestTemplateFactory.test()).thenReturn(LmsSetupTestResult.ofOkay(LmsType.MOODLE));
|
||||
|
||||
final MoodleCourseAccess moodleCourseAccess = new MoodleCourseAccess(
|
||||
|
@ -140,7 +143,8 @@ public class MoodleCourseAccessTest {
|
|||
public void testInitAPIAccessError2() {
|
||||
final MoodleRestTemplateFactoryImpl moodleRestTemplateFactory = mock(MoodleRestTemplateFactoryImpl.class);
|
||||
final MoodleAPIRestTemplateImpl moodleAPIRestTemplate = mock(MoodleAPIRestTemplateImpl.class);
|
||||
when(moodleRestTemplateFactory.createRestTemplate()).thenReturn(Result.of(moodleAPIRestTemplate));
|
||||
when(moodleRestTemplateFactory.createRestTemplate(Mockito.anyString()))
|
||||
.thenReturn(Result.of(moodleAPIRestTemplate));
|
||||
doThrow(RuntimeException.class).when(moodleAPIRestTemplate).testAPIConnection(any());
|
||||
when(moodleRestTemplateFactory.test()).thenReturn(LmsSetupTestResult.ofOkay(LmsType.MOODLE));
|
||||
|
||||
|
@ -162,7 +166,8 @@ public class MoodleCourseAccessTest {
|
|||
public void testInitAPIAccessOK() {
|
||||
final MoodleRestTemplateFactoryImpl moodleRestTemplateFactory = mock(MoodleRestTemplateFactoryImpl.class);
|
||||
final MoodleAPIRestTemplateImpl moodleAPIRestTemplate = mock(MoodleAPIRestTemplateImpl.class);
|
||||
when(moodleRestTemplateFactory.createRestTemplate()).thenReturn(Result.of(moodleAPIRestTemplate));
|
||||
when(moodleRestTemplateFactory.createRestTemplate(Mockito.anyString()))
|
||||
.thenReturn(Result.of(moodleAPIRestTemplate));
|
||||
when(moodleRestTemplateFactory.test()).thenReturn(LmsSetupTestResult.ofOkay(LmsType.MOODLE));
|
||||
|
||||
final MoodleCourseAccess moodleCourseAccess = new MoodleCourseAccess(
|
||||
|
|
Loading…
Reference in a new issue