Skip to content

Commit 64fbf0c

Browse files
author
hideki
committed
Fixed #1303 - API to remove stored session cookies & auth tokens
- Ported iOS implementation: couchbase/couchbase-lite-ios#1330
1 parent 1a30b3f commit 64fbf0c

10 files changed

Lines changed: 116 additions & 19 deletions

src/main/java/com/couchbase/lite/auth/Authenticator.java

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,4 @@
1414
package com.couchbase.lite.auth;
1515

1616
public interface Authenticator {
17-
// @optional
18-
String getUsername();
1917
}

src/main/java/com/couchbase/lite/auth/Authorizer.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,9 @@ public interface Authorizer extends Authenticator {
2626
URL getRemoteURL();
2727

2828
void setRemoteURL(URL remoteURL);
29+
30+
boolean removeStoredCredentials();
31+
32+
// @optional
33+
String getUsername();
2934
}

src/main/java/com/couchbase/lite/auth/BaseAuthorizer.java

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,7 @@ public abstract class BaseAuthorizer implements Authorizer {
2525
protected URL remoteURL;
2626

2727
////////////////////////////////////////////////////////////
28-
// Implementation of Authenticator
29-
////////////////////////////////////////////////////////////
30-
@Override
31-
public String getUsername() {
32-
// @optional
33-
return null;
34-
}
35-
36-
////////////////////////////////////////////////////////////
37-
// Implementations of IAuthorizer
28+
// Implementations of Authorizer
3829
////////////////////////////////////////////////////////////
3930

4031
@Override
@@ -46,4 +37,15 @@ public URL getRemoteURL() {
4637
public void setRemoteURL(URL remoteURL) {
4738
this.remoteURL = remoteURL;
4839
}
40+
41+
@Override
42+
public boolean removeStoredCredentials() {
43+
return true;
44+
}
45+
46+
@Override
47+
public String getUsername() {
48+
// @optional
49+
return null;
50+
}
4951
}

src/main/java/com/couchbase/lite/auth/OpenIDConnectAuthorizer.java

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public boolean authorizeURLRequest(Request.Builder builder) {
8888
}
8989

9090
////////////////////////////////////////////////////////////
91-
// Implementations of ISessionCookieAuthorizer(ILoginAuthorizer)
91+
// Implementations of SessionCookieAuthorizer(LoginAuthorizer)
9292
////////////////////////////////////////////////////////////
9393

9494
// #pragma mark - LOGIN:
@@ -184,19 +184,30 @@ public void loginResponse(Object jsonResponse,
184184
block.call(false, error);
185185
}
186186

187+
@Override
188+
public boolean implementedLoginResponse() {
189+
return true;
190+
}
187191

188192
////////////////////////////////////////////////////////////
189-
// Implementation of Authenticator
193+
// Implementation of Authorizer
190194
////////////////////////////////////////////////////////////
195+
191196
@Override
192-
public String getUsername() {
193-
// @optional
194-
return username;
197+
public boolean removeStoredCredentials() {
198+
if(!deleteTokens())
199+
return false;
200+
IDToken = null;
201+
refreshToken = null;
202+
haveSessionCookie = false;
203+
authURL = null;
204+
return true;
195205
}
196206

197207
@Override
198-
public boolean implementedLoginResponse() {
199-
return true;
208+
public String getUsername() {
209+
// @optional
210+
return username;
200211
}
201212

202213
////////////////////////////////////////////////////////////

src/main/java/com/couchbase/lite/auth/PasswordAuthorizer.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,4 +69,20 @@ public String authUserInfo() {
6969
}
7070
return null;
7171
}
72+
////////////////////////////////////////////////////////////
73+
// Implementation of Authorizer
74+
////////////////////////////////////////////////////////////
75+
76+
@Override
77+
public boolean removeStoredCredentials() {
78+
this.username = null;
79+
this.password = null;
80+
return true;
81+
}
82+
83+
@Override
84+
public String getUsername() {
85+
// @optional
86+
return username;
87+
}
7288
}

src/main/java/com/couchbase/lite/replicator/Replication.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,13 @@
2121
import com.couchbase.lite.ReplicationFilter;
2222
import com.couchbase.lite.RevisionList;
2323
import com.couchbase.lite.auth.Authenticator;
24+
import com.couchbase.lite.auth.Authorizer;
2425
import com.couchbase.lite.internal.InterfaceAudience;
2526
import com.couchbase.lite.support.CouchbaseLiteHttpClientFactory;
2627
import com.couchbase.lite.support.HttpClientFactory;
2728
import com.couchbase.lite.support.PersistentCookieJar;
2829
import com.couchbase.lite.util.Log;
30+
import com.couchbase.lite.util.URLUtils;
2931

3032
import java.net.URL;
3133
import java.util.Date;
@@ -694,6 +696,12 @@ public void setFilterParams(Map<String, Object> filterParams) {
694696
replicationInternal.setFilterParams(filterParams);
695697
}
696698

699+
/** The server user name that the authenticator has logged in as, if known. Observable. */
700+
@InterfaceAudience.Public
701+
public String getUsername(){
702+
return replicationInternal.getUsername();
703+
}
704+
697705
/**
698706
* Sets an HTTP cookie for the Replication.
699707
*
@@ -738,6 +746,23 @@ public void deleteCookie(String name) {
738746
replicationInternal.deleteCookie(name);
739747
}
740748

749+
/**
750+
* Deletes any persistent credentials (passwords, auth tokens...) associated with this
751+
* replication's CBLAuthenticator. Also removes session cookies from the cookie store.
752+
*/
753+
@InterfaceAudience.Public
754+
public boolean removeStoredCredentials(){
755+
if (getAuthenticator() != null) {
756+
if (!(getAuthenticator() instanceof Authorizer) ||
757+
!((Authorizer) getAuthenticator()).removeStoredCredentials())
758+
return false;
759+
}else {
760+
// CBL Java does not use credential. No thing to do
761+
}
762+
replicationInternal.resetCookieStore();
763+
return true;
764+
}
765+
741766
/**
742767
* Get the remote UUID representing the remote server.
743768
*/

src/main/java/com/couchbase/lite/replicator/ReplicationInternal.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import com.couchbase.lite.util.Log;
4040
import com.couchbase.lite.util.TextUtils;
4141
import com.couchbase.lite.util.URIUtils;
42+
import com.couchbase.lite.util.URLUtils;
4243
import com.couchbase.lite.util.Utils;
4344
import com.github.oxo42.stateless4j.StateMachine;
4445
import com.github.oxo42.stateless4j.delegates.Action1;
@@ -104,6 +105,7 @@ protected enum ChangeListenerNotifyStyle {
104105
protected String lastSequence;
105106
protected Authenticator authenticator;
106107
protected boolean authenticating = false;
108+
protected String username;
107109
protected String filterName;
108110
protected Map<String, Object> filterParams;
109111
protected List<String> documentIDs;
@@ -158,6 +160,7 @@ protected enum ChangeListenerNotifyStyle {
158160
this.lifecycle = lifecycle;
159161
this.requestHeaders = new HashMap<String, Object>();
160162
this.authenticating = false;
163+
this.username = URLUtils.getUser(remote);
161164

162165
// The reason that notifications are ASYNC is to make the public API call
163166
// Replication.getStatus() work as expected. Because if this is set to SYNC,
@@ -547,6 +550,8 @@ private void loginFinishedWithError(Throwable error) {
547550
setError(error);
548551
} else {
549552
Log.v(TAG, "%s: Successfully logged in!", this);
553+
if (authenticator != null && authenticator instanceof OpenIDConnectAuthorizer)
554+
this.username = ((OpenIDConnectAuthorizer) authenticator).getUsername();
550555
fetchRemoteCheckpointDoc();
551556
}
552557
}
@@ -1794,6 +1799,10 @@ public void deleteCookie(String name) {
17941799
this.clientFactory.deleteCookie(name);
17951800
}
17961801

1802+
/* package */ void resetCookieStore(){
1803+
this.clientFactory.resetCookieStore();
1804+
}
1805+
17971806
protected HttpClientFactory getClientFactory() {
17981807
return clientFactory;
17991808
}
@@ -1955,4 +1964,8 @@ protected void waitPendingFuturesCompleted() {
19551964
Log.e(TAG, "Exception waiting for pending futures: %s", e);
19561965
}
19571966
}
1967+
1968+
/*package*/ String getUsername() {
1969+
return username;
1970+
}
19581971
}

src/main/java/com/couchbase/lite/support/CouchbaseLiteHttpClientFactory.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,10 @@ public void setSSLSocketFactory(SSLSocketFactory sslSocketFactory) {
6666
this.sslSocketFactory = sslSocketFactory;
6767
}
6868

69+
////////////////////////////////////////////////////////////
70+
// Implementations of HttpClientFactory
71+
////////////////////////////////////////////////////////////
72+
6973
@Override
7074
@InterfaceAudience.Private
7175
synchronized public OkHttpClient getOkHttpClient() {
@@ -92,6 +96,7 @@ synchronized public OkHttpClient getOkHttpClient() {
9296
return client;
9397
}
9498

99+
@Override
95100
@InterfaceAudience.Private
96101
synchronized public void addCookies(List<Cookie> cookies) {
97102
if (cookieJar != null) {
@@ -100,6 +105,8 @@ synchronized public void addCookies(List<Cookie> cookies) {
100105
}
101106
}
102107

108+
@Override
109+
@InterfaceAudience.Private
103110
synchronized public void deleteCookie(String name) {
104111
// since CookieStore does not have a way to delete an individual cookie, do workaround:
105112
// 1. get all cookies
@@ -121,6 +128,15 @@ synchronized public void deleteCookie(String name) {
121128
cookieJar.saveFromResponse(null, retainedCookies);
122129
}
123130

131+
@Override
132+
@InterfaceAudience.Private
133+
synchronized public void resetCookieStore(){
134+
if (cookieJar == null)
135+
return;
136+
cookieJar.clear();
137+
}
138+
139+
@Override
124140
@InterfaceAudience.Private
125141
public CookieJar getCookieStore() {
126142
return cookieJar;

src/main/java/com/couchbase/lite/support/HttpClientFactory.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,7 @@ public interface HttpClientFactory {
2626

2727
void deleteCookie(String name);
2828

29+
void resetCookieStore();
30+
2931
CookieJar getCookieStore();
3032
}

src/main/java/com/couchbase/lite/util/URLUtils.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,13 @@ public static Map<String, List<String>> splitQuery(URL url) throws UnsupportedEn
3939
}
4040
return query_pairs;
4141
}
42+
43+
public static String getUser(URL url) {
44+
if (url == null || url.getUserInfo() == null)
45+
return null;
46+
String[] tokens = url.getUserInfo().split(":");
47+
if (tokens == null || tokens.length == 0)
48+
return null;
49+
return tokens[0];
50+
}
4251
}

0 commit comments

Comments
 (0)