fix white text on configuration screen
[pub/Android/ownCloud.git] / src / eu / alefzero / owncloud / authenticator / AuthUtils.java
1 /* ownCloud Android client application
2 * Copyright (C) 2011 Bartek Przybylski
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 */
18
19 package eu.alefzero.owncloud.authenticator;
20
21 import java.io.IOException;
22 import java.net.MalformedURLException;
23 import java.net.URL;
24 import java.net.UnknownHostException;
25 import org.apache.http.conn.ClientConnectionManager;
26 import org.apache.http.conn.scheme.Scheme;
27 import org.apache.http.conn.scheme.SchemeRegistry;
28
29 import org.apache.http.impl.client.DefaultHttpClient;
30
31 import org.apache.commons.httpclient.auth.BasicScheme;
32 import org.apache.http.HttpHost;
33 import org.apache.http.HttpResponse;
34 import org.apache.http.HttpVersion;
35 import org.apache.http.auth.AuthScope;
36 import org.apache.http.auth.UsernamePasswordCredentials;
37 import org.apache.http.client.ClientProtocolException;
38 import org.apache.http.client.methods.HttpHead;
39 import org.apache.http.conn.params.ConnManagerPNames;
40 import org.apache.http.conn.params.ConnPerRouteBean;
41 import org.apache.http.conn.scheme.PlainSocketFactory;
42 import org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;
43 import org.apache.http.params.BasicHttpParams;
44 import org.apache.http.params.HttpParams;
45 import org.apache.http.params.HttpProtocolParams;
46 import org.apache.http.protocol.BasicHttpContext;
47
48 import eu.alefzero.owncloud.ui.activity.AuthenticatorActivity;
49
50
51 import android.accounts.Account;
52 import android.accounts.AccountManager;
53 import android.content.Context;
54 import android.content.SharedPreferences;
55 import android.os.Handler;
56 import android.preference.PreferenceManager;
57 import android.util.Log;
58
59 public class AuthUtils {
60 public static final String WEBDAV_PATH_1_2 = "/webdav/owncloud.php";
61 public static final String WEBDAV_PATH_2_0 = "/files/webdav.php";
62 public static final String CARDDAV_PATH_2_0 = "/apps/contacts/carddav.php";
63
64 private static String mResultMsg = "";
65
66 public static boolean authenticate(URL url, String username, String password,
67 Handler handler, Context context) {
68 String strippedPath = url.toString().endsWith("/") ?
69 url.toString().substring(0, url.toString().length()-1) :
70 url.toString();
71 String webdatPath = strippedPath + WEBDAV_PATH_2_0;
72 URL complete_url = null;
73 try {
74 complete_url = new URL(webdatPath);
75 } catch (MalformedURLException e) {
76 // should never happend
77 sendResult(false, handler, context, "URL error");
78 return false;
79 }
80
81 // version 2.0 success
82 if (tryGetWebdav(complete_url, username, password, handler, context)) {
83 sendResult(true, handler, context, complete_url.toString());
84 return true;
85 }
86
87 if (mResultMsg.equals("401")) {
88 sendResult(false, handler, context, "Invalid login or/and password");
89 return false;
90 }
91
92 if (!mResultMsg.equals("404")) {
93 sendResult(false, handler, context, "Server error: " + mResultMsg);
94 return false;
95 }
96
97 webdatPath = strippedPath + WEBDAV_PATH_1_2;
98 try {
99 complete_url = new URL(webdatPath);
100 } catch (MalformedURLException e) {
101 // should never happend
102 sendResult(false, handler, context, "URL error");
103 return false;
104 }
105
106 // version 1.2 success
107 if (tryGetWebdav(complete_url, username, password, handler, context)) {
108 sendResult(true, handler, context, complete_url.toString());
109 return true;
110 }
111
112 if (mResultMsg.equals("401")) {
113 sendResult(false, handler, context, "Invalid login or/and password");
114 return false;
115 }
116
117 if (mResultMsg.equals("404")) {
118 sendResult(false, handler, context, "Wrong path given");
119 return false;
120 }
121
122 sendResult(false, handler, context, "Server error: " + mResultMsg);
123 return false;
124 }
125
126 public static boolean tryGetWebdav(URL url, String username, String pwd,
127 Handler handler, Context context) {
128 SchemeRegistry schemeRegistry = new SchemeRegistry();
129 // http scheme
130 schemeRegistry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80));
131 // https scheme
132 schemeRegistry.register(new Scheme("https", new EasySSLSocketFactory(), 443));
133
134 HttpParams params = new BasicHttpParams();
135 params.setParameter(ConnManagerPNames.MAX_TOTAL_CONNECTIONS, 30);
136 params.setParameter(ConnManagerPNames.MAX_CONNECTIONS_PER_ROUTE, new ConnPerRouteBean(30));
137 params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
138 HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
139
140 ClientConnectionManager cm = new ThreadSafeClientConnManager(params, schemeRegistry);
141
142 DefaultHttpClient c = new DefaultHttpClient(cm, params);
143
144 c.getCredentialsProvider().setCredentials(
145 new AuthScope(url.getHost(), (url.getPort() == -1)?80:url.getPort()),
146 new UsernamePasswordCredentials(username, pwd));
147
148 BasicHttpContext localcontext = new BasicHttpContext();
149 BasicScheme basicAuth = new BasicScheme();
150
151 localcontext.setAttribute("preemptive-auth", basicAuth);
152 HttpHost targetHost = new HttpHost(url.getHost(), (url.getPort() == -1)
153 ? 80
154 : url.getPort(), (url.getProtocol().equals("https")) ? "https" : "http");
155 HttpHead httpget = new HttpHead(url.toString());
156 httpget.setHeader("Host", url.getHost());
157 HttpResponse response = null;
158 try {
159 response = c.execute(targetHost, httpget, localcontext);
160 } catch (ClientProtocolException e1) {
161 sendResult(false, handler, context, "Protocol error: "
162 + e1.getLocalizedMessage());
163 return false;
164 } catch (UnknownHostException e1) {
165 mResultMsg = "Unknowh host: " + e1.getLocalizedMessage();
166 return false;
167 } catch (IOException e1) {
168 mResultMsg = "Error: " + e1.getLocalizedMessage();
169 return false;
170 }
171 String status = response.getStatusLine().toString();
172
173 status = status.split(" ")[1];
174 Log.i("AuthUtils", "Status returned: " + status);
175 if (status.equals("200")) {
176 return true;
177 } else if (status.equals("404")) {
178 mResultMsg = "404";
179 return false;
180 } else if (status.equals("401")) {
181 mResultMsg = "401";
182 return false;
183 }
184 mResultMsg = status;
185 return false;
186 }
187
188 public static Thread performOnBackgroundThread(final Runnable r) {
189 final Thread t = new Thread() {
190 @Override
191 public void run() {
192 try {
193 r.run();
194 } finally {}
195 }
196 };
197 t.start();
198 return t;
199 }
200
201 public static void sendResult(final Boolean result,
202 final Handler handler,
203 final Context context,
204 final String message) {
205 if (handler == null || context == null) {
206 return;
207 }
208 handler.post(new Runnable() {
209 public void run() {
210 ((AuthenticatorActivity) context).onAuthenticationResult(result, message);
211 }
212 });
213 }
214
215 public static Thread attemptAuth(final URL url, final String username,
216 final String password, final Handler handler,
217 final Context context) {
218 final Runnable r = new Runnable() {
219
220 public void run() {
221 authenticate(url, username, password, handler, context);
222 }
223 };
224 return performOnBackgroundThread(r);
225 }
226
227 /**
228 * Can be used to get the currently selected ownCloud account in the preferences
229 *
230 * @param context The current appContext
231 * @return The current account or null, if there is none yet.
232 */
233 public static Account getCurrentOwnCloudAccount(Context context){
234 Account[] ocAccounts = AccountManager.get(context).getAccountsByType(AccountAuthenticator.ACCOUNT_TYPE);
235 Account defaultAccount = null;
236
237 SharedPreferences appPreferences = PreferenceManager.getDefaultSharedPreferences(context);
238 String accountName = appPreferences.getString("select_oc_account", null);
239
240 if(accountName != null){
241 for(Account account : ocAccounts){
242 if(account.name.equals(accountName)){
243 defaultAccount = account;
244 break;
245 }
246 }
247 } else if (ocAccounts.length != 0) {
248 // we at least need to take first account as fallback
249 defaultAccount = ocAccounts[0];
250 }
251
252 return defaultAccount;
253 }
254 }