Merge remote-tracking branch 'origin/dev-lms-ans' into development

This commit is contained in:
anhefti 2021-06-30 14:23:14 +02:00
commit 6a8fdac7b1
3 changed files with 102 additions and 30 deletions

View file

@ -61,7 +61,7 @@ public final class LmsSetup implements GrantEntity, Activatable {
/** The Moodle binding features only the course access API so far */
MOODLE(Features.COURSE_API /* , Features.SEB_RESTRICTION */),
/** The Ans Delft binding is on the way */
ANS_DELFT(/* Features.COURSE_API , Features.SEB_RESTRICTION */),
ANS_DELFT(Features.COURSE_API, Features.SEB_RESTRICTION),
/** The OpenOLAT binding is on the way */
OPEN_OLAT(/* Features.COURSE_API , Features.SEB_RESTRICTION */);

View file

@ -20,10 +20,16 @@ import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;
import org.springframework.cache.CacheManager;
import org.springframework.core.env.Environment;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.security.oauth2.client.OAuth2RestTemplate;
import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails;
import ch.ethz.seb.sebserver.ClientHttpRequestFactoryService;
import ch.ethz.seb.sebserver.gbl.api.APIMessage;
import ch.ethz.seb.sebserver.gbl.async.AsyncService;
import ch.ethz.seb.sebserver.gbl.client.ClientCredentialService;
import ch.ethz.seb.sebserver.gbl.client.ClientCredentials;
import ch.ethz.seb.sebserver.gbl.client.ProxyData;
import ch.ethz.seb.sebserver.gbl.model.Domain.LMS_SETUP;
import ch.ethz.seb.sebserver.gbl.model.exam.Chapters;
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
@ -45,11 +51,18 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.AbstractCachedCour
public class AnsLmsAPITemplate extends AbstractCachedCourseAccess implements LmsAPITemplate {
// TODO add needed dependencies here
private final ClientHttpRequestFactoryService clientHttpRequestFactoryService;
private final ClientCredentialService clientCredentialService;
private final APITemplateDataSupplier apiTemplateDataSupplier;
private final Long lmsSetupId;
protected AnsLmsAPITemplate(
// TODO if you need more dependencies inject them here and set the reference
final ClientHttpRequestFactoryService clientHttpRequestFactoryService,
final ClientCredentialService clientCredentialService,
final APITemplateDataSupplier apiTemplateDataSupplier,
final AsyncService asyncService,
final Environment environment,
@ -57,6 +70,8 @@ public class AnsLmsAPITemplate extends AbstractCachedCourseAccess implements Lms
super(asyncService, environment, cacheManager);
this.clientHttpRequestFactoryService = clientHttpRequestFactoryService;
this.clientCredentialService = clientCredentialService;
this.apiTemplateDataSupplier = apiTemplateDataSupplier;
this.lmsSetupId = apiTemplateDataSupplier.getLmsSetup().id;
}
@ -191,38 +206,41 @@ public class AnsLmsAPITemplate extends AbstractCachedCourseAccess implements Lms
@Override
protected Supplier<List<QuizData>> allQuizzesSupplier(final FilterMap filterMap) {
@SuppressWarnings("unused")
final String quizName = filterMap.getString(QuizData.FILTER_ATTR_QUIZ_NAME);
@SuppressWarnings("unused")
final DateTime quizFromTime = (filterMap != null) ? filterMap.getQuizFromTime() : null;
// TODO get all course / quiz data from remote LMS that matches the filter criteria.
// put loaded QuizData to the cache: super.putToCache(quizDataCollection);
// before returning it.
return () -> {
// TODO get all course / quiz data from remote LMS that matches the filter criteria.
// put loaded QuizData to the cache: super.putToCache(quizDataCollection);
// before returning it.
throw new RuntimeException("TODO");
};
}
@Override
protected Supplier<Collection<QuizData>> quizzesSupplier(final Set<String> ids) {
// TODO get all quiz / course data for specified identifiers from remote LMS
// and put it to the cache: super.putToCache(quizDataCollection);
// before returning it.
return () -> {
// TODO get all quiz / course data for specified identifiers from remote LMS
// and put it to the cache: super.putToCache(quizDataCollection);
// before returning it.
throw new RuntimeException("TODO");
};
}
@Override
protected Supplier<QuizData> quizSupplier(final String id) {
// TODO get the specified quiz / course data for specified identifier from remote LMS
// and put it to the cache: super.putToCache(quizDataCollection);
// before returning it.
return () -> {
// TODO get the specified quiz / course data for specified identifier from remote LMS
// and put it to the cache: super.putToCache(quizDataCollection);
// before returning it.
throw new RuntimeException("TODO");
};
}
@ -230,10 +248,11 @@ public class AnsLmsAPITemplate extends AbstractCachedCourseAccess implements Lms
@Override
protected Supplier<ExamineeAccountDetails> accountDetailsSupplier(final String examineeSessionId) {
// TODO get the examinee's account details by the given examineeSessionId from remote LMS.
// Currently only the name is needed to display on monitoring view.
return () -> {
// TODO get the examinee's account details by the given examineeSessionId from remote LMS.
// Currently only the name is needed to display on monitoring view.
throw new RuntimeException("TODO");
};
}
@ -247,13 +266,17 @@ public class AnsLmsAPITemplate extends AbstractCachedCourseAccess implements Lms
@Override
public Result<SEBRestriction> getSEBClientRestriction(final Exam exam) {
@SuppressWarnings("unused")
final String quizId = exam.externalId;
// TODO get the SEB client restrictions that are currently set on the remote LMS for
// the given quiz / course derived from the given exam
return Result.tryCatch(() -> {
return Result.ofRuntimeError("TODO");
// TODO get the SEB client restrictions that are currently set on the remote LMS for
// the given quiz / course derived from the given exam
throw new RuntimeException("TODO");
});
}
@Override
@ -261,22 +284,61 @@ public class AnsLmsAPITemplate extends AbstractCachedCourseAccess implements Lms
final String externalExamId,
final SEBRestriction sebRestrictionData) {
// TODO apply the given sebRestrictionData settings as current SEB client restriction setting
// to the remote LMS for the given quiz / course.
// Mainly SEBRestriction.configKeys and SEBRestriction.browserExamKeys
return Result.tryCatch(() -> {
return Result.ofRuntimeError("TODO");
// TODO apply the given sebRestrictionData settings as current SEB client restriction setting
// to the remote LMS for the given quiz / course.
// Mainly SEBRestriction.configKeys and SEBRestriction.browserExamKeys
throw new RuntimeException("TODO");
});
}
@Override
public Result<Exam> releaseSEBClientRestriction(final Exam exam) {
@SuppressWarnings("unused")
final String quizId = exam.externalId;
// TODO Release respectively delete all SEB client restrictions for the given
// course / quize on the remote LMS.
return Result.tryCatch(() -> {
return Result.ofRuntimeError("TODO");
// TODO Release respectively delete all SEB client restrictions for the given
// course / quize on the remote LMS.
throw new RuntimeException("TODO");
});
}
// TODO: This is an example of how to create a RestTemplate for the service to access the LMS API
// The example deals with a Http based API that is secured by an OAuth2 client-credential flow.
// You might need some different template, then you have to adapt this code
// To your needs.
@SuppressWarnings("unused")
private OAuth2RestTemplate createRestTemplate(final String accessTokenRequestPath) {
final LmsSetup lmsSetup = this.apiTemplateDataSupplier.getLmsSetup();
final ClientCredentials credentials = this.apiTemplateDataSupplier.getLmsClientCredentials();
final ProxyData proxyData = this.apiTemplateDataSupplier.getProxyData();
final CharSequence plainClientId = credentials.clientId;
final CharSequence plainClientSecret = this.clientCredentialService
.getPlainClientSecret(credentials)
.getOrThrow();
final ClientCredentialsResourceDetails details = new ClientCredentialsResourceDetails();
details.setAccessTokenUri(lmsSetup.lmsApiUrl + accessTokenRequestPath);
details.setClientId(plainClientId.toString());
details.setClientSecret(plainClientSecret.toString());
final ClientHttpRequestFactory clientHttpRequestFactory = this.clientHttpRequestFactoryService
.getClientHttpRequestFactory(proxyData)
.getOrThrow();
final OAuth2RestTemplate template = new OAuth2RestTemplate(details);
template.setRequestFactory(clientHttpRequestFactory);
return template;
}
}

View file

@ -13,7 +13,9 @@ import org.springframework.context.annotation.Lazy;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import ch.ethz.seb.sebserver.ClientHttpRequestFactoryService;
import ch.ethz.seb.sebserver.gbl.async.AsyncService;
import ch.ethz.seb.sebserver.gbl.client.ClientCredentialService;
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType;
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
import ch.ethz.seb.sebserver.gbl.util.Result;
@ -33,15 +35,21 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplateFactory;
* as usual. Just add the additionally needed dependencies used to build a AnsLmsAPITemplateFactory */
public class AnsLmsAPITemplateFactory implements LmsAPITemplateFactory {
private final ClientHttpRequestFactoryService clientHttpRequestFactoryService;
private final ClientCredentialService clientCredentialService;
private final AsyncService asyncService;
private final Environment environment;
private final CacheManager cacheManager;
public AnsLmsAPITemplateFactory(
final ClientHttpRequestFactoryService clientHttpRequestFactoryService,
final ClientCredentialService clientCredentialService,
final AsyncService asyncService,
final Environment environment,
final CacheManager cacheManager) {
this.clientHttpRequestFactoryService = clientHttpRequestFactoryService;
this.clientCredentialService = clientCredentialService;
this.asyncService = asyncService;
this.environment = environment;
this.cacheManager = cacheManager;
@ -56,6 +64,8 @@ public class AnsLmsAPITemplateFactory implements LmsAPITemplateFactory {
public Result<LmsAPITemplate> create(final APITemplateDataSupplier apiTemplateDataSupplier) {
return Result.tryCatch(() -> {
return new AnsLmsAPITemplate(
this.clientHttpRequestFactoryService,
this.clientCredentialService,
apiTemplateDataSupplier,
this.asyncService,
this.environment,