From 2587b7dfc1b244d7678e97e81c5fcd33556c28d7 Mon Sep 17 00:00:00 2001
From: srosse <stephane.rosse@frentix.com>
Date: Tue, 3 Dec 2019 15:09:15 +0100
Subject: [PATCH] OO-4389: adapt the podcast / feed url to last versions of iOS
 / macOS

---
 .../admin/sysinfo/SchedulerController.java    | 19 ++++
 .../olat/modules/webFeed/FeedViewHelper.java  | 19 ++--
 .../dispatching/FeedMediaDispatcher.java      |  8 +-
 .../modules/webFeed/dispatching/Path.java     |  6 +-
 .../webFeed/ui/podcast/_content/info.html     |  4 +-
 .../ldap/manager/LDAPLoginManagerTest.java    | 19 ++++
 .../modules/webFeed/dispatching/PathTest.java | 94 +++++++++++++++++++
 .../java/org/olat/test/AllTestsJunit4.java    |  1 +
 8 files changed, 147 insertions(+), 23 deletions(-)
 create mode 100644 src/test/java/org/olat/modules/webFeed/dispatching/PathTest.java

diff --git a/src/main/java/org/olat/admin/sysinfo/SchedulerController.java b/src/main/java/org/olat/admin/sysinfo/SchedulerController.java
index 79a9705265d..5c6a5d61e11 100644
--- a/src/main/java/org/olat/admin/sysinfo/SchedulerController.java
+++ b/src/main/java/org/olat/admin/sysinfo/SchedulerController.java
@@ -1,3 +1,22 @@
+/**
+ * <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.admin.sysinfo;
 
 import java.util.ArrayList;
diff --git a/src/main/java/org/olat/modules/webFeed/FeedViewHelper.java b/src/main/java/org/olat/modules/webFeed/FeedViewHelper.java
index 136686e6320..7c0c97d07f6 100644
--- a/src/main/java/org/olat/modules/webFeed/FeedViewHelper.java
+++ b/src/main/java/org/olat/modules/webFeed/FeedViewHelper.java
@@ -132,17 +132,17 @@ public class FeedViewHelper {
 	/**
 	 * @return The iTunes subscription url
 	 */
-	public String getITunesUrl(String protocol) {
+	public String getPodcastAppUrl() {
 		String iTunesfeed = null;
 		if (StringHelper.containsNonWhitespace(feedUrl)) {
 			try {
 				URL url = new URL(feedUrl);
-				if (!StringHelper.containsNonWhitespace(protocol)) {
-					protocol = "itpc";
+				iTunesfeed = "podcast://" + url.getHost() + url.getPath();
+				if (iTunesfeed.endsWith("/" + FeedManager.RSS_FEED_NAME)) {
+					iTunesfeed = iTunesfeed.replace("/" + FeedManager.RSS_FEED_NAME, "/feed.xml");
 				}
-				iTunesfeed = protocol + "://" + url.getHost() + url.getPath();
 			} catch (MalformedURLException e) {
-				log.warn("Malformed podcast URL: " + feedUrl, e);
+				log.warn("Malformed podcast URL: {}", feedUrl, e);
 			}
 		}
 		return iTunesfeed;
@@ -598,13 +598,6 @@ public class FeedViewHelper {
 	 * @return
 	 */
 	public boolean isAuthor(Item item) {
-		boolean isAuthor = false;
-		
-		if (item != null && item.getAuthorKey() != null && item.getAuthorKey().equals(identity.getKey().longValue())) {
-			isAuthor = true;
-		}
-		
-		return isAuthor;
+		return item != null && item.getAuthorKey() != null && item.getAuthorKey().equals(identity.getKey());
 	}
-
 }
\ No newline at end of file
diff --git a/src/main/java/org/olat/modules/webFeed/dispatching/FeedMediaDispatcher.java b/src/main/java/org/olat/modules/webFeed/dispatching/FeedMediaDispatcher.java
index 477b74524d9..95c8aa48e14 100644
--- a/src/main/java/org/olat/modules/webFeed/dispatching/FeedMediaDispatcher.java
+++ b/src/main/java/org/olat/modules/webFeed/dispatching/FeedMediaDispatcher.java
@@ -25,6 +25,7 @@ import java.util.List;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
+import org.apache.logging.log4j.Logger;
 import org.olat.basesecurity.Authentication;
 import org.olat.basesecurity.BaseSecurity;
 import org.olat.core.CoreSpringFactory;
@@ -41,7 +42,6 @@ import org.olat.core.id.Identity;
 import org.olat.core.id.IdentityEnvironment;
 import org.olat.core.id.OLATResourceable;
 import org.olat.core.id.Roles;
-import org.apache.logging.log4j.Logger;
 import org.olat.core.logging.Tracing;
 import org.olat.core.util.StringHelper;
 import org.olat.core.util.WebappHelper;
@@ -207,14 +207,14 @@ public class FeedMediaDispatcher implements Dispatcher, GenericEventListener {
 			if(isAccessible(ureq, path, feed)) {
 				deliverFile(request, response, feed, path);
 			} else {
-				log.info("Access was denied. Path::" + path);
+				log.info("Access was denied. Path::{}", path);
 				DispatcherModule.sendForbidden(request.getRequestURI(), response);
 			}
 		} catch (InvalidPathException e) {
-			log.warn("The requested path is invalid. path::" + path, e);
+			log.warn("The requested path is invalid. path::{}", path, e);
 			DispatcherModule.sendBadRequest(request.getRequestURI(), response);
 		} catch (Exception e) {
-			log.warn("Nothing was delivered. Path::" + path, e);
+			log.warn("Nothing was delivered. Path::{}", path, e);
 			DispatcherModule.sendNotFound(request.getRequestURI(), response);
 		}
 	}
diff --git a/src/main/java/org/olat/modules/webFeed/dispatching/Path.java b/src/main/java/org/olat/modules/webFeed/dispatching/Path.java
index 5a439f26182..ca1210be4ae 100644
--- a/src/main/java/org/olat/modules/webFeed/dispatching/Path.java
+++ b/src/main/java/org/olat/modules/webFeed/dispatching/Path.java
@@ -24,8 +24,6 @@ import java.util.List;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
-import org.olat.modules.webFeed.manager.FeedManager;
-
 /**
  * The Path class.
  * <p>
@@ -72,13 +70,13 @@ public class Path {
 	private static final String SLASH = "/";
 	private static final String BASE_PATH_DELIMITER = "/_/";
 	public static final String COURSE_NODE_INDICATOR = "coursenode";
-	public static final String MEDIA_DIR = "media";	
+	public static final String MEDIA_DIR = "media";
 
 	private static final String AUTHENTICATION = NUMBER + SLASH + WORD + SLASH;
 	private static final String COURSE_PREFIX = COURSE_NODE_INDICATOR + SLASH;
 	private static final String COURSE_NODE = NUMBER + SLASH + WORD + SLASH;
 	private static final String FEED_ID = NUMBER + BASE_PATH_DELIMITER;
-	private static final String FEED_PATH = FEED_ID + FeedManager.RSS_FEED_NAME;
+	private static final String FEED_PATH = FEED_ID + "(feed.rss|feed.xml)";
 	private static final String FEED_MEDIA_PATH = FEED_ID + MEDIA_DIR + SLASH + FILE_NAME;
 	private static final String ITEM_MEDIA_PATH = FEED_ID + WORD + SLASH + MEDIA_DIR + SLASH + FILE_NAME;
 
diff --git a/src/main/java/org/olat/modules/webFeed/ui/podcast/_content/info.html b/src/main/java/org/olat/modules/webFeed/ui/podcast/_content/info.html
index 71d0fa39c67..1f2784b42ee 100644
--- a/src/main/java/org/olat/modules/webFeed/ui/podcast/_content/info.html
+++ b/src/main/java/org/olat/modules/webFeed/ui/podcast/_content/info.html
@@ -27,11 +27,11 @@
 					<i class="o_icon o_icon-fw o_icon_rss"></i> 
 					$r.translate("podcast.subscribe.rss")
 				</a>
-				<a href="$!helper.getITunesUrl("itpc")" class="btn btn-default " target="_blank" title="$r.translateInAttribute("podcast.subscribe.to.this.feed")">
+				<a href="$!helper.getPodcastAppUrl()" class="btn btn-default " target="_blank" title="$r.translateInAttribute("podcast.subscribe.to.this.feed")">
 					<i class="o_icon o_icon-fw o_icon_apple"></i> 		
 					$r.translate("podcast.subscribe.itunes")
 				</a>
-				<a href="$!helper.getITunesUrl("feed")" class="btn btn-default " target="_blank" title="$r.translateInAttribute("podcast.subscribe.to.this.feed")">
+				<a href="$!helper.getPodcastAppUrl()" class="btn btn-default " target="_blank" title="$r.translateInAttribute("podcast.subscribe.to.this.feed")">
 					<i class="o_icon o_icon-fw o_icon_mobile"></i> 		
 					$r.translate("podcast.subscribe.feed")
 				</a>
diff --git a/src/test/java/org/olat/ldap/manager/LDAPLoginManagerTest.java b/src/test/java/org/olat/ldap/manager/LDAPLoginManagerTest.java
index 1f1a26eed0e..a681c79c81f 100644
--- a/src/test/java/org/olat/ldap/manager/LDAPLoginManagerTest.java
+++ b/src/test/java/org/olat/ldap/manager/LDAPLoginManagerTest.java
@@ -1,3 +1,22 @@
+/**
+ * <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.ldap.manager;
 
 import java.util.ArrayList;
diff --git a/src/test/java/org/olat/modules/webFeed/dispatching/PathTest.java b/src/test/java/org/olat/modules/webFeed/dispatching/PathTest.java
new file mode 100644
index 00000000000..a7afb0cc34a
--- /dev/null
+++ b/src/test/java/org/olat/modules/webFeed/dispatching/PathTest.java
@@ -0,0 +1,94 @@
+/**
+ * <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.modules.webFeed.dispatching;
+
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+
+/**
+ * 
+ * Initial date: 3 déc. 2019<br>
+ * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com
+ *
+ */
+
+@RunWith(Parameterized.class)
+public class PathTest {
+	
+	@Parameters
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] {
+        	{ "720898/Wm3T3q/91225001686048/_/feed.rss", 11, 91225001686048l, "Wm3T3q", 720898l, null, null, null },
+        	{ "720898/Wm3T3q/91225001686048/_/feed.xml", 11, 91225001686048l, "Wm3T3q", 720898l, null, null, null },
+        	{ "720898/Wm3T3q/91225001686050/_/sropenpg_1_90970840170422/media/demo-video.mp4", 13, 91225001686050l, "Wm3T3q", 720898l, null, null, "demo-video.mp4" },
+        	
+        	{ "coursenode/720898/Wm3T3q/91163349354954/90987128749136/91163349354956/_/feed.rss", 31, 91163349354956l, "Wm3T3q", 720898l, 91163349354954l, "90987128749136", null },
+        	{ "coursenode/720898/Wm3T3q/91163349354954/90987128749136/91163349354956/_/feed.xml", 31, 91163349354956l, "Wm3T3q", 720898l, 91163349354954l, "90987128749136", null },
+        	{ "coursenode/720898/Wm3T3q/91163349354954/90987128749136/91163349354956/_/sropenpg_1_90987128749491/media/shark.m4v", 33, 91163349354956l, "Wm3T3q", 720898l, 91163349354954l, "90987128749136", "shark.m4v" }
+        });
+    }
+	
+	
+	private String url;
+	private int type;
+	private String token;
+	private Long feedId;
+	private Long identityKey;
+	private Long courseId;
+	private String courseNodeId;
+	private String filename;
+	
+	public PathTest(String url, int type, Long feedId, String token, Long identityKey, Long courseId, String courseNodeId, String filename) {
+		this.url = url;
+		this.type = type;
+		this.feedId = feedId;
+		this.token = token;
+		this.courseId = courseId;
+		this.courseNodeId = courseNodeId;
+		this.identityKey = identityKey;
+		this.filename = filename;
+	}
+	
+	
+	@Test
+	public void testPath() throws InvalidPathException {
+		Path path = new Path(url);
+		path.compile();
+		
+		Assert.assertEquals(token, path.getToken());
+		Assert.assertEquals(feedId, path.getFeedId());
+		Assert.assertEquals(identityKey, path.getIdentityKey());
+
+		Assert.assertEquals(courseId, path.getCourseId());
+		Assert.assertEquals(courseNodeId, path.getNodeId());
+		
+		Assert.assertEquals(filename, path.getItemFileName());
+		
+		Assert.assertEquals(type, path.getType());
+	}
+
+}
diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java
index 0e3dede58ec..05f9b84335f 100644
--- a/src/test/java/org/olat/test/AllTestsJunit4.java
+++ b/src/test/java/org/olat/test/AllTestsJunit4.java
@@ -296,6 +296,7 @@ import org.junit.runners.Suite;
 	org.olat.modules.video.manager.VideoManagerTest.class,
 	org.olat.modules.video.spi.youtube.YoutubeProviderTest.class,
 	org.olat.modules.video.spi.youtube.YoutubeVideoIdTest.class,
+	org.olat.modules.webFeed.dispatching.PathTest.class,
 	org.olat.modules.webFeed.manager.FeedDAOTest.class,
 	org.olat.modules.webFeed.manager.ItemDAOTest.class,
 	org.olat.modules.webFeed.manager.FeedFileStorgeTest.class,
-- 
GitLab