diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ClientConnectionDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ClientConnectionDAO.java index 0365fd92..6b3d5241 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ClientConnectionDAO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/ClientConnectionDAO.java @@ -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> getsecurityKeyConnectionRecords(Long examId); - Result> 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> getAllActiveNotGranted(Long examId); Result countSignatureHashes(Long examId, String signatureHash); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ClientConnectionDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ClientConnectionDAOImpl.java index 9e7f7573..108e06a5 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ClientConnectionDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/ClientConnectionDAOImpl.java @@ -783,12 +783,15 @@ public class ClientConnectionDAOImpl implements ClientConnectionDAO { @Override @Transactional(readOnly = true) - public Result> getAllActiveNotGranted() { + public Result> 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), diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleAPIRestTemplate.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleAPIRestTemplate.java index 6ec3934d..0faf7031 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleAPIRestTemplate.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleAPIRestTemplate.java @@ -31,8 +31,6 @@ public interface MoodleAPIRestTemplate { String getService(); - void setService(String service); - CharSequence getAccessToken(); void testAPIConnection(String... functions); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleRestTemplateFactory.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleRestTemplateFactory.java index 91291d80..172043c7 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleRestTemplateFactory.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleRestTemplateFactory.java @@ -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 createRestTemplate(); + Result 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 createRestTemplate(final String accessTokenPath); + Result createRestTemplate(String service, String accessTokenPath); } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleRestTemplateFactoryImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleRestTemplateFactoryImpl.java index ac946f49..856f1565 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleRestTemplateFactoryImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleRestTemplateFactoryImpl.java @@ -136,13 +136,13 @@ public class MoodleRestTemplateFactoryImpl implements MoodleRestTemplateFactory } @Override - public Result createRestTemplate() { + public Result 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 createRestTemplate(final String accessTokenPath) { + public Result 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) { diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/legacy/MoodleCourseAccess.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/legacy/MoodleCourseAccess.java index e5c1651f..eca881df 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/legacy/MoodleCourseAccess.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/legacy/MoodleCourseAccess.java @@ -722,7 +722,7 @@ public class MoodleCourseAccess implements CourseAccessAPI { private Result getRestTemplate() { if (this.restTemplate == null) { final Result templateRequest = this.restTemplateFactory - .createRestTemplate(); + .createRestTemplate(MoodleLmsAPITemplateFactory.MOODLE_MOBILE_APP_SERVICE); if (templateRequest.hasError()) { return templateRequest; } else { diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/legacy/MoodleLmsAPITemplateFactory.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/legacy/MoodleLmsAPITemplateFactory.java index ff15d935..8c21f7c1 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/legacy/MoodleLmsAPITemplateFactory.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/legacy/MoodleLmsAPITemplateFactory.java @@ -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; diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodlePluginCheck.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCheck.java similarity index 88% rename from src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodlePluginCheck.java rename to src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCheck.java index fd720eaf..08d74f09 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodlePluginCheck.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCheck.java @@ -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 { diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCourseAccess.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCourseAccess.java index d551e78c..2e3a464e 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCourseAccess.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCourseAccess.java @@ -575,12 +575,11 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme private Result getRestTemplate() { if (this.restTemplate == null) { final Result 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; } } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCourseRestriction.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCourseRestriction.java index b642955b..3fe0eb89 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCourseRestriction.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MoodlePluginCourseRestriction.java @@ -265,12 +265,11 @@ public class MoodlePluginCourseRestriction implements SEBRestrictionAPI { private Result getRestTemplate() { if (this.restTemplate == null) { final Result 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; } } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MooldePluginLmsAPITemplateFactory.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MooldePluginLmsAPITemplateFactory.java index a21622e1..b455e7b8 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MooldePluginLmsAPITemplateFactory.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/plugin/MooldePluginLmsAPITemplateFactory.java @@ -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; diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBClientSessionServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBClientSessionServiceImpl.java index 643ddb36..d9971fec 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBClientSessionServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/session/impl/SEBClientSessionServiceImpl.java @@ -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); + } + } + } diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties index 04d9518a..72d55400 100644 --- a/src/main/resources/messages.properties +++ b/src/main/resources/messages.properties @@ -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 diff --git a/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleMockupRestTemplateFactory.java b/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleMockupRestTemplateFactory.java index a2e1d1e3..fdfdd593 100644 --- a/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleMockupRestTemplateFactory.java +++ b/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/MoodleMockupRestTemplateFactory.java @@ -68,12 +68,12 @@ public class MoodleMockupRestTemplateFactory implements MoodleRestTemplateFactor } @Override - public Result createRestTemplate() { + public Result createRestTemplate(final String service) { return Result.of(new MockupMoodleRestTemplate(this.apiTemplateDataSupplier.getLmsSetup().lmsApiUrl)); } @Override - public Result createRestTemplate(final String accessTokenPath) { + public Result 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; diff --git a/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/legacy/MoodleCourseAccessTest.java b/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/legacy/MoodleCourseAccessTest.java index 58bd4862..920b611e 100644 --- a/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/legacy/MoodleCourseAccessTest.java +++ b/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/moodle/legacy/MoodleCourseAccessTest.java @@ -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(