diff --git a/assignment/impl/src/java/org/sakaiproject/assignment/impl/AssignmentServiceImpl.java b/assignment/impl/src/java/org/sakaiproject/assignment/impl/AssignmentServiceImpl.java index 5717907921b..d77ebdfab0b 100644 --- a/assignment/impl/src/java/org/sakaiproject/assignment/impl/AssignmentServiceImpl.java +++ b/assignment/impl/src/java/org/sakaiproject/assignment/impl/AssignmentServiceImpl.java @@ -3902,7 +3902,7 @@ public class AssignmentServiceImpl implements AssignmentService, EntityTransferr @Override public Optional> getTransferOptions() { - return Optional.of(Arrays.asList(new String[] { EntityTransferrer.PUBLISH_OPTION })); + return Optional.of(Arrays.asList(new String[] { EntityTransferrer.PUBLISH_OPTION, EntityTransferrer.LTI_COPY_SECRET_OPTION })); } @Override @@ -3989,7 +3989,7 @@ public class AssignmentServiceImpl implements AssignmentService, EntityTransferr // If there is a LTI launch associated with this copy it over if ( oAssignment.getContentId() != null ) { Long contentKey = oAssignment.getContentId().longValue(); - Object retval = SakaiBLTIUtil.copyLTIContent(contentKey, toContext, fromContext); + Object retval = SakaiBLTIUtil.copyLTIContent(contentKey, toContext, fromContext, transferOptions); if ( retval instanceof Long ) { nAssignment.setContentId(((Long) retval).intValue()); // If something went wrong, we can't be an LTI submission in the new site diff --git a/basiclti/basiclti-common/src/java/org/sakaiproject/basiclti/util/SakaiBLTIUtil.java b/basiclti/basiclti-common/src/java/org/sakaiproject/basiclti/util/SakaiBLTIUtil.java index 1befc9317b1..8d58fc8c98c 100644 --- a/basiclti/basiclti-common/src/java/org/sakaiproject/basiclti/util/SakaiBLTIUtil.java +++ b/basiclti/basiclti-common/src/java/org/sakaiproject/basiclti/util/SakaiBLTIUtil.java @@ -61,6 +61,7 @@ import org.sakaiproject.component.cover.ComponentManager; import org.sakaiproject.component.cover.ServerConfigurationService; import org.sakaiproject.component.api.ServerConfigurationService.ConfigData; import org.sakaiproject.component.api.ServerConfigurationService.ConfigItem; +import org.sakaiproject.entity.api.EntityTransferrer; import org.sakaiproject.entity.api.ResourceProperties; import org.sakaiproject.event.cover.UsageSessionService; import org.sakaiproject.exception.IdUnusedException; @@ -3145,11 +3146,11 @@ public class SakaiBLTIUtil { * @param siteId The site id that the item is being copied from * @param oldSiteId The site id that the item is being copied from */ - public static Object copyLTIContent(Long contentKey, String siteId, String oldSiteId) + public static Object copyLTIContent(Long contentKey, String siteId, String oldSiteId, List options) { LTIService ltiService = (LTIService) ComponentManager.get("org.sakaiproject.lti.api.LTIService"); Map ltiContent = ltiService.getContentDao(contentKey, oldSiteId, true); - return copyLTIContent(ltiContent, siteId, oldSiteId); + return copyLTIContent(ltiContent, siteId, oldSiteId, options); } /** @@ -3168,7 +3169,7 @@ public class SakaiBLTIUtil { * @param siteId The site id that the item is being copied from * @param oldSiteId The site id that the item is being copied from */ - public static Object copyLTIContent(Map ltiContent, String siteId, String oldSiteId) + public static Object copyLTIContent(Map ltiContent, String siteId, String oldSiteId, List options) { LTIService ltiService = (LTIService) ComponentManager.get("org.sakaiproject.lti.api.LTIService"); @@ -3261,7 +3262,9 @@ public class SakaiBLTIUtil { contentProps.remove(LTIService.LTI_UPDATED_AT); // Most secrets are in the tool, it is rare to override in the content - contentProps.remove(LTIService.LTI_SECRET); + if (options == null || !options.contains(EntityTransferrer.LTI_COPY_SECRET_OPTION)) { + contentProps.remove(LTIService.LTI_SECRET); + } contentProps.remove("launch_url"); // Derived on retrieval Object result = ltiService.insertContent(contentProps, siteId); diff --git a/kernel/api/src/main/java/org/sakaiproject/entity/api/EntityTransferrer.java b/kernel/api/src/main/java/org/sakaiproject/entity/api/EntityTransferrer.java index 0b18c8fe5fb..090f7b73a25 100644 --- a/kernel/api/src/main/java/org/sakaiproject/entity/api/EntityTransferrer.java +++ b/kernel/api/src/main/java/org/sakaiproject/entity/api/EntityTransferrer.java @@ -33,6 +33,7 @@ import java.util.Optional; public interface EntityTransferrer { public static final String PUBLISH_OPTION = "publish"; + public static final String LTI_COPY_SECRET_OPTION = "lti.copy.secret"; /** * transfer a copy of Entities from the source context into the destination context diff --git a/lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/service/LessonBuilderEntityProducer.java b/lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/service/LessonBuilderEntityProducer.java index 6708763cb0e..4f746f61b54 100644 --- a/lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/service/LessonBuilderEntityProducer.java +++ b/lessonbuilder/tool/src/java/org/sakaiproject/lessonbuildertool/service/LessonBuilderEntityProducer.java @@ -61,6 +61,7 @@ import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Optional; import java.util.Properties; import java.util.Set; import java.util.Stack; @@ -735,7 +736,7 @@ public class LessonBuilderEntityProducer extends AbstractEntityProvider } // the pages are already made. this adds the elements - private boolean makePage(Element element, String oldServer, String siteId, String fromSiteId, Map pageMap, Map itemMap, Map entityMap) { + private boolean makePage(Element element, String oldServer, String siteId, String fromSiteId, Map pageMap, Map itemMap, Map entityMap, List options) { String oldSiteId = element.getAttribute("siteid"); String oldPageIdString = element.getAttribute("pageid"); @@ -785,7 +786,7 @@ public class LessonBuilderEntityProducer extends AbstractEntityProvider String[] bltiId = sakaiId.split("/"); Long ltiContentId = Long.valueOf(bltiId[2]); Map ltiContent = ltiService.getContentDao(ltiContentId, oldSiteId, securityService.isSuperUser()); - String newSakaiId = copyLTIContent(ltiContent, siteId, oldSiteId); + String newSakaiId = copyLTIContent(ltiContent, siteId, oldSiteId, options); if ( newSakaiId != null ) sakaiId = newSakaiId; } catch (Exception e) { log.warn("Unable to import LTI tool to new site: {}", e); @@ -803,7 +804,7 @@ public class LessonBuilderEntityProducer extends AbstractEntityProvider foundLtiLink = true; try { Map ltiContent = ltiService.getContentDao(ltiContentId, oldSiteId, securityService.isSuperUser()); - String newSakaiId = copyLTIContent(ltiContent, siteId, oldSiteId); + String newSakaiId = copyLTIContent(ltiContent, siteId, oldSiteId, options); if ( newSakaiId != null ) sakaiId = newSakaiId; String[] bltiId = sakaiId.split("/"); ltiContentId = Long.valueOf(bltiId[2]); @@ -1107,14 +1108,14 @@ public class LessonBuilderEntityProducer extends AbstractEntityProvider public String merge(String siteId, Element root, String archivePath, String fromSiteId, Map attachmentNames, Map userIdTrans, Set userListAllowImport) { - return merge(siteId, root, archivePath, fromSiteId, attachmentNames, userIdTrans, userListAllowImport, null); + return merge(siteId, root, archivePath, fromSiteId, attachmentNames, userIdTrans, userListAllowImport, null, null); } /** * {@inheritDoc} */ public String merge(String siteId, Element root, String archivePath, String fromSiteId, Map attachmentNames, Map userIdTrans, - Set userListAllowImport, Map entityMap) + Set userListAllowImport, Map entityMap, List options) { StringBuilder results = new StringBuilder(); // map old to new page ids @@ -1189,7 +1190,7 @@ public class LessonBuilderEntityProducer extends AbstractEntityProvider Node pageNode = pageNodes.item(p); if (pageNode.getNodeType() == Node.ELEMENT_NODE) { Element pageElement = (Element) pageNode; - if (makePage(pageElement, oldServer, siteId, fromSiteId, pageMap, itemMap, entityMap)) + if (makePage(pageElement, oldServer, siteId, fromSiteId, pageMap, itemMap, entityMap, options)) needFix = true; } } @@ -1422,14 +1423,14 @@ public class LessonBuilderEntityProducer extends AbstractEntityProvider } public Map transferCopyEntities(String fromContext, String toContext, List ids, List options) { - return transferCopyEntitiesImpl(fromContext, toContext, ids, false); + return transferCopyEntitiesImpl(fromContext, toContext, ids, options, false); } public Map transferCopyEntities(String fromContext, String toContext, List ids, List options, boolean cleanup) { - return transferCopyEntitiesImpl(fromContext, toContext, ids, cleanup); + return transferCopyEntitiesImpl(fromContext, toContext, ids, options, cleanup); } - public Map transferCopyEntitiesImpl(String fromContext, String toContext, List ids, boolean cleanup) + public Map transferCopyEntitiesImpl(String fromContext, String toContext, List ids, List options, boolean cleanup) { Map entityMap = new HashMap(); @@ -1488,7 +1489,7 @@ public class LessonBuilderEntityProducer extends AbstractEntityProvider stack.pop(); - merge(toContext, (Element)doc.getFirstChild().getFirstChild(), "/tmp/archive", fromContext, null, null, null, entityMap); + merge(toContext, (Element)doc.getFirstChild().getFirstChild(), "/tmp/archive", fromContext, null, null, null, entityMap, options); ToolSession session = sessionManager.getCurrentToolSession(); @@ -1520,6 +1521,11 @@ public class LessonBuilderEntityProducer extends AbstractEntityProvider return entityMap; } + + @Override + public Optional> getTransferOptions() { + return Optional.of(Arrays.asList(new String[] { EntityTransferrer.LTI_COPY_SECRET_OPTION })); + } // update our references to Sakai objects that live in other tools. ID numbers in new site // will of course be different than in the old site @@ -2304,9 +2310,9 @@ public class LessonBuilderEntityProducer extends AbstractEntityProvider return replacedBody; } - private String copyLTIContent(Map ltiContent, String siteId, String oldSiteId) + private String copyLTIContent(Map ltiContent, String siteId, String oldSiteId, List options) { - Object result = SakaiBLTIUtil.copyLTIContent(ltiContent, siteId, oldSiteId); + Object result = SakaiBLTIUtil.copyLTIContent(ltiContent, siteId, oldSiteId, options); String sakaiId = null; if ( result == null ) { return null; diff --git a/site-manage/site-manage-tool/tool/src/bundle/sitesetupgeneric.properties b/site-manage/site-manage-tool/tool/src/bundle/sitesetupgeneric.properties index a11fc93c0dd..16cabdfb76e 100644 --- a/site-manage/site-manage-tool/tool/src/bundle/sitesetupgeneric.properties +++ b/site-manage/site-manage-tool/tool/src/bundle/sitesetupgeneric.properties @@ -223,6 +223,8 @@ import.options.title = Options import.options.help = This tool has import options. Click to see them. import.options.publish = Publish content import.options.publish.help = Selecting this will publish the tool content and will also import all the associated items. Those may be gradebook items, calendar events, etc. +import.options.lti.copy.secret = Copy External Tool secret keys +import.options.lti.copy.secret.help = Selecting this will copy external tool (LTI) secret keys if the tool contains LTI tools or links. #List Vm list.view = View