SEBSERV-301 implementation
This commit is contained in:
		
							parent
							
								
									a141eccfa1
								
							
						
					
					
						commit
						71ae9fc755
					
				
					 12 changed files with 471 additions and 108 deletions
				
			
		| 
						 | 
					@ -270,4 +270,14 @@ public class POSTMapper {
 | 
				
			||||||
        this.params.putIfAbsent(name, Arrays.asList(value));
 | 
					        this.params.putIfAbsent(name, Arrays.asList(value));
 | 
				
			||||||
        return (T) this;
 | 
					        return (T) this;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public String toString() {
 | 
				
			||||||
 | 
					        final StringBuilder builder = new StringBuilder();
 | 
				
			||||||
 | 
					        builder.append("POSTMapper [params=");
 | 
				
			||||||
 | 
					        builder.append(this.params);
 | 
				
			||||||
 | 
					        builder.append("]");
 | 
				
			||||||
 | 
					        return builder.toString();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -60,6 +60,8 @@ public final class LmsSetup implements GrantEntity, Activatable {
 | 
				
			||||||
        OPEN_EDX(Features.COURSE_API, Features.SEB_RESTRICTION),
 | 
					        OPEN_EDX(Features.COURSE_API, Features.SEB_RESTRICTION),
 | 
				
			||||||
        /** The Moodle binding features only the course access API so far */
 | 
					        /** The Moodle binding features only the course access API so far */
 | 
				
			||||||
        MOODLE(Features.COURSE_API /* , Features.SEB_RESTRICTION */),
 | 
					        MOODLE(Features.COURSE_API /* , Features.SEB_RESTRICTION */),
 | 
				
			||||||
 | 
					        /** The Moodle binding features with SEB Server integration plugin for fully featured */
 | 
				
			||||||
 | 
					        MOODLE_PLUGIN(Features.COURSE_API, Features.SEB_RESTRICTION),
 | 
				
			||||||
        /** The Ans Delft binding is on the way */
 | 
					        /** 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 */
 | 
					        /** The OpenOLAT binding is on the way */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,87 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2022 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.webservice.servicelayer.lms.impl.moodle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.springframework.util.MultiValueMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.fasterxml.jackson.annotation.JsonCreator;
 | 
				
			||||||
 | 
					import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 | 
				
			||||||
 | 
					import com.fasterxml.jackson.annotation.JsonProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public interface MoodleAPIRestTemplate {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    String URI_VAR_USER_NAME = "username";
 | 
				
			||||||
 | 
					    String URI_VAR_PASSWORD = "pwd";
 | 
				
			||||||
 | 
					    String URI_VAR_SERVICE = "service";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    String MOODLE_DEFAULT_TOKEN_REQUEST_PATH =
 | 
				
			||||||
 | 
					            "/login/token.php?username={" + URI_VAR_USER_NAME +
 | 
				
			||||||
 | 
					                    "}&password={" + URI_VAR_PASSWORD + "}&service={" + URI_VAR_SERVICE + "}";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    String MOODLE_DEFAULT_REST_API_PATH = "/webservice/rest/server.php";
 | 
				
			||||||
 | 
					    String REST_REQUEST_TOKEN_NAME = "wstoken";
 | 
				
			||||||
 | 
					    String REST_REQUEST_FUNCTION_NAME = "wsfunction";
 | 
				
			||||||
 | 
					    String REST_REQUEST_FORMAT_NAME = "moodlewsrestformat";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    String getService();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void setService(String service);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    CharSequence getAccessToken();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    void testAPIConnection(String... functions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    String callMoodleAPIFunction(String functionName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    String callMoodleAPIFunction(
 | 
				
			||||||
 | 
					            final String functionName,
 | 
				
			||||||
 | 
					            final MultiValueMap<String, String> queryAttributes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    String callMoodleAPIFunction(
 | 
				
			||||||
 | 
					            final String functionName,
 | 
				
			||||||
 | 
					            final MultiValueMap<String, String> queryParams,
 | 
				
			||||||
 | 
					            final MultiValueMap<String, String> queryAttributes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** This maps a Moodle warning JSON object */
 | 
				
			||||||
 | 
					    @JsonIgnoreProperties(ignoreUnknown = true)
 | 
				
			||||||
 | 
					    static final class Warning {
 | 
				
			||||||
 | 
					        final String item;
 | 
				
			||||||
 | 
					        final String itemid;
 | 
				
			||||||
 | 
					        final String warningcode;
 | 
				
			||||||
 | 
					        final String message;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @JsonCreator
 | 
				
			||||||
 | 
					        public Warning(
 | 
				
			||||||
 | 
					                @JsonProperty(value = "item") final String item,
 | 
				
			||||||
 | 
					                @JsonProperty(value = "itemid") final String itemid,
 | 
				
			||||||
 | 
					                @JsonProperty(value = "warningcode") final String warningcode,
 | 
				
			||||||
 | 
					                @JsonProperty(value = "message") final String message) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this.item = item;
 | 
				
			||||||
 | 
					            this.itemid = itemid;
 | 
				
			||||||
 | 
					            this.warningcode = warningcode;
 | 
				
			||||||
 | 
					            this.message = message;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @Override
 | 
				
			||||||
 | 
					        public String toString() {
 | 
				
			||||||
 | 
					            final StringBuilder builder = new StringBuilder();
 | 
				
			||||||
 | 
					            builder.append("Warning [item=");
 | 
				
			||||||
 | 
					            builder.append(this.item);
 | 
				
			||||||
 | 
					            builder.append(", itemid=");
 | 
				
			||||||
 | 
					            builder.append(this.itemid);
 | 
				
			||||||
 | 
					            builder.append(", warningcode=");
 | 
				
			||||||
 | 
					            builder.append(this.warningcode);
 | 
				
			||||||
 | 
					            builder.append(", message=");
 | 
				
			||||||
 | 
					            builder.append(this.message);
 | 
				
			||||||
 | 
					            builder.append("]");
 | 
				
			||||||
 | 
					            return builder.toString();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -6,7 +6,7 @@
 | 
				
			||||||
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
					 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.legacy;
 | 
					package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.util.ArrayList;
 | 
					import java.util.ArrayList;
 | 
				
			||||||
import java.util.Arrays;
 | 
					import java.util.Arrays;
 | 
				
			||||||
| 
						 | 
					@ -57,11 +57,11 @@ public class MoodleRestTemplateFactory {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private static final Logger log = LoggerFactory.getLogger(MoodleRestTemplateFactory.class);
 | 
					    private static final Logger log = LoggerFactory.getLogger(MoodleRestTemplateFactory.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    final JSONMapper jsonMapper;
 | 
					    public final JSONMapper jsonMapper;
 | 
				
			||||||
    final APITemplateDataSupplier apiTemplateDataSupplier;
 | 
					    public final APITemplateDataSupplier apiTemplateDataSupplier;
 | 
				
			||||||
    final ClientHttpRequestFactoryService clientHttpRequestFactoryService;
 | 
					    public final ClientHttpRequestFactoryService clientHttpRequestFactoryService;
 | 
				
			||||||
    final ClientCredentialService clientCredentialService;
 | 
					    public final ClientCredentialService clientCredentialService;
 | 
				
			||||||
    final Set<String> knownTokenAccessPaths;
 | 
					    public final Set<String> knownTokenAccessPaths;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public MoodleRestTemplateFactory(
 | 
					    public MoodleRestTemplateFactory(
 | 
				
			||||||
            final JSONMapper jsonMapper,
 | 
					            final JSONMapper jsonMapper,
 | 
				
			||||||
| 
						 | 
					@ -75,11 +75,12 @@ public class MoodleRestTemplateFactory {
 | 
				
			||||||
        this.clientCredentialService = clientCredentialService;
 | 
					        this.clientCredentialService = clientCredentialService;
 | 
				
			||||||
        this.clientHttpRequestFactoryService = clientHttpRequestFactoryService;
 | 
					        this.clientHttpRequestFactoryService = clientHttpRequestFactoryService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.knownTokenAccessPaths = new HashSet<>();
 | 
					        final Set<String> paths = new HashSet<>();
 | 
				
			||||||
        this.knownTokenAccessPaths.add(MoodleAPIRestTemplate.MOODLE_DEFAULT_TOKEN_REQUEST_PATH);
 | 
					        paths.add(MoodleAPIRestTemplate.MOODLE_DEFAULT_TOKEN_REQUEST_PATH);
 | 
				
			||||||
        if (alternativeTokenRequestPaths != null) {
 | 
					        if (alternativeTokenRequestPaths != null) {
 | 
				
			||||||
            this.knownTokenAccessPaths.addAll(Arrays.asList(alternativeTokenRequestPaths));
 | 
					            paths.addAll(Arrays.asList(alternativeTokenRequestPaths));
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        this.knownTokenAccessPaths = Utils.immutableSetOf(paths);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    APITemplateDataSupplier getApiTemplateDataSupplier() {
 | 
					    APITemplateDataSupplier getApiTemplateDataSupplier() {
 | 
				
			||||||
| 
						 | 
					@ -125,7 +126,7 @@ public class MoodleRestTemplateFactory {
 | 
				
			||||||
        return LmsSetupTestResult.ofOkay(LmsType.MOODLE);
 | 
					        return LmsSetupTestResult.ofOkay(LmsType.MOODLE);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Result<MoodleAPIRestTemplate> createRestTemplate() {
 | 
					    public Result<MoodleAPIRestTemplate> createRestTemplate() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        final LmsSetup lmsSetup = this.apiTemplateDataSupplier.getLmsSetup();
 | 
					        final LmsSetup lmsSetup = this.apiTemplateDataSupplier.getLmsSetup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -149,7 +150,7 @@ public class MoodleRestTemplateFactory {
 | 
				
			||||||
                                ") on paths: " + this.knownTokenAccessPaths));
 | 
					                                ") on paths: " + this.knownTokenAccessPaths));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Result<MoodleAPIRestTemplate> createRestTemplate(final String accessTokenPath) {
 | 
					    public Result<MoodleAPIRestTemplate> createRestTemplate(final String accessTokenPath) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        final LmsSetup lmsSetup = this.apiTemplateDataSupplier.getLmsSetup();
 | 
					        final LmsSetup lmsSetup = this.apiTemplateDataSupplier.getLmsSetup();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -162,8 +163,9 @@ public class MoodleRestTemplateFactory {
 | 
				
			||||||
                    .getPlainClientSecret(credentials)
 | 
					                    .getPlainClientSecret(credentials)
 | 
				
			||||||
                    .getOrThrow();
 | 
					                    .getOrThrow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            final MoodleAPIRestTemplate restTemplate = new MoodleAPIRestTemplate(
 | 
					            final MoodleAPIRestTemplateImpl restTemplate = new MoodleAPIRestTemplateImpl(
 | 
				
			||||||
                    this.jsonMapper,
 | 
					                    this.jsonMapper,
 | 
				
			||||||
 | 
					                    this.apiTemplateDataSupplier,
 | 
				
			||||||
                    lmsSetup.lmsApiUrl,
 | 
					                    lmsSetup.lmsApiUrl,
 | 
				
			||||||
                    accessTokenPath,
 | 
					                    accessTokenPath,
 | 
				
			||||||
                    lmsSetup.lmsRestApiToken,
 | 
					                    lmsSetup.lmsRestApiToken,
 | 
				
			||||||
| 
						 | 
					@ -187,22 +189,13 @@ public class MoodleRestTemplateFactory {
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public class MoodleAPIRestTemplate extends RestTemplate {
 | 
					    public static class MoodleAPIRestTemplateImpl extends RestTemplate implements MoodleAPIRestTemplate {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        public static final String URI_VAR_USER_NAME = "username";
 | 
					 | 
				
			||||||
        public static final String URI_VAR_PASSWORD = "pwd";
 | 
					 | 
				
			||||||
        public static final String URI_VAR_SERVICE = "service";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private static final String MOODLE_DEFAULT_TOKEN_REQUEST_PATH =
 | 
					 | 
				
			||||||
                "/login/token.php?username={" + URI_VAR_USER_NAME +
 | 
					 | 
				
			||||||
                        "}&password={" + URI_VAR_PASSWORD + "}&service={" + URI_VAR_SERVICE + "}";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private static final String MOODLE_DEFAULT_REST_API_PATH = "/webservice/rest/server.php";
 | 
					 | 
				
			||||||
        private static final String REST_REQUEST_TOKEN_NAME = "wstoken";
 | 
					 | 
				
			||||||
        private static final String REST_REQUEST_FUNCTION_NAME = "wsfunction";
 | 
					 | 
				
			||||||
        private static final String REST_REQUEST_FORMAT_NAME = "moodlewsrestformat";
 | 
					 | 
				
			||||||
        private static final String REST_API_TEST_FUNCTION = "core_webservice_get_site_info";
 | 
					        private static final String REST_API_TEST_FUNCTION = "core_webservice_get_site_info";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        final JSONMapper jsonMapper;
 | 
				
			||||||
 | 
					        final APITemplateDataSupplier apiTemplateDataSupplier;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private final String serverURL;
 | 
					        private final String serverURL;
 | 
				
			||||||
        private final String tokenPath;
 | 
					        private final String tokenPath;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -211,14 +204,18 @@ public class MoodleRestTemplateFactory {
 | 
				
			||||||
        private final Map<String, String> tokenReqURIVars;
 | 
					        private final Map<String, String> tokenReqURIVars;
 | 
				
			||||||
        private final HttpEntity<?> tokenReqEntity = new HttpEntity<>(new LinkedMultiValueMap<>());
 | 
					        private final HttpEntity<?> tokenReqEntity = new HttpEntity<>(new LinkedMultiValueMap<>());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        protected MoodleAPIRestTemplate(
 | 
					        protected MoodleAPIRestTemplateImpl(
 | 
				
			||||||
                final JSONMapper jsonMapper,
 | 
					                final JSONMapper jsonMapper,
 | 
				
			||||||
 | 
					                final APITemplateDataSupplier apiTemplateDataSupplier,
 | 
				
			||||||
                final String serverURL,
 | 
					                final String serverURL,
 | 
				
			||||||
                final String tokenPath,
 | 
					                final String tokenPath,
 | 
				
			||||||
                final CharSequence accessToken,
 | 
					                final CharSequence accessToken,
 | 
				
			||||||
                final CharSequence username,
 | 
					                final CharSequence username,
 | 
				
			||||||
                final CharSequence password) {
 | 
					                final CharSequence password) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this.jsonMapper = jsonMapper;
 | 
				
			||||||
 | 
					            this.apiTemplateDataSupplier = apiTemplateDataSupplier;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            this.serverURL = serverURL;
 | 
					            this.serverURL = serverURL;
 | 
				
			||||||
            this.tokenPath = tokenPath;
 | 
					            this.tokenPath = tokenPath;
 | 
				
			||||||
            this.accessToken = StringUtils.isNotBlank(accessToken) ? accessToken : null;
 | 
					            this.accessToken = StringUtils.isNotBlank(accessToken) ? accessToken : null;
 | 
				
			||||||
| 
						 | 
					@ -230,14 +227,17 @@ public class MoodleRestTemplateFactory {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @Override
 | 
				
			||||||
        public String getService() {
 | 
					        public String getService() {
 | 
				
			||||||
            return this.tokenReqURIVars.get(URI_VAR_SERVICE);
 | 
					            return this.tokenReqURIVars.get(URI_VAR_SERVICE);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @Override
 | 
				
			||||||
        public void setService(final String service) {
 | 
					        public void setService(final String service) {
 | 
				
			||||||
            this.tokenReqURIVars.put(URI_VAR_SERVICE, service);
 | 
					            this.tokenReqURIVars.put(URI_VAR_SERVICE, service);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @Override
 | 
				
			||||||
        public CharSequence getAccessToken() {
 | 
					        public CharSequence getAccessToken() {
 | 
				
			||||||
            if (this.accessToken == null) {
 | 
					            if (this.accessToken == null) {
 | 
				
			||||||
                requestAccessToken();
 | 
					                requestAccessToken();
 | 
				
			||||||
| 
						 | 
					@ -246,16 +246,20 @@ public class MoodleRestTemplateFactory {
 | 
				
			||||||
            return this.accessToken;
 | 
					            return this.accessToken;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @Override
 | 
				
			||||||
        public void testAPIConnection(final String... functions) {
 | 
					        public void testAPIConnection(final String... functions) {
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                final String apiInfo = this.callMoodleAPIFunction(REST_API_TEST_FUNCTION);
 | 
					                final String apiInfo = this.callMoodleAPIFunction(REST_API_TEST_FUNCTION);
 | 
				
			||||||
                final WebserviceInfo webserviceInfo =
 | 
					                final WebserviceInfo webserviceInfo = this.jsonMapper.readValue(
 | 
				
			||||||
                        MoodleRestTemplateFactory.this.jsonMapper.readValue(apiInfo, WebserviceInfo.class);
 | 
					                        apiInfo,
 | 
				
			||||||
 | 
					                        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: " + webserviceInfo);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (functions != null) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    final List<String> missingAPIFunctions = Arrays.stream(functions)
 | 
					                    final List<String> missingAPIFunctions = Arrays.stream(functions)
 | 
				
			||||||
                            .filter(f -> !webserviceInfo.functions.containsKey(f))
 | 
					                            .filter(f -> !webserviceInfo.functions.containsKey(f))
 | 
				
			||||||
                            .collect(Collectors.toList());
 | 
					                            .collect(Collectors.toList());
 | 
				
			||||||
| 
						 | 
					@ -263,6 +267,7 @@ public class MoodleRestTemplateFactory {
 | 
				
			||||||
                    if (!missingAPIFunctions.isEmpty()) {
 | 
					                    if (!missingAPIFunctions.isEmpty()) {
 | 
				
			||||||
                        throw new RuntimeException("Missing Moodle Webservice API functions: " + missingAPIFunctions);
 | 
					                        throw new RuntimeException("Missing Moodle Webservice API functions: " + missingAPIFunctions);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            } catch (final RuntimeException re) {
 | 
					            } catch (final RuntimeException re) {
 | 
				
			||||||
                throw re;
 | 
					                throw re;
 | 
				
			||||||
| 
						 | 
					@ -271,16 +276,19 @@ public class MoodleRestTemplateFactory {
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @Override
 | 
				
			||||||
        public String callMoodleAPIFunction(final String functionName) {
 | 
					        public String callMoodleAPIFunction(final String functionName) {
 | 
				
			||||||
            return callMoodleAPIFunction(functionName, null, null);
 | 
					            return callMoodleAPIFunction(functionName, null, null);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @Override
 | 
				
			||||||
        public String callMoodleAPIFunction(
 | 
					        public String callMoodleAPIFunction(
 | 
				
			||||||
                final String functionName,
 | 
					                final String functionName,
 | 
				
			||||||
                final MultiValueMap<String, String> queryAttributes) {
 | 
					                final MultiValueMap<String, String> queryAttributes) {
 | 
				
			||||||
            return callMoodleAPIFunction(functionName, null, queryAttributes);
 | 
					            return callMoodleAPIFunction(functionName, null, queryAttributes);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @Override
 | 
				
			||||||
        public String callMoodleAPIFunction(
 | 
					        public String callMoodleAPIFunction(
 | 
				
			||||||
                final String functionName,
 | 
					                final String functionName,
 | 
				
			||||||
                final MultiValueMap<String, String> queryParams,
 | 
					                final MultiValueMap<String, String> queryParams,
 | 
				
			||||||
| 
						 | 
					@ -319,9 +327,7 @@ public class MoodleRestTemplateFactory {
 | 
				
			||||||
                    functionReqEntity,
 | 
					                    functionReqEntity,
 | 
				
			||||||
                    String.class);
 | 
					                    String.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            final LmsSetup lmsSetup = MoodleRestTemplateFactory.this.apiTemplateDataSupplier
 | 
					            final LmsSetup lmsSetup = this.apiTemplateDataSupplier.getLmsSetup();
 | 
				
			||||||
                    .getLmsSetup();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            if (response.getStatusCode() != HttpStatus.OK) {
 | 
					            if (response.getStatusCode() != HttpStatus.OK) {
 | 
				
			||||||
                throw new RuntimeException(
 | 
					                throw new RuntimeException(
 | 
				
			||||||
                        "Failed to call Moodle webservice API function: " + functionName + " lms setup: " +
 | 
					                        "Failed to call Moodle webservice API function: " + functionName + " lms setup: " +
 | 
				
			||||||
| 
						 | 
					@ -347,9 +353,7 @@ public class MoodleRestTemplateFactory {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private void requestAccessToken() {
 | 
					        private void requestAccessToken() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            final LmsSetup lmsSetup = MoodleRestTemplateFactory.this.apiTemplateDataSupplier
 | 
					            final LmsSetup lmsSetup = this.apiTemplateDataSupplier.getLmsSetup();
 | 
				
			||||||
                    .getLmsSetup();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                final ResponseEntity<String> response = super.exchange(
 | 
					                final ResponseEntity<String> response = super.exchange(
 | 
				
			||||||
| 
						 | 
					@ -369,7 +373,7 @@ public class MoodleRestTemplateFactory {
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                try {
 | 
					                try {
 | 
				
			||||||
                    final MoodleToken moodleToken = MoodleRestTemplateFactory.this.jsonMapper.readValue(
 | 
					                    final MoodleToken moodleToken = this.jsonMapper.readValue(
 | 
				
			||||||
                            response.getBody(),
 | 
					                            response.getBody(),
 | 
				
			||||||
                            MoodleToken.class);
 | 
					                            MoodleToken.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -48,9 +48,11 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.APITemplateDataSupplier;
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.APITemplateDataSupplier;
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.CourseAccessAPI;
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.CourseAccessAPI;
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPIService;
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPIService;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleAPIRestTemplate;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleAPIRestTemplate.Warning;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleRestTemplateFactory;
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.legacy.MoodleCourseDataAsyncLoader.CourseDataShort;
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.legacy.MoodleCourseDataAsyncLoader.CourseDataShort;
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.legacy.MoodleCourseDataAsyncLoader.CourseQuizShort;
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.legacy.MoodleCourseDataAsyncLoader.CourseQuizShort;
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.legacy.MoodleRestTemplateFactory.MoodleAPIRestTemplate;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** Implements the LmsAPITemplate for Open edX LMS Course API access.
 | 
					/** Implements the LmsAPITemplate for Open edX LMS Course API access.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -885,40 +887,4 @@ public class MoodleCourseAccess implements CourseAccessAPI {
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @JsonIgnoreProperties(ignoreUnknown = true)
 | 
					 | 
				
			||||||
    static final class Warning {
 | 
					 | 
				
			||||||
        final String item;
 | 
					 | 
				
			||||||
        final String itemid;
 | 
					 | 
				
			||||||
        final String warningcode;
 | 
					 | 
				
			||||||
        final String message;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        @JsonCreator
 | 
					 | 
				
			||||||
        public Warning(
 | 
					 | 
				
			||||||
                @JsonProperty(value = "item") final String item,
 | 
					 | 
				
			||||||
                @JsonProperty(value = "itemid") final String itemid,
 | 
					 | 
				
			||||||
                @JsonProperty(value = "warningcode") final String warningcode,
 | 
					 | 
				
			||||||
                @JsonProperty(value = "message") final String message) {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            this.item = item;
 | 
					 | 
				
			||||||
            this.itemid = itemid;
 | 
					 | 
				
			||||||
            this.warningcode = warningcode;
 | 
					 | 
				
			||||||
            this.message = message;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        @Override
 | 
					 | 
				
			||||||
        public String toString() {
 | 
					 | 
				
			||||||
            final StringBuilder builder = new StringBuilder();
 | 
					 | 
				
			||||||
            builder.append("Warning [item=");
 | 
					 | 
				
			||||||
            builder.append(this.item);
 | 
					 | 
				
			||||||
            builder.append(", itemid=");
 | 
					 | 
				
			||||||
            builder.append(this.itemid);
 | 
					 | 
				
			||||||
            builder.append(", warningcode=");
 | 
					 | 
				
			||||||
            builder.append(this.warningcode);
 | 
					 | 
				
			||||||
            builder.append(", message=");
 | 
					 | 
				
			||||||
            builder.append(this.message);
 | 
					 | 
				
			||||||
            builder.append("]");
 | 
					 | 
				
			||||||
            return builder.toString();
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,8 +47,8 @@ import ch.ethz.seb.sebserver.gbl.async.AsyncService;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.async.CircuitBreaker;
 | 
					import ch.ethz.seb.sebserver.gbl.async.CircuitBreaker;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
 | 
					import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.util.Utils;
 | 
					import ch.ethz.seb.sebserver.gbl.util.Utils;
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.legacy.MoodleCourseAccess.Warning;
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleAPIRestTemplate;
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.legacy.MoodleRestTemplateFactory.MoodleAPIRestTemplate;
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleAPIRestTemplate.Warning;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Lazy
 | 
					@Lazy
 | 
				
			||||||
@Component
 | 
					@Component
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,7 +30,8 @@ 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.SEBRestrictionAPI;
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.SEBRestrictionAPI;
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.NoSEBRestrictionException;
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.NoSEBRestrictionException;
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.legacy.MoodleRestTemplateFactory.MoodleAPIRestTemplate;
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleAPIRestTemplate;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleRestTemplateFactory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/** GET:
 | 
					/** GET:
 | 
				
			||||||
 * http://yourmoodle.org/webservice/rest/server.php?wstoken={token}&moodlewsrestformat=json&wsfunction=seb_restriction&courseId=123
 | 
					 * http://yourmoodle.org/webservice/rest/server.php?wstoken={token}&moodlewsrestformat=json&wsfunction=seb_restriction&courseId=123
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,10 +6,11 @@
 | 
				
			||||||
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 | 
					 * 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.legacy;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import org.apache.commons.lang3.StringUtils;
 | 
					import org.apache.commons.lang3.StringUtils;
 | 
				
			||||||
import org.springframework.beans.factory.annotation.Value;
 | 
					import org.springframework.beans.factory.annotation.Value;
 | 
				
			||||||
 | 
					import org.springframework.cache.CacheManager;
 | 
				
			||||||
import org.springframework.context.ApplicationContext;
 | 
					import org.springframework.context.ApplicationContext;
 | 
				
			||||||
import org.springframework.context.annotation.Lazy;
 | 
					import org.springframework.context.annotation.Lazy;
 | 
				
			||||||
import org.springframework.core.env.Environment;
 | 
					import org.springframework.core.env.Environment;
 | 
				
			||||||
| 
						 | 
					@ -28,10 +29,7 @@ import ch.ethz.seb.sebserver.webservice.servicelayer.lms.APITemplateDataSupplier
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplate;
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplate;
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplateFactory;
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplateFactory;
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.LmsAPITemplateAdapter;
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.LmsAPITemplateAdapter;
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.legacy.MoodleCourseAccess;
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleRestTemplateFactory;
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.legacy.MoodleCourseDataAsyncLoader;
 | 
					 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.legacy.MoodleCourseRestriction;
 | 
					 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.legacy.MoodleRestTemplateFactory;
 | 
					 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.plugin.MoodlePluginCheck;
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.plugin.MoodlePluginCheck;
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.plugin.MoodlePluginCourseAccess;
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.plugin.MoodlePluginCourseAccess;
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.plugin.MoodlePluginCourseRestriction;
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.plugin.MoodlePluginCourseRestriction;
 | 
				
			||||||
| 
						 | 
					@ -43,6 +41,7 @@ public class MoodleLmsAPITemplateFactory implements LmsAPITemplateFactory {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private final MoodlePluginCheck moodlePluginCheck;
 | 
					    private final MoodlePluginCheck moodlePluginCheck;
 | 
				
			||||||
    private final JSONMapper jsonMapper;
 | 
					    private final JSONMapper jsonMapper;
 | 
				
			||||||
 | 
					    private final CacheManager cacheManager;
 | 
				
			||||||
    private final AsyncService asyncService;
 | 
					    private final AsyncService asyncService;
 | 
				
			||||||
    private final Environment environment;
 | 
					    private final Environment environment;
 | 
				
			||||||
    private final ClientCredentialService clientCredentialService;
 | 
					    private final ClientCredentialService clientCredentialService;
 | 
				
			||||||
| 
						 | 
					@ -53,6 +52,7 @@ public class MoodleLmsAPITemplateFactory implements LmsAPITemplateFactory {
 | 
				
			||||||
    protected MoodleLmsAPITemplateFactory(
 | 
					    protected MoodleLmsAPITemplateFactory(
 | 
				
			||||||
            final MoodlePluginCheck moodlePluginCheck,
 | 
					            final MoodlePluginCheck moodlePluginCheck,
 | 
				
			||||||
            final JSONMapper jsonMapper,
 | 
					            final JSONMapper jsonMapper,
 | 
				
			||||||
 | 
					            final CacheManager cacheManager,
 | 
				
			||||||
            final AsyncService asyncService,
 | 
					            final AsyncService asyncService,
 | 
				
			||||||
            final Environment environment,
 | 
					            final Environment environment,
 | 
				
			||||||
            final ClientCredentialService clientCredentialService,
 | 
					            final ClientCredentialService clientCredentialService,
 | 
				
			||||||
| 
						 | 
					@ -62,6 +62,7 @@ public class MoodleLmsAPITemplateFactory implements LmsAPITemplateFactory {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.moodlePluginCheck = moodlePluginCheck;
 | 
					        this.moodlePluginCheck = moodlePluginCheck;
 | 
				
			||||||
        this.jsonMapper = jsonMapper;
 | 
					        this.jsonMapper = jsonMapper;
 | 
				
			||||||
 | 
					        this.cacheManager = cacheManager;
 | 
				
			||||||
        this.asyncService = asyncService;
 | 
					        this.asyncService = asyncService;
 | 
				
			||||||
        this.environment = environment;
 | 
					        this.environment = environment;
 | 
				
			||||||
        this.clientCredentialService = clientCredentialService;
 | 
					        this.clientCredentialService = clientCredentialService;
 | 
				
			||||||
| 
						 | 
					@ -87,9 +88,19 @@ public class MoodleLmsAPITemplateFactory implements LmsAPITemplateFactory {
 | 
				
			||||||
                    .getBean(MoodleCourseDataAsyncLoader.class);
 | 
					                    .getBean(MoodleCourseDataAsyncLoader.class);
 | 
				
			||||||
            asyncLoaderPrototype.init(lmsSetup.getModelId());
 | 
					            asyncLoaderPrototype.init(lmsSetup.getModelId());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            final MoodleRestTemplateFactory moodleRestTemplateFactory = new MoodleRestTemplateFactory(
 | 
				
			||||||
 | 
					                    this.jsonMapper,
 | 
				
			||||||
 | 
					                    apiTemplateDataSupplier,
 | 
				
			||||||
 | 
					                    this.clientCredentialService,
 | 
				
			||||||
 | 
					                    this.clientHttpRequestFactoryService,
 | 
				
			||||||
 | 
					                    this.alternativeTokenRequestPaths);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (this.moodlePluginCheck.checkPluginAvailable(lmsSetup)) {
 | 
					            if (this.moodlePluginCheck.checkPluginAvailable(lmsSetup)) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                final MoodlePluginCourseAccess moodlePluginCourseAccess = new MoodlePluginCourseAccess();
 | 
					                final MoodlePluginCourseAccess moodlePluginCourseAccess = new MoodlePluginCourseAccess(
 | 
				
			||||||
 | 
					                        this.jsonMapper,
 | 
				
			||||||
 | 
					                        moodleRestTemplateFactory,
 | 
				
			||||||
 | 
					                        this.cacheManager);
 | 
				
			||||||
                final MoodlePluginCourseRestriction moodlePluginCourseRestriction = new MoodlePluginCourseRestriction();
 | 
					                final MoodlePluginCourseRestriction moodlePluginCourseRestriction = new MoodlePluginCourseRestriction();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return new LmsAPITemplateAdapter(
 | 
					                return new LmsAPITemplateAdapter(
 | 
				
			||||||
| 
						 | 
					@ -101,13 +112,6 @@ public class MoodleLmsAPITemplateFactory implements LmsAPITemplateFactory {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                final MoodleRestTemplateFactory moodleRestTemplateFactory = new MoodleRestTemplateFactory(
 | 
					 | 
				
			||||||
                        this.jsonMapper,
 | 
					 | 
				
			||||||
                        apiTemplateDataSupplier,
 | 
					 | 
				
			||||||
                        this.clientCredentialService,
 | 
					 | 
				
			||||||
                        this.clientHttpRequestFactoryService,
 | 
					 | 
				
			||||||
                        this.alternativeTokenRequestPaths);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                final MoodleCourseAccess moodleCourseAccess = new MoodleCourseAccess(
 | 
					                final MoodleCourseAccess moodleCourseAccess = new MoodleCourseAccess(
 | 
				
			||||||
                        this.jsonMapper,
 | 
					                        this.jsonMapper,
 | 
				
			||||||
                        moodleRestTemplateFactory,
 | 
					                        moodleRestTemplateFactory,
 | 
				
			||||||
| 
						 | 
					@ -8,30 +8,96 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.plugin;
 | 
					package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.plugin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
import java.util.Collection;
 | 
					import java.util.Collection;
 | 
				
			||||||
 | 
					import java.util.Collections;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.Set;
 | 
					import java.util.Set;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.slf4j.Logger;
 | 
				
			||||||
 | 
					import org.slf4j.LoggerFactory;
 | 
				
			||||||
 | 
					import org.springframework.cache.CacheManager;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.fasterxml.jackson.annotation.JsonCreator;
 | 
				
			||||||
 | 
					import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
 | 
				
			||||||
 | 
					import com.fasterxml.jackson.annotation.JsonProperty;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.model.exam.Chapters;
 | 
					import ch.ethz.seb.sebserver.gbl.model.exam.Chapters;
 | 
				
			||||||
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.institution.LmsSetup.LmsType;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult;
 | 
					import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.model.user.ExamineeAccountDetails;
 | 
					import ch.ethz.seb.sebserver.gbl.model.user.ExamineeAccountDetails;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
 | 
					import ch.ethz.seb.sebserver.gbl.util.Result;
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.dao.FilterMap;
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.CourseAccessAPI;
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.CourseAccessAPI;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.AbstractCachedCourseAccess;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleAPIRestTemplate;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleAPIRestTemplate.Warning;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleRestTemplateFactory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class MoodlePluginCourseAccess implements CourseAccessAPI {
 | 
					public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess implements CourseAccessAPI {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private static final Logger log = LoggerFactory.getLogger(MoodlePluginCourseAccess.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static final String COURSES_API_FUNCTION_NAME = "local_sebserver_get_courses";
 | 
				
			||||||
 | 
					    static final String QUIZZES_BY_COURSES_API_FUNCTION_NAME = "local_sebserver_get_quizzes_by_courses";
 | 
				
			||||||
 | 
					    static final String USERS_API_FUNCTION_NAME = "local_sebserver_get_users";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    static final String CRITERIA_FROM_DATE = "from_date";
 | 
				
			||||||
 | 
					    static final String CRITERIA_TO_DATE = "to_date";
 | 
				
			||||||
 | 
					    static final String CRITERIA_LIMIT_FROM = "limitfrom";
 | 
				
			||||||
 | 
					    static final String CRITERIA_LIMIT_NUM = "limitnum";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private final JSONMapper jsonMapper;
 | 
				
			||||||
 | 
					    private final MoodleRestTemplateFactory moodleRestTemplateFactory;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private MoodleAPIRestTemplate restTemplate;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public MoodlePluginCourseAccess(
 | 
				
			||||||
 | 
					            final JSONMapper jsonMapper,
 | 
				
			||||||
 | 
					            final MoodleRestTemplateFactory moodleRestTemplateFactory,
 | 
				
			||||||
 | 
					            final CacheManager cacheManager) {
 | 
				
			||||||
 | 
					        super(cacheManager);
 | 
				
			||||||
 | 
					        this.jsonMapper = jsonMapper;
 | 
				
			||||||
 | 
					        this.moodleRestTemplateFactory = moodleRestTemplateFactory;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public LmsSetupTestResult testCourseAccessAPI() {
 | 
					    public LmsSetupTestResult testCourseAccessAPI() {
 | 
				
			||||||
        // TODO Auto-generated method stub
 | 
					        final LmsSetupTestResult attributesCheck = this.moodleRestTemplateFactory.test();
 | 
				
			||||||
        return null;
 | 
					        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.moodleRestTemplateFactory.knownTokenAccessPaths;
 | 
				
			||||||
 | 
					            log.error(message + " cause: {}", restTemplateRequest.getError().getMessage());
 | 
				
			||||||
 | 
					            return LmsSetupTestResult.ofTokenRequestError(LmsType.MOODLE_PLUGIN, message);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        final MoodleAPIRestTemplate restTemplate = restTemplateRequest.get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//        try {
 | 
				
			||||||
 | 
					//            restTemplate.testAPIConnection(
 | 
				
			||||||
 | 
					//                    COURSES_API_FUNCTION_NAME,
 | 
				
			||||||
 | 
					//                    QUIZZES_BY_COURSES_API_FUNCTION_NAME,
 | 
				
			||||||
 | 
					//                    USERS_API_FUNCTION_NAME);
 | 
				
			||||||
 | 
					//        } catch (final RuntimeException e) {
 | 
				
			||||||
 | 
					//            log.error("Failed to access Moodle course API: ", e);
 | 
				
			||||||
 | 
					//            return LmsSetupTestResult.ofQuizAccessAPIError(LmsType.MOODLE_PLUGIN, e.getMessage());
 | 
				
			||||||
 | 
					//        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return LmsSetupTestResult.ofOkay(LmsType.MOODLE_PLUGIN);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public Result<List<QuizData>> getQuizzes(final FilterMap filterMap) {
 | 
					    public Result<List<QuizData>> getQuizzes(final FilterMap filterMap) {
 | 
				
			||||||
 | 
					        System.out.println("***************** filterMap: " + filterMap);
 | 
				
			||||||
        // TODO Auto-generated method stub
 | 
					        // TODO Auto-generated method stub
 | 
				
			||||||
        return null;
 | 
					        return Result.of(Collections.emptyList());
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
| 
						 | 
					@ -46,12 +112,6 @@ public class MoodlePluginCourseAccess implements CourseAccessAPI {
 | 
				
			||||||
        return null;
 | 
					        return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					 | 
				
			||||||
    public void clearCourseCache() {
 | 
					 | 
				
			||||||
        // TODO Auto-generated method stub
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public Result<ExamineeAccountDetails> getExamineeAccountDetails(final String examineeUserId) {
 | 
					    public Result<ExamineeAccountDetails> getExamineeAccountDetails(final String examineeUserId) {
 | 
				
			||||||
        // TODO Auto-generated method stub
 | 
					        // TODO Auto-generated method stub
 | 
				
			||||||
| 
						 | 
					@ -70,4 +130,119 @@ public class MoodlePluginCourseAccess implements CourseAccessAPI {
 | 
				
			||||||
        return null;
 | 
					        return null;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    protected Long getLmsSetupId() {
 | 
				
			||||||
 | 
					        // TODO Auto-generated method stub
 | 
				
			||||||
 | 
					        return null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private Result<MoodleAPIRestTemplate> getRestTemplate() {
 | 
				
			||||||
 | 
					        if (this.restTemplate == null) {
 | 
				
			||||||
 | 
					            final Result<MoodleAPIRestTemplate> templateRequest = this.moodleRestTemplateFactory
 | 
				
			||||||
 | 
					                    .createRestTemplate();
 | 
				
			||||||
 | 
					            if (templateRequest.hasError()) {
 | 
				
			||||||
 | 
					                return templateRequest;
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					                this.restTemplate = templateRequest.get();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return Result.of(this.restTemplate);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // ---- Mapping Classes ---
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @JsonIgnoreProperties(ignoreUnknown = true)
 | 
				
			||||||
 | 
					    private static final class Courses {
 | 
				
			||||||
 | 
					        final Collection<CourseData> courses;
 | 
				
			||||||
 | 
					        final Collection<Warning> warnings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @JsonCreator
 | 
				
			||||||
 | 
					        protected Courses(
 | 
				
			||||||
 | 
					                @JsonProperty(value = "courses") final Collection<CourseData> courses,
 | 
				
			||||||
 | 
					                @JsonProperty(value = "warnings") final Collection<Warning> warnings) {
 | 
				
			||||||
 | 
					            this.courses = courses;
 | 
				
			||||||
 | 
					            this.warnings = warnings;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** Maps the Moodle course API course data */
 | 
				
			||||||
 | 
					    @JsonIgnoreProperties(ignoreUnknown = true)
 | 
				
			||||||
 | 
					    private static final class CourseData {
 | 
				
			||||||
 | 
					        final String id;
 | 
				
			||||||
 | 
					        final String short_name;
 | 
				
			||||||
 | 
					        final String idnumber;
 | 
				
			||||||
 | 
					        final String full_name;
 | 
				
			||||||
 | 
					        final String display_name;
 | 
				
			||||||
 | 
					        final Long start_date; // unix-time seconds UTC
 | 
				
			||||||
 | 
					        final Long end_date; // unix-time seconds UTC
 | 
				
			||||||
 | 
					        final Long time_created; // unix-time seconds UTC
 | 
				
			||||||
 | 
					        final Collection<CourseQuiz> quizzes = new ArrayList<>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @JsonCreator
 | 
				
			||||||
 | 
					        protected CourseData(
 | 
				
			||||||
 | 
					                @JsonProperty(value = "id") final String id,
 | 
				
			||||||
 | 
					                @JsonProperty(value = "shortname") final String short_name,
 | 
				
			||||||
 | 
					                @JsonProperty(value = "idnumber") final String idnumber,
 | 
				
			||||||
 | 
					                @JsonProperty(value = "fullname") final String full_name,
 | 
				
			||||||
 | 
					                @JsonProperty(value = "displayname") final String display_name,
 | 
				
			||||||
 | 
					                @JsonProperty(value = "startdate") final Long start_date,
 | 
				
			||||||
 | 
					                @JsonProperty(value = "enddate") final Long end_date,
 | 
				
			||||||
 | 
					                @JsonProperty(value = "timecreated") final Long time_created) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this.id = id;
 | 
				
			||||||
 | 
					            this.short_name = short_name;
 | 
				
			||||||
 | 
					            this.idnumber = idnumber;
 | 
				
			||||||
 | 
					            this.full_name = full_name;
 | 
				
			||||||
 | 
					            this.display_name = display_name;
 | 
				
			||||||
 | 
					            this.start_date = start_date;
 | 
				
			||||||
 | 
					            this.end_date = end_date;
 | 
				
			||||||
 | 
					            this.time_created = time_created;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @JsonIgnoreProperties(ignoreUnknown = true)
 | 
				
			||||||
 | 
					    private static final class CourseQuizData {
 | 
				
			||||||
 | 
					        final Collection<CourseQuiz> quizzes;
 | 
				
			||||||
 | 
					        final Collection<Warning> warnings;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @JsonCreator
 | 
				
			||||||
 | 
					        protected CourseQuizData(
 | 
				
			||||||
 | 
					                @JsonProperty(value = "quizzes") final Collection<CourseQuiz> quizzes,
 | 
				
			||||||
 | 
					                @JsonProperty(value = "warnings") final Collection<Warning> warnings) {
 | 
				
			||||||
 | 
					            this.quizzes = quizzes;
 | 
				
			||||||
 | 
					            this.warnings = warnings;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @JsonIgnoreProperties(ignoreUnknown = true)
 | 
				
			||||||
 | 
					    static final class CourseQuiz {
 | 
				
			||||||
 | 
					        final String id;
 | 
				
			||||||
 | 
					        final String course;
 | 
				
			||||||
 | 
					        final String course_module;
 | 
				
			||||||
 | 
					        final String name;
 | 
				
			||||||
 | 
					        final String intro; // HTML
 | 
				
			||||||
 | 
					        final Long time_open; // unix-time seconds UTC
 | 
				
			||||||
 | 
					        final Long time_close; // unix-time seconds UTC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        @JsonCreator
 | 
				
			||||||
 | 
					        protected CourseQuiz(
 | 
				
			||||||
 | 
					                @JsonProperty(value = "id") final String id,
 | 
				
			||||||
 | 
					                @JsonProperty(value = "course") final String course,
 | 
				
			||||||
 | 
					                @JsonProperty(value = "coursemodule") final String course_module,
 | 
				
			||||||
 | 
					                @JsonProperty(value = "name") final String name,
 | 
				
			||||||
 | 
					                @JsonProperty(value = "intro") final String intro,
 | 
				
			||||||
 | 
					                @JsonProperty(value = "timeopen") final Long time_open,
 | 
				
			||||||
 | 
					                @JsonProperty(value = "timeclose") final Long time_close) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            this.id = id;
 | 
				
			||||||
 | 
					            this.course = course;
 | 
				
			||||||
 | 
					            this.course_module = course_module;
 | 
				
			||||||
 | 
					            this.name = name;
 | 
				
			||||||
 | 
					            this.intro = intro;
 | 
				
			||||||
 | 
					            this.time_open = time_open;
 | 
				
			||||||
 | 
					            this.time_close = time_close;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,6 +10,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.plugin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
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.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.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.webservice.servicelayer.lms.SEBRestrictionAPI;
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.SEBRestrictionAPI;
 | 
				
			||||||
| 
						 | 
					@ -19,7 +20,7 @@ public class MoodlePluginCourseRestriction implements SEBRestrictionAPI {
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public LmsSetupTestResult testCourseRestrictionAPI() {
 | 
					    public LmsSetupTestResult testCourseRestrictionAPI() {
 | 
				
			||||||
        // TODO Auto-generated method stub
 | 
					        // TODO Auto-generated method stub
 | 
				
			||||||
        return null;
 | 
					        return LmsSetupTestResult.ofOkay(LmsType.MOODLE_PLUGIN);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,112 @@
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * Copyright (c) 2022 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.webservice.servicelayer.lms.impl.moodle.plugin;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import org.apache.commons.lang3.StringUtils;
 | 
				
			||||||
 | 
					import org.springframework.beans.factory.annotation.Value;
 | 
				
			||||||
 | 
					import org.springframework.cache.CacheManager;
 | 
				
			||||||
 | 
					import org.springframework.context.ApplicationContext;
 | 
				
			||||||
 | 
					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.Constants;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
 | 
				
			||||||
 | 
					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;
 | 
				
			||||||
 | 
					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;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.APITemplateDataSupplier;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplate;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplateFactory;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.LmsAPITemplateAdapter;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleRestTemplateFactory;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.legacy.MoodleCourseDataAsyncLoader;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Lazy
 | 
				
			||||||
 | 
					@Service
 | 
				
			||||||
 | 
					@WebServiceProfile
 | 
				
			||||||
 | 
					public class MooldePluginLmsAPITemplateFactory implements LmsAPITemplateFactory {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private final MoodlePluginCheck moodlePluginCheck;
 | 
				
			||||||
 | 
					    private final JSONMapper jsonMapper;
 | 
				
			||||||
 | 
					    private final CacheManager cacheManager;
 | 
				
			||||||
 | 
					    private final AsyncService asyncService;
 | 
				
			||||||
 | 
					    private final Environment environment;
 | 
				
			||||||
 | 
					    private final ClientCredentialService clientCredentialService;
 | 
				
			||||||
 | 
					    private final ClientHttpRequestFactoryService clientHttpRequestFactoryService;
 | 
				
			||||||
 | 
					    private final ApplicationContext applicationContext;
 | 
				
			||||||
 | 
					    private final String[] alternativeTokenRequestPaths;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    protected MooldePluginLmsAPITemplateFactory(
 | 
				
			||||||
 | 
					            final MoodlePluginCheck moodlePluginCheck,
 | 
				
			||||||
 | 
					            final JSONMapper jsonMapper,
 | 
				
			||||||
 | 
					            final CacheManager cacheManager,
 | 
				
			||||||
 | 
					            final AsyncService asyncService,
 | 
				
			||||||
 | 
					            final Environment environment,
 | 
				
			||||||
 | 
					            final ClientCredentialService clientCredentialService,
 | 
				
			||||||
 | 
					            final ClientHttpRequestFactoryService clientHttpRequestFactoryService,
 | 
				
			||||||
 | 
					            final ApplicationContext applicationContext,
 | 
				
			||||||
 | 
					            @Value("${sebserver.webservice.lms.moodle.api.token.request.paths:}") final String alternativeTokenRequestPaths) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.moodlePluginCheck = moodlePluginCheck;
 | 
				
			||||||
 | 
					        this.jsonMapper = jsonMapper;
 | 
				
			||||||
 | 
					        this.cacheManager = cacheManager;
 | 
				
			||||||
 | 
					        this.asyncService = asyncService;
 | 
				
			||||||
 | 
					        this.environment = environment;
 | 
				
			||||||
 | 
					        this.clientCredentialService = clientCredentialService;
 | 
				
			||||||
 | 
					        this.clientHttpRequestFactoryService = clientHttpRequestFactoryService;
 | 
				
			||||||
 | 
					        this.applicationContext = applicationContext;
 | 
				
			||||||
 | 
					        this.alternativeTokenRequestPaths = (alternativeTokenRequestPaths != null)
 | 
				
			||||||
 | 
					                ? StringUtils.split(alternativeTokenRequestPaths, Constants.LIST_SEPARATOR)
 | 
				
			||||||
 | 
					                : null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public LmsType lmsType() {
 | 
				
			||||||
 | 
					        return LmsType.MOODLE_PLUGIN;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @Override
 | 
				
			||||||
 | 
					    public Result<LmsAPITemplate> create(final APITemplateDataSupplier apiTemplateDataSupplier) {
 | 
				
			||||||
 | 
					        return Result.tryCatch(() -> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            final LmsSetup lmsSetup = apiTemplateDataSupplier.getLmsSetup();
 | 
				
			||||||
 | 
					            final MoodleCourseDataAsyncLoader asyncLoaderPrototype = this.applicationContext
 | 
				
			||||||
 | 
					                    .getBean(MoodleCourseDataAsyncLoader.class);
 | 
				
			||||||
 | 
					            asyncLoaderPrototype.init(lmsSetup.getModelId());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            final MoodleRestTemplateFactory moodleRestTemplateFactory = new MoodleRestTemplateFactory(
 | 
				
			||||||
 | 
					                    this.jsonMapper,
 | 
				
			||||||
 | 
					                    apiTemplateDataSupplier,
 | 
				
			||||||
 | 
					                    this.clientCredentialService,
 | 
				
			||||||
 | 
					                    this.clientHttpRequestFactoryService,
 | 
				
			||||||
 | 
					                    this.alternativeTokenRequestPaths);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            final MoodlePluginCourseAccess moodlePluginCourseAccess = new MoodlePluginCourseAccess(
 | 
				
			||||||
 | 
					                    this.jsonMapper,
 | 
				
			||||||
 | 
					                    moodleRestTemplateFactory,
 | 
				
			||||||
 | 
					                    this.cacheManager);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            final MoodlePluginCourseRestriction moodlePluginCourseRestriction = new MoodlePluginCourseRestriction();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return new LmsAPITemplateAdapter(
 | 
				
			||||||
 | 
					                    this.asyncService,
 | 
				
			||||||
 | 
					                    this.environment,
 | 
				
			||||||
 | 
					                    apiTemplateDataSupplier,
 | 
				
			||||||
 | 
					                    moodlePluginCourseAccess,
 | 
				
			||||||
 | 
					                    moodlePluginCourseRestriction);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -27,7 +27,8 @@ import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult.ErrorType;
 | 
					import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult.ErrorType;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.model.user.ExamineeAccountDetails;
 | 
					import ch.ethz.seb.sebserver.gbl.model.user.ExamineeAccountDetails;
 | 
				
			||||||
import ch.ethz.seb.sebserver.gbl.util.Result;
 | 
					import ch.ethz.seb.sebserver.gbl.util.Result;
 | 
				
			||||||
import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.legacy.MoodleRestTemplateFactory.MoodleAPIRestTemplate;
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleRestTemplateFactory;
 | 
				
			||||||
 | 
					import ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle.MoodleRestTemplateFactory.MoodleAPIRestTemplateImpl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public class MoodleCourseAccessTest {
 | 
					public class MoodleCourseAccessTest {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,7 +39,7 @@ public class MoodleCourseAccessTest {
 | 
				
			||||||
    public void testGetExamineeAccountDetails() {
 | 
					    public void testGetExamineeAccountDetails() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        final MoodleRestTemplateFactory moodleRestTemplateFactory = mock(MoodleRestTemplateFactory.class);
 | 
					        final MoodleRestTemplateFactory moodleRestTemplateFactory = mock(MoodleRestTemplateFactory.class);
 | 
				
			||||||
        final MoodleAPIRestTemplate moodleAPIRestTemplate = mock(MoodleAPIRestTemplate.class);
 | 
					        final MoodleAPIRestTemplateImpl moodleAPIRestTemplate = mock(MoodleAPIRestTemplateImpl.class);
 | 
				
			||||||
        when(moodleRestTemplateFactory.createRestTemplate()).thenReturn(Result.of(moodleAPIRestTemplate));
 | 
					        when(moodleRestTemplateFactory.createRestTemplate()).thenReturn(Result.of(moodleAPIRestTemplate));
 | 
				
			||||||
        when(moodleAPIRestTemplate.callMoodleAPIFunction(
 | 
					        when(moodleAPIRestTemplate.callMoodleAPIFunction(
 | 
				
			||||||
                anyString(),
 | 
					                anyString(),
 | 
				
			||||||
| 
						 | 
					@ -132,7 +133,7 @@ public class MoodleCourseAccessTest {
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    public void testInitAPIAccessError2() {
 | 
					    public void testInitAPIAccessError2() {
 | 
				
			||||||
        final MoodleRestTemplateFactory moodleRestTemplateFactory = mock(MoodleRestTemplateFactory.class);
 | 
					        final MoodleRestTemplateFactory moodleRestTemplateFactory = mock(MoodleRestTemplateFactory.class);
 | 
				
			||||||
        final MoodleAPIRestTemplate moodleAPIRestTemplate = mock(MoodleAPIRestTemplate.class);
 | 
					        final MoodleAPIRestTemplateImpl moodleAPIRestTemplate = mock(MoodleAPIRestTemplateImpl.class);
 | 
				
			||||||
        when(moodleRestTemplateFactory.createRestTemplate()).thenReturn(Result.of(moodleAPIRestTemplate));
 | 
					        when(moodleRestTemplateFactory.createRestTemplate()).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));
 | 
				
			||||||
| 
						 | 
					@ -153,7 +154,7 @@ public class MoodleCourseAccessTest {
 | 
				
			||||||
    @Test
 | 
					    @Test
 | 
				
			||||||
    public void testInitAPIAccessOK() {
 | 
					    public void testInitAPIAccessOK() {
 | 
				
			||||||
        final MoodleRestTemplateFactory moodleRestTemplateFactory = mock(MoodleRestTemplateFactory.class);
 | 
					        final MoodleRestTemplateFactory moodleRestTemplateFactory = mock(MoodleRestTemplateFactory.class);
 | 
				
			||||||
        final MoodleAPIRestTemplate moodleAPIRestTemplate = mock(MoodleAPIRestTemplate.class);
 | 
					        final MoodleAPIRestTemplateImpl moodleAPIRestTemplate = mock(MoodleAPIRestTemplateImpl.class);
 | 
				
			||||||
        when(moodleRestTemplateFactory.createRestTemplate()).thenReturn(Result.of(moodleAPIRestTemplate));
 | 
					        when(moodleRestTemplateFactory.createRestTemplate()).thenReturn(Result.of(moodleAPIRestTemplate));
 | 
				
			||||||
        when(moodleRestTemplateFactory.test()).thenReturn(LmsSetupTestResult.ofOkay(LmsType.MOODLE));
 | 
					        when(moodleRestTemplateFactory.test()).thenReturn(LmsSetupTestResult.ofOkay(LmsType.MOODLE));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue