/**
* Shadow - Anonymous web browser for Android devices
* Copyright (C) 2009 Connell Gauld
*
* Thanks to University of Cambridge,
* Alastair Beresford and Andrew Rice
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package uk.ac.cam.cl.dtg.android.tor.Shadow;
import java.net.MalformedURLException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.apache.http.cookie.Cookie;
import android.content.Context;
import android.widget.Toast;
public class CookieManager {
public static final int ACCEPT_ALL = 1;
public static final int WHITELIST = 2;
public static final int BLOCK_ALL = 3;
private class BlockedCookie {
public String domain;
public Cookie cookie;
public String header;
public String url;
}
// Singleton
private static CookieManager mCookieManager = null;
// Member variables
private ArrayList<String> mDomainWhitelist = new ArrayList<String>();
private ArrayList<BlockedCookie> mBlockedCookies = new ArrayList<BlockedCookie>();
private ArrayList<String> mBlockedCookiesDomains = new ArrayList<String>();
private int mBehaviour = WHITELIST;
private CookieManagerDataStore mDataStore = null;
private CookieManager() {
// Do nothing
}
private void openDataStore(Context c) {
mDataStore = new CookieManagerDataStore(c);
mDomainWhitelist = mDataStore.getWhitelist();
}
/**
* Get an instance of the cookie manager
* @param c application context
* @return the cookie manager
*/
public static CookieManager getInstance(Context c) {
CookieManager m = CookieManager.getInstance();
if (m.mDataStore == null) {
m.openDataStore(c);
}
return mCookieManager;
}
/**
* Get an instance of the CookieManager.
* *Must* have used getInstance(Context c) once with a valid
* context before using this version.
* @return the cookie manager
*/
public static CookieManager getInstance() {
if (mCookieManager == null) mCookieManager = new CookieManager();
return mCookieManager;
}
/**
* Set the behaviour of the cookie manager.
* @param behaviour one of ACCEPT_ALL, WHITELIST, BLOCK_ALL
*/
public void setBehaviour(int behaviour) {
mBehaviour = behaviour;
}
/**
* Set the behaviour of the cookie manager.
* @param behaviour one of "accept", "whitelist", or "block"
*/
public void setBehaviour(String behaviour) {
if ("accept".equals(behaviour)) mBehaviour = ACCEPT_ALL;
else if ("whitelist".equals(behaviour)) mBehaviour = WHITELIST;
else mBehaviour = BLOCK_ALL;
}
/**
* Add a site to the cookie whitelist
* @param s the site to add
* @param c the application context
* @throws URISyntaxException
*/
public synchronized void addToWhitelist(String s, Context c) throws URISyntaxException {
String host = s;
if (host.length() == 0) throw new URISyntaxException(s, "No host");
if (mDomainWhitelist.contains(host)) return;
mDomainWhitelist.add(host);
if (mDataStore != null) mDataStore.addToWhitelist(host);
if (c != null) {
Toast.makeText(c, "Site added to cookie whitelist", Toast.LENGTH_SHORT).show();
}
}
/**
* Return an array of the sites in the whitelist
* @return ArrayList<String> of sites
*/
public synchronized ArrayList<String> getWhitelist() {
return new ArrayList<String>(mDomainWhitelist);
}
/**
* Remove a site from the whitelist
* @param s the site to remove
*/
public synchronized void removeFromWhitelist(String s) {
mDomainWhitelist.remove(s);
if (mDataStore != null) mDataStore.removeFromWhitelist(s);
}
/**
* Determine whether to allow a cookie to be set for a domain
* @param domain the domain to check
* @return true if cookie should be set otherwise false
*/
public synchronized boolean setCookieForDomain(String domain) {
if (mBehaviour == BLOCK_ALL) return false;
if (mBehaviour == ACCEPT_ALL) return true;
return mDomainWhitelist.contains(domain);
}
/**
* Register that a cookie has been blocked
* @param c the cookie that was blocked
* @param header the set-cookie header of the cookie
* @param url the address that added the cookie
*/
public synchronized void cookieBlocked(Cookie c, String header, String url) {
String domain = c.getDomain();
//Log.i("CookieManager", "Cookie blocked from: " + domain);
BlockedCookie b = new BlockedCookie();
b.cookie = c;
b.header = header;
b.domain = domain;
b.url = url;
mBlockedCookies.add(b);
if (!mBlockedCookiesDomains.contains(domain))
mBlockedCookiesDomains.add(domain);
}
/**
* Determine if there are any currently blocked cookies
* @return true if there are currently blocked cookies
*/
public synchronized boolean hasBlockedCookies() {
if (mBlockedCookies.size()>0) return true;
else return false;
}
/**
* Clear all currently blocked cookies
*/
public synchronized void clearBlockedCookies() {
mBlockedCookies.clear();
mBlockedCookiesDomains.clear();
}
/**
* Get a list of the domains of the currently blocked cookies
* @return a List<String> of the domains
*/
public synchronized List<String> getBlockedCookiesDomains() {
return new ArrayList<String>(mBlockedCookiesDomains);
}
/**
* Accept all currently blocked cookies for a domain
* @param domain the domain to accept blocked cookies for
*/
public synchronized void acceptBlockedCookies(String domain) {
//Log.d("CookieManager", "Accepting blocked cookies for: " + domain);
android.webkit.CookieManager c = android.webkit.CookieManager.getInstance();
int size = mBlockedCookies.size();
for (int i=0; i<size; i++) {
BlockedCookie thisCookie = mBlockedCookies.get(i);
if (thisCookie.domain.equals(domain))
c.setCookie(thisCookie.url, thisCookie.header);
}
}
/**
* Determine whether to send cookies to a URL
* @param url the URL to check
* @return true if cookies should be sent
*/
public synchronized boolean sendCookiesFor(String url) {
if (mBehaviour == BLOCK_ALL) return false;
if (mBehaviour == ACCEPT_ALL) return true;
URL u = null;
try {
u = new URL(url);
} catch (MalformedURLException e) {
return false;
}
String host = u.getHost();
int size = mDomainWhitelist.size();
for (int i=0; i<size; i++) {
String whitelist = mDomainWhitelist.get(i);
if (host.endsWith(whitelist)) return true;
}
return false;
}
/**
* Clear all cookies
*/
public synchronized void clearAllCookies() {
android.webkit.CookieManager c = android.webkit.CookieManager.getInstance();
c.removeAllCookie();
}
}