Skip to content
This repository was archived by the owner on Mar 19, 2024. It is now read-only.

Commit 87a0549

Browse files
authored
Merge pull request #368 from owncloud/fix/cookie_handling
[Fix] Cookie handling
2 parents 9ffe758 + f248448 commit 87a0549

File tree

16 files changed

+729
-281
lines changed

16 files changed

+729
-281
lines changed

owncloudComLibrary/build.gradle

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ dependencies {
99
api 'com.github.AppDevNext.Logcat:LogcatCore:2.2.2'
1010

1111
// Moshi
12-
implementation ("com.squareup.moshi:moshi-kotlin:$moshiVersion") {
12+
implementation("com.squareup.moshi:moshi-kotlin:$moshiVersion") {
1313
exclude module: "kotlin-reflect"
1414
}
1515
kapt "com.squareup.moshi:moshi-kotlin-codegen:$moshiVersion"
1616

1717
testImplementation 'junit:junit:4.13.2'
18+
testImplementation 'org.robolectric:robolectric:4.3.1'
1819
}
1920

2021
android {
@@ -37,4 +38,10 @@ android {
3738
sourceCompatibility JavaVersion.VERSION_1_8
3839
targetCompatibility JavaVersion.VERSION_1_8
3940
}
41+
42+
testOptions {
43+
unitTests {
44+
includeAndroidResources = true
45+
}
46+
}
4047
}

owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/OwnCloudClientFactory.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@
2727
import android.content.Context;
2828
import android.net.Uri;
2929

30+
import com.owncloud.android.lib.common.http.HttpClient;
31+
import com.owncloud.android.lib.resources.status.GetRemoteStatusOperation;
32+
3033
public class OwnCloudClientFactory {
3134

3235
/**
@@ -42,8 +45,14 @@ public static OwnCloudClient createOwnCloudClient(Uri uri, Context context, bool
4245

4346
client.setFollowRedirects(followRedirects);
4447

45-
client.setContext(context);
48+
HttpClient.setContext(context);
49+
retrieveCookiesFromMiddleware(client);
4650

4751
return client;
4852
}
53+
54+
private static void retrieveCookiesFromMiddleware(OwnCloudClient client) {
55+
final GetRemoteStatusOperation statusOperation = new GetRemoteStatusOperation();
56+
statusOperation.run(client);
57+
}
4958
}

owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/SingleSessionManager.java

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,6 @@
2424

2525
package com.owncloud.android.lib.common;
2626

27-
import android.accounts.Account;
28-
import android.accounts.AccountManager;
2927
import android.accounts.AuthenticatorException;
3028
import android.accounts.OperationCanceledException;
3129
import android.content.Context;
@@ -37,7 +35,6 @@
3735
import timber.log.Timber;
3836

3937
import java.io.IOException;
40-
import java.util.Iterator;
4138
import java.util.concurrent.ConcurrentHashMap;
4239
import java.util.concurrent.ConcurrentMap;
4340

@@ -111,6 +108,12 @@ public OwnCloudClient getClientFor(OwnCloudAccount account, Context context) thr
111108
account.getBaseUri(),
112109
context.getApplicationContext(),
113110
true); // TODO remove dependency on OwnCloudClientFactory
111+
112+
//the next two lines are a hack because okHttpclient is used as a singleton instead of being an
113+
//injected instance that can be deleted when required
114+
client.clearCookies();
115+
client.clearCredentials();
116+
114117
client.setAccount(account);
115118
HttpClient.setContext(context);
116119

@@ -130,7 +133,6 @@ public OwnCloudClient getClientFor(OwnCloudAccount account, Context context) thr
130133
Timber.v("reusing client for session %s", sessionName);
131134
}
132135

133-
keepCookiesUpdated(context, account, client);
134136
keepUriUpdated(account, client);
135137
}
136138
Timber.d("getClientFor finishing ");
@@ -161,32 +163,6 @@ public void removeClientFor(OwnCloudAccount account) {
161163
Timber.d("removeClientFor finishing ");
162164
}
163165

164-
public void saveAllClients(Context context, String accountType) {
165-
Timber.d("Saving sessions... ");
166-
167-
Iterator<String> accountNames = mClientsWithKnownUsername.keySet().iterator();
168-
String accountName;
169-
Account account;
170-
while (accountNames.hasNext()) {
171-
accountName = accountNames.next();
172-
account = new Account(accountName, accountType);
173-
AccountUtils.saveClient(mClientsWithKnownUsername.get(accountName), account, context);
174-
}
175-
176-
Timber.d("All sessions saved");
177-
}
178-
179-
private void keepCookiesUpdated(Context context, OwnCloudAccount account, OwnCloudClient reusedClient) {
180-
AccountManager am = AccountManager.get(context.getApplicationContext());
181-
if (am != null && account.getSavedAccount() != null) {
182-
String recentCookies = am.getUserData(account.getSavedAccount(), AccountUtils.Constants.KEY_COOKIES);
183-
String previousCookies = reusedClient.getCookiesString();
184-
if (recentCookies != null && !previousCookies.equals("") && !recentCookies.equals(previousCookies)) {
185-
AccountUtils.restoreCookies(account.getSavedAccount(), reusedClient, context);
186-
}
187-
}
188-
}
189-
190166
public void refreshCredentialsForAccount(String accountName, OwnCloudCredentials credentials) {
191167
OwnCloudClient ownCloudClient = mClientsWithKnownUsername.get(accountName);
192168
if (ownCloudClient == null) {

owncloudComLibrary/src/main/java/com/owncloud/android/lib/common/accounts/AccountUtils.java

Lines changed: 0 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,10 @@
3636
import com.owncloud.android.lib.common.OwnCloudClient;
3737
import com.owncloud.android.lib.common.authentication.OwnCloudCredentials;
3838
import com.owncloud.android.lib.common.authentication.OwnCloudCredentialsFactory;
39-
import com.owncloud.android.lib.resources.files.FileUtils;
4039
import com.owncloud.android.lib.resources.status.OwnCloudVersion;
41-
import okhttp3.Cookie;
4240
import timber.log.Timber;
4341

44-
import java.io.File;
4542
import java.io.IOException;
46-
import java.util.ArrayList;
47-
import java.util.List;
4843

4944
public class AccountUtils {
5045
/**
@@ -202,64 +197,6 @@ public static String buildAccountName(Uri serverBaseUrl, String username) {
202197
return username + "@" + url;
203198
}
204199

205-
public static void saveClient(OwnCloudClient client, Account savedAccount, Context context) {
206-
// Account Manager
207-
AccountManager ac = AccountManager.get(context.getApplicationContext());
208-
209-
if (client != null) {
210-
String cookiesString = client.getCookiesString();
211-
if (!"".equals(cookiesString)) {
212-
ac.setUserData(savedAccount, Constants.KEY_COOKIES, cookiesString);
213-
Timber.d("Saving Cookies: %s", cookiesString);
214-
}
215-
}
216-
}
217-
218-
/**
219-
* Restore the client cookies persisted in an account stored in the system AccountManager.
220-
*
221-
* @param account Stored account.
222-
* @param client Client to restore cookies in.
223-
* @param context Android context used to access the system AccountManager.
224-
*/
225-
public static void restoreCookies(Account account, OwnCloudClient client, Context context) {
226-
if (account == null) {
227-
Timber.d("Cannot restore cookie for null account");
228-
229-
} else {
230-
Timber.d("Restoring cookies for %s", account.name);
231-
232-
// Account Manager
233-
AccountManager am = AccountManager.get(context.getApplicationContext());
234-
235-
Uri serverUri = (client.getBaseUri() != null) ? client.getBaseUri() : client.getUserFilesWebDavUri();
236-
237-
String cookiesString = am.getUserData(account, Constants.KEY_COOKIES);
238-
if (cookiesString != null) {
239-
String[] rawCookies = cookiesString.split(";");
240-
List<Cookie> cookieList = new ArrayList<>(rawCookies.length);
241-
for (String rawCookie : rawCookies) {
242-
rawCookie = rawCookie.replace(" ", "");
243-
final int equalPos = rawCookie.indexOf('=');
244-
if (equalPos == -1) {
245-
continue;
246-
}
247-
cookieList.add(new Cookie.Builder()
248-
.name(rawCookie.substring(0, equalPos))
249-
.value(rawCookie.substring(equalPos + 1))
250-
.domain(serverUri.getHost())
251-
.path(
252-
serverUri.getPath().equals("")
253-
? File.separator
254-
: serverUri.getPath()
255-
)
256-
.build());
257-
}
258-
client.setCookiesForCurrentAccount(cookieList);
259-
}
260-
}
261-
}
262-
263200
public static class AccountNotFoundException extends AccountsException {
264201

265202
/**
@@ -299,11 +236,6 @@ public static class Constants {
299236

300237
public static final String OAUTH_SUPPORTED_TRUE = "TRUE";
301238

302-
/**
303-
* OC account cookies
304-
*/
305-
public static final String KEY_COOKIES = "oc_account_cookies";
306-
307239
/**
308240
* OC account version
309241
*/
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/* ownCloud Android Library is available under MIT license
2+
* Copyright (C) 2021 ownCloud GmbH.
3+
*
4+
* Permission is hereby granted, free of charge, to any person obtaining a copy
5+
* of this software and associated documentation files (the "Software"), to deal
6+
* in the Software without restriction, including without limitation the rights
7+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8+
* copies of the Software, and to permit persons to whom the Software is
9+
* furnished to do so, subject to the following conditions:
10+
*
11+
* The above copyright notice and this permission notice shall be included in
12+
* all copies or substantial portions of the Software.
13+
*
14+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15+
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16+
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17+
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
18+
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19+
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20+
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*
23+
*/
24+
package com.owncloud.android.lib.common.http
25+
26+
import okhttp3.Cookie
27+
import okhttp3.CookieJar
28+
import okhttp3.HttpUrl
29+
30+
class CookieJarImpl(
31+
private val sCookieStore: HashMap<String, List<Cookie>>
32+
) : CookieJar {
33+
34+
fun containsCookieWithName(cookies: List<Cookie>, name: String): Boolean {
35+
for (cookie: Cookie in cookies) {
36+
if (cookie.name == name) {
37+
return true
38+
}
39+
}
40+
return false
41+
}
42+
43+
fun getUpdatedCookies(oldCookies: List<Cookie>, newCookies: List<Cookie>): List<Cookie> {
44+
val updatedList = ArrayList<Cookie>(newCookies)
45+
for (oldCookie: Cookie in oldCookies) {
46+
if (!containsCookieWithName(updatedList, oldCookie.name)) {
47+
updatedList.add(oldCookie)
48+
}
49+
}
50+
return updatedList
51+
}
52+
53+
override fun saveFromResponse(url: HttpUrl, cookies: List<Cookie>) {
54+
// Avoid duplicated cookies but update
55+
val currentCookies: List<Cookie> = sCookieStore[url.host] ?: ArrayList()
56+
val updatedCookies: List<Cookie> = getUpdatedCookies(currentCookies, cookies)
57+
sCookieStore[url.host] = updatedCookies
58+
}
59+
60+
override fun loadForRequest(url: HttpUrl) =
61+
sCookieStore[url.host] ?: ArrayList()
62+
63+
}

0 commit comments

Comments
 (0)