SEBSERV-417 access token for Moodle
This commit is contained in:
parent
0f27ef0f38
commit
6e2feafc5a
23 changed files with 241 additions and 86 deletions
|
@ -286,7 +286,7 @@ public class WebserviceInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getOAuthTokenURI() {
|
public String getOAuthTokenURI() {
|
||||||
return getExternalServerURL() + API.OAUTH_ENDPOINT + API.OAUTH_TOKEN_ENDPOINT;
|
return getExternalServerURL() + API.OAUTH_TOKEN_ENDPOINT;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isLightSetup() {
|
public boolean isLightSetup() {
|
||||||
|
|
|
@ -53,4 +53,6 @@ public interface LmsSetupDAO extends ActivatableEntityDAO<LmsSetup, LmsSetup>, B
|
||||||
Result<LmsSetup> setIntegrationActive(Long lmsSetupId, boolean active);
|
Result<LmsSetup> setIntegrationActive(Long lmsSetupId, boolean active);
|
||||||
|
|
||||||
Result<Collection<Long>> idsOfActiveWithFullIntegration(Long institutionId);
|
Result<Collection<Long>> idsOfActiveWithFullIntegration(Long institutionId);
|
||||||
|
|
||||||
|
Result<Collection<Long>> allIdsFullIntegration();
|
||||||
}
|
}
|
||||||
|
|
|
@ -133,6 +133,27 @@ public class LmsSetupDAOImpl implements LmsSetupDAO {
|
||||||
.execute());
|
.execute());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Transactional(readOnly = true)
|
||||||
|
public Result<Collection<Long>> allIdsFullIntegration() {
|
||||||
|
return Result.tryCatch(() -> {
|
||||||
|
final List<String> types = Arrays.stream(LmsType.values())
|
||||||
|
.filter(type -> type.features.contains(LmsSetup.Features.LMS_FULL_INTEGRATION))
|
||||||
|
.map(LmsType::name)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
return this.lmsSetupRecordMapper.selectIdsByExample()
|
||||||
|
.where(
|
||||||
|
LmsSetupRecordDynamicSqlSupport.active,
|
||||||
|
isEqualTo(1))
|
||||||
|
.and(
|
||||||
|
lmsType,
|
||||||
|
isIn(types))
|
||||||
|
.build()
|
||||||
|
.execute();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(readOnly = true)
|
@Transactional(readOnly = true)
|
||||||
public Result<Collection<LmsSetup>> allMatching(
|
public Result<Collection<LmsSetup>> allMatching(
|
||||||
|
|
|
@ -8,11 +8,20 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.webservice.servicelayer.lms;
|
package ch.ethz.seb.sebserver.webservice.servicelayer.lms;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.FullLmsIntegrationService.IntegrationData;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.FullLmsIntegrationService.IntegrationData;
|
||||||
|
|
||||||
public interface FullLmsIntegrationAPI {
|
public interface FullLmsIntegrationAPI {
|
||||||
|
|
||||||
|
/** Performs a test for the underling {@link LmsSetup } configuration and checks if the
|
||||||
|
* LMS and the full LMS integration API of the LMS can be accessed or if there are some difficulties,
|
||||||
|
* missing API functions
|
||||||
|
*
|
||||||
|
* @return {@link LmsSetupTestResult } instance with the test result report */
|
||||||
|
LmsSetupTestResult testFullIntegrationAPI();
|
||||||
|
|
||||||
Result<IntegrationData> applyConnectionDetails(IntegrationData data);
|
Result<IntegrationData> applyConnectionDetails(IntegrationData data);
|
||||||
|
|
||||||
Result<Void> deleteConnectionDetails();
|
Result<Void> deleteConnectionDetails();
|
||||||
|
|
|
@ -10,6 +10,8 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl;
|
||||||
|
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -61,7 +63,7 @@ public class FullLmsIntegrationServiceImpl implements FullLmsIntegrationService
|
||||||
private final ExamTemplateDAO examTemplateDAO;
|
private final ExamTemplateDAO examTemplateDAO;
|
||||||
private final WebserviceInfo webserviceInfo;
|
private final WebserviceInfo webserviceInfo;
|
||||||
|
|
||||||
//private final ClientCredentialsResourceDetails resource;
|
private final ClientCredentialsResourceDetails resource;
|
||||||
|
|
||||||
private final OAuth2RestTemplate restTemplate;
|
private final OAuth2RestTemplate restTemplate;
|
||||||
|
|
||||||
|
@ -83,7 +85,7 @@ public class FullLmsIntegrationServiceImpl implements FullLmsIntegrationService
|
||||||
this.examTemplateDAO = examTemplateDAO;
|
this.examTemplateDAO = examTemplateDAO;
|
||||||
this.webserviceInfo = webserviceInfo;
|
this.webserviceInfo = webserviceInfo;
|
||||||
|
|
||||||
final ClientCredentialsResourceDetails resource = new ClientCredentialsResourceDetails();
|
resource = new ClientCredentialsResourceDetails();
|
||||||
resource.setAccessTokenUri(webserviceInfo.getOAuthTokenURI());
|
resource.setAccessTokenUri(webserviceInfo.getOAuthTokenURI());
|
||||||
resource.setClientId(clientId);
|
resource.setClientId(clientId);
|
||||||
resource.setClientSecret(clientSecret);
|
resource.setClientSecret(clientSecret);
|
||||||
|
@ -104,10 +106,18 @@ public class FullLmsIntegrationServiceImpl implements FullLmsIntegrationService
|
||||||
@Override
|
@Override
|
||||||
public void notifyLmsSetupChange(final LmsSetupChangeEvent event) {
|
public void notifyLmsSetupChange(final LmsSetupChangeEvent event) {
|
||||||
final LmsSetup lmsSetup = event.getLmsSetup();
|
final LmsSetup lmsSetup = event.getLmsSetup();
|
||||||
if (lmsSetup.integrationActive) {
|
if (!lmsSetup.getLmsType().features.contains(LmsSetup.Features.LMS_FULL_INTEGRATION)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lmsSetup.active) {
|
||||||
applyFullLmsIntegration(lmsSetup.id)
|
applyFullLmsIntegration(lmsSetup.id)
|
||||||
.onError(error -> log.warn("Failed to update LMS integration for: {}", lmsSetup, error))
|
.onError(error -> log.warn("Failed to update LMS integration for: {}", lmsSetup, error))
|
||||||
.onSuccess( data -> log.debug("Successfully updated LMS integration for: {} data: {}", lmsSetup, data));
|
.onSuccess(data -> log.debug("Successfully updated LMS integration for: {} data: {}", lmsSetup, data));
|
||||||
|
} else if (lmsSetup.integrationActive) {
|
||||||
|
deleteFullLmsIntegration(lmsSetup.id)
|
||||||
|
.onError(error -> log.warn("Failed to delete LMS integration for: {}", lmsSetup, error))
|
||||||
|
.onSuccess(data -> log.debug("Successfully deleted LMS integration for: {} data: {}", lmsSetup, data));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -144,11 +154,16 @@ public class FullLmsIntegrationServiceImpl implements FullLmsIntegrationService
|
||||||
throw new IllegalStateException("No LMS Setup connectionId available for: " + lmsSetup);
|
throw new IllegalStateException("No LMS Setup connectionId available for: " + lmsSetup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reset old token to get actual one
|
||||||
|
resource.setScope(Arrays.asList(String.valueOf(lmsSetupId)));
|
||||||
|
restTemplate.getOAuth2ClientContext().setAccessToken(null);
|
||||||
|
final String accessToken = restTemplate.getAccessToken().getValue();
|
||||||
|
|
||||||
final IntegrationData data = new IntegrationData(
|
final IntegrationData data = new IntegrationData(
|
||||||
connectionId,
|
connectionId,
|
||||||
lmsSetup.name,
|
lmsSetup.name,
|
||||||
webserviceInfo.getExternalServerURL(),
|
webserviceInfo.getExternalServerURL(),
|
||||||
restTemplate.getAccessToken().getValue(),
|
accessToken,
|
||||||
this.getIntegrationTemplates(lmsSetup.institutionId)
|
this.getIntegrationTemplates(lmsSetup.institutionId)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -156,8 +156,17 @@ public class LmsAPIServiceImpl implements LmsAPIService {
|
||||||
final LmsSetupTestResult lmsSetupTestResult = template.testCourseRestrictionAPI();
|
final LmsSetupTestResult lmsSetupTestResult = template.testCourseRestrictionAPI();
|
||||||
if (!lmsSetupTestResult.isOk()) {
|
if (!lmsSetupTestResult.isOk()) {
|
||||||
this.cache.remove(new CacheKey(template.lmsSetup().getModelId(), 0));
|
this.cache.remove(new CacheKey(template.lmsSetup().getModelId(), 0));
|
||||||
|
return lmsSetupTestResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (template.lmsSetup().getLmsType().features.contains(LmsSetup.Features.LMS_FULL_INTEGRATION)) {
|
||||||
|
final LmsSetupTestResult lmsSetupTestResult = template.testFullIntegrationAPI();
|
||||||
|
if (!lmsSetupTestResult.isOk()) {
|
||||||
|
this.cache.remove(new CacheKey(template.lmsSetup().getModelId(), 0));
|
||||||
|
return lmsSetupTestResult;
|
||||||
}
|
}
|
||||||
return lmsSetupTestResult;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return LmsSetupTestResult.ofOkay(template.lmsSetup().getLmsType());
|
return LmsSetupTestResult.ofOkay(template.lmsSetup().getLmsType());
|
||||||
|
@ -184,8 +193,19 @@ public class LmsAPIServiceImpl implements LmsAPIService {
|
||||||
return testCourseAccessAPI;
|
return testCourseAccessAPI;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lmsSetupTemplate.lmsSetup().getLmsType().features.contains(LmsSetup.Features.SEB_RESTRICTION)) {
|
final LmsType lmsType = lmsSetupTemplate.lmsSetup().getLmsType();
|
||||||
return lmsSetupTemplate.testCourseRestrictionAPI();
|
if (lmsType.features.contains(LmsSetup.Features.SEB_RESTRICTION)) {
|
||||||
|
final LmsSetupTestResult lmsSetupTestResult = lmsSetupTemplate.testCourseRestrictionAPI();
|
||||||
|
if (!lmsSetupTestResult.isOk()) {
|
||||||
|
return lmsSetupTestResult;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lmsType.features.contains(LmsSetup.Features.LMS_FULL_INTEGRATION)) {
|
||||||
|
final LmsSetupTestResult lmsSetupTestResult = lmsSetupTemplate.testFullIntegrationAPI();
|
||||||
|
if (!lmsSetupTestResult.isOk()) {
|
||||||
|
return lmsSetupTestResult;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return LmsSetupTestResult.ofOkay(lmsSetupTemplate.lmsSetup().getLmsType());
|
return LmsSetupTestResult.ofOkay(lmsSetupTemplate.lmsSetup().getLmsType());
|
||||||
|
|
|
@ -397,10 +397,6 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate {
|
||||||
return this.sebRestrictionAPI.testCourseRestrictionAPI();
|
return this.sebRestrictionAPI.testCourseRestrictionAPI();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (log.isDebugEnabled()) {
|
|
||||||
log.debug("Test course restriction API for LMSSetup: {}", lmsSetup());
|
|
||||||
}
|
|
||||||
|
|
||||||
return LmsSetupTestResult.ofAPINotSupported(getType());
|
return LmsSetupTestResult.ofAPINotSupported(getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -476,6 +472,16 @@ public class LmsAPITemplateAdapter implements LmsAPITemplate {
|
||||||
return protectedRun;
|
return protectedRun;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LmsSetupTestResult testFullIntegrationAPI() {
|
||||||
|
if (this.lmsIntegrationAPI != null) {
|
||||||
|
return this.lmsIntegrationAPI.testFullIntegrationAPI();
|
||||||
|
}
|
||||||
|
|
||||||
|
return LmsSetupTestResult.ofAPINotSupported(getType());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<IntegrationData> applyConnectionDetails(final IntegrationData data) {
|
public Result<IntegrationData> applyConnectionDetails(final IntegrationData data) {
|
||||||
if (this.lmsIntegrationAPI == null) {
|
if (this.lmsIntegrationAPI == null) {
|
||||||
|
|
|
@ -421,6 +421,11 @@ public class AnsLmsAPITemplate extends AbstractCachedCourseAccess implements Lms
|
||||||
.map(x -> exam);
|
.map(x -> exam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LmsSetupTestResult testFullIntegrationAPI() {
|
||||||
|
return LmsSetupTestResult.ofAPINotSupported(LmsType.ANS_DELFT);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<IntegrationData> applyConnectionDetails(final IntegrationData data) {
|
public Result<IntegrationData> applyConnectionDetails(final IntegrationData data) {
|
||||||
return Result.ofRuntimeError("Not Supported");
|
return Result.ofRuntimeError("Not Supported");
|
||||||
|
|
|
@ -8,12 +8,18 @@
|
||||||
|
|
||||||
package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.mockup;
|
package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.mockup;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.FullLmsIntegrationAPI;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.FullLmsIntegrationAPI;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.FullLmsIntegrationService.IntegrationData;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.FullLmsIntegrationService.IntegrationData;
|
||||||
|
|
||||||
public class MockupFullIntegration implements FullLmsIntegrationAPI {
|
public class MockupFullIntegration implements FullLmsIntegrationAPI {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LmsSetupTestResult testFullIntegrationAPI() {
|
||||||
|
return LmsSetupTestResult.ofAPINotSupported(LmsSetup.LmsType.MOODLE_PLUGIN);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<IntegrationData> applyConnectionDetails(final IntegrationData data) {
|
public Result<IntegrationData> applyConnectionDetails(final IntegrationData data) {
|
||||||
|
|
|
@ -32,6 +32,8 @@ public interface MoodleRestTemplateFactory {
|
||||||
* @return Set of known and configured API access token paths */
|
* @return Set of known and configured API access token paths */
|
||||||
Set<String> getKnownTokenAccessPaths();
|
Set<String> getKnownTokenAccessPaths();
|
||||||
|
|
||||||
|
Result<MoodleAPIRestTemplate> getRestTemplate();
|
||||||
|
|
||||||
/** Creates a MoodleAPIRestTemplate for the bundled LMSSetup of this factory.
|
/** Creates a MoodleAPIRestTemplate for the bundled LMSSetup of this factory.
|
||||||
*
|
*
|
||||||
* @param service The moodle web service name to within requesting an access token for
|
* @param service The moodle web service name to within requesting an access token for
|
||||||
|
|
|
@ -63,6 +63,8 @@ public class MoodleRestTemplateFactoryImpl implements MoodleRestTemplateFactory
|
||||||
public final ClientCredentialService clientCredentialService;
|
public final ClientCredentialService clientCredentialService;
|
||||||
public final Set<String> knownTokenAccessPaths;
|
public final Set<String> knownTokenAccessPaths;
|
||||||
|
|
||||||
|
private Result<MoodleAPIRestTemplate> activeRestTemplate = Result.ofRuntimeError("Not Initialized");
|
||||||
|
|
||||||
public MoodleRestTemplateFactoryImpl(
|
public MoodleRestTemplateFactoryImpl(
|
||||||
final JSONMapper jsonMapper,
|
final JSONMapper jsonMapper,
|
||||||
final APITemplateDataSupplier apiTemplateDataSupplier,
|
final APITemplateDataSupplier apiTemplateDataSupplier,
|
||||||
|
@ -88,6 +90,11 @@ public class MoodleRestTemplateFactoryImpl implements MoodleRestTemplateFactory
|
||||||
return this.knownTokenAccessPaths;
|
return this.knownTokenAccessPaths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result<MoodleAPIRestTemplate> getRestTemplate() {
|
||||||
|
return activeRestTemplate;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public APITemplateDataSupplier getApiTemplateDataSupplier() {
|
public APITemplateDataSupplier getApiTemplateDataSupplier() {
|
||||||
return this.apiTemplateDataSupplier;
|
return this.apiTemplateDataSupplier;
|
||||||
|
@ -139,13 +146,12 @@ public class MoodleRestTemplateFactoryImpl implements MoodleRestTemplateFactory
|
||||||
public Result<MoodleAPIRestTemplate> createRestTemplate(final String service) {
|
public Result<MoodleAPIRestTemplate> createRestTemplate(final String service) {
|
||||||
|
|
||||||
final LmsSetup lmsSetup = this.apiTemplateDataSupplier.getLmsSetup();
|
final LmsSetup lmsSetup = this.apiTemplateDataSupplier.getLmsSetup();
|
||||||
|
this. activeRestTemplate = this.knownTokenAccessPaths
|
||||||
return this.knownTokenAccessPaths
|
|
||||||
.stream()
|
.stream()
|
||||||
.map(path -> this.createRestTemplate(service, path))
|
.map(path -> this.createRestTemplate(service, path))
|
||||||
.map(result -> {
|
.map(result -> {
|
||||||
if (result.hasError()) {
|
if (result.hasError()) {
|
||||||
log.warn("Failed to get access token for LMS: {}({})",
|
log.warn("Failed to get access token for LMS: {}({}), error {}",
|
||||||
lmsSetup.name,
|
lmsSetup.name,
|
||||||
lmsSetup.id,
|
lmsSetup.id,
|
||||||
result.getError().getMessage());
|
result.getError().getMessage());
|
||||||
|
@ -158,6 +164,10 @@ public class MoodleRestTemplateFactoryImpl implements MoodleRestTemplateFactory
|
||||||
"Failed to gain any access for LMS " +
|
"Failed to gain any access for LMS " +
|
||||||
lmsSetup.name + "(" + lmsSetup.id +
|
lmsSetup.name + "(" + lmsSetup.id +
|
||||||
") on paths: " + this.knownTokenAccessPaths));
|
") on paths: " + this.knownTokenAccessPaths));
|
||||||
|
|
||||||
|
log.info("Created new MoodleAPIRestTemplate for service: {} factory: {}", service, this.hashCode());
|
||||||
|
|
||||||
|
return activeRestTemplate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -199,6 +209,7 @@ public class MoodleRestTemplateFactoryImpl implements MoodleRestTemplateFactory
|
||||||
") on path: " + accessTokenPath);
|
") on path: " + accessTokenPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
activeRestTemplate = Result.of(restTemplate);
|
||||||
return restTemplate;
|
return restTemplate;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -266,7 +277,7 @@ public class MoodleRestTemplateFactoryImpl implements MoodleRestTemplateFactory
|
||||||
WebserviceInfo.class);
|
WebserviceInfo.class);
|
||||||
|
|
||||||
if (StringUtils.isBlank(webserviceInfo.username) || StringUtils.isBlank(webserviceInfo.userid)) {
|
if (StringUtils.isBlank(webserviceInfo.username) || StringUtils.isBlank(webserviceInfo.userid)) {
|
||||||
throw new RuntimeException("Invalid WebserviceInfo: " + webserviceInfo);
|
throw new RuntimeException("Invalid WebserviceInfo Response");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (functions != null) {
|
if (functions != null) {
|
||||||
|
@ -281,8 +292,10 @@ public class MoodleRestTemplateFactoryImpl implements MoodleRestTemplateFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (final RuntimeException re) {
|
} catch (final RuntimeException re) {
|
||||||
|
log.warn("Failed to Moodle API access: {}", re.getMessage());
|
||||||
throw re;
|
throw re;
|
||||||
} catch (final Exception e) {
|
} catch (final Exception e) {
|
||||||
|
log.warn("Failed to Moodle API access: {}", e.getMessage());
|
||||||
throw new RuntimeException("Failed to test Moodle rest API: ", e);
|
throw new RuntimeException("Failed to test Moodle rest API: ", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,7 +118,7 @@ public abstract class MoodleUtils {
|
||||||
return idNumber.equals(Constants.EMPTY_NOTE) ? null : idNumber;
|
return idNumber.equals(Constants.EMPTY_NOTE) ? null : idNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final void logMoodleWarning(
|
public static void logMoodleWarning(
|
||||||
final Collection<Warning> warnings,
|
final Collection<Warning> warnings,
|
||||||
final String lmsSetupName,
|
final String lmsSetupName,
|
||||||
final String function) {
|
final String function) {
|
||||||
|
@ -148,7 +148,7 @@ public abstract class MoodleUtils {
|
||||||
private static final Pattern ACCESS_DENIED_PATTERN_2 =
|
private static final Pattern ACCESS_DENIED_PATTERN_2 =
|
||||||
Pattern.compile(Pattern.quote("access denied"), Pattern.CASE_INSENSITIVE);
|
Pattern.compile(Pattern.quote("access denied"), Pattern.CASE_INSENSITIVE);
|
||||||
|
|
||||||
public static final boolean checkAccessDeniedError(final String courseKeyPageJSON) {
|
public static boolean checkAccessDeniedError(final String courseKeyPageJSON) {
|
||||||
return ACCESS_DENIED_PATTERN_1
|
return ACCESS_DENIED_PATTERN_1
|
||||||
.matcher(courseKeyPageJSON)
|
.matcher(courseKeyPageJSON)
|
||||||
.find() ||
|
.find() ||
|
||||||
|
|
|
@ -20,6 +20,7 @@ import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.plugin.MooldePluginLmsAPITemplateFactory;
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -103,7 +104,6 @@ public class MoodleCourseAccess implements CourseAccessAPI {
|
||||||
private final int pageSize;
|
private final int pageSize;
|
||||||
private final int maxSize;
|
private final int maxSize;
|
||||||
|
|
||||||
private MoodleAPIRestTemplate restTemplate;
|
|
||||||
|
|
||||||
public MoodleCourseAccess(
|
public MoodleCourseAccess(
|
||||||
final JSONMapper jsonMapper,
|
final JSONMapper jsonMapper,
|
||||||
|
@ -583,17 +583,12 @@ public class MoodleCourseAccess implements CourseAccessAPI {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result<MoodleAPIRestTemplate> getRestTemplate() {
|
private Result<MoodleAPIRestTemplate> getRestTemplate() {
|
||||||
if (this.restTemplate == null) {
|
final Result<MoodleAPIRestTemplate> result = this.restTemplateFactory.getRestTemplate();
|
||||||
final Result<MoodleAPIRestTemplate> templateRequest = this.restTemplateFactory
|
if (!result.hasError()) {
|
||||||
.createRestTemplate(MoodleLmsAPITemplateFactory.MOODLE_MOBILE_APP_SERVICE);
|
return result;
|
||||||
if (templateRequest.hasError()) {
|
|
||||||
return templateRequest;
|
|
||||||
} else {
|
|
||||||
this.restTemplate = templateRequest.get();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result.of(this.restTemplate);
|
return this.restTemplateFactory.createRestTemplate(MoodleLmsAPITemplateFactory.MOODLE_MOBILE_APP_SERVICE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Collection<CourseData> getCoursesPage(
|
private Collection<CourseData> getCoursesPage(
|
||||||
|
|
|
@ -98,8 +98,6 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme
|
||||||
private final int cutoffTimeOffset;
|
private final int cutoffTimeOffset;
|
||||||
private final boolean applyNameCriteria;
|
private final boolean applyNameCriteria;
|
||||||
|
|
||||||
private MoodleAPIRestTemplate restTemplate;
|
|
||||||
|
|
||||||
public MoodlePluginCourseAccess(
|
public MoodlePluginCourseAccess(
|
||||||
final JSONMapper jsonMapper,
|
final JSONMapper jsonMapper,
|
||||||
final AsyncService asyncService,
|
final AsyncService asyncService,
|
||||||
|
@ -595,19 +593,12 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result<MoodleAPIRestTemplate> getRestTemplate() {
|
private Result<MoodleAPIRestTemplate> getRestTemplate() {
|
||||||
|
final Result<MoodleAPIRestTemplate> result = this.restTemplateFactory.getRestTemplate();
|
||||||
if (this.restTemplate == null) {
|
if (!result.hasError()) {
|
||||||
|
return result;
|
||||||
final Result<MoodleAPIRestTemplate> templateRequest = this.restTemplateFactory
|
|
||||||
.createRestTemplate(MooldePluginLmsAPITemplateFactory.SEB_SERVER_SERVICE_NAME);
|
|
||||||
if (templateRequest.hasError()) {
|
|
||||||
return templateRequest;
|
|
||||||
} else {
|
|
||||||
this.restTemplate = templateRequest.get();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result.of(this.restTemplate);
|
return this.restTemplateFactory.createRestTemplate(MooldePluginLmsAPITemplateFactory.SEB_SERVER_SERVICE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String toTestString() {
|
protected String toTestString() {
|
||||||
|
@ -619,7 +610,7 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme
|
||||||
builder.append(", cutoffTimeOffset=");
|
builder.append(", cutoffTimeOffset=");
|
||||||
builder.append(this.cutoffTimeOffset);
|
builder.append(this.cutoffTimeOffset);
|
||||||
builder.append(", restTemplate=");
|
builder.append(", restTemplate=");
|
||||||
builder.append(this.restTemplate);
|
builder.append(this.getRestTemplate().getOr(null));
|
||||||
builder.append("]");
|
builder.append("]");
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,8 +55,6 @@ public class MoodlePluginCourseRestriction implements SEBRestrictionAPI {
|
||||||
private final MoodleRestTemplateFactory restTemplateFactory;
|
private final MoodleRestTemplateFactory restTemplateFactory;
|
||||||
private final ExamConfigurationValueService examConfigurationValueService;
|
private final ExamConfigurationValueService examConfigurationValueService;
|
||||||
|
|
||||||
private MoodleAPIRestTemplate restTemplate;
|
|
||||||
|
|
||||||
public MoodlePluginCourseRestriction(
|
public MoodlePluginCourseRestriction(
|
||||||
final JSONMapper jsonMapper,
|
final JSONMapper jsonMapper,
|
||||||
final MoodleRestTemplateFactory restTemplateFactory,
|
final MoodleRestTemplateFactory restTemplateFactory,
|
||||||
|
@ -90,7 +88,6 @@ public class MoodlePluginCourseRestriction implements SEBRestrictionAPI {
|
||||||
RESTRICTION_SET_FUNCTION_NAME);
|
RESTRICTION_SET_FUNCTION_NAME);
|
||||||
|
|
||||||
} catch (final RuntimeException e) {
|
} catch (final RuntimeException e) {
|
||||||
log.error("Failed to access Moodle course API: ", e);
|
|
||||||
return LmsSetupTestResult.ofQuizAccessAPIError(LmsType.MOODLE_PLUGIN, e.getMessage());
|
return LmsSetupTestResult.ofQuizAccessAPIError(LmsType.MOODLE_PLUGIN, e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -285,24 +282,18 @@ public class MoodlePluginCourseRestriction implements SEBRestrictionAPI {
|
||||||
}
|
}
|
||||||
|
|
||||||
private Result<MoodleAPIRestTemplate> getRestTemplate() {
|
private Result<MoodleAPIRestTemplate> getRestTemplate() {
|
||||||
if (this.restTemplate == null) {
|
final Result<MoodleAPIRestTemplate> result = this.restTemplateFactory.getRestTemplate();
|
||||||
|
if (!result.hasError()) {
|
||||||
final Result<MoodleAPIRestTemplate> templateRequest = this.restTemplateFactory
|
return result;
|
||||||
.createRestTemplate(MooldePluginLmsAPITemplateFactory.SEB_SERVER_SERVICE_NAME);
|
|
||||||
if (templateRequest.hasError()) {
|
|
||||||
return templateRequest;
|
|
||||||
} else {
|
|
||||||
this.restTemplate = templateRequest.get();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result.of(this.restTemplate);
|
return this.restTemplateFactory.createRestTemplate(MooldePluginLmsAPITemplateFactory.SEB_SERVER_SERVICE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toTestString() {
|
public String toTestString() {
|
||||||
final StringBuilder builder = new StringBuilder();
|
final StringBuilder builder = new StringBuilder();
|
||||||
builder.append("MoodlePluginCourseRestriction [restTemplate=");
|
builder.append("MoodlePluginCourseRestriction [restTemplate=");
|
||||||
builder.append(this.restTemplate);
|
builder.append(this.getRestTemplate().getOr(null));
|
||||||
builder.append("]");
|
builder.append("]");
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.plugin;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
|
import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
|
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.FullLmsIntegrationService.IntegrationData;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.FullLmsIntegrationService.IntegrationData;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.FullLmsIntegrationAPI;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.FullLmsIntegrationAPI;
|
||||||
|
@ -32,8 +33,6 @@ public class MoodlePluginFullIntegration implements FullLmsIntegrationAPI {
|
||||||
private final JSONMapper jsonMapper;
|
private final JSONMapper jsonMapper;
|
||||||
private final MoodleRestTemplateFactory restTemplateFactory;
|
private final MoodleRestTemplateFactory restTemplateFactory;
|
||||||
|
|
||||||
private MoodleAPIRestTemplate restTemplate;
|
|
||||||
|
|
||||||
public MoodlePluginFullIntegration(
|
public MoodlePluginFullIntegration(
|
||||||
final JSONMapper jsonMapper,
|
final JSONMapper jsonMapper,
|
||||||
final MoodleRestTemplateFactory restTemplateFactory) {
|
final MoodleRestTemplateFactory restTemplateFactory) {
|
||||||
|
@ -42,6 +41,34 @@ public class MoodlePluginFullIntegration implements FullLmsIntegrationAPI {
|
||||||
this.restTemplateFactory = restTemplateFactory;
|
this.restTemplateFactory = restTemplateFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LmsSetupTestResult testFullIntegrationAPI() {
|
||||||
|
final LmsSetupTestResult attributesCheck = this.restTemplateFactory.test();
|
||||||
|
if (!attributesCheck.isOk()) {
|
||||||
|
return attributesCheck;
|
||||||
|
}
|
||||||
|
|
||||||
|
final Result<MoodleAPIRestTemplate> restTemplateRequest = getRestTemplate();
|
||||||
|
if (restTemplateRequest.hasError()) {
|
||||||
|
final String message = "Failed to gain access token from Moodle Rest API:\n tried token endpoints: " +
|
||||||
|
this.restTemplateFactory.getKnownTokenAccessPaths();
|
||||||
|
log.error(message + " cause: {}", restTemplateRequest.getError().getMessage());
|
||||||
|
return LmsSetupTestResult.ofTokenRequestError(LmsSetup.LmsType.MOODLE_PLUGIN, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
final MoodleAPIRestTemplate restTemplate = restTemplateRequest.get();
|
||||||
|
restTemplate.testAPIConnection(
|
||||||
|
FUNCTION_NAME_SEBSERVER_CONNECTION,
|
||||||
|
FUNCTION_NAME_SEBSERVER_CONNECTION_DELETE);
|
||||||
|
|
||||||
|
} catch (final RuntimeException e) {
|
||||||
|
return LmsSetupTestResult.ofQuizAccessAPIError(LmsSetup.LmsType.MOODLE_PLUGIN, e.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
return LmsSetupTestResult.ofOkay(LmsSetup.LmsType.MOODLE_PLUGIN);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<IntegrationData> applyConnectionDetails(final IntegrationData data) {
|
public Result<IntegrationData> applyConnectionDetails(final IntegrationData data) {
|
||||||
return Result.tryCatch(() -> {
|
return Result.tryCatch(() -> {
|
||||||
|
@ -116,17 +143,11 @@ public class MoodlePluginFullIntegration implements FullLmsIntegrationAPI {
|
||||||
|
|
||||||
private Result<MoodleAPIRestTemplate> getRestTemplate() {
|
private Result<MoodleAPIRestTemplate> getRestTemplate() {
|
||||||
|
|
||||||
if (this.restTemplate == null) {
|
final Result<MoodleAPIRestTemplate> result = this.restTemplateFactory.getRestTemplate();
|
||||||
|
if (!result.hasError()) {
|
||||||
final Result<MoodleAPIRestTemplate> templateRequest = this.restTemplateFactory
|
return result;
|
||||||
.createRestTemplate(MooldePluginLmsAPITemplateFactory.SEB_SERVER_SERVICE_NAME);
|
|
||||||
if (templateRequest.hasError()) {
|
|
||||||
return templateRequest;
|
|
||||||
} else {
|
|
||||||
this.restTemplate = templateRequest.get();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Result.of(this.restTemplate);
|
return this.restTemplateFactory.createRestTemplate(MooldePluginLmsAPITemplateFactory.SEB_SERVER_SERVICE_NAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -408,6 +408,11 @@ public class OlatLmsAPITemplate extends AbstractCachedCourseAccess implements Lm
|
||||||
.map(x -> exam);
|
.map(x -> exam);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LmsSetupTestResult testFullIntegrationAPI() {
|
||||||
|
return LmsSetupTestResult.ofAPINotSupported(LmsType.OPEN_OLAT);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<IntegrationData> applyConnectionDetails(final IntegrationData data) {
|
public Result<IntegrationData> applyConnectionDetails(final IntegrationData data) {
|
||||||
return Result.ofRuntimeError("Not Supported");
|
return Result.ofRuntimeError("Not Supported");
|
||||||
|
|
|
@ -10,35 +10,65 @@ package ch.ethz.seb.sebserver.webservice.weblayer.oauth;
|
||||||
|
|
||||||
import ch.ethz.seb.sebserver.WebSecurityConfig;
|
import ch.ethz.seb.sebserver.WebSecurityConfig;
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
|
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.LmsSetupDAO;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
import org.springframework.beans.factory.annotation.Qualifier;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.context.annotation.Lazy;
|
import org.springframework.context.annotation.Lazy;
|
||||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||||
|
import org.springframework.security.oauth2.provider.ClientDetails;
|
||||||
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
|
import org.springframework.security.oauth2.provider.client.BaseClientDetails;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
@Lazy
|
@Lazy
|
||||||
@Component
|
@Component
|
||||||
public class LmsAPIClientDetails extends BaseClientDetails {
|
public class LmsAPIClientDetails {
|
||||||
|
|
||||||
|
private final PasswordEncoder clientPasswordEncoder;
|
||||||
|
private final String clientId;
|
||||||
|
private final String clientSecret;
|
||||||
|
private final Integer accessTokenValiditySeconds;
|
||||||
|
private final LmsSetupDAO lmsSetupDAO;
|
||||||
|
|
||||||
public LmsAPIClientDetails(
|
public LmsAPIClientDetails(
|
||||||
@Qualifier(WebSecurityConfig.CLIENT_PASSWORD_ENCODER_BEAN_NAME) final PasswordEncoder clientPasswordEncoder,
|
@Qualifier(WebSecurityConfig.CLIENT_PASSWORD_ENCODER_BEAN_NAME) final PasswordEncoder clientPasswordEncoder,
|
||||||
|
final LmsSetupDAO lmsSetupDAO,
|
||||||
@Value("${sebserver.webservice.lms.api.clientId}") final String clientId,
|
@Value("${sebserver.webservice.lms.api.clientId}") final String clientId,
|
||||||
@Value("${sebserver.webservice.api.admin.clientSecret}") final String clientSecret,
|
@Value("${sebserver.webservice.api.admin.clientSecret}") final String clientSecret,
|
||||||
@Value("${sebserver.webservice.lms.api.accessTokenValiditySeconds:-1}") final Integer accessTokenValiditySeconds
|
@Value("${sebserver.webservice.lms.api.accessTokenValiditySeconds:-1}") final Integer accessTokenValiditySeconds
|
||||||
) {
|
) {
|
||||||
super(
|
this.clientPasswordEncoder = clientPasswordEncoder;
|
||||||
|
this.lmsSetupDAO = lmsSetupDAO;
|
||||||
|
this.clientId = clientId;
|
||||||
|
this.clientSecret = clientSecret;
|
||||||
|
this.accessTokenValiditySeconds = accessTokenValiditySeconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getClientId() {
|
||||||
|
return clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// It seems this get called multiple times per token request
|
||||||
|
// TODO do we need very short time caching here?
|
||||||
|
|
||||||
|
public ClientDetails getClientDetails() {
|
||||||
|
|
||||||
|
final String joinIds = StringUtils.join(
|
||||||
|
lmsSetupDAO.allIdsFullIntegration().getOrThrow(),
|
||||||
|
Constants.LIST_SEPARATOR
|
||||||
|
);
|
||||||
|
|
||||||
|
final BaseClientDetails clientDetails = new BaseClientDetails(
|
||||||
clientId,
|
clientId,
|
||||||
WebserviceResourceConfiguration.LMS_API_RESOURCE_ID,
|
WebserviceResourceConfiguration.LMS_API_RESOURCE_ID,
|
||||||
StringUtils.joinWith(
|
joinIds,
|
||||||
Constants.LIST_SEPARATOR,
|
|
||||||
Constants.OAUTH2_SCOPE_READ,
|
|
||||||
Constants.OAUTH2_SCOPE_WRITE),
|
|
||||||
Constants.OAUTH2_GRANT_TYPE_CLIENT_CREDENTIALS,
|
Constants.OAUTH2_GRANT_TYPE_CLIENT_CREDENTIALS,
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
super.setClientSecret(clientPasswordEncoder.encode(clientSecret));
|
clientDetails.setClientSecret(clientPasswordEncoder.encode(clientSecret));
|
||||||
super.setAccessTokenValiditySeconds(accessTokenValiditySeconds);
|
clientDetails.setAccessTokenValiditySeconds(accessTokenValiditySeconds);
|
||||||
|
return clientDetails;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,7 +68,7 @@ public class WebClientDetailsService implements ClientDetailsService {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clientId.equals(this.lmsAPIClientDetails.getClientId())) {
|
if (clientId.equals(this.lmsAPIClientDetails.getClientId())) {
|
||||||
return this.lmsAPIClientDetails;
|
return this.lmsAPIClientDetails.getClientDetails();
|
||||||
}
|
}
|
||||||
|
|
||||||
return getForExamClientAPI(clientId)
|
return getForExamClientAPI(clientId)
|
||||||
|
|
|
@ -46,6 +46,8 @@ public class MoodleMockupRestTemplateFactory implements MoodleRestTemplateFactor
|
||||||
|
|
||||||
private final APITemplateDataSupplier apiTemplateDataSupplier;
|
private final APITemplateDataSupplier apiTemplateDataSupplier;
|
||||||
|
|
||||||
|
private Result<MoodleAPIRestTemplate> template = null;
|
||||||
|
|
||||||
public MoodleMockupRestTemplateFactory(final APITemplateDataSupplier apiTemplateDataSupplier) {
|
public MoodleMockupRestTemplateFactory(final APITemplateDataSupplier apiTemplateDataSupplier) {
|
||||||
this.apiTemplateDataSupplier = apiTemplateDataSupplier;
|
this.apiTemplateDataSupplier = apiTemplateDataSupplier;
|
||||||
}
|
}
|
||||||
|
@ -67,14 +69,25 @@ public class MoodleMockupRestTemplateFactory implements MoodleRestTemplateFactor
|
||||||
return paths;
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Result<MoodleAPIRestTemplate> getRestTemplate() {
|
||||||
|
return createRestTemplate("");
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<MoodleAPIRestTemplate> createRestTemplate(final String service) {
|
public Result<MoodleAPIRestTemplate> createRestTemplate(final String service) {
|
||||||
return Result.of(new MockupMoodleRestTemplate(this.apiTemplateDataSupplier.getLmsSetup().lmsApiUrl));
|
if (template == null) {
|
||||||
|
template = Result.of(new MockupMoodleRestTemplate(this.apiTemplateDataSupplier.getLmsSetup().lmsApiUrl));
|
||||||
|
}
|
||||||
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Result<MoodleAPIRestTemplate> createRestTemplate(final String service, final String accessTokenPath) {
|
public Result<MoodleAPIRestTemplate> createRestTemplate(final String service, final String accessTokenPath) {
|
||||||
return Result.of(new MockupMoodleRestTemplate(this.apiTemplateDataSupplier.getLmsSetup().lmsApiUrl));
|
if (template == null) {
|
||||||
|
template = Result.of(new MockupMoodleRestTemplate(this.apiTemplateDataSupplier.getLmsSetup().lmsApiUrl));
|
||||||
|
}
|
||||||
|
return template;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static final class MockupMoodleRestTemplate implements MoodleAPIRestTemplate {
|
public static final class MockupMoodleRestTemplate implements MoodleAPIRestTemplate {
|
||||||
|
|
|
@ -47,6 +47,8 @@ public class MoodleCourseAccessTest {
|
||||||
final MoodleAPIRestTemplateImpl moodleAPIRestTemplate = mock(MoodleAPIRestTemplateImpl.class);
|
final MoodleAPIRestTemplateImpl moodleAPIRestTemplate = mock(MoodleAPIRestTemplateImpl.class);
|
||||||
when(moodleRestTemplateFactory.createRestTemplate(Mockito.anyString()))
|
when(moodleRestTemplateFactory.createRestTemplate(Mockito.anyString()))
|
||||||
.thenReturn(Result.of(moodleAPIRestTemplate));
|
.thenReturn(Result.of(moodleAPIRestTemplate));
|
||||||
|
when(moodleRestTemplateFactory.getRestTemplate())
|
||||||
|
.thenReturn(Result.of(moodleAPIRestTemplate));
|
||||||
when(moodleAPIRestTemplate.callMoodleAPIFunction(
|
when(moodleAPIRestTemplate.callMoodleAPIFunction(
|
||||||
anyString(),
|
anyString(),
|
||||||
any())).thenReturn("[\r\n" +
|
any())).thenReturn("[\r\n" +
|
||||||
|
@ -122,6 +124,8 @@ public class MoodleCourseAccessTest {
|
||||||
final MoodleRestTemplateFactoryImpl moodleRestTemplateFactory = mock(MoodleRestTemplateFactoryImpl.class);
|
final MoodleRestTemplateFactoryImpl moodleRestTemplateFactory = mock(MoodleRestTemplateFactoryImpl.class);
|
||||||
when(moodleRestTemplateFactory.createRestTemplate(Mockito.anyString()))
|
when(moodleRestTemplateFactory.createRestTemplate(Mockito.anyString()))
|
||||||
.thenReturn(Result.ofRuntimeError("Error1"));
|
.thenReturn(Result.ofRuntimeError("Error1"));
|
||||||
|
when(moodleRestTemplateFactory.getRestTemplate())
|
||||||
|
.thenReturn(Result.ofRuntimeError("Error1"));
|
||||||
when(moodleRestTemplateFactory.test()).thenReturn(LmsSetupTestResult.ofOkay(LmsType.MOODLE));
|
when(moodleRestTemplateFactory.test()).thenReturn(LmsSetupTestResult.ofOkay(LmsType.MOODLE));
|
||||||
|
|
||||||
final MoodleCourseAccess moodleCourseAccess = new MoodleCourseAccess(
|
final MoodleCourseAccess moodleCourseAccess = new MoodleCourseAccess(
|
||||||
|
@ -143,6 +147,8 @@ public class MoodleCourseAccessTest {
|
||||||
final MoodleAPIRestTemplateImpl moodleAPIRestTemplate = mock(MoodleAPIRestTemplateImpl.class);
|
final MoodleAPIRestTemplateImpl moodleAPIRestTemplate = mock(MoodleAPIRestTemplateImpl.class);
|
||||||
when(moodleRestTemplateFactory.createRestTemplate(Mockito.anyString()))
|
when(moodleRestTemplateFactory.createRestTemplate(Mockito.anyString()))
|
||||||
.thenReturn(Result.of(moodleAPIRestTemplate));
|
.thenReturn(Result.of(moodleAPIRestTemplate));
|
||||||
|
when(moodleRestTemplateFactory.getRestTemplate())
|
||||||
|
.thenReturn(Result.of(moodleAPIRestTemplate));
|
||||||
doThrow(RuntimeException.class).when(moodleAPIRestTemplate).testAPIConnection(any());
|
doThrow(RuntimeException.class).when(moodleAPIRestTemplate).testAPIConnection(any());
|
||||||
when(moodleRestTemplateFactory.test()).thenReturn(LmsSetupTestResult.ofOkay(LmsType.MOODLE));
|
when(moodleRestTemplateFactory.test()).thenReturn(LmsSetupTestResult.ofOkay(LmsType.MOODLE));
|
||||||
|
|
||||||
|
@ -165,6 +171,8 @@ public class MoodleCourseAccessTest {
|
||||||
final MoodleAPIRestTemplateImpl moodleAPIRestTemplate = mock(MoodleAPIRestTemplateImpl.class);
|
final MoodleAPIRestTemplateImpl moodleAPIRestTemplate = mock(MoodleAPIRestTemplateImpl.class);
|
||||||
when(moodleRestTemplateFactory.createRestTemplate(Mockito.anyString()))
|
when(moodleRestTemplateFactory.createRestTemplate(Mockito.anyString()))
|
||||||
.thenReturn(Result.of(moodleAPIRestTemplate));
|
.thenReturn(Result.of(moodleAPIRestTemplate));
|
||||||
|
when(moodleRestTemplateFactory.getRestTemplate())
|
||||||
|
.thenReturn(Result.of(moodleAPIRestTemplate));
|
||||||
when(moodleRestTemplateFactory.test()).thenReturn(LmsSetupTestResult.ofOkay(LmsType.MOODLE));
|
when(moodleRestTemplateFactory.test()).thenReturn(LmsSetupTestResult.ofOkay(LmsType.MOODLE));
|
||||||
|
|
||||||
final MoodleCourseAccess moodleCourseAccess = new MoodleCourseAccess(
|
final MoodleCourseAccess moodleCourseAccess = new MoodleCourseAccess(
|
||||||
|
|
|
@ -47,11 +47,13 @@ public class MoodlePluginCourseAccessTest {
|
||||||
public void testSetup() {
|
public void testSetup() {
|
||||||
final MoodlePluginCourseAccess candidate = crateMockup();
|
final MoodlePluginCourseAccess candidate = crateMockup();
|
||||||
|
|
||||||
assertEquals("MoodlePluginCourseAccess ["
|
assertEquals(
|
||||||
+ "pageSize=500, "
|
"MoodlePluginCourseAccess [" +
|
||||||
+ "maxSize=10000, "
|
"pageSize=500, " +
|
||||||
+ "cutoffTimeOffset=3, "
|
"maxSize=10000, " +
|
||||||
+ "restTemplate=null]", candidate.toTestString());
|
"cutoffTimeOffset=3, " +
|
||||||
|
"restTemplate=MockupMoodleRestTemplate [accessToken=MockupMoodleRestTemplate-Test-Token, url=https://test.org/, testLog=[], callLog=[]]]",
|
||||||
|
candidate.toTestString());
|
||||||
|
|
||||||
final LmsSetupTestResult testCourseAccessAPI = candidate.testCourseAccessAPI();
|
final LmsSetupTestResult testCourseAccessAPI = candidate.testCourseAccessAPI();
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ public class MoodlePluginCourseRestrictionTest {
|
||||||
|
|
||||||
final MoodlePluginCourseRestriction candidate = crateMockup();
|
final MoodlePluginCourseRestriction candidate = crateMockup();
|
||||||
|
|
||||||
assertEquals("MoodlePluginCourseRestriction [restTemplate=null]", candidate.toTestString());
|
assertEquals("MoodlePluginCourseRestriction [restTemplate=MockupMoodleRestTemplate [accessToken=MockupMoodleRestTemplate-Test-Token, url=https://test.org/, testLog=[], callLog=[]]]", candidate.toTestString());
|
||||||
|
|
||||||
final LmsSetupTestResult testCourseRestrictionAPI = candidate.testCourseRestrictionAPI();
|
final LmsSetupTestResult testCourseRestrictionAPI = candidate.testCourseRestrictionAPI();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue