Skip to content

Commit 01b37b5

Browse files
Merge branch '202-new-credential-types' into 'dev'
[Sync] Support new credential types See merge request objectbox/objectbox-java!133
2 parents 1cd4e4f + 4207b83 commit 01b37b5

File tree

7 files changed

+86
-31
lines changed

7 files changed

+86
-31
lines changed

objectbox-java/src/main/java/io/objectbox/sync/Sync.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@ public static SyncBuilder client(BoxStore boxStore, String url, SyncCredentials
3737
* Start building a sync server. Requires the BoxStore the server should use,
3838
* the URL and port the server should bind to and authenticator credentials to authenticate clients.
3939
* Additional authenticator credentials can be supplied using the builder.
40+
* <p>
41+
* For the embedded server, currently only {@link SyncCredentials#sharedSecret} and {@link SyncCredentials#none}
42+
* are supported.
4043
*/
4144
public static SyncServerBuilder server(BoxStore boxStore, String url, SyncCredentials authenticatorCredentials) {
4245
return new SyncServerBuilder(boxStore, url, authenticatorCredentials);

objectbox-java/src/main/java/io/objectbox/sync/SyncClientImpl.java

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -167,9 +167,17 @@ public void setSyncListener(@Nullable SyncListener listener) {
167167

168168
@Override
169169
public void setLoginCredentials(SyncCredentials credentials) {
170-
SyncCredentialsToken credentialsInternal = (SyncCredentialsToken) credentials;
171-
nativeSetLoginInfo(getHandle(), credentialsInternal.getTypeId(), credentialsInternal.getTokenBytes());
172-
credentialsInternal.clear(); // Clear immediately, not needed anymore.
170+
if (credentials instanceof SyncCredentialsToken) {
171+
SyncCredentialsToken credToken = (SyncCredentialsToken) credentials;
172+
nativeSetLoginInfo(getHandle(), credToken.getTypeId(), credToken.getTokenBytes());
173+
credToken.clear(); // Clear immediately, not needed anymore.
174+
} else if (credentials instanceof SyncCredentialsUserPassword) {
175+
SyncCredentialsUserPassword credUserPassword = (SyncCredentialsUserPassword) credentials;
176+
nativeSetLoginInfoUserPassword(getHandle(), credUserPassword.getTypeId(), credUserPassword.getUsername(),
177+
credUserPassword.getPassword());
178+
} else {
179+
throw new IllegalArgumentException("credentials is not a supported type");
180+
}
173181
}
174182

175183
@Override
@@ -296,6 +304,8 @@ public ObjectsMessageBuilder startObjectsMessage(long flags, @Nullable String to
296304

297305
private native void nativeSetLoginInfo(long handle, long credentialsType, @Nullable byte[] credentials);
298306

307+
private native void nativeSetLoginInfoUserPassword(long handle, long credentialsType, String username, String password);
308+
299309
private native void nativeSetListener(long handle, @Nullable InternalSyncClientListener listener);
300310

301311
private native void nativeSetSyncChangesListener(long handle, @Nullable SyncChangeListener advancedListener);
Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
11
package io.objectbox.sync;
22

3-
import io.objectbox.annotation.apihint.Experimental;
4-
53
/**
64
* Use the static helper methods to build Sync credentials,
75
* for example {@link #sharedSecret(String) SyncCredentials.sharedSecret("secret")}.
86
*/
97
@SuppressWarnings("unused")
10-
@Experimental
118
public class SyncCredentials {
129

10+
private final CredentialsType type;
11+
1312
/**
1413
* Authenticate with a shared secret. This could be a passphrase, big number or randomly chosen bytes.
1514
* The string is expected to use UTF-8 characters.
1615
*/
1716
public static SyncCredentials sharedSecret(String secret) {
18-
return new SyncCredentialsToken(CredentialsType.SHARED_SECRET, secret);
17+
return new SyncCredentialsToken(CredentialsType.SHARED_SECRET_SIPPED, secret);
1918
}
2019

2120
/**
2221
* Authenticate with a shared secret. This could be a passphrase, big number or randomly chosen bytes.
2322
*/
2423
public static SyncCredentials sharedSecret(byte[] secret) {
25-
return new SyncCredentialsToken(CredentialsType.SHARED_SECRET, secret);
24+
return new SyncCredentialsToken(CredentialsType.SHARED_SECRET_SIPPED, secret);
2625
}
2726

2827
/**
@@ -33,6 +32,10 @@ public static SyncCredentials google(String idToken) {
3332
return new SyncCredentialsToken(CredentialsType.GOOGLE, idToken);
3433
}
3534

35+
public static SyncCredentials userAndPassword(String user, String password) {
36+
return new SyncCredentialsUserPassword(user, password);
37+
}
38+
3639
/**
3740
* No authentication, unsecured. Use only for development and testing purposes.
3841
*/
@@ -44,10 +47,11 @@ public enum CredentialsType {
4447
// Note: this needs to match with CredentialsType in Core.
4548

4649
NONE(1),
47-
4850
SHARED_SECRET(2),
49-
50-
GOOGLE(3);
51+
GOOGLE(3),
52+
SHARED_SECRET_SIPPED(4),
53+
OBX_ADMIN_USER(5),
54+
USER_PASSWORD(6);
5155

5256
public final long id;
5357

@@ -56,7 +60,16 @@ public enum CredentialsType {
5660
}
5761
}
5862

59-
SyncCredentials() {
63+
SyncCredentials(CredentialsType type) {
64+
this.type = type;
65+
}
66+
67+
public CredentialsType getType() {
68+
return type;
69+
}
70+
71+
public long getTypeId() {
72+
return type.id;
6073
}
6174

6275
}

objectbox-java/src/main/java/io/objectbox/sync/SyncCredentialsToken.java

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package io.objectbox.sync;
22

3-
import java.io.UnsupportedEncodingException;
3+
import java.nio.charset.StandardCharsets;
44
import java.util.Arrays;
55

66
import javax.annotation.Nullable;
@@ -11,31 +11,28 @@
1111
* Internal credentials implementation. Use {@link SyncCredentials} to build credentials.
1212
*/
1313
@Internal
14-
public class SyncCredentialsToken extends SyncCredentials {
14+
public final class SyncCredentialsToken extends SyncCredentials {
1515

16-
private final CredentialsType type;
1716
@Nullable private byte[] token;
1817
private volatile boolean cleared;
1918

2019
SyncCredentialsToken(CredentialsType type) {
21-
this.type = type;
20+
super(type);
2221
this.token = null;
2322
}
2423

25-
SyncCredentialsToken(CredentialsType type, @SuppressWarnings("NullableProblems") byte[] token) {
24+
SyncCredentialsToken(CredentialsType type, byte[] token) {
2625
this(type);
26+
// Annotations do not guarantee non-null values
27+
//noinspection ConstantValue
2728
if (token == null || token.length == 0) {
2829
throw new IllegalArgumentException("Token must not be empty");
2930
}
3031
this.token = token;
3132
}
3233

3334
SyncCredentialsToken(CredentialsType type, String token) {
34-
this(type, asUtf8Bytes(token));
35-
}
36-
37-
public long getTypeId() {
38-
return type.id;
35+
this(type, token.getBytes(StandardCharsets.UTF_8));
3936
}
4037

4138
@Nullable
@@ -61,12 +58,4 @@ public void clear() {
6158
this.token = null;
6259
}
6360

64-
private static byte[] asUtf8Bytes(String token) {
65-
try {
66-
//noinspection CharsetObjectCanBeUsed On Android not available until SDK 19.
67-
return token.getBytes("UTF-8");
68-
} catch (UnsupportedEncodingException e) {
69-
throw new RuntimeException(e);
70-
}
71-
}
7261
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package io.objectbox.sync;
2+
3+
import io.objectbox.annotation.apihint.Internal;
4+
5+
/**
6+
* Internal credentials implementation for user and password authentication.
7+
* Use {@link SyncCredentials} to build credentials.
8+
*/
9+
@Internal
10+
public final class SyncCredentialsUserPassword extends SyncCredentials {
11+
12+
private final String username;
13+
private final String password;
14+
15+
SyncCredentialsUserPassword(String username, String password) {
16+
super(CredentialsType.USER_PASSWORD);
17+
this.username = username;
18+
this.password = password;
19+
}
20+
21+
public String getUsername() {
22+
return username;
23+
}
24+
25+
public String getPassword() {
26+
return password;
27+
}
28+
}

objectbox-java/src/main/java/io/objectbox/sync/server/SyncServerBuilder.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ public SyncServerBuilder certificatePath(String certificatePath) {
4646

4747
/**
4848
* Adds additional authenticator credentials to authenticate clients with.
49+
* <p>
50+
* For the embedded server, currently only {@link SyncCredentials#sharedSecret} and {@link SyncCredentials#none}
51+
* are supported.
4952
*/
5053
public SyncServerBuilder authenticatorCredentials(SyncCredentials authenticatorCredentials) {
5154
checkNotNull(authenticatorCredentials, "Authenticator credentials must not be null.");

objectbox-java/src/main/java/io/objectbox/sync/server/SyncServerImpl.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
import io.objectbox.annotation.apihint.Internal;
66
import io.objectbox.sync.SyncCredentials;
7+
import io.objectbox.sync.SyncCredentials.CredentialsType;
78
import io.objectbox.sync.SyncCredentialsToken;
89
import io.objectbox.sync.listener.SyncChangeListener;
910

@@ -31,8 +32,16 @@ public class SyncServerImpl implements SyncServer {
3132
this.handle = handle;
3233

3334
for (SyncCredentials credentials : builder.credentials) {
35+
if (!(credentials instanceof SyncCredentialsToken)) {
36+
throw new IllegalArgumentException("Sync credentials of type " + credentials.getType() + " are not supported");
37+
}
3438
SyncCredentialsToken credentialsInternal = (SyncCredentialsToken) credentials;
35-
nativeSetAuthenticator(handle, credentialsInternal.getTypeId(), credentialsInternal.getTokenBytes());
39+
// The core API used by nativeSetAuthenticator only supports the NONE and SHARED_SECRET types
40+
// (however, protocol v3 versions do also add SHARED_SECRET_SIPPED if SHARED_SECRET is given).
41+
final CredentialsType type = credentialsInternal.getType() == CredentialsType.SHARED_SECRET_SIPPED
42+
? CredentialsType.SHARED_SECRET
43+
: credentialsInternal.getType();
44+
nativeSetAuthenticator(handle, type.id, credentialsInternal.getTokenBytes());
3645
credentialsInternal.clear(); // Clear immediately, not needed anymore.
3746
}
3847

0 commit comments

Comments
 (0)