Commit dce870a8 authored by Toni Beier's avatar Toni Beier

Olat webview provides downloads.

parent 8d63ee8b
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" /> <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- <!--
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
......
package de.bps.asist.module.olat;
import android.content.Context;
import java.net.URL;
import java.util.HashSet;
import java.util.Set;
public class HostSetBuilder {
private HashSet<String> hosts;
private void addHost(String addingHost) {
if (addingHost != null) {
if (!addingHost.isEmpty()) {
if (this.hosts == null) {
this.hosts = new HashSet<>();
}
this.hosts.add(addingHost);
}
}
}
public HostSetBuilder extractHost(URL url) {
throwExceptionIfNull(url, "url");
this.addHost(url.getHost());
return this;
}
public HostSetBuilder host(String host) {
throwExceptionIfNull(host, "host");
this.addHost(host);
return this;
}
public HostSetBuilder host(int resId, Context context) {
this.host(context.getString(resId));
return this;
}
public HostSetBuilder hosts(int resId, Context context) {
String[] addingUrls = context.getResources().getStringArray(resId);
for (String url : addingUrls) {
this.host(url);
}
return this;
}
public Set<String> build() {
if (this.hosts == null) {
return new HashSet<>();
} else {
return new HashSet<>(this.hosts);
}
}
private static void throwExceptionIfNull(Object object, String paramterName) {
if (object == null) {
throw new NullPointerException(paramterName + "should not be null.");
}
}
}
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
package de.bps.asist.module.olat; package de.bps.asist.module.olat;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.app.DownloadManager;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
...@@ -21,17 +22,26 @@ import android.view.View; ...@@ -21,17 +22,26 @@ import android.view.View;
import android.view.ViewGroup; import android.view.ViewGroup;
import android.webkit.CookieManager; import android.webkit.CookieManager;
import android.webkit.CookieSyncManager; import android.webkit.CookieSyncManager;
import android.webkit.DownloadListener;
import android.webkit.URLUtil;
import android.webkit.ValueCallback; import android.webkit.ValueCallback;
import android.webkit.WebChromeClient; import android.webkit.WebChromeClient;
import android.webkit.WebView; import android.webkit.WebView;
import android.webkit.WebViewClient; import android.webkit.WebViewClient;
import android.widget.Toast;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Array;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Objects;
import java.util.Set;
import de.bps.asist.R; import de.bps.asist.R;
import de.bps.asist.core.manager.push.PushNotificationManager; import de.bps.asist.core.manager.push.PushNotificationManager;
...@@ -115,6 +125,14 @@ public class OlatFragment extends AbstractASiSTFragment { ...@@ -115,6 +125,14 @@ public class OlatFragment extends AbstractASiSTFragment {
return true; return true;
} }
}); });
Set<String> allowedHosts = new HostSetBuilder()
.host(R.string.olat_url, getContext())
.hosts(R.array.olat_allowed_download_hosts, getContext())
.build();
webView.setDownloadListener(new OpalDownloadListener(this.getContext(), allowedHosts));
return view; return view;
} }
...@@ -221,4 +239,134 @@ public class OlatFragment extends AbstractASiSTFragment { ...@@ -221,4 +239,134 @@ public class OlatFragment extends AbstractASiSTFragment {
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
return File.createTempFile(imageFileName,".jpg",storageDir); return File.createTempFile(imageFileName,".jpg",storageDir);
} }
/**
* Download listener for opal web view. This download listner will block every download which is not in the given hosts.
*/
private class OpalDownloadListener implements DownloadListener {
private final static String USER_AGENT_HEADER = "User-Agent";
private final static String COOKIE_HEADER = "Cookie";
private Context context;
private Set<String> allowedHosts;
/**
* Contructs a new OpalDownloadListener instance.
*
* @param context - context wich will be used for system calls
*/
OpalDownloadListener(Context context) {
this.context = context;
this.allowedHosts = null;
}
/**
* Contructs a new OpalDownloadListener instance.
*
* @param context - context which will be used for system calls
* @param allowedHosts - allowed hosts for downloading
*/
OpalDownloadListener(Context context, Collection<String> allowedHosts) {
this.context = context;
this.allowedHosts = new HashSet<>(allowedHosts);
}
/**
* Contructs a new OpalDownloadListener instance.
*
* @param context - context which will be used for system calls
* @param allowedHost - allowed host for downloading
*/
OpalDownloadListener(Context context, String allowedHost) {
this(context, Arrays.asList(allowedHost));
}
/**
* Contructs a new OpalDownloadListener instance.
*
* @param context - context which will be used for system calls
* @param allowedHost - allowed host for downloading
*/
OpalDownloadListener(Context context, Uri allowedHost) {
this(context, allowedHost.getHost());
}
@Override
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
Uri downloadUri = Uri.parse(url);
if (this.isHostAllowed(downloadUri)) {
String downloadFileName = guessFileName(url, contentDisposition, mimetype);
DownloadManager.Request downloadRequest = new DownloadManager.Request(Uri.parse(url));
downloadRequest.setMimeType(mimetype);
downloadRequest.setTitle(downloadFileName);
downloadRequest.setDescription(this.context.getString(R.string.module_olat_download_description) + " " + downloadFileName + ".");
downloadRequest.addRequestHeader(COOKIE_HEADER, CookieManager.getInstance().getCookie(url));
downloadRequest.addRequestHeader(USER_AGENT_HEADER, userAgent);
downloadRequest.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, downloadFileName);
downloadRequest.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE | DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
downloadRequest.allowScanningByMediaScanner();
DownloadManager downloadManager = (DownloadManager) this.context.getSystemService(Context.DOWNLOAD_SERVICE);
downloadManager.enqueue(downloadRequest);
} else {
Toast.makeText(this.context, getString( R.string.module_olat_download_blocking, downloadUri.getHost()), Toast.LENGTH_LONG).show();
}
}
/**
* Check wether the included uri host is permitted in downloading files.
*
* @param checkingUri - Uri wich will be checked
* @param allowedHosts - List of allowed hosts
* @return true if host is allowed or false if not
*/
private boolean isHostAllowed(Uri checkingUri, Set<String> allowedHosts) {
boolean isHostAllowed = true;
if (allowedHosts != null) {
isHostAllowed = allowedHosts.contains(checkingUri.getHost());
}
return isHostAllowed;
}
/**
* Check wether the included uri host is permitted in downloading files.
*
* @param checkingUri - Uri wich will be checked
* @return true if host is allowed or false if not
*/
private boolean isHostAllowed(Uri checkingUri) {
return this.isHostAllowed(checkingUri, this.allowedHosts);
}
/**
* Guesses a filename that a download would have, using url and contentDisposition. Is no file extension spicified the mime type is used as fallback.
*
* @param url
* @param contentDisposition
* @param mimetype
* @return
*/
private String guessFileName(String url, String contentDisposition, String mimetype) {
String guessingFileName = URLUtil.guessFileName(url, contentDisposition, mimetype);
String contentDispositionContentParts[] = contentDisposition.split(";");
for (String contentDispositionContentPart : contentDispositionContentParts) {
contentDispositionContentPart = contentDispositionContentPart.trim();
if (contentDispositionContentPart.startsWith("filename=")) {
guessingFileName = contentDispositionContentPart.substring(contentDispositionContentPart.indexOf('=') + 1);
if (guessingFileName.startsWith("\"") && guessingFileName.endsWith("\"")) {
guessingFileName = guessingFileName.substring(1, guessingFileName.length() - 1);
}
break;
}
}
return guessingFileName;
}
}
} }
...@@ -201,6 +201,8 @@ ...@@ -201,6 +201,8 @@
<!-- OLAT Module --> <!-- OLAT Module -->
<string name="module_olat_name">OPAL</string> <string name="module_olat_name">OPAL</string>
<string name="module_olat_download_description">Downloading</string>
<string name="module_olat_download_blocking">Downloading from %1$s is not allowed.</string>
<!-- Impressum Module --> <!-- Impressum Module -->
<string name="module_impressum_name">Legal Notice</string> <string name="module_impressum_name">Legal Notice</string>
......
...@@ -47,4 +47,8 @@ ...@@ -47,4 +47,8 @@
<!-- Module Room --> <!-- Module Room -->
<string name="module_room_url">https://your-openasistserver.net/raum.html?content</string> <string name="module_room_url">https://your-openasistserver.net/raum.html?content</string>
<!-- special settings for olat module -->
<string-array name="olat_allowed_download_hosts">
</string-array>
</resources> </resources>
\ No newline at end of file
...@@ -203,6 +203,8 @@ ...@@ -203,6 +203,8 @@
<!-- OLAT Module --> <!-- OLAT Module -->
<string name="module_olat_name">OPAL</string> <string name="module_olat_name">OPAL</string>
<string name="module_olat_download_description">Download gestartet.</string>
<string name="module_olat_download_blocking">Downloaden von %1$s ist nicht erlaubt.</string>
<!-- Impressum Module --> <!-- Impressum Module -->
<string name="module_impressum_name">Impressum</string> <string name="module_impressum_name">Impressum</string>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment