Skip to content
Snippets Groups Projects
Commit 9bb056a1 authored by srosse's avatar srosse
Browse files

Merge remote-tracking branch 'origin/OpenOLAT_15.1' into OpenOLAT_15.2

parents 67bf8f0b bd0ccab1
No related branches found
No related tags found
No related merge requests found
......@@ -42,7 +42,7 @@ import org.olat.core.id.Persistable;
*/
@Entity(name="bidentitylastlogin")
@Table(name="o_bs_identity")
@NamedQuery(name="updateIdentityLastLogin", query="update bidentitylastlogin set lastLogin=:now where key=:identityKey")
@NamedQuery(name="updateIdentityLastLogin", query="update bidentitylastlogin set lastLogin=:now, inactivationEmailDate=null where key=:identityKey")
public class IdentityLastLoginImpl implements Persistable, IdentityRef {
private static final long serialVersionUID = 2090002193918262648L;
......@@ -56,6 +56,10 @@ public class IdentityLastLoginImpl implements Persistable, IdentityRef {
@Column(name="lastlogin", nullable=false, insertable=true, updatable=true)
private Date lastLogin;
@Temporal(TemporalType.TIMESTAMP)
@Column(name="inactivationemaildate", nullable=false, insertable=true, updatable=true)
private Date inactivationEmailDate;
public IdentityLastLoginImpl() {
//
}
......
/**
* <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.ims.qti21.restapi;
import static org.olat.restapi.security.RestSecurityHelper.getRoles;
import java.io.File;
import java.net.URI;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.Status;
import org.apache.logging.log4j.Logger;
import org.olat.core.id.Roles;
import org.olat.core.logging.Tracing;
import org.olat.core.util.StringHelper;
import org.olat.fileresource.FileResourceManager;
import org.olat.ims.qti21.QTI21Service;
import org.olat.repository.RepositoryEntry;
import org.olat.repository.RepositoryManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import uk.ac.ed.ph.jqtiplus.node.test.AssessmentTest;
import uk.ac.ed.ph.jqtiplus.node.test.ItemSessionControl;
import uk.ac.ed.ph.jqtiplus.node.test.TestPart;
import uk.ac.ed.ph.jqtiplus.resolution.ResolvedAssessmentTest;
/**
*
* Initial date: 2 sept. 2020<br>
* @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
*
*/
@Component
@Path("repo/tests")
public class AssessmentTestWebService {
private static final Logger log = Tracing.createLoggerFor(AssessmentTestWebService.class);
@Autowired
private QTI21Service qtiService;
@Autowired
private RepositoryManager repositoryManager;
@PUT
@Path("{repoEntryKey}/parts/maxattempts")
public Response getRepositoryEntryResource(@PathParam("repoEntryKey")String repoEntryKey, @Context HttpServletRequest httpRequest)
throws WebApplicationException {
Roles roles = getRoles(httpRequest);
if(roles == null || !roles.isAdministrator()) {
throw new WebApplicationException(Status.FORBIDDEN);
}
RepositoryEntry re = lookupRepositoryEntry(repoEntryKey);
if(re == null) {
throw new WebApplicationException(Status.NOT_FOUND);
}
FileResourceManager frm = FileResourceManager.getInstance();
File unzippedDirRoot = frm.unzipFileResource(re.getOlatResource());
ResolvedAssessmentTest resolvedObject = qtiService.loadAndResolveAssessmentTest(unzippedDirRoot, false, true);
AssessmentTest assessmentTest = resolvedObject.getRootNodeLookup().extractIfSuccessful();
List<TestPart> parts = assessmentTest.getChildAbstractParts();
for(TestPart part:parts) {
ItemSessionControl itemSessionControl = part.getItemSessionControl();
itemSessionControl.setMaxAttempts(Integer.valueOf(0));
}
URI testURI = resolvedObject.getTestLookup().getSystemId();
File testFile = new File(testURI);
qtiService.updateAssesmentObject(testFile, resolvedObject);
return Response.ok().build();
}
private RepositoryEntry lookupRepositoryEntry(String key) {
RepositoryEntry re = null;
if (StringHelper.isLong(key)) {// looks like a primary key
try {
re = repositoryManager.lookupRepositoryEntry(Long.valueOf(key));
} catch (NumberFormatException e) {
log.warn("", e);
}
}
return re;
}
}
......@@ -92,7 +92,6 @@ public class UserAdminLifecycleConfigurationController extends FormBasicControll
formLayout.add(buttonsLayout);
uifactory.addFormSubmitButton("save", buttonsLayout);
}
protected void initDeactivationForm(FormItemContainer formLayout) {
String[] onValues = new String[] { translate("enabled") };
......@@ -116,8 +115,8 @@ public class UserAdminLifecycleConfigurationController extends FormBasicControll
initDays(numberOfDayBeforeDeactivationMailEl);
// subject + content mail
TranslationBundle beforeBundleSubject = initForm("mail.before.deactivation.subject.label", "mail.before.deactivation.subject", formLayout);
TranslationBundle beforeBundle = initForm("mail.before.deactivation.body.label", "mail.before.deactivation.body", formLayout);
TranslationBundle beforeBundleSubject = initForm("mail.before.deactivation.subject.label", "mail.before.deactivation.subject", false, formLayout);
TranslationBundle beforeBundle = initForm("mail.before.deactivation.body.label", "mail.before.deactivation.body", true, formLayout);
mailBeforeDeactivationBundles = new TranslationBundles(beforeBundleSubject, beforeBundle);
// enable mail after
......@@ -126,8 +125,8 @@ public class UserAdminLifecycleConfigurationController extends FormBasicControll
enableMailAfterDeactivationEl.select(onKeys[0], userModule.isMailAfterDeactivation());
// subject + content mail
TranslationBundle afterBundleSubject = initForm("mail.after.deactivation.subject.label", "mail.after.deactivation.subject", formLayout);
TranslationBundle afterBundle = initForm("mail.after.deactivation.body.label", "mail.after.deactivation.body", formLayout);
TranslationBundle afterBundleSubject = initForm("mail.after.deactivation.subject.label", "mail.after.deactivation.subject", false, formLayout);
TranslationBundle afterBundle = initForm("mail.after.deactivation.body.label", "mail.after.deactivation.body", true, formLayout);
mailAfterDeactivationBundles = new TranslationBundles(afterBundleSubject, afterBundle);
}
......@@ -152,8 +151,8 @@ public class UserAdminLifecycleConfigurationController extends FormBasicControll
initDays(numberOfDayBeforeDeletionMailEl);
// subject + content mail
TranslationBundle beforeBundleSubject = initForm("mail.before.deletion.subject.label", "mail.before.deletion.subject", formLayout);
TranslationBundle beforeBundle = initForm("mail.before.deletion.body.label", "mail.before.deletion.body", formLayout);
TranslationBundle beforeBundleSubject = initForm("mail.before.deletion.subject.label", "mail.before.deletion.subject", false, formLayout);
TranslationBundle beforeBundle = initForm("mail.before.deletion.body.label", "mail.before.deletion.body", true, formLayout);
mailBeforeDeletionBundles = new TranslationBundles(beforeBundleSubject, beforeBundle);
// enable mail after
......@@ -162,17 +161,17 @@ public class UserAdminLifecycleConfigurationController extends FormBasicControll
enableMailAfterDeletionEl.select(onKeys[0], userModule.isMailAfterDeletion());
// subject + content mail
TranslationBundle afterBundleSubject = initForm("mail.after.deletion.subject.label", "mail.after.deletion.subject", formLayout);
TranslationBundle afterBundle = initForm("mail.after.deletion.body.label", "mail.after.deletion.body", formLayout);
TranslationBundle afterBundleSubject = initForm("mail.after.deletion.subject.label", "mail.after.deletion.subject", false, formLayout);
TranslationBundle afterBundle = initForm("mail.after.deletion.body.label", "mail.after.deletion.body", true, formLayout);
mailAfterDeletionBundles = new TranslationBundles(afterBundleSubject, afterBundle);
}
private TranslationBundle initForm(String labelI18nKey, String textI18nKey, FormItemContainer formLayout) {
private TranslationBundle initForm(String labelI18nKey, String textI18nKey, boolean textArea, FormItemContainer formLayout) {
String text = translate(textI18nKey);
StaticTextElement viewEl = uifactory.addStaticTextElement("view." + counter++, labelI18nKey, text, formLayout);
FormLink translationLink = uifactory.addFormLink("translate." + counter++, "translation.edit", null, formLayout, Link.LINK);
TranslationBundle bundle = new TranslationBundle(textI18nKey, labelI18nKey, viewEl, translationLink);
TranslationBundle bundle = new TranslationBundle(textI18nKey, labelI18nKey, viewEl, translationLink, textArea);
translationLink.setUserObject(bundle);
return bundle;
}
......@@ -310,7 +309,7 @@ public class UserAdminLifecycleConfigurationController extends FormBasicControll
if(guardModalController(translatorCtrl)) return;
translatorCtrl = new SingleKeyTranslatorController(ureq, getWindowControl(), bundle.getI18nKey(),
UserAdminLifecycleConfigurationController.class);
UserAdminLifecycleConfigurationController.class, bundle.isTextArea());
translatorCtrl.setUserObject(bundle);
listenTo(translatorCtrl);
......@@ -326,12 +325,14 @@ public class UserAdminLifecycleConfigurationController extends FormBasicControll
private static class TranslationBundle {
private final boolean textArea;
private final String i18nKey;
private final String labelI18nKey;
private final StaticTextElement viewEl;
private final FormLink translationLink;
public TranslationBundle(String i18nKey, String labelI18nKey, StaticTextElement viewEl, FormLink translationLink) {
public TranslationBundle(String i18nKey, String labelI18nKey, StaticTextElement viewEl, FormLink translationLink, boolean textArea) {
this.textArea = textArea;
this.i18nKey = i18nKey;
this.viewEl = viewEl;
this.labelI18nKey = labelI18nKey;
......@@ -341,6 +342,10 @@ public class UserAdminLifecycleConfigurationController extends FormBasicControll
public StaticTextElement getViewEl() {
return viewEl;
}
public boolean isTextArea() {
return textArea;
}
public String getI18nKey() {
return i18nKey;
......
......@@ -722,6 +722,29 @@ public class BaseSecurityManagerTest extends OlatTestCase {
Assert.assertNotNull(lastLogin);
}
@Test
public void updateLastLoginAndInactivationDate() {
Identity id = JunitTestHelper.createAndPersistIdentityAsRndUser("last-login-0");
((IdentityImpl)id).setInactivationEmailDate(new Date());
id = dbInstance.getCurrentEntityManager().merge(id);
dbInstance.commitAndCloseSession();
id = securityManager.loadIdentityByKey(id.getKey());
Date mergedInactivationDate = ((IdentityImpl)id).getInactivationEmailDate();
Assert.assertNotNull(mergedInactivationDate);
dbInstance.commitAndCloseSession();
securityManager.setIdentityLastLogin(id);
dbInstance.commitAndCloseSession();
id = securityManager.loadIdentityByKey(id.getKey());
Date lastLogin = id.getLastLogin();
Assert.assertNotNull(lastLogin);
Date inactivationDate = ((IdentityImpl)id).getInactivationEmailDate();
Assert.assertNull(inactivationDate);
}
@Test
public void countUniqueUserLoginsSince() {
Calendar cal = Calendar.getInstance();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment