SEBSERV-301 finished implementation and testing with token

This commit is contained in:
anhefti 2023-01-25 13:30:53 +01:00
parent b97152f91a
commit a5bab8fc9f
12 changed files with 95 additions and 106 deletions

View file

@ -664,7 +664,7 @@ public final class Utils {
if (sb.length() > 0) { if (sb.length() > 0) {
sb.append(Constants.AMPERSAND); sb.append(Constants.AMPERSAND);
} }
if (sb.length() == 1) { if (values.size() == 1) {
return sb.append(name).append(Constants.EQUALITY_SIGN).append(values.get(0)); return sb.append(name).append(Constants.EQUALITY_SIGN).append(values.get(0));
} }
return sb.append(toAppFormUrlEncodedBody(name, values)); return sb.append(toAppFormUrlEncodedBody(name, values));

View file

@ -221,19 +221,16 @@ public class LmsSetupForm implements TemplateComposer {
lmsSetup.getLmsAuthName()) lmsSetup.getLmsAuthName())
.mandatory(!readonly)) .mandatory(!readonly))
.addFieldIf( .addField(FormBuilder.password(
isEdit, Domain.LMS_SETUP.ATTR_LMS_CLIENTSECRET,
() -> FormBuilder.text( FORM_SECRET_LMS_TEXT_KEY,
Domain.LMS_SETUP.ATTR_LMS_CLIENTSECRET, lmsSetup.getLmsAuthSecret())
FORM_SECRET_LMS_TEXT_KEY) .mandatory(!readonly))
.asPasswordField()
.mandatory(!readonly))
.addFieldIf( .addField(FormBuilder.password(
isEdit, Domain.LMS_SETUP.ATTR_LMS_REST_API_TOKEN,
() -> FormBuilder.text( FORM_TOKEN_LMS_TEXT_KEY,
Domain.LMS_SETUP.ATTR_LMS_REST_API_TOKEN, lmsSetup.lmsRestApiToken))
FORM_TOKEN_LMS_TEXT_KEY))
.addFieldIf( .addFieldIf(
isEdit, isEdit,
@ -277,10 +274,10 @@ public class LmsSetupForm implements TemplateComposer {
.withEmptyCellSpan(0)) .withEmptyCellSpan(0))
.addFieldIf( .addFieldIf(
() -> !readonly, () -> !readonly,
() -> FormBuilder.text( () -> FormBuilder.password(
Domain.LMS_SETUP.ATTR_LMS_PROXY_AUTH_SECRET, Domain.LMS_SETUP.ATTR_LMS_PROXY_AUTH_SECRET,
FORM_PROXY_PWD_KEY) FORM_PROXY_PWD_KEY,
.asPasswordField() lmsSetup.proxyAuthSecret)
.withInputSpan(3) .withInputSpan(3)
.withLabelSpan(2) .withLabelSpan(2)
.withEmptyCellSeparation(true) .withEmptyCellSeparation(true)

View file

@ -40,7 +40,6 @@ 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.model.institution.LmsSetup.LmsType;
import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile;
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.datalayer.batis.mapper.InstitutionRecordDynamicSqlSupport; import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.InstitutionRecordDynamicSqlSupport;
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.LmsSetupRecordDynamicSqlSupport; import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.LmsSetupRecordDynamicSqlSupport;
import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.LmsSetupRecordMapper; import ch.ethz.seb.sebserver.webservice.datalayer.batis.mapper.LmsSetupRecordMapper;
@ -171,32 +170,28 @@ public class LmsSetupDAOImpl implements LmsSetupDAO {
checkUniqueName(lmsSetup); checkUniqueName(lmsSetup);
final LmsSetupRecord savedRecord = recordById(lmsSetup.id) // final LmsSetupRecord savedRecord = recordById(lmsSetup.id)
.getOrThrow(); // .getOrThrow();
final ClientCredentials lmsCredentials = createAPIClientCredentials(lmsSetup); // final ClientCredentials lmsCredentials = createAPIClientCredentials(lmsSetup);
final ClientCredentials proxyCredentials = createProxyClientCredentials(lmsSetup); // final ClientCredentials proxyCredentials = createProxyClientCredentials(lmsSetup);
final LmsSetupRecord newRecord = new LmsSetupRecord( final LmsSetupRecord newRecord = new LmsSetupRecord(
lmsSetup.id, lmsSetup.id,
lmsSetup.institutionId, lmsSetup.institutionId,
lmsSetup.name, lmsSetup.name,
(lmsSetup.lmsType != null) ? lmsSetup.lmsType.name() : null, (lmsSetup.lmsType != null) ? lmsSetup.lmsType.name() : null,
lmsSetup.lmsApiUrl, lmsSetup.lmsApiUrl,
lmsCredentials.clientIdAsString(), lmsSetup.lmsAuthName,
(lmsCredentials.hasSecret()) this.encryptForSave(lmsSetup.lmsAuthSecret),
? lmsCredentials.secretAsString() this.encryptForSave(lmsSetup.lmsRestApiToken),
: savedRecord.getLmsClientsecret(),
(lmsCredentials.hasAccessToken())
? lmsCredentials.accessTokenAsString()
: savedRecord.getLmsRestApiToken(),
lmsSetup.getProxyHost(), lmsSetup.getProxyHost(),
lmsSetup.getProxyPort(), lmsSetup.getProxyPort(),
proxyCredentials.clientIdAsString(), lmsSetup.proxyAuthUsername,
proxyCredentials.secretAsString(), this.encryptForSave(lmsSetup.proxyAuthSecret),
System.currentTimeMillis(), System.currentTimeMillis(),
savedRecord.getActive()); null);
this.lmsSetupRecordMapper.updateByPrimaryKey(newRecord); this.lmsSetupRecordMapper.updateByPrimaryKeySelective(newRecord);
return this.lmsSetupRecordMapper.selectByPrimaryKey(lmsSetup.id); return this.lmsSetupRecordMapper.selectByPrimaryKey(lmsSetup.id);
}) })
.flatMap(this::toDomainModel) .flatMap(this::toDomainModel)
@ -210,21 +205,19 @@ public class LmsSetupDAOImpl implements LmsSetupDAO {
checkUniqueName(lmsSetup); checkUniqueName(lmsSetup);
final ClientCredentials lmsCredentials = createAPIClientCredentials(lmsSetup);
final ClientCredentials proxyCredentials = createProxyClientCredentials(lmsSetup);
final LmsSetupRecord newRecord = new LmsSetupRecord( final LmsSetupRecord newRecord = new LmsSetupRecord(
null, null,
lmsSetup.institutionId, lmsSetup.institutionId,
lmsSetup.name, lmsSetup.name,
(lmsSetup.lmsType != null) ? lmsSetup.lmsType.name() : null, (lmsSetup.lmsType != null) ? lmsSetup.lmsType.name() : null,
lmsSetup.lmsApiUrl, lmsSetup.lmsApiUrl,
lmsCredentials.clientIdAsString(), lmsSetup.lmsAuthName,
lmsCredentials.secretAsString(), this.encryptForSave(lmsSetup.lmsAuthSecret),
lmsCredentials.accessTokenAsString(), this.encryptForSave(lmsSetup.lmsRestApiToken),
lmsSetup.getProxyHost(), lmsSetup.getProxyHost(),
lmsSetup.getProxyPort(), lmsSetup.getProxyPort(),
proxyCredentials.clientIdAsString(), lmsSetup.proxyAuthUsername,
proxyCredentials.secretAsString(), this.encryptForSave(lmsSetup.proxyAuthSecret),
System.currentTimeMillis(), System.currentTimeMillis(),
BooleanUtils.toInteger(false)); BooleanUtils.toInteger(false));
@ -390,35 +383,35 @@ public class LmsSetupDAOImpl implements LmsSetupDAO {
private Result<LmsSetup> toDomainModel(final LmsSetupRecord record) { private Result<LmsSetup> toDomainModel(final LmsSetupRecord record) {
final ClientCredentials clientCredentials = new ClientCredentials(
record.getLmsClientname(),
record.getLmsClientsecret(),
record.getLmsRestApiToken());
final ClientCredentials proxyCredentials = new ClientCredentials(
record.getLmsProxyAuthUsername(),
record.getLmsProxyAuthSecret());
return Result.tryCatch(() -> new LmsSetup( return Result.tryCatch(() -> new LmsSetup(
record.getId(), record.getId(),
record.getInstitutionId(), record.getInstitutionId(),
record.getName(), record.getName(),
LmsType.valueOf(record.getLmsType()), LmsType.valueOf(record.getLmsType()),
Utils.toString(clientCredentials.clientId), record.getLmsClientname(),
null, record.getLmsClientsecret(),
record.getLmsUrl(), record.getLmsUrl(),
Utils.toString( record.getLmsRestApiToken(),
this.clientCredentialService
.getPlainAccessToken(clientCredentials)
.getOr(null)),
record.getLmsProxyHost(), record.getLmsProxyHost(),
record.getLmsProxyPort(), record.getLmsProxyPort(),
Utils.toString(proxyCredentials.clientId), record.getLmsProxyAuthUsername(),
Utils.toString(proxyCredentials.secret), record.getLmsProxyAuthSecret(),
BooleanUtils.toBooleanObject(record.getActive()), BooleanUtils.toBooleanObject(record.getActive()),
record.getUpdateTime())); record.getUpdateTime()));
} }
private String encryptForSave(final String input) {
if (StringUtils.isBlank(input)) {
return input;
}
// check if input is already encrypted and possible to decrypt
if (this.clientCredentialService.decrypt(input).hasError()) {
return this.clientCredentialService.encrypt(input).get().toString();
} else {
return input;
}
}
// check if same name already exists for the same institution // check if same name already exists for the same institution
// if true an APIMessageException with a field validation error is thrown // if true an APIMessageException with a field validation error is thrown
private void checkUniqueName(final LmsSetup lmsSetup) { private void checkUniqueName(final LmsSetup lmsSetup) {
@ -438,21 +431,4 @@ public class LmsSetupDAOImpl implements LmsSetupDAO {
} }
} }
private ClientCredentials createProxyClientCredentials(final LmsSetup lmsSetup) {
return (StringUtils.isBlank(lmsSetup.proxyAuthUsername))
? new ClientCredentials(null, null)
: this.clientCredentialService.encryptClientCredentials(
lmsSetup.proxyAuthUsername,
lmsSetup.proxyAuthSecret)
.getOrThrow();
}
private ClientCredentials createAPIClientCredentials(final LmsSetup lmsSetup) {
return this.clientCredentialService.encryptClientCredentials(
lmsSetup.lmsAuthName,
lmsSetup.lmsAuthSecret,
lmsSetup.lmsRestApiToken)
.getOrThrow();
}
} }

View file

@ -291,7 +291,8 @@ public class LmsAPIServiceImpl implements LmsAPIService {
public ClientCredentials getLmsClientCredentials() { public ClientCredentials getLmsClientCredentials() {
return this.clientCredentialService.encryptClientCredentials( return this.clientCredentialService.encryptClientCredentials(
this.lmsSetup.getLmsAuthName(), this.lmsSetup.getLmsAuthName(),
this.lmsSetup.getLmsAuthSecret()) this.lmsSetup.getLmsAuthSecret(),
this.lmsSetup.lmsRestApiToken)
.getOrThrow(); .getOrThrow();
} }
@ -303,7 +304,8 @@ public class LmsAPIServiceImpl implements LmsAPIService {
this.lmsSetup.proxyPort, this.lmsSetup.proxyPort,
this.clientCredentialService.encryptClientCredentials( this.clientCredentialService.encryptClientCredentials(
this.lmsSetup.proxyAuthUsername, this.lmsSetup.proxyAuthUsername,
this.lmsSetup.proxyAuthSecret) this.lmsSetup.proxyAuthSecret,
this.lmsSetup.lmsRestApiToken)
.getOrThrow()) .getOrThrow())
: null; : null;
} }

View file

@ -344,8 +344,6 @@ public class MoodleRestTemplateFactoryImpl implements MoodleRestTemplateFactory
functionReqEntity, functionReqEntity,
String.class); String.class);
System.out.println("*************** response: " + response);
final LmsSetup lmsSetup = this.apiTemplateDataSupplier.getLmsSetup(); final LmsSetup lmsSetup = this.apiTemplateDataSupplier.getLmsSetup();
if (response.getStatusCode() != HttpStatus.OK) { if (response.getStatusCode() != HttpStatus.OK) {
throw new RuntimeException( throw new RuntimeException(
@ -358,6 +356,10 @@ public class MoodleRestTemplateFactoryImpl implements MoodleRestTemplateFactory
// NOTE: for some unknown reason, Moodles API error responses come with a 200 OK response HTTP Status // NOTE: for some unknown reason, Moodles API error responses come with a 200 OK response HTTP Status
// So this is a special Moodle specific error handling here... // So this is a special Moodle specific error handling here...
if (body.startsWith("{exception") || body.contains("\"exception\":")) { if (body.startsWith("{exception") || body.contains("\"exception\":")) {
// if no courses has been found for this page, just return (Plugin)
if (body.contains("nocoursefound")) {
return body;
}
// Reset access token to get new on next call (fix access if token is expired) // Reset access token to get new on next call (fix access if token is expired)
// NOTE: find a way to verify token invalidity response from Moodle. // NOTE: find a way to verify token invalidity response from Moodle.
// Unfortunately there is not a lot of Moodle documentation for the API error handling around. // Unfortunately there is not a lot of Moodle documentation for the API error handling around.

View file

@ -510,16 +510,16 @@ public abstract class MoodleUtils {
@JsonIgnoreProperties(ignoreUnknown = true) @JsonIgnoreProperties(ignoreUnknown = true)
public static final class MoodleQuizRestriction { public static final class MoodleQuizRestriction {
public final String quizid; public final String quizid;
public final String configkeys; public final List<String> configkeys;
public final String browserkeys; public final List<String> browserkeys;
public final String quitlink; public final String quitlink;
public final String quitsecret; public final String quitsecret;
@JsonCreator @JsonCreator
public MoodleQuizRestriction( public MoodleQuizRestriction(
@JsonProperty("quizid") final String quizid, @JsonProperty("quizid") final String quizid,
@JsonProperty("configkeys") final String configkeys, @JsonProperty("configkeys") final List<String> configkeys,
@JsonProperty("browserkeys") final String browserkeys, @JsonProperty("browserkeys") final List<String> browserkeys,
@JsonProperty("quitlink") final String quitlink, @JsonProperty("quitlink") final String quitlink,
@JsonProperty("quitsecret") final String quitsecret) { @JsonProperty("quitsecret") final String quitsecret) {

View file

@ -72,6 +72,7 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme
public static final String ATTR_FIELD = "field"; public static final String ATTR_FIELD = "field";
public static final String ATTR_VALUE = "value"; public static final String ATTR_VALUE = "value";
public static final String ATTR_VALUE_ARRAY = "values[]";
public static final String ATTR_ID = "id"; public static final String ATTR_ID = "id";
public static final String ATTR_SHORTNAME = "shortname"; public static final String ATTR_SHORTNAME = "shortname";
@ -300,7 +301,7 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme
final MultiValueMap<String, String> queryAttributes = new LinkedMultiValueMap<>(); final MultiValueMap<String, String> queryAttributes = new LinkedMultiValueMap<>();
queryAttributes.add(ATTR_FIELD, ATTR_ID); queryAttributes.add(ATTR_FIELD, ATTR_ID);
queryAttributes.add(ATTR_VALUE, examineeSessionId); queryAttributes.add(ATTR_VALUE_ARRAY, examineeSessionId);
final String userDetailsJSON = template.callMoodleAPIFunction( final String userDetailsJSON = template.callMoodleAPIFunction(
USERS_API_FUNCTION_NAME, USERS_API_FUNCTION_NAME,
@ -442,6 +443,21 @@ public class MoodlePluginCourseAccess extends AbstractCachedCourseAccess impleme
MoodleUtils.checkJSONFormat(courseKeyPageJSON); MoodleUtils.checkJSONFormat(courseKeyPageJSON);
if (courseKeyPageJSON.startsWith("{\"exception\":")) {
if (courseKeyPageJSON.contains("nocoursefound")) {
if (log.isDebugEnabled()) {
log.debug(
"Got nocoursefound exception from Moodle for page: {}. "
+ "Assuming that there are no more courses and stop fetching.",
page);
}
return Collections.emptyList();
}
log.error("Moodle exception while page fetching on page: {}, response: {}", page, courseKeyPageJSON);
log.info("Stop fetching because of Moodle error response");
return Collections.emptyList();
}
final CoursesPlugin coursePage = this.jsonMapper.readValue(courseKeyPageJSON, CoursesPlugin.class); final CoursesPlugin coursePage = this.jsonMapper.readValue(courseKeyPageJSON, CoursesPlugin.class);
if (coursePage == null) { if (coursePage == null) {

View file

@ -9,10 +9,8 @@
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.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -20,7 +18,6 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.LinkedMultiValueMap;
import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.api.JSONMapper; import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
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;
@ -254,24 +251,14 @@ public class MoodlePluginCourseRestriction implements SEBRestrictionAPI {
final Exam exam, final Exam exam,
final MoodleQuizRestriction moodleRestriction) { final MoodleQuizRestriction moodleRestriction) {
final List<String> configKeys = StringUtils.isNoneBlank(moodleRestriction.configkeys)
? Arrays.asList(StringUtils.split(
moodleRestriction.configkeys,
Constants.LIST_SEPARATOR))
: Collections.emptyList();
final List<String> browserExamKeys = StringUtils.isNoneBlank(moodleRestriction.browserkeys)
? new ArrayList<>(Arrays.asList(StringUtils.split(
moodleRestriction.browserkeys,
Constants.LIST_SEPARATOR)))
: Collections.emptyList();
final Map<String, String> additionalProperties = new HashMap<>(); final Map<String, String> additionalProperties = new HashMap<>();
additionalProperties.put(ATTRIBUTE_QUIT_URL, moodleRestriction.quitlink); additionalProperties.put(ATTRIBUTE_QUIT_URL, moodleRestriction.quitlink);
additionalProperties.put(ATTRIBUTE_QUIT_SECRET, moodleRestriction.quitsecret); additionalProperties.put(ATTRIBUTE_QUIT_SECRET, moodleRestriction.quitsecret);
return new SEBRestriction( return new SEBRestriction(
exam.id, exam.id,
configKeys, moodleRestriction.configkeys,
browserExamKeys, moodleRestriction.browserkeys,
additionalProperties); additionalProperties);
} }

View file

@ -92,6 +92,9 @@ public class SEBClientSessionServiceImpl implements SEBClientSessionService {
@Override @Override
public void updateASKGrants() { public void updateASKGrants() {
// TODO check only for exams with enabled ASK check!!!
this.clientConnectionDAO this.clientConnectionDAO
.getAllActiveNotGranted() .getAllActiveNotGranted()
.onError(error -> log.error("Failed to get none granted active client connections: ", error)) .onError(error -> log.error("Failed to get none granted active client connections: ", error))

View file

@ -103,8 +103,7 @@ public class LmsSetupAPITest extends AdministrationAPIIntegrationTester {
assertEquals("new LmsSetup 1", lmsSetup.name); assertEquals("new LmsSetup 1", lmsSetup.name);
assertTrue(LmsType.MOCKUP == lmsSetup.lmsType); assertTrue(LmsType.MOCKUP == lmsSetup.lmsType);
assertEquals("lms1Name", lmsSetup.lmsAuthName); assertEquals("lms1Name", lmsSetup.lmsAuthName);
// secrets, once set are not exposed assertNotNull(lmsSetup.lmsAuthSecret);
assertEquals(null, lmsSetup.lmsAuthSecret);
assertFalse(lmsSetup.active); assertFalse(lmsSetup.active);
// activate // activate

View file

@ -10,6 +10,7 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.lms.impl.moodle;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
@ -29,7 +30,6 @@ import org.springframework.web.util.UriComponentsBuilder;
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.JsonProcessingException;
import ch.ethz.seb.sebserver.gbl.Constants;
import ch.ethz.seb.sebserver.gbl.api.JSONMapper; import ch.ethz.seb.sebserver.gbl.api.JSONMapper;
import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup.LmsType; 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;
@ -286,8 +286,8 @@ public class MoodleMockupRestTemplateFactory implements MoodleRestTemplateFactor
final MoodleQuizRestriction moodleQuizRestriction = new MoodleQuizRestriction( final MoodleQuizRestriction moodleQuizRestriction = new MoodleQuizRestriction(
quizId, quizId,
StringUtils.join(configKeys, Constants.LIST_SEPARATOR), trimList(configKeys),
StringUtils.join(beks, Constants.LIST_SEPARATOR), trimList(beks),
quitURL, quitURL,
quitSecret); quitSecret);
@ -303,6 +303,13 @@ public class MoodleMockupRestTemplateFactory implements MoodleRestTemplateFactor
} }
} }
private List<String> trimList(final List<String> list) {
if (list.size() == 1 && StringUtils.isBlank(list.get(0))) {
return Collections.emptyList();
}
return list;
}
private String respondGetRestriction(final String quizId, final MultiValueMap<String, String> queryAttributes) { private String respondGetRestriction(final String quizId, final MultiValueMap<String, String> queryAttributes) {
final MoodleQuizRestrictions moodleQuizRestriction = this.restrcitions.get(quizId); final MoodleQuizRestrictions moodleQuizRestriction = this.restrcitions.get(quizId);
if (moodleQuizRestriction != null) { if (moodleQuizRestriction != null) {
@ -328,7 +335,7 @@ public class MoodleMockupRestTemplateFactory implements MoodleRestTemplateFactor
} }
private String respondUsers(final MultiValueMap<String, String> queryAttributes) { private String respondUsers(final MultiValueMap<String, String> queryAttributes) {
final String id = queryAttributes.getFirst(MoodlePluginCourseAccess.ATTR_VALUE); final String id = queryAttributes.getFirst(MoodlePluginCourseAccess.ATTR_VALUE_ARRAY);
final String field = queryAttributes.getFirst(MoodlePluginCourseAccess.ATTR_FIELD); final String field = queryAttributes.getFirst(MoodlePluginCourseAccess.ATTR_FIELD);
if (!field.equals(MoodlePluginCourseAccess.ATTR_ID)) { if (!field.equals(MoodlePluginCourseAccess.ATTR_ID)) {

View file

@ -260,7 +260,7 @@ public class MoodlePluginCourseAccessTest {
+ "testLog=[" + "testLog=["
+ "callMoodleAPIFunction: core_user_get_users_by_field], " + "callMoodleAPIFunction: core_user_get_users_by_field], "
+ "callLog=[" + "callLog=["
+ "<field=id&value=2,[Content-Type:\"application/x-www-form-urlencoded\"]>]]]", + "<field=id&values[]=2,[Content-Type:\"application/x-www-form-urlencoded\"]>]]]",
candidate.toTestString()); candidate.toTestString());
} }
@ -277,7 +277,7 @@ public class MoodlePluginCourseAccessTest {
"MoodlePluginCourseAccess [pageSize=500, maxSize=10000, cutoffTimeOffset=3, " "MoodlePluginCourseAccess [pageSize=500, maxSize=10000, cutoffTimeOffset=3, "
+ "restTemplate=MockupMoodleRestTemplate [accessToken=MockupMoodleRestTemplate-Test-Token, url=https://test.org/, " + "restTemplate=MockupMoodleRestTemplate [accessToken=MockupMoodleRestTemplate-Test-Token, url=https://test.org/, "
+ "testLog=[callMoodleAPIFunction: core_user_get_users_by_field], " + "testLog=[callMoodleAPIFunction: core_user_get_users_by_field], "
+ "callLog=[<field=id&value=1,[Content-Type:\"application/x-www-form-urlencoded\"]>]]]", + "callLog=[<field=id&values[]=1,[Content-Type:\"application/x-www-form-urlencoded\"]>]]]",
candidate.toTestString()); candidate.toTestString());
} }
@ -306,7 +306,7 @@ public class MoodlePluginCourseAccessTest {
@Override @Override
public ClientCredentials getLmsClientCredentials() { public ClientCredentials getLmsClientCredentials() {
return new ClientCredentials("lms-user", "lms-user-secret"); return new ClientCredentials("lms-user", "lms-user-secret", "lms-user-token");
} }
@Override @Override