SEBSERV-91 implementation
This commit is contained in:
parent
422147dd7f
commit
f442b9885f
8 changed files with 152 additions and 15 deletions
|
@ -119,6 +119,7 @@ public final class API {
|
||||||
public static final String EXAM_ADMINISTRATION_SEB_RESTRICTION_PATH_SEGMENT = "/seb-restriction";
|
public static final String EXAM_ADMINISTRATION_SEB_RESTRICTION_PATH_SEGMENT = "/seb-restriction";
|
||||||
public static final String EXAM_ADMINISTRATION_CHECK_RESTRICTION_PATH_SEGMENT = "/check-seb-restriction";
|
public static final String EXAM_ADMINISTRATION_CHECK_RESTRICTION_PATH_SEGMENT = "/check-seb-restriction";
|
||||||
public static final String EXAM_ADMINISTRATION_CHECK_IMPORTED_PATH_SEGMENT = "/check-imported";
|
public static final String EXAM_ADMINISTRATION_CHECK_IMPORTED_PATH_SEGMENT = "/check-imported";
|
||||||
|
public static final String EXAM_ADMINISTRATION_SEB_RESTRICTION_CHAPTERS_PATH_SEGMENT = "/chapters";
|
||||||
|
|
||||||
public static final String EXAM_INDICATOR_ENDPOINT = "/indicator";
|
public static final String EXAM_INDICATOR_ENDPOINT = "/indicator";
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ public final class Chapters {
|
||||||
public final String id;
|
public final String id;
|
||||||
|
|
||||||
@JsonCreator
|
@JsonCreator
|
||||||
protected Chapter(
|
public Chapter(
|
||||||
@JsonProperty(ATTR_NAME) final String name,
|
@JsonProperty(ATTR_NAME) final String name,
|
||||||
@JsonProperty(ATTR_ID) final String id) {
|
@JsonProperty(ATTR_ID) final String id) {
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ import java.util.function.Consumer;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.function.Predicate;
|
import java.util.function.Predicate;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
import org.apache.commons.lang3.BooleanUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
@ -23,9 +24,11 @@ import org.eclipse.swt.widgets.Composite;
|
||||||
import ch.ethz.seb.sebserver.gbl.Constants;
|
import ch.ethz.seb.sebserver.gbl.Constants;
|
||||||
import ch.ethz.seb.sebserver.gbl.api.API;
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.exam.Chapters;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.OpenEdxSebRestriction;
|
import ch.ethz.seb.sebserver.gbl.model.exam.OpenEdxSebRestriction;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.SebRestriction;
|
import ch.ethz.seb.sebserver.gbl.model.exam.SebRestriction;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType;
|
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.util.Tuple;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
import ch.ethz.seb.sebserver.gui.form.Form;
|
import ch.ethz.seb.sebserver.gui.form.Form;
|
||||||
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
import ch.ethz.seb.sebserver.gui.form.FormBuilder;
|
||||||
|
@ -40,6 +43,7 @@ import ch.ethz.seb.sebserver.gui.service.page.impl.PageAction;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestService;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.ActivateSebRestriction;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.ActivateSebRestriction;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.DeactivateSebRestriction;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.DeactivateSebRestriction;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetCourseChapters;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetSebRestriction;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.GetSebRestriction;
|
||||||
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.SaveSebRestriction;
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam.SaveSebRestriction;
|
||||||
|
|
||||||
|
@ -190,6 +194,13 @@ public class ExamSebRestrictionSettings {
|
||||||
.call()
|
.call()
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
|
|
||||||
|
final Chapters chapters = restService
|
||||||
|
.getBuilder(GetCourseChapters.class)
|
||||||
|
.withURIVariable(API.PARAM_MODEL_ID, entityKey.modelId)
|
||||||
|
.call()
|
||||||
|
.onError(t -> t.printStackTrace())
|
||||||
|
.getOr(null);
|
||||||
|
|
||||||
final PageContext formContext = this.pageContext
|
final PageContext formContext = this.pageContext
|
||||||
.copyOf(content)
|
.copyOf(content)
|
||||||
.clearEntityKeys();
|
.clearEntityKeys();
|
||||||
|
@ -231,16 +242,7 @@ public class ExamSebRestrictionSettings {
|
||||||
resourceService::sebRestrictionWhiteListResources))
|
resourceService::sebRestrictionWhiteListResources))
|
||||||
|
|
||||||
.addFieldIf(
|
.addFieldIf(
|
||||||
() -> lmsType == LmsType.OPEN_EDX,
|
() -> chapters == null && lmsType == LmsType.OPEN_EDX,
|
||||||
() -> FormBuilder.multiCheckboxSelection(
|
|
||||||
OpenEdxSebRestriction.ATTR_PERMISSION_COMPONENTS,
|
|
||||||
SEB_RESTRICTION_FORM_EDX_PERMISSIONS,
|
|
||||||
sebRestriction.getAdditionalProperties()
|
|
||||||
.get(OpenEdxSebRestriction.ATTR_PERMISSION_COMPONENTS),
|
|
||||||
resourceService::sebRestrictionPermissionResources))
|
|
||||||
|
|
||||||
.addFieldIf(
|
|
||||||
() -> lmsType == LmsType.OPEN_EDX,
|
|
||||||
() -> FormBuilder.text(
|
() -> FormBuilder.text(
|
||||||
OpenEdxSebRestriction.ATTR_BLACKLIST_CHAPTERS,
|
OpenEdxSebRestriction.ATTR_BLACKLIST_CHAPTERS,
|
||||||
SEB_RESTRICTION_FORM_EDX_BLACKLIST_CHAPTERS,
|
SEB_RESTRICTION_FORM_EDX_BLACKLIST_CHAPTERS,
|
||||||
|
@ -250,6 +252,28 @@ public class ExamSebRestrictionSettings {
|
||||||
.get(OpenEdxSebRestriction.ATTR_BLACKLIST_CHAPTERS)))
|
.get(OpenEdxSebRestriction.ATTR_BLACKLIST_CHAPTERS)))
|
||||||
.asArea())
|
.asArea())
|
||||||
|
|
||||||
|
.addFieldIf(
|
||||||
|
() -> chapters != null && lmsType == LmsType.OPEN_EDX,
|
||||||
|
() -> FormBuilder.multiCheckboxSelection(
|
||||||
|
OpenEdxSebRestriction.ATTR_BLACKLIST_CHAPTERS,
|
||||||
|
SEB_RESTRICTION_FORM_EDX_BLACKLIST_CHAPTERS,
|
||||||
|
sebRestriction
|
||||||
|
.getAdditionalProperties()
|
||||||
|
.get(OpenEdxSebRestriction.ATTR_BLACKLIST_CHAPTERS),
|
||||||
|
() -> chapters.chapters
|
||||||
|
.stream()
|
||||||
|
.map(chapter -> new Tuple<>(chapter.id, chapter.name))
|
||||||
|
.collect(Collectors.toList())))
|
||||||
|
|
||||||
|
.addFieldIf(
|
||||||
|
() -> lmsType == LmsType.OPEN_EDX,
|
||||||
|
() -> FormBuilder.multiCheckboxSelection(
|
||||||
|
OpenEdxSebRestriction.ATTR_PERMISSION_COMPONENTS,
|
||||||
|
SEB_RESTRICTION_FORM_EDX_PERMISSIONS,
|
||||||
|
sebRestriction.getAdditionalProperties()
|
||||||
|
.get(OpenEdxSebRestriction.ATTR_PERMISSION_COMPONENTS),
|
||||||
|
resourceService::sebRestrictionPermissionResources))
|
||||||
|
|
||||||
.addFieldIf(
|
.addFieldIf(
|
||||||
() -> lmsType == LmsType.OPEN_EDX,
|
() -> lmsType == LmsType.OPEN_EDX,
|
||||||
() -> FormBuilder.checkbox(
|
() -> FormBuilder.checkbox(
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2020 ETH Zürich, Educational Development and Technology (LET)
|
||||||
|
*
|
||||||
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package ch.ethz.seb.sebserver.gui.service.remote.webservice.api.exam;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Lazy;
|
||||||
|
import org.springframework.http.HttpMethod;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
|
|
||||||
|
import ch.ethz.seb.sebserver.gbl.api.API;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.api.EntityType;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.exam.Chapters;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.profile.GuiProfile;
|
||||||
|
import ch.ethz.seb.sebserver.gui.service.remote.webservice.api.RestCall;
|
||||||
|
|
||||||
|
@Lazy
|
||||||
|
@Component
|
||||||
|
@GuiProfile
|
||||||
|
public class GetCourseChapters extends RestCall<Chapters> {
|
||||||
|
|
||||||
|
public GetCourseChapters() {
|
||||||
|
super(new TypeKey<>(
|
||||||
|
CallType.UNDEFINED,
|
||||||
|
EntityType.EXAM,
|
||||||
|
new TypeReference<Chapters>() {
|
||||||
|
}),
|
||||||
|
HttpMethod.GET,
|
||||||
|
MediaType.APPLICATION_FORM_URLENCODED,
|
||||||
|
API.EXAM_ADMINISTRATION_ENDPOINT +
|
||||||
|
API.MODEL_ID_VAR_PATH_SEGMENT +
|
||||||
|
API.EXAM_ADMINISTRATION_SEB_RESTRICTION_CHAPTERS_PATH_SEGMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -109,6 +109,15 @@ public interface LmsAPITemplate {
|
||||||
// examinee identifier received by on SEB-Client connection.
|
// examinee identifier received by on SEB-Client connection.
|
||||||
//Result<ExamineeAccountDetails> getExamineeAccountDetails(String examineeUserId);
|
//Result<ExamineeAccountDetails> getExamineeAccountDetails(String examineeUserId);
|
||||||
|
|
||||||
|
/** Used to get a list of chapters (display name and chapter-identifier) that can be used to
|
||||||
|
* apply chapter-based SEB restriction for a specified course.
|
||||||
|
*
|
||||||
|
* The availability of this depends on the type of LMS and on installed plugins that supports this feature.
|
||||||
|
* If this is not supported by the underling LMS a UnsupportedOperationException will be presented
|
||||||
|
* within the Result.
|
||||||
|
*
|
||||||
|
* @param courseId The course identifier
|
||||||
|
* @return Result referencing to the Chapters model for the given course or to an error when happened. */
|
||||||
Result<Chapters> getCourseChapters(String courseId);
|
Result<Chapters> getCourseChapters(String courseId);
|
||||||
|
|
||||||
/** Get SEB restriction data form LMS within a SebRestrictionData instance if available
|
/** Get SEB restriction data form LMS within a SebRestrictionData instance if available
|
||||||
|
|
|
@ -89,7 +89,7 @@ public abstract class CourseAccess {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Result<Chapters> getCourseChapters(final String courseId) {
|
protected Result<Chapters> getCourseChapters(final String courseId) {
|
||||||
return null;
|
return this.chaptersRequest.protectedRun(getCourseChaptersSupplier(courseId));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract Supplier<List<QuizData>> allQuizzesSupplier();
|
protected abstract Supplier<List<QuizData>> allQuizzesSupplier();
|
||||||
|
|
|
@ -10,11 +10,11 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.edx;
|
||||||
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
|
@ -30,6 +30,8 @@ import org.springframework.security.oauth2.client.OAuth2RestTemplate;
|
||||||
import org.springframework.security.oauth2.client.http.AccessTokenRequiredException;
|
import org.springframework.security.oauth2.client.http.AccessTokenRequiredException;
|
||||||
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
|
import org.springframework.security.oauth2.client.resource.OAuth2ProtectedResourceDetails;
|
||||||
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
import org.springframework.security.oauth2.common.OAuth2AccessToken;
|
||||||
|
import org.springframework.web.util.DefaultUriBuilderFactory;
|
||||||
|
import org.springframework.web.util.DefaultUriBuilderFactory.EncodingMode;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
|
||||||
|
|
||||||
|
@ -40,6 +42,7 @@ import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
|
||||||
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.model.institution.LmsSetupTestResult;
|
||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
|
import ch.ethz.seb.sebserver.gbl.util.Result;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.util.Utils;
|
||||||
import ch.ethz.seb.sebserver.webservice.WebserviceInfo;
|
import ch.ethz.seb.sebserver.webservice.WebserviceInfo;
|
||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.CourseAccess;
|
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.CourseAccess;
|
||||||
|
|
||||||
|
@ -53,6 +56,7 @@ final class OpenEdxCourseAccess extends CourseAccess {
|
||||||
private static final String OPEN_EDX_DEFAULT_COURSE_ENDPOINT = "/api/courses/v1/courses/";
|
private static final String OPEN_EDX_DEFAULT_COURSE_ENDPOINT = "/api/courses/v1/courses/";
|
||||||
private static final String OPEN_EDX_DEFAULT_BLOCKS_ENDPOINT =
|
private static final String OPEN_EDX_DEFAULT_BLOCKS_ENDPOINT =
|
||||||
"/api/courses/v1/blocks/?depth=1&all_blocks=true&course_id=";
|
"/api/courses/v1/blocks/?depth=1&all_blocks=true&course_id=";
|
||||||
|
private static final String OPEN_EDX_DEFAULT_BLOCKS_TYPE_CHAPTER = "chapter";
|
||||||
private static final String OPEN_EDX_DEFAULT_COURSE_START_URL_PREFIX = "/courses/";
|
private static final String OPEN_EDX_DEFAULT_COURSE_START_URL_PREFIX = "/courses/";
|
||||||
|
|
||||||
private final LmsSetup lmsSetup;
|
private final LmsSetup lmsSetup;
|
||||||
|
@ -116,7 +120,18 @@ final class OpenEdxCourseAccess extends CourseAccess {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Supplier<Chapters> getCourseChaptersSupplier(final String courseId) {
|
protected Supplier<Chapters> getCourseChaptersSupplier(final String courseId) {
|
||||||
throw new UnsupportedOperationException("not available yet");
|
return () -> {
|
||||||
|
final String uri =
|
||||||
|
this.lmsSetup.lmsApiUrl +
|
||||||
|
OPEN_EDX_DEFAULT_BLOCKS_ENDPOINT +
|
||||||
|
Utils.encodeFormURL_UTF_8(courseId);
|
||||||
|
return new Chapters(getCourseBlocks(uri)
|
||||||
|
.getBody().blocks.values()
|
||||||
|
.stream()
|
||||||
|
.filter(block -> OPEN_EDX_DEFAULT_BLOCKS_TYPE_CHAPTER.equals(block.type))
|
||||||
|
.map(block -> new Chapters.Chapter(block.display_name, block.block_id))
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList<QuizData> collectAllQuizzes(final OAuth2RestTemplate restTemplate) {
|
private ArrayList<QuizData> collectAllQuizzes(final OAuth2RestTemplate restTemplate) {
|
||||||
|
@ -186,6 +201,17 @@ final class OpenEdxCourseAccess extends CourseAccess {
|
||||||
EdXPage.class);
|
EdXPage.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ResponseEntity<Blocks> getCourseBlocks(final String uri) {
|
||||||
|
final HttpHeaders httpHeaders = new HttpHeaders();
|
||||||
|
return getRestTemplateNoEncoding()
|
||||||
|
.getOrThrow()
|
||||||
|
.exchange(
|
||||||
|
uri,
|
||||||
|
HttpMethod.GET,
|
||||||
|
new HttpEntity<>(httpHeaders),
|
||||||
|
Blocks.class);
|
||||||
|
}
|
||||||
|
|
||||||
private static QuizData quizDataOf(
|
private static QuizData quizDataOf(
|
||||||
final LmsSetup lmsSetup,
|
final LmsSetup lmsSetup,
|
||||||
final CourseData courseData,
|
final CourseData courseData,
|
||||||
|
@ -230,13 +256,14 @@ final class OpenEdxCourseAccess extends CourseAccess {
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
static final class Blocks {
|
static final class Blocks {
|
||||||
public String root;
|
public String root;
|
||||||
public Collection<Block> blocks;
|
public Map<String, Block> blocks;
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
static final class Block {
|
static final class Block {
|
||||||
public String block_id;
|
public String block_id;
|
||||||
public String display_name;
|
public String display_name;
|
||||||
|
public String type;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static final class EdxOAuth2RequestAuthenticator implements OAuth2RequestAuthenticator {
|
private static final class EdxOAuth2RequestAuthenticator implements OAuth2RequestAuthenticator {
|
||||||
|
@ -257,6 +284,17 @@ final class OpenEdxCourseAccess extends CourseAccess {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Result<OAuth2RestTemplate> getRestTemplateNoEncoding() {
|
||||||
|
return this.openEdxRestTemplateFactory
|
||||||
|
.createOAuthRestTemplate()
|
||||||
|
.map(tempalte -> {
|
||||||
|
final DefaultUriBuilderFactory builderFactory = new DefaultUriBuilderFactory();
|
||||||
|
builderFactory.setEncodingMode(EncodingMode.NONE);
|
||||||
|
tempalte.setUriTemplateHandler(builderFactory);
|
||||||
|
return tempalte;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private Result<OAuth2RestTemplate> getRestTemplate() {
|
private Result<OAuth2RestTemplate> getRestTemplate() {
|
||||||
if (this.restTemplate == null) {
|
if (this.restTemplate == null) {
|
||||||
final Result<OAuth2RestTemplate> templateRequest = this.openEdxRestTemplateFactory
|
final Result<OAuth2RestTemplate> templateRequest = this.openEdxRestTemplateFactory
|
||||||
|
|
|
@ -48,6 +48,7 @@ import ch.ethz.seb.sebserver.gbl.model.Domain.EXAM;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
import ch.ethz.seb.sebserver.gbl.model.EntityKey;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.Page;
|
import ch.ethz.seb.sebserver.gbl.model.Page;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.PageSortOrder;
|
import ch.ethz.seb.sebserver.gbl.model.PageSortOrder;
|
||||||
|
import ch.ethz.seb.sebserver.gbl.model.exam.Chapters;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
import ch.ethz.seb.sebserver.gbl.model.exam.Exam;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
|
import ch.ethz.seb.sebserver.gbl.model.exam.QuizData;
|
||||||
import ch.ethz.seb.sebserver.gbl.model.exam.SebRestriction;
|
import ch.ethz.seb.sebserver.gbl.model.exam.SebRestriction;
|
||||||
|
@ -351,6 +352,28 @@ public class ExamAdministrationController extends EntityController<Exam, Exam> {
|
||||||
.getOrThrow();
|
.getOrThrow();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequestMapping(
|
||||||
|
path = API.MODEL_ID_VAR_PATH_SEGMENT
|
||||||
|
+ API.EXAM_ADMINISTRATION_SEB_RESTRICTION_CHAPTERS_PATH_SEGMENT,
|
||||||
|
method = RequestMethod.GET,
|
||||||
|
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
|
||||||
|
public Chapters getChapters(
|
||||||
|
@RequestParam(
|
||||||
|
name = API.PARAM_INSTITUTION_ID,
|
||||||
|
required = true,
|
||||||
|
defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId,
|
||||||
|
@PathVariable(API.PARAM_MODEL_ID) final Long examlId) {
|
||||||
|
|
||||||
|
checkReadPrivilege(institutionId);
|
||||||
|
return this.entityDAO.byPK(examlId)
|
||||||
|
.flatMap(this.authorization::checkRead)
|
||||||
|
.flatMap(exam -> this.lmsAPIService
|
||||||
|
.getLmsAPITemplate(exam.lmsSetupId)
|
||||||
|
.getOrThrow()
|
||||||
|
.getCourseChapters(exam.externalId))
|
||||||
|
.getOrThrow();
|
||||||
|
}
|
||||||
|
|
||||||
// **** SEB Restriction
|
// **** SEB Restriction
|
||||||
// ****************************************************************************
|
// ****************************************************************************
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue