diff --git a/src/main/java/org/olat/basesecurity/BaseSecurity.java b/src/main/java/org/olat/basesecurity/BaseSecurity.java index eed2a302bcb3618b601f9e3b9ed640bb03396005..2e19b38d70a8e5736f810d32814e313823e71aee 100644 --- a/src/main/java/org/olat/basesecurity/BaseSecurity.java +++ b/src/main/java/org/olat/basesecurity/BaseSecurity.java @@ -310,6 +310,14 @@ public interface BaseSecurity { * found */ public Authentication findAuthentication(Identity identity, String provider); + + /** + * Return the credential or null + * @param identity + * @param provider + * @return + */ + public String findCredentials(Identity identity, String provider); //fxdiff: FXOLAT-219 decrease the load for synching groups public boolean hasAuthentication(Long identityKey, String provider); @@ -626,6 +634,14 @@ public interface BaseSecurity { * @return */ public boolean isIdentityVisible(String identityName); + + /** + * Check if identity is visible. Deleted or login-denied users are not visible. + * @param identity + * @return + */ + public boolean isIdentityVisible(Identity identity); + /** * Get all SecurtityGroups an Identity is in diff --git a/src/main/java/org/olat/basesecurity/BaseSecurityManager.java b/src/main/java/org/olat/basesecurity/BaseSecurityManager.java index be6b281f4e778ce6cac4e73bd639d1e7132afe33..664d8d63328e632e95eeab20c5b92eb4c0d5d462 100644 --- a/src/main/java/org/olat/basesecurity/BaseSecurityManager.java +++ b/src/main/java/org/olat/basesecurity/BaseSecurityManager.java @@ -1417,6 +1417,26 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { return results.get(0); } + @Override + public String findCredentials(Identity identity, String provider) { + if (identity==null) { + throw new IllegalArgumentException("identity must not be null"); + } + + StringBuilder sb = new StringBuilder(); + sb.append("select auth.credential from ").append(AuthenticationImpl.class.getName()) + .append(" as auth where auth.identity.key=:identityKey and auth.provider=:provider"); + + List<String> results = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), String.class) + .setParameter("identityKey", identity.getKey()) + .setParameter("provider", provider) + .getResultList(); + if (results == null || results.size() == 0) return null; + if (results.size() > 1) throw new AssertException("Found more than one Authentication for a given subject and a given provider."); + return results.get(0); + } + @Override //fxdiff: FXOLAT-219 decrease the load for synching groups public boolean hasAuthentication(Long identityKey, String provider) { @@ -1827,6 +1847,13 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { return (cntL.longValue() > 0); } + @Override + public boolean isIdentityVisible(Identity identity) { + if(identity == null) return false; + Integer status = identity.getStatus(); + return (status != null && status.intValue() < Identity.STATUS_VISIBLE_LIMIT); + } + private boolean checkAnd(StringBuilder sb, boolean needsAnd) { if (needsAnd) sb.append(" and "); return true; @@ -1873,7 +1900,7 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { */ @Override public Identity saveIdentityStatus(Identity identity, Integer status) { - Identity reloadedIdentity = loadForUpdate(identity.getKey()); + Identity reloadedIdentity = loadForUpdate(identity); reloadedIdentity.setStatus(status); reloadedIdentity = dbInstance.getCurrentEntityManager().merge(reloadedIdentity); dbInstance.commit(); @@ -1882,7 +1909,7 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { @Override public Identity setIdentityLastLogin(Identity identity) { - Identity reloadedIdentity = loadForUpdate(identity.getKey()); + Identity reloadedIdentity = loadForUpdate(identity); reloadedIdentity.setLastLogin(new Date()); reloadedIdentity = dbInstance.getCurrentEntityManager().merge(reloadedIdentity); dbInstance.commit(); @@ -1894,22 +1921,22 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { * @param identityKey * @return */ - private IdentityImpl loadForUpdate(Long identityKey) { + private IdentityImpl loadForUpdate(Identity identity) { StringBuilder sb = new StringBuilder(); sb.append("select id from ").append(IdentityImpl.class.getName()).append(" as id") .append(" inner join fetch id.user user ") .append(" where id.key=:identityKey"); - List<IdentityImpl> identity = dbInstance.getCurrentEntityManager() + dbInstance.getCurrentEntityManager().detach(identity); + List<IdentityImpl> identities = dbInstance.getCurrentEntityManager() .createQuery(sb.toString(), IdentityImpl.class) - .setParameter("identityKey", identityKey) + .setParameter("identityKey", identity.getKey()) .setLockMode(LockModeType.PESSIMISTIC_WRITE) .getResultList(); - - if(identity.isEmpty()) { + if(identities.isEmpty()) { return null; } - return identity.get(0); + return identities.get(0); } @Override diff --git a/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVAuthManager.java b/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVAuthManager.java index bda7135b44aa4473026f175a947b24bf973d5bf2..56db6a7b680efb2e51af94a8aad7b515a2654a99 100644 --- a/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVAuthManager.java +++ b/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVAuthManager.java @@ -21,6 +21,7 @@ package org.olat.core.commons.services.webdav.manager; import org.olat.basesecurity.Authentication; +import org.olat.basesecurity.BaseSecurity; import org.olat.basesecurity.BaseSecurityManager; import org.olat.core.commons.persistence.DBFactory; import org.olat.core.id.Identity; @@ -87,15 +88,21 @@ public class WebDAVAuthManager { * @return Identity if authentication was successful, null otherwise. */ public static Identity authenticate(String login, String pass) { - Identity ident = BaseSecurityManager.getInstance().findIdentityByName(login); - if (ident == null) return null; - boolean visible = BaseSecurityManager.getInstance().isIdentityVisible(login); - if (!visible) return null; + BaseSecurity securityManager = BaseSecurityManager.getInstance(); + Identity ident = securityManager.findIdentityByName(login); + if (ident == null) return null; + boolean visible = securityManager.isIdentityVisible(ident); + if (!visible) { + return null; + } + //find WEBDAV authentication provider - Authentication auth = BaseSecurityManager.getInstance().findAuthentication(ident, PROVIDER_WEBDAV); - if (auth != null && auth.getCredential().equals(Encoder.encrypt(pass))) return ident; + String auth = securityManager.findCredentials(ident, PROVIDER_WEBDAV); + if (auth != null && auth.equals(Encoder.encrypt(pass))) { + return ident; + } //fallback to OLAT authentication provider - return OLATAuthenticationController.authenticate(login, pass); + return OLATAuthenticationController.authenticate(ident, login, pass); } } diff --git a/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVManagerImpl.java b/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVManagerImpl.java index 61045c3b21c532cd1d630399841c8ae1aa3092e0..2544bd64220fe308c12cb9087d5724a167794fa8 100644 --- a/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVManagerImpl.java +++ b/src/main/java/org/olat/core/commons/services/webdav/manager/WebDAVManagerImpl.java @@ -154,7 +154,7 @@ public class WebDAVManagerImpl extends WebDAVManager { return null; } - private UserSession handleBasicAuthentication(String credentials, HttpServletRequest request) { + protected UserSession handleBasicAuthentication(String credentials, HttpServletRequest request) { // This example uses sun.misc.* classes. // You will need to provide your own // if you are not comfortable with that. diff --git a/src/main/java/org/olat/core/id/context/HistoryManager.java b/src/main/java/org/olat/core/id/context/HistoryManager.java index 0b7769b82dff577da34953b0d6d13db83525593c..d855fd740d5f12fb3285ead2cc0755c466c1d7aa 100644 --- a/src/main/java/org/olat/core/id/context/HistoryManager.java +++ b/src/main/java/org/olat/core/id/context/HistoryManager.java @@ -53,6 +53,8 @@ public class HistoryManager extends BasicManager { historyReadStream.omitField(BusinessGroup.class, "groupContext"); historyReadStream.omitField(BusinessGroupImpl.class, "groupContext"); historyReadStream.alias("org.olat.core.util.resource.OresHelper$1", Resourceable.class); + historyReadStream.alias("org.olat.core.util.resource.OresHelper$2", Resourceable.class); + historyReadStream.alias("org.olat.core.util.resource.OresHelper$3", Resourceable.class); historyReadStream.aliasAttribute(Resourceable.class, "resourceableTypeName", "val_-type"); historyReadStream.aliasAttribute(Resourceable.class, "resourceableTypeName", "val$type"); historyReadStream.aliasAttribute(Resourceable.class, "resourceableId", "val_-key"); diff --git a/src/main/java/org/olat/instantMessaging/ui/InstantMessagingMainController.java b/src/main/java/org/olat/instantMessaging/ui/InstantMessagingMainController.java index 70ea34afee0f1f8e39c97fc4bff7dedc1fbebfa4..a7b9a12e8f48045ba40af1b843ad19631d4dd348 100644 --- a/src/main/java/org/olat/instantMessaging/ui/InstantMessagingMainController.java +++ b/src/main/java/org/olat/instantMessaging/ui/InstantMessagingMainController.java @@ -336,7 +336,9 @@ public class InstantMessagingMainController extends BasicController implements G inAssessment = true; main.contextPut("inAssessment", true); chatMgrCtrl.closeAllChats(); - rosterPanelCtr.executeCloseCommand(); + if(rosterPanelCtr != null) { + rosterPanelCtr.executeCloseCommand(); + } } else if(event.getEventType().equals(AssessmentEvent.TYPE.STOPPED)) { OLATResourceable a = OresHelper.createOLATResourceableType(AssessmentInstance.class); if (singleUserEventCenter.getListeningIdentityCntFor(a) < 1) { diff --git a/src/main/java/org/olat/login/OLATAuthenticationController.java b/src/main/java/org/olat/login/OLATAuthenticationController.java index ac5c5dbe778a9d5f0d92cdafb8f0f3e7d9c24515..b7fd129ec5bddca16361f59d377d0579e12e43c1 100644 --- a/src/main/java/org/olat/login/OLATAuthenticationController.java +++ b/src/main/java/org/olat/login/OLATAuthenticationController.java @@ -285,11 +285,18 @@ public class OLATAuthenticationController extends AuthenticationController imple * @deprecated should not be part of the controller */ public static Identity authenticate(String login, String pass) { - if (pass == null) return null; // do never accept empty passwords - Identity ident = BaseSecurityManager.getInstance().findIdentityByName(login); - + return authenticate(ident, login, pass); + } + + /** + * @param login + * @param pass + * @return Identity if authentication was successfull, null otherwise. + * @deprecated should not be part of the controller + */ + public static Identity authenticate(Identity ident, String login, String pass) { // check for email instead of username if ident is null if (ident == null && LoginModule.allowLoginUsingEmail()) { if (MailHelper.isValidEmailAddress(login)){ @@ -306,10 +313,8 @@ public class OLATAuthenticationController extends AuthenticationController imple } // find OLAT authentication provider - Authentication auth = BaseSecurityManager.getInstance().findAuthentication( - ident, BaseSecurityModule.getDefaultAuthProviderIdentifier()); - - if (auth != null && auth.getCredential().equals(Encoder.encrypt(pass))) return ident; + String auth = BaseSecurityManager.getInstance().findCredentials(ident, BaseSecurityModule.getDefaultAuthProviderIdentifier()); + if (auth != null && auth.equals(Encoder.encrypt(pass))) return ident; Tracing.createLoggerFor(OLATAuthenticationController.class).audit( "Error authenticating user "+login+" via provider OLAT", diff --git a/src/main/java/org/olat/restapi/repository/course/CourseGroupWebService.java b/src/main/java/org/olat/restapi/repository/course/CourseGroupWebService.java index fc4afda97ca3db6b5a4cb701c9ac31239ad20849..fec09072bec9daf5cd1f464589c79af73c2dda2b 100644 --- a/src/main/java/org/olat/restapi/repository/course/CourseGroupWebService.java +++ b/src/main/java/org/olat/restapi/repository/course/CourseGroupWebService.java @@ -211,15 +211,22 @@ public class CourseGroupWebService { UserRequest ureq = RestSecurityHelper.getUserRequest(request); BusinessGroupService bgm = CoreSpringFactory.getImpl(BusinessGroupService.class); - - String name = group.getName(); - String desc = group.getDescription(); - Integer min = normalize(group.getMinParticipants()); - Integer max = normalize(group.getMaxParticipants()); - RepositoryEntry courseRe = RepositoryManager.getInstance().lookupRepositoryEntry(course, false); - BusinessGroup bg = bgm.createBusinessGroup(ureq.getIdentity(), name, desc, min, max, false, false, courseRe); - GroupVO savedVO = ObjectFactory.get(bg); + + BusinessGroup bg; + if(group.getKey() != null && group.getKey() > 0) { + //group already exists + bg = bgm.loadBusinessGroup(group.getKey()); + bgm.addResourceTo(bg, courseRe); + } else { + String name = group.getName(); + String desc = group.getDescription(); + Integer min = normalize(group.getMinParticipants()); + Integer max = normalize(group.getMaxParticipants()); + + bg = bgm.createBusinessGroup(ureq.getIdentity(), name, desc, min, max, false, false, courseRe); + } + GroupVO savedVO = ObjectFactory.get(bg); return Response.ok(savedVO).build(); } diff --git a/src/main/java/org/olat/restapi/repository/course/CourseWebService.java b/src/main/java/org/olat/restapi/repository/course/CourseWebService.java index 0e099c45097a2917255b1f2a17a80f7096a777db..609045735e18e2fb21d31be954d9a2df55ae5cbf 100644 --- a/src/main/java/org/olat/restapi/repository/course/CourseWebService.java +++ b/src/main/java/org/olat/restapi/repository/course/CourseWebService.java @@ -62,6 +62,7 @@ import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.StringHelper; import org.olat.core.util.coordinate.LockResult; +import org.olat.core.util.mail.MailPackage; import org.olat.core.util.resource.OresHelper; import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.xml.XStreamHelper; @@ -641,6 +642,94 @@ public class CourseWebService { return Response.ok().build(); } + /** + * Add a coach to the course + * @response.representation.200.doc The user is a coach of the course + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The course or the user not found + * @param courseId The course resourceable's id + * @param identityKey The user identifier + * @param httpRequest The HTTP request + * @return It returns 200 if the user is added as coach of the course + */ + @PUT + @Path("tutors/{identityKey}") + public Response addCoach(@PathParam("courseId") Long courseId, @PathParam("identityKey") Long identityKey, + @Context HttpServletRequest httpRequest) { + if(!isAuthor(httpRequest)) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + + OLATResourceable course = getCourseOLATResource(courseId); + if(course == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } else if (!isAuthorEditor(course, httpRequest)) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + + BaseSecurity securityManager = BaseSecurityManager.getInstance(); + Identity tutor = securityManager.loadIdentityByKey(identityKey, false); + if(tutor == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + + Identity identity = getIdentity(httpRequest); + UserRequest ureq = getUserRequest(httpRequest); + + //add the author as owner of the course + RepositoryManager rm = RepositoryManager.getInstance(); + RepositoryEntry repositoryEntry = rm.lookupRepositoryEntry(course, true); + List<Identity> tutors = Collections.singletonList(tutor); + IdentitiesAddEvent iae = new IdentitiesAddEvent(tutors); + rm.addTutors(identity, ureq.getUserSession().getRoles(), iae, repositoryEntry, new MailPackage(false)); + + return Response.ok().build(); + } + + /** + * Add an participant to the course + * @response.representation.200.doc The user is a participant of the course + * @response.representation.401.doc The roles of the authenticated user are not sufficient + * @response.representation.404.doc The course or the user not found + * @param courseId The course resourceable's id + * @param identityKey The user identifier + * @param httpRequest The HTTP request + * @return It returns 200 if the user is added as owner and author of the course + */ + @PUT + @Path("participants/{identityKey}") + public Response addParticipant(@PathParam("courseId") Long courseId, @PathParam("identityKey") Long identityKey, + @Context HttpServletRequest httpRequest) { + if(!isAuthor(httpRequest)) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + + OLATResourceable course = getCourseOLATResource(courseId); + if(course == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } else if (!isAuthorEditor(course, httpRequest)) { + return Response.serverError().status(Status.UNAUTHORIZED).build(); + } + + BaseSecurity securityManager = BaseSecurityManager.getInstance(); + Identity participant = securityManager.loadIdentityByKey(identityKey, false); + if(participant == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } + + Identity identity = getIdentity(httpRequest); + UserRequest ureq = getUserRequest(httpRequest); + + //add the author as owner of the course + RepositoryManager rm = RepositoryManager.getInstance(); + RepositoryEntry repositoryEntry = rm.lookupRepositoryEntry(course, true); + List<Identity> participants = Collections.singletonList(participant); + IdentitiesAddEvent iae = new IdentitiesAddEvent(participants); + rm.addParticipants(identity, ureq.getUserSession().getRoles(), iae, repositoryEntry, new MailPackage(false)); + + return Response.ok().build(); + } + private OLATResource getCourseOLATResource(Long courseId) { String typeName = OresHelper.calculateTypeName(CourseModule.class); OLATResource ores = OLATResourceManager.getInstance().findResourceable(courseId, typeName); diff --git a/src/test/java/org/olat/basesecurity/BaseSecurityManagerTest.java b/src/test/java/org/olat/basesecurity/BaseSecurityManagerTest.java index 58a581bf277da092d0b4ebfa18127909579df46f..e46abe3ec513c38f679f50e09e179fcb06f87b38 100644 --- a/src/test/java/org/olat/basesecurity/BaseSecurityManagerTest.java +++ b/src/test/java/org/olat/basesecurity/BaseSecurityManagerTest.java @@ -833,4 +833,15 @@ public class BaseSecurityManagerTest extends OlatTestCase { Assert.assertTrue(permissions.contains("test.gpor-1_2")); Assert.assertFalse(permissions.contains("test.gpor-1_3")); } + + @Test + public void findCredentials() { + //create a user with the default provider + Identity id = JunitTestHelper.createAndPersistIdentityAsUser("find-cred-" + UUID.randomUUID().toString()); + + dbInstance.commitAndCloseSession(); + + String credential = securityManager.findCredentials(id, BaseSecurityModule.getDefaultAuthProviderIdentifier()); + Assert.assertNotNull(credential); + } } diff --git a/src/test/java/org/olat/core/commons/services/webdav/manager/WebDAVManagerTest.java b/src/test/java/org/olat/core/commons/services/webdav/manager/WebDAVManagerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..b3bb9ada2eb78e1a752df6f06514ea556178d8b3 --- /dev/null +++ b/src/test/java/org/olat/core/commons/services/webdav/manager/WebDAVManagerTest.java @@ -0,0 +1,152 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.webdav.manager; + +import static org.junit.Assert.assertTrue; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.UUID; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.TimeUnit; + +import javax.servlet.http.HttpServletRequest; + +import junit.framework.Assert; + +import org.junit.Test; +import org.olat.core.commons.persistence.DB; +import org.olat.core.commons.persistence.DBFactory; +import org.olat.core.id.Identity; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; +import org.olat.core.util.UserSession; +import org.olat.test.JunitTestHelper; +import org.olat.test.OlatTestCase; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.mock.web.MockHttpServletRequest; + +import com.oreilly.servlet.Base64Encoder; + +/** + * + * Initial date: 21.05.2013<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class WebDAVManagerTest extends OlatTestCase { + + private static final OLog log = Tracing.createLoggerFor(WebDAVManagerTest.class); + + @Autowired + private DB dbInstance; + @Autowired + private WebDAVManagerImpl webDAVManager; + + @Test + public void handleBasicAuthentication() { + Identity id = JunitTestHelper.createAndPersistIdentityAsUser("dav-user-" + UUID.randomUUID().toString()); + + String credentialsClearText = id.getName() + ":" + JunitTestHelper.PWD; + String credentials = Base64Encoder.encode(credentialsClearText); + HttpServletRequest request = new MockHttpServletRequest(); + UserSession usess = webDAVManager.handleBasicAuthentication(credentials, request); + Assert.assertNotNull(usess); + dbInstance.commit(); + } + + @Test + public void testSetIdentityAsActiv() { + Identity id = JunitTestHelper.createAndPersistIdentityAsUser("dav-user-" + UUID.randomUUID().toString()); + String credentialsClearText = id.getName() + ":" + JunitTestHelper.PWD; + String credentials = Base64Encoder.encode(credentialsClearText); + + final int maxLoop = 50; // => 4000 x 11ms => 44sec => finished in 50sec + final int numThreads = 10; + // Let two thread call UserDeletionManager.setIdentityAsActiv + final List<Exception> exceptionHolder = Collections.synchronizedList(new ArrayList<Exception>(1)); + + CountDownLatch latch = new CountDownLatch(numThreads); + ActivThread[] threads = new ActivThread[numThreads]; + for(int i=0; i<threads.length;i++) { + threads[i] = new ActivThread(maxLoop, latch, exceptionHolder, webDAVManager, credentials); + } + + for(int i=0; i<threads.length;i++) { + threads[i].start(); + } + + try { + latch.await(120, TimeUnit.SECONDS); + } catch (InterruptedException e) { + exceptionHolder.add(e); + } + + // if not -> they are in deadlock and the db did not detect it + for (Exception exception : exceptionHolder) { + log.error("exception: ", exception); + } + assertTrue("Exceptions #" + exceptionHolder.size(), exceptionHolder.size() == 0); + } + + private static class ActivThread extends Thread { + + private final int maxLoop; + private final CountDownLatch countDown; + private final List<Exception> exceptionHolder; + private final WebDAVManagerImpl webDAVManager; + private final String credentials; + + public ActivThread(int maxLoop, CountDownLatch countDown, List<Exception> exceptionHolder, WebDAVManagerImpl webDAVManager, String credentials) { + this.maxLoop = maxLoop; + this.countDown = countDown; + this.exceptionHolder = exceptionHolder; + this.webDAVManager = webDAVManager; + this.credentials = credentials; + } + + @Override + public void run() { + try { + sleep(10); + for (int i=0; i<maxLoop; i++) { + try { + HttpServletRequest request = new MockHttpServletRequest(); + webDAVManager.handleBasicAuthentication(credentials, request); + DBFactory.getInstance().commit(); + } catch (Exception e) { + exceptionHolder.add(e); + } finally { + try { + DBFactory.getInstance().commitAndCloseSession(); + } catch (Exception e) { + // ignore + } + } + } + } catch (Exception e) { + exceptionHolder.add(e); + } finally { + countDown.countDown(); + } + } + } +} \ No newline at end of file diff --git a/src/test/java/org/olat/core/id/context/HistoryManagerTest.java b/src/test/java/org/olat/core/id/context/HistoryManagerTest.java index 7c884831641867f05262247acb52d78ba7f552d9..ecbeb75987cb3e0e7276a1f2ac3300fc82bd9bb5 100644 --- a/src/test/java/org/olat/core/id/context/HistoryManagerTest.java +++ b/src/test/java/org/olat/core/id/context/HistoryManagerTest.java @@ -83,4 +83,19 @@ public class HistoryManagerTest extends OlatTestCase { HistoryPoint history = historyManager.readHistory(resumeXml); Assert.assertNotNull(history); } + + /** + * Test the compatibility with version 8.3 + * @throws IOException + * @throws URISyntaxException + */ + @Test + public void testRead_v83() throws IOException, URISyntaxException { + URL xmlUrl = HistoryManagerTest.class.getResource("resume_ver83.xml"); + assertNotNull(xmlUrl); + File resumeXml = new File(xmlUrl.toURI()); + HistoryPoint history = historyManager.readHistory(resumeXml); + Assert.assertNotNull(history); + } + } diff --git a/src/test/java/org/olat/core/id/context/resume_ver83.xml b/src/test/java/org/olat/core/id/context/resume_ver83.xml new file mode 100644 index 0000000000000000000000000000000000000000..47c21b669f29c33ee9857ee7d8dd7582904daf19 --- /dev/null +++ b/src/test/java/org/olat/core/id/context/resume_ver83.xml @@ -0,0 +1,18 @@ +<org.olat.core.id.context.HistoryPointImpl> + <uuid>8568</uuid> + <businessPath>[RepositoryEntry:4718607][CourseNode:84791741596431]</businessPath> + <entries> + <org.olat.core.id.context.MyContextEntry> + <olatResourceable class="org.olat.core.util.resource.OresHelper$3"> + <val_-type>RepositoryEntry</val_-type> + <val_-key>4718607</val_-key> + </olatResourceable> + </org.olat.core.id.context.MyContextEntry> + <org.olat.core.id.context.MyContextEntry> + <olatResourceable class="org.olat.core.util.resource.OresHelper$1"> + <val_-type>CourseNode</val_-type> + <val_-key>84791741596431</val_-key> + </olatResourceable> + </org.olat.core.id.context.MyContextEntry> + </entries> +</org.olat.core.id.context.HistoryPointImpl> \ No newline at end of file diff --git a/src/test/java/org/olat/restapi/CourseTest.java b/src/test/java/org/olat/restapi/CourseTest.java index 9ec57d2d33b4630ffdb7dac3797535f89b873af1..9b6a19823f4c0072ef86fb9fb04d0c54c707da00 100644 --- a/src/test/java/org/olat/restapi/CourseTest.java +++ b/src/test/java/org/olat/restapi/CourseTest.java @@ -219,6 +219,7 @@ public class CourseTest extends OlatJerseyTestCase { HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true); HttpResponse response = conn.execute(method); assertEquals(200, response.getStatusLine().getStatusCode()); + EntityUtils.consume(response.getEntity()); //is auth0 author BaseSecurity securityManager = BaseSecurityManager.getInstance(); @@ -318,6 +319,44 @@ public class CourseTest extends OlatJerseyTestCase { DBFactory.getInstance().intermediateCommit(); } + @Test + public void testAddCoach() throws IOException, URISyntaxException { + assertTrue(conn.login("administrator", "openolat")); + URI request = UriBuilder.fromUri(getContextURI()).path("/repo/courses/" + course1.getResourceableId() + "/tutors/" + auth1.getKey()).build(); + HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true); + HttpResponse response = conn.execute(method); + assertEquals(200, response.getStatusLine().getStatusCode()); + EntityUtils.consume(response.getEntity()); + + //is auth0 coach/tutor + RepositoryManager rm = RepositoryManager.getInstance(); + BaseSecurity securityManager = BaseSecurityManager.getInstance(); + RepositoryEntry repositoryEntry = rm.lookupRepositoryEntry(course1, true); + SecurityGroup tutorGroup = repositoryEntry.getTutorGroup(); + boolean isTutor = securityManager.isIdentityInSecurityGroup(auth1, tutorGroup); + DBFactory.getInstance().intermediateCommit(); + assertTrue(isTutor); + } + + @Test + public void testAddParticipant() throws IOException, URISyntaxException { + assertTrue(conn.login("administrator", "openolat")); + URI request = UriBuilder.fromUri(getContextURI()).path("/repo/courses/" + course1.getResourceableId() + "/participants/" + auth2.getKey()).build(); + HttpPut method = conn.createPut(request, MediaType.APPLICATION_JSON, true); + HttpResponse response = conn.execute(method); + assertEquals(200, response.getStatusLine().getStatusCode()); + EntityUtils.consume(response.getEntity()); + + //is auth2 participant + RepositoryManager rm = RepositoryManager.getInstance(); + BaseSecurity securityManager = BaseSecurityManager.getInstance(); + RepositoryEntry repositoryEntry = rm.lookupRepositoryEntry(course1, true); + SecurityGroup participant = repositoryEntry.getParticipantGroup(); + boolean isParticipant = securityManager.isIdentityInSecurityGroup(auth2, participant); + DBFactory.getInstance().intermediateCommit(); + assertTrue(isParticipant); + } + protected List<UserVO> parseUserArray(InputStream body) { try { ObjectMapper mapper = new ObjectMapper(jsonFactory);