diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/InternalEncryptionService.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/InternalEncryptionService.java index 26bc9744..085256af 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/InternalEncryptionService.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/InternalEncryptionService.java @@ -24,7 +24,8 @@ public class InternalEncryptionService { private static final Logger log = LoggerFactory.getLogger(InternalEncryptionService.class); - private static final String NO_SALT = "NO_SALT"; + static final String SEBSERVER_WEBSERVICE_INTERNAL_SECRET_KEY = "sebserver.webservice.internalSecret"; + private static final String DEFAULT_SALT = "b7dbe99bbfa3e21e"; private final Environment environment; @@ -35,8 +36,8 @@ public class InternalEncryptionService { public String encrypt(final String text) { try { return Encryptors.text( - this.environment.getRequiredProperty("sebserver.webservice.internalSecret"), - NO_SALT).encrypt(text); + this.environment.getRequiredProperty(SEBSERVER_WEBSERVICE_INTERNAL_SECRET_KEY), + DEFAULT_SALT).encrypt(text); } catch (final Exception e) { log.error("Failed to encrypt text: ", e); return text; @@ -46,8 +47,8 @@ public class InternalEncryptionService { public String decrypt(final String text) { try { return Encryptors.text( - this.environment.getRequiredProperty("sebserver.webservice.internalSecret"), - NO_SALT).decrypt(text); + this.environment.getRequiredProperty(SEBSERVER_WEBSERVICE_INTERNAL_SECRET_KEY), + DEFAULT_SALT).decrypt(text); } catch (final Exception e) { log.error("Failed to decrypt text: ", e); return text; @@ -57,7 +58,7 @@ public class InternalEncryptionService { public String encrypt(final String text, final CharSequence salt) { try { return Encryptors.text( - this.environment.getRequiredProperty("sebserver.webservice.internalSecret"), + this.environment.getRequiredProperty(SEBSERVER_WEBSERVICE_INTERNAL_SECRET_KEY), salt).encrypt(text); } catch (final Exception e) { log.error("Failed to encrypt text: ", e); @@ -68,7 +69,7 @@ public class InternalEncryptionService { public String decrypt(final String text, final CharSequence salt) { try { return Encryptors.text( - this.environment.getRequiredProperty("sebserver.webservice.internalSecret"), + this.environment.getRequiredProperty(SEBSERVER_WEBSERVICE_INTERNAL_SECRET_KEY), salt).decrypt(text); } catch (final Exception e) { log.error("Failed to decrypt text: ", e); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/LmsSetupDAO.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/LmsSetupDAO.java index 815e9662..5d7a7d43 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/LmsSetupDAO.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/LmsSetupDAO.java @@ -9,8 +9,25 @@ package ch.ethz.seb.sebserver.webservice.servicelayer.dao; import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetup; +import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.webservice.servicelayer.bulkaction.BulkActionSupportDAO; public interface LmsSetupDAO extends ActivatableEntityDAO, BulkActionSupportDAO { + Result getLmsAPIAccessCredentials(String lmsSetupId); + + Result getSEBClientCredentials(String lmsSetupId); + + final class Credentials { + public final String clientId; + public final String secret; + public final String accessToken; + + public Credentials(final String clientId, final String secret, final String accessToken) { + super(); + this.clientId = clientId; + this.secret = secret; + this.accessToken = accessToken; + } + } } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/LmsSetupDAOImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/LmsSetupDAOImpl.java index cc3de0f4..3e7932ef 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/LmsSetupDAOImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/dao/impl/LmsSetupDAOImpl.java @@ -254,6 +254,34 @@ public class LmsSetupDAOImpl implements LmsSetupDAO { }); } + @Override + @Transactional(readOnly = true) + public Result getLmsAPIAccessCredentials(final String lmsSetupId) { + return Result.tryCatch(() -> { + final LmsSetupRecord record = this.lmsSetupRecordMapper + .selectByPrimaryKey(Long.parseLong(lmsSetupId)); + + return new Credentials( + record.getLmsClientname(), + record.getLmsClientsecret(), + record.getLmsRestApiToken()); + }); + } + + @Override + @Transactional(readOnly = true) + public Result getSEBClientCredentials(final String lmsSetupId) { + return Result.tryCatch(() -> { + final LmsSetupRecord record = this.lmsSetupRecordMapper + .selectByPrimaryKey(Long.parseLong(lmsSetupId)); + + return new Credentials( + record.getSebClientname(), + record.getSebClientsecret(), + null); + }); + } + private Result> allIdsOfInstitution(final EntityKey institutionKey) { return Result.tryCatch(() -> { return this.lmsSetupRecordMapper.selectIdsByExample() diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/LmsAPITemplate.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/LmsAPITemplate.java index 7d821222..12761e99 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/LmsAPITemplate.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/LmsAPITemplate.java @@ -20,7 +20,7 @@ import ch.ethz.seb.sebserver.gbl.util.Result; public interface LmsAPITemplate { - LmsSetup lmsSetup(); + Result lmsSetup(); LmsSetupTestResult testLmsSetup(); @@ -35,4 +35,6 @@ public interface LmsAPITemplate { Result getExamineeAccountDetails(String examineeUserId); + void reset(); + } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/LmsAPIServiceImpl.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/LmsAPIServiceImpl.java index 5052ec0c..43b6a2a8 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/LmsAPIServiceImpl.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/LmsAPIServiceImpl.java @@ -33,6 +33,8 @@ public class LmsAPIServiceImpl implements LmsAPIService { private final ClientHttpRequestFactory clientHttpRequestFactory; private final String[] openEdxAlternativeTokenRequestPaths; + // TODO internal caching of LmsAPITemplate per LmsSetup (Id) + public LmsAPIServiceImpl( final LmsSetupDAO lmsSetupDAO, final InternalEncryptionService internalEncryptionService, @@ -59,10 +61,14 @@ public class LmsAPIServiceImpl implements LmsAPIService { public Result createLmsAPITemplate(final LmsSetup lmsSetup) { switch (lmsSetup.lmsType) { case MOCKUP: - return Result.of(new MockupLmsAPITemplate(lmsSetup)); + return Result.of(new MockupLmsAPITemplate( + this.lmsSetupDAO, + lmsSetup, + this.internalEncryptionService)); case OPEN_EDX: return Result.of(new OpenEdxLmsAPITemplate( - lmsSetup, + lmsSetup.getModelId(), + this.lmsSetupDAO, this.internalEncryptionService, this.clientHttpRequestFactory, this.openEdxAlternativeTokenRequestPaths)); diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/MockupLmsAPITemplate.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/MockupLmsAPITemplate.java index c1c36ad7..cfd7df25 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/MockupLmsAPITemplate.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/MockupLmsAPITemplate.java @@ -24,16 +24,30 @@ 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.user.ExamineeAccountDetails; import ch.ethz.seb.sebserver.gbl.util.Result; +import ch.ethz.seb.sebserver.webservice.servicelayer.InternalEncryptionService; import ch.ethz.seb.sebserver.webservice.servicelayer.PaginationService.SortOrder; +import ch.ethz.seb.sebserver.webservice.servicelayer.dao.LmsSetupDAO; import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplate; final class MockupLmsAPITemplate implements LmsAPITemplate { + public static final String MOCKUP_LMS_CLIENT_NAME = "mockupLmsClientName"; + public static final String MOCKUP_LMS_CLIENT_SECRET = "mockupLmsClientSecret"; + + private final InternalEncryptionService internalEncryptionService; + private final LmsSetupDAO lmsSetupDao; private final LmsSetup setup; + private LmsSetupDAO.Credentials credentials = null; private final Collection mockups; - MockupLmsAPITemplate(final LmsSetup setup) { + MockupLmsAPITemplate( + final LmsSetupDAO lmsSetupDao, + final LmsSetup setup, + final InternalEncryptionService internalEncryptionService) { + + this.lmsSetupDao = lmsSetupDao; + this.internalEncryptionService = internalEncryptionService; if (!setup.isActive() || setup.lmsType != LmsType.MOCKUP) { throw new IllegalArgumentException(); } @@ -64,8 +78,8 @@ final class MockupLmsAPITemplate implements LmsAPITemplate { } @Override - public LmsSetup lmsSetup() { - return this.setup; + public Result lmsSetup() { + return Result.of(this.setup); } @Override @@ -73,10 +87,8 @@ final class MockupLmsAPITemplate implements LmsAPITemplate { if (this.setup.lmsType != LmsType.MOCKUP) { return LmsSetupTestResult.ofMissingAttributes(LMS_SETUP.ATTR_LMS_TYPE); } - if (this.setup.lmsApiUrl.equals("mockup") && - this.setup.lmsAuthName.equals("mockup") && - this.setup.lmsAuthSecret.equals("mockup")) { - + initCredentials(); + if (this.credentials != null) { return LmsSetupTestResult.ofOkay(); } else { return LmsSetupTestResult.ofMissingAttributes( @@ -121,6 +133,11 @@ final class MockupLmsAPITemplate implements LmsAPITemplate { final int pageSize) { return Result.tryCatch(() -> { + initCredentials(); + if (this.credentials == null) { + throw new IllegalArgumentException("Wrong clientId or secret"); + } + final int startIndex = pageNumber * pageSize; final int endIndex = startIndex + pageSize; int index = 0; @@ -142,6 +159,11 @@ final class MockupLmsAPITemplate implements LmsAPITemplate { @Override public Collection> getQuizzes(final Set ids) { + initCredentials(); + if (this.credentials == null) { + throw new IllegalArgumentException("Wrong clientId or secret"); + } + return this.mockups.stream() .filter(mockup -> ids.contains(mockup.id)) .map(mockup -> Result.of(mockup)) @@ -150,7 +172,31 @@ final class MockupLmsAPITemplate implements LmsAPITemplate { @Override public Result getExamineeAccountDetails(final String examineeUserId) { + initCredentials(); + if (this.credentials == null) { + throw new IllegalArgumentException("Wrong clientId or secret"); + } + return Result.of(new ExamineeAccountDetails(examineeUserId, "mockup", "mockup", "mockup")); } + @Override + public void reset() { + this.credentials = null; + } + + private void initCredentials() { + try { + this.credentials = this.lmsSetupDao + .getLmsAPIAccessCredentials(this.setup.getModelId()) + .getOrThrow(); + + assert (this.credentials.clientId.equals("lmsMockupClientId")) : "wrong clientId"; + assert (this.internalEncryptionService.decrypt(this.credentials.clientId) + .equals("lmsMockupSecret")) : "wrong clientId"; + } catch (final Exception e) { + this.credentials = null; + } + } + } diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/OpenEdxLmsAPITemplate.java b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/OpenEdxLmsAPITemplate.java index 2d16ce82..7d720eb5 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/OpenEdxLmsAPITemplate.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/servicelayer/lms/impl/OpenEdxLmsAPITemplate.java @@ -24,11 +24,8 @@ import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.security.crypto.encrypt.Encryptors; -import org.springframework.security.crypto.encrypt.TextEncryptor; import org.springframework.security.oauth2.client.OAuth2RestTemplate; import org.springframework.security.oauth2.client.token.grant.client.ClientCredentialsResourceDetails; -import org.springframework.security.oauth2.common.DefaultOAuth2AccessToken; import org.springframework.security.oauth2.common.OAuth2AccessToken; import ch.ethz.seb.sebserver.gbl.model.Domain.LMS_SETUP; @@ -40,6 +37,8 @@ import ch.ethz.seb.sebserver.gbl.model.institution.LmsSetupTestResult; import ch.ethz.seb.sebserver.gbl.model.user.ExamineeAccountDetails; import ch.ethz.seb.sebserver.gbl.util.Result; import ch.ethz.seb.sebserver.webservice.servicelayer.InternalEncryptionService; +import ch.ethz.seb.sebserver.webservice.servicelayer.dao.LmsSetupDAO; +import ch.ethz.seb.sebserver.webservice.servicelayer.dao.LmsSetupDAO.Credentials; import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplate; final class OpenEdxLmsAPITemplate implements LmsAPITemplate { @@ -50,7 +49,8 @@ final class OpenEdxLmsAPITemplate implements LmsAPITemplate { private static final String OPEN_EDX_DEFAULT_COURSE_ENDPOINT = "/api/courses/v1/courses/"; private static final String OPEN_EDX_DEFAULT_COURSE_START_URL_PREFIX = "/courses/"; - private final LmsSetup lmsSetup; + private final String lmsSetupId; + private final LmsSetupDAO lmsSetupDAO; private final ClientHttpRequestFactory clientHttpRequestFactory; private final InternalEncryptionService internalEncryptionService; private final Set knownTokenAccessPaths; @@ -58,12 +58,14 @@ final class OpenEdxLmsAPITemplate implements LmsAPITemplate { private OAuth2RestTemplate restTemplate = null; OpenEdxLmsAPITemplate( - final LmsSetup lmsSetup, + final String lmsSetupId, + final LmsSetupDAO lmsSetupDAO, final InternalEncryptionService internalEncryptionService, final ClientHttpRequestFactory clientHttpRequestFactory, final String[] alternativeTokenRequestPaths) { - this.lmsSetup = lmsSetup; + this.lmsSetupId = lmsSetupId; + this.lmsSetupDAO = lmsSetupDAO; this.clientHttpRequestFactory = clientHttpRequestFactory; this.internalEncryptionService = internalEncryptionService; @@ -75,27 +77,30 @@ final class OpenEdxLmsAPITemplate implements LmsAPITemplate { } @Override - public LmsSetup lmsSetup() { - return this.lmsSetup; + public Result lmsSetup() { + return this.lmsSetupDAO + .byModelId(this.lmsSetupId); } @Override public LmsSetupTestResult testLmsSetup() { - log.info("Test Lms Binding for OpenEdX and LmsSetup: {}", this.lmsSetup); + final LmsSetup lmsSetup = lmsSetup().getOrThrow(); + + log.info("Test Lms Binding for OpenEdX and LmsSetup: {}", lmsSetup); // validation of LmsSetup - if (this.lmsSetup.lmsType != LmsType.MOCKUP) { + if (lmsSetup.lmsType != LmsType.MOCKUP) { return LmsSetupTestResult.ofMissingAttributes(LMS_SETUP.ATTR_LMS_TYPE); } final List missingAttrs = new ArrayList<>(); - if (StringUtils.isBlank(this.lmsSetup.lmsApiUrl)) { + if (StringUtils.isBlank(lmsSetup.lmsApiUrl)) { missingAttrs.add(LMS_SETUP.ATTR_LMS_TYPE); } - if (StringUtils.isBlank(this.lmsSetup.getLmsAuthName())) { + if (StringUtils.isBlank(lmsSetup.getLmsAuthName())) { missingAttrs.add(LMS_SETUP.ATTR_LMS_CLIENTNAME); } - if (StringUtils.isBlank(this.lmsSetup.getLmsAuthSecret())) { + if (StringUtils.isBlank(lmsSetup.getLmsAuthSecret())) { missingAttrs.add(LMS_SETUP.ATTR_LMS_CLIENTSECRET); } @@ -104,7 +109,7 @@ final class OpenEdxLmsAPITemplate implements LmsAPITemplate { } // request OAuth2 access token on OpenEdx API - initRestTemplateAndRequestAccessToken(); + initRestTemplateAndRequestAccessToken(lmsSetup); if (this.restTemplate == null) { return LmsSetupTestResult.ofTokenRequestError( "Failed to gain access token form OpenEdX Rest API: tried token endpoints: " + @@ -124,34 +129,35 @@ final class OpenEdxLmsAPITemplate implements LmsAPITemplate { final int pageNumber, final int pageSize) { - return Result.tryCatch(() -> { - initRestTemplateAndRequestAccessToken(); + return this.lmsSetup() + .flatMap(this::initRestTemplateAndRequestAccessToken) + .map(lmsSetup -> { - // TODO sort and pagination - final HttpHeaders httpHeaders = new HttpHeaders(); + // TODO sort and pagination + final HttpHeaders httpHeaders = new HttpHeaders(); - final ResponseEntity response = this.restTemplate.exchange( - this.lmsSetup.lmsApiUrl + OPEN_EDX_DEFAULT_COURSE_ENDPOINT, - HttpMethod.GET, - new HttpEntity<>(httpHeaders), - EdXPage.class); - final EdXPage edxpage = response.getBody(); + final ResponseEntity response = this.restTemplate.exchange( + lmsSetup.lmsApiUrl + OPEN_EDX_DEFAULT_COURSE_ENDPOINT, + HttpMethod.GET, + new HttpEntity<>(httpHeaders), + EdXPage.class); + final EdXPage edxpage = response.getBody(); - final List content = edxpage.results - .stream() - .reduce( - new ArrayList(), - (list, courseData) -> { - list.add(quizDataOf(courseData)); - return list; - }, - (list1, list2) -> { - list1.addAll(list2); - return list1; - }); + final List content = edxpage.results + .stream() + .reduce( + new ArrayList(), + (list, courseData) -> { + list.add(quizDataOf(lmsSetup, courseData)); + return list; + }, + (list1, list2) -> { + list1.addAll(list2); + return list1; + }); - return new Page<>(edxpage.num_pages, pageNumber, sort, content); - }); + return new Page<>(edxpage.num_pages, pageNumber, sort, content); + }); } @Override @@ -166,45 +172,67 @@ final class OpenEdxLmsAPITemplate implements LmsAPITemplate { return null; } - private void initRestTemplateAndRequestAccessToken() { - - log.info("Initialize Rest Template for OpenEdX API access. LmsSetup: {}", this.lmsSetup); - - if (this.restTemplate != null) { - try { - this.restTemplate.getAccessToken(); - return; - } catch (final Exception e) { - log.warn( - "Error while trying to get access token within already existing OAuth2RestTemplate instance. Try to create new one.", - e); - this.restTemplate = null; - } - } - - final Iterator tokenAccessPaths = this.knownTokenAccessPaths.iterator(); - while (this.restTemplate == null && tokenAccessPaths.hasNext()) { - final String accessTokenRequestPath = tokenAccessPaths.next(); - try { - final OAuth2RestTemplate template = createRestTemplate(accessTokenRequestPath); - final OAuth2AccessToken accessToken = template.getAccessToken(); - if (accessToken != null) { - this.restTemplate = template; - storeAccessToken(accessToken); - } - } catch (final Exception e) { - log.info("Failed to request access token on access token request path: {}", accessTokenRequestPath, e); - } - } + @Override + public void reset() { + this.restTemplate = null; } - private OAuth2RestTemplate createRestTemplate(final String accessTokenRequestPath) { + private Result initRestTemplateAndRequestAccessToken(final LmsSetup lmsSetup) { - final String lmsAuthSecret = this.internalEncryptionService.decrypt(this.lmsSetup.lmsAuthSecret); + log.info("Initialize Rest Template for OpenEdX API access. LmsSetup: {}", lmsSetup); + + return Result.tryCatch(() -> { + if (this.restTemplate != null) { + try { + this.restTemplate.getAccessToken(); + return lmsSetup; + } catch (final Exception e) { + log.warn( + "Error while trying to get access token within already existing OAuth2RestTemplate instance. Try to create new one.", + e); + this.restTemplate = null; + } + } + + final Credentials credentials = this.lmsSetupDAO + .getLmsAPIAccessCredentials(this.lmsSetupId) + .getOrThrow(); + + final Iterator tokenAccessPaths = this.knownTokenAccessPaths.iterator(); + while (tokenAccessPaths.hasNext()) { + final String accessTokenRequestPath = tokenAccessPaths.next(); + try { + + final OAuth2RestTemplate template = createRestTemplate( + lmsSetup, + credentials, + accessTokenRequestPath); + + final OAuth2AccessToken accessToken = template.getAccessToken(); + if (accessToken != null) { + this.restTemplate = template; + return lmsSetup; + } + } catch (final Exception e) { + log.info("Failed to request access token on access token request path: {}", accessTokenRequestPath, + e); + } + } + + throw new IllegalArgumentException("Unable to establish OpenEdX API connection for lmsSetup: " + lmsSetup); + }); + } + + private OAuth2RestTemplate createRestTemplate( + final LmsSetup lmsSetup, + final LmsSetupDAO.Credentials credentials, + final String accessTokenRequestPath) { + + final String lmsAuthSecret = this.internalEncryptionService.decrypt(credentials.secret); final ClientCredentialsResourceDetails details = new ClientCredentialsResourceDetails(); - details.setAccessTokenUri(this.lmsSetup.lmsApiUrl + accessTokenRequestPath); - details.setClientId(this.lmsSetup.lmsAuthName); + details.setAccessTokenUri(lmsSetup.lmsApiUrl + accessTokenRequestPath); + details.setClientId(credentials.clientId); details.setClientSecret(lmsAuthSecret); details.setGrantType("client_credentials"); @@ -214,51 +242,14 @@ final class OpenEdxLmsAPITemplate implements LmsAPITemplate { final OAuth2RestTemplate template = new OAuth2RestTemplate(details); template.setRequestFactory(this.clientHttpRequestFactory); - - final OAuth2AccessToken previousAccessToken = loadPreviousAccessToken(); - if (previousAccessToken != null) { - template.getOAuth2ClientContext().setAccessToken(previousAccessToken); - } return template; } - private void storeAccessToken(final OAuth2AccessToken accessToken) { - try { + private QuizData quizDataOf( + final LmsSetup lmsSetup, + final CourseData courseData) { - final String accessTokenString = accessToken.getValue(); - final TextEncryptor textEncryptor = Encryptors.text(this.lmsSetup.lmsAuthSecret, this.lmsSetup.lmsAuthName); - final String accessTokenEncrypted = textEncryptor.encrypt(accessTokenString); - - // TODO store the accessTokenEncrypted to additional attributes of LmsSetup - - } catch (final Exception e) { - log.warn("Failed to store access token for later use.", e); - } - } - - private OAuth2AccessToken loadPreviousAccessToken() { - - // TODO get the previous token from additional attributes of LmsSetup - final String prevTokenEncrypted = null; - - if (StringUtils.isBlank(prevTokenEncrypted)) { - return null; - } - - try { - - final TextEncryptor textEncryptor = Encryptors.text(this.lmsSetup.lmsAuthSecret, this.lmsSetup.lmsAuthName); - final String prevTokenDecrypt = textEncryptor.decrypt(prevTokenEncrypted); - return new DefaultOAuth2AccessToken(prevTokenDecrypt); - - } catch (final Exception e) { - log.warn("Failed to decrypt previous access-token.", e); - return null; - } - } - - private QuizData quizDataOf(final CourseData courseData) { - final String startURI = this.lmsSetup.lmsApiUrl + OPEN_EDX_DEFAULT_COURSE_START_URL_PREFIX + courseData.id; + final String startURI = lmsSetup.lmsApiUrl + OPEN_EDX_DEFAULT_COURSE_START_URL_PREFIX + courseData.id; return new QuizData( courseData.id, courseData.name, diff --git a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/QuizImportController.java b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/QuizImportController.java index fb1ef5f8..726f29d5 100644 --- a/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/QuizImportController.java +++ b/src/main/java/ch/ethz/seb/sebserver/webservice/weblayer/api/QuizImportController.java @@ -16,6 +16,7 @@ import org.springframework.web.bind.annotation.RestController; import ch.ethz.seb.sebserver.gbl.api.SEBServerRestEndpoints; import ch.ethz.seb.sebserver.gbl.model.Domain.LMS_SETUP; +import ch.ethz.seb.sebserver.gbl.model.Entity; import ch.ethz.seb.sebserver.gbl.model.EntityType; import ch.ethz.seb.sebserver.gbl.model.Page; import ch.ethz.seb.sebserver.gbl.model.exam.QuizData; @@ -23,6 +24,7 @@ import ch.ethz.seb.sebserver.gbl.profile.WebServiceProfile; import ch.ethz.seb.sebserver.gbl.util.Utils; import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.AuthorizationGrantService; import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.PrivilegeType; +import ch.ethz.seb.sebserver.webservice.servicelayer.authorization.UserService; import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPIService; import ch.ethz.seb.sebserver.webservice.servicelayer.lms.LmsAPITemplate; @@ -51,6 +53,10 @@ public class QuizImportController { @RequestMapping(method = RequestMethod.GET) public Page search( + @RequestParam( + name = Entity.FILTER_ATTR_INSTITUTION, + required = true, + defaultValue = UserService.USERS_INSTITUTION_AS_DEFAULT) final Long institutionId, @RequestParam(name = LMS_SETUP.ATTR_ID, required = true) final Long lmsSetupId, @RequestParam(name = QuizData.FILTER_ATTR_NAME, required = false) final String nameLike, @RequestParam(name = QuizData.FILTER_ATTR_START_TIME, required = false) final String startTime, @@ -65,7 +71,7 @@ public class QuizImportController { this.authorizationGrantService.checkPrivilege( EntityType.EXAM, PrivilegeType.READ_ONLY, - lmsAPITemplate.lmsSetup().institutionId); + institutionId); return lmsAPITemplate.getQuizzes( nameLike, diff --git a/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/InternalEncryptionServiceTest.java b/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/InternalEncryptionServiceTest.java new file mode 100644 index 00000000..a6a179d7 --- /dev/null +++ b/src/test/java/ch/ethz/seb/sebserver/webservice/servicelayer/InternalEncryptionServiceTest.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019 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; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import org.junit.Test; +import org.springframework.core.env.Environment; + +public class InternalEncryptionServiceTest { + + @Test + public void testEncryptSimpleSecret() { + final Environment envMock = mock(Environment.class); + when(envMock.getRequiredProperty(InternalEncryptionService.SEBSERVER_WEBSERVICE_INTERNAL_SECRET_KEY)) + .thenReturn("secret1"); + + final InternalEncryptionService service = new InternalEncryptionService(envMock); + final String encrypt = service.encrypt("text1"); + final String decrypt = service.decrypt(encrypt); + assertEquals("text1", decrypt); + } + +}