mirror of
https://github.com/etesync/android
synced 2024-11-25 17:38:13 +00:00
Kotlin: more kotlin migration.
This commit is contained in:
parent
943611a511
commit
c26ae4fba6
@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering).
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the GNU Public License v3.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.gnu.org/licenses/gpl.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.etesync.syncadapter.journalmanager;
|
|
||||||
|
|
||||||
import com.etesync.syncadapter.HttpClient;
|
|
||||||
import com.etesync.syncadapter.utils.Base64;
|
|
||||||
|
|
||||||
import org.apache.commons.codec.Charsets;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import okhttp3.HttpUrl;
|
|
||||||
import okhttp3.OkHttpClient;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNotEquals;
|
|
||||||
|
|
||||||
public class AuthenticatorTest {
|
|
||||||
private OkHttpClient httpClient;
|
|
||||||
private HttpUrl remote;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() throws IOException {
|
|
||||||
httpClient = HttpClient.create(null);
|
|
||||||
remote = HttpUrl.parse("http://localhost:8000"); // FIXME: hardcode for now, should make configureable
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() throws IOException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAuthToken() throws IOException, Exceptions.HttpException {
|
|
||||||
JournalAuthenticator journalAuthenticator = new JournalAuthenticator(httpClient, remote);
|
|
||||||
String authToken = journalAuthenticator.getAuthToken(Helpers.USER, Helpers.PASSWORD);
|
|
||||||
assertNotEquals(authToken.length(), 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected=Exceptions.UnauthorizedException.class)
|
|
||||||
public void testNoUser() throws Exceptions.IntegrityException, Exceptions.VersionTooNewException, IOException, Exceptions.HttpException {
|
|
||||||
JournalAuthenticator journalAuthenticator = new JournalAuthenticator(httpClient, remote);
|
|
||||||
String authToken = journalAuthenticator.getAuthToken(Helpers.USER, "BadPassword");
|
|
||||||
assertNotEquals(authToken.length(), 0);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering).
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the GNU Public License v3.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.gnu.org/licenses/gpl.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.etesync.syncadapter.journalmanager
|
||||||
|
|
||||||
|
import com.etesync.syncadapter.HttpClient
|
||||||
|
import com.etesync.syncadapter.utils.Base64
|
||||||
|
|
||||||
|
import org.apache.commons.codec.Charsets
|
||||||
|
import org.junit.After
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
import okhttp3.HttpUrl
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Assert.assertNotEquals
|
||||||
|
|
||||||
|
class AuthenticatorTest {
|
||||||
|
private var httpClient: OkHttpClient? = null
|
||||||
|
private var remote: HttpUrl? = null
|
||||||
|
|
||||||
|
@Before
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun setUp() {
|
||||||
|
httpClient = HttpClient.create(null)
|
||||||
|
remote = HttpUrl.parse("http://localhost:8000") // FIXME: hardcode for now, should make configureable
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun tearDown() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Throws(IOException::class, Exceptions.HttpException::class)
|
||||||
|
fun testAuthToken() {
|
||||||
|
val journalAuthenticator = JournalAuthenticator(httpClient!!, remote!!)
|
||||||
|
val authToken = journalAuthenticator.getAuthToken(Helpers.USER, Helpers.PASSWORD)
|
||||||
|
assertNotEquals(authToken!!.length.toLong(), 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = Exceptions.UnauthorizedException::class)
|
||||||
|
@Throws(Exceptions.IntegrityException::class, Exceptions.VersionTooNewException::class, IOException::class, Exceptions.HttpException::class)
|
||||||
|
fun testNoUser() {
|
||||||
|
val journalAuthenticator = JournalAuthenticator(httpClient!!, remote!!)
|
||||||
|
val authToken = journalAuthenticator.getAuthToken(Helpers.USER, "BadPassword")
|
||||||
|
assertNotEquals(authToken!!.length.toLong(), 0)
|
||||||
|
}
|
||||||
|
}
|
@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering).
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the GNU Public License v3.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.gnu.org/licenses/gpl.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.etesync.syncadapter.journalmanager;
|
|
||||||
|
|
||||||
import com.etesync.syncadapter.utils.Base64;
|
|
||||||
|
|
||||||
import org.apache.commons.codec.Charsets;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
import org.spongycastle.util.encoders.Hex;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
|
|
||||||
public class EncryptionTest {
|
|
||||||
@Before
|
|
||||||
public void setUp() throws IOException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() throws IOException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDerivePassword() {
|
|
||||||
String key = Crypto.deriveKey(Helpers.USER, Helpers.PASSWORD);
|
|
||||||
assertEquals(key, Helpers.keyBase64);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCryptoV1() throws Exceptions.IntegrityException, Exceptions.GenericCryptoException {
|
|
||||||
Crypto.CryptoManager cryptoManager = new Crypto.CryptoManager(1, Helpers.keyBase64, "TestSaltShouldBeJournalId");
|
|
||||||
|
|
||||||
String clearText = "This Is Some Test Cleartext.";
|
|
||||||
byte[] cipher = cryptoManager.encrypt(clearText.getBytes(Charsets.UTF_8));
|
|
||||||
assertEquals(clearText, new String(cryptoManager.decrypt(cipher), Charsets.UTF_8));
|
|
||||||
|
|
||||||
String expected = "Lz+HUFzh1HdjxuGdQrBwBG1IzHT0ug6mO8fwePSbXtc=";
|
|
||||||
assertEquals(expected, Base64.encodeToString(cryptoManager.hmac("Some test data".getBytes(Charsets.UTF_8)), Base64.NO_WRAP));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testCryptoV2() throws Exceptions.IntegrityException, Exceptions.GenericCryptoException {
|
|
||||||
Crypto.CryptoManager cryptoManager = new Crypto.CryptoManager(2, Helpers.keyBase64, "TestSaltShouldBeJournalId");
|
|
||||||
|
|
||||||
String clearText = "This Is Some Test Cleartext.";
|
|
||||||
byte[] cipher = cryptoManager.encrypt(clearText.getBytes(Charsets.UTF_8));
|
|
||||||
assertEquals(clearText, new String(cryptoManager.decrypt(cipher), Charsets.UTF_8));
|
|
||||||
|
|
||||||
String expected = "XQ/A0gentOaE98R9wzf3zEIAHj4OH1GF8J4C6JiJupo=";
|
|
||||||
assertEquals(expected, Base64.encodeToString(cryptoManager.hmac("Some test data".getBytes(Charsets.UTF_8)), Base64.NO_WRAP));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected=Exceptions.VersionTooNewException.class)
|
|
||||||
public void testCryptoVersionTooNew() throws Exceptions.IntegrityException, Exceptions.VersionTooNewException {
|
|
||||||
new Crypto.CryptoManager(120, Helpers.keyBase64, "TestSaltShouldBeJournalId");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected=Exceptions.IntegrityException.class)
|
|
||||||
public void testCryptoVersionOutOfRange() throws Exceptions.IntegrityException, Exceptions.VersionTooNewException {
|
|
||||||
new Crypto.CryptoManager(999, Helpers.keyBase64, "TestSaltShouldBeJournalId");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testAsymCrypto() throws Exceptions.IntegrityException, Exceptions.GenericCryptoException {
|
|
||||||
Crypto.AsymmetricKeyPair keyPair = Crypto.generateKeyPair();
|
|
||||||
Crypto.AsymmetricCryptoManager cryptoManager = new Crypto.AsymmetricCryptoManager(keyPair);
|
|
||||||
|
|
||||||
byte[] clearText = "This Is Some Test Cleartext.".getBytes(Charsets.UTF_8);
|
|
||||||
byte[] cipher = cryptoManager.encrypt(keyPair.getPublicKey(), clearText);
|
|
||||||
byte[] clearText2 = cryptoManager.decrypt(cipher);
|
|
||||||
assertArrayEquals(clearText, clearText2);
|
|
||||||
|
|
||||||
// Mostly for coverage. Make sure it's the expected sha256 value.
|
|
||||||
assertEquals("ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb",
|
|
||||||
Hex.toHexString(Crypto.AsymmetricCryptoManager.Companion.getKeyFingerprint("a".getBytes(Charsets.UTF_8))).toLowerCase());
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering).
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the GNU Public License v3.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.gnu.org/licenses/gpl.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.etesync.syncadapter.journalmanager
|
||||||
|
|
||||||
|
import com.etesync.syncadapter.utils.Base64
|
||||||
|
|
||||||
|
import org.apache.commons.codec.Charsets
|
||||||
|
import org.junit.After
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
import org.spongycastle.util.encoders.Hex
|
||||||
|
|
||||||
|
import java.io.IOException
|
||||||
|
|
||||||
|
import org.junit.Assert.assertArrayEquals
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
|
||||||
|
class EncryptionTest {
|
||||||
|
@Before
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun setUp() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun tearDown() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testDerivePassword() {
|
||||||
|
val key = Crypto.deriveKey(Helpers.USER, Helpers.PASSWORD)
|
||||||
|
assertEquals(key, Helpers.keyBase64)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Throws(Exceptions.IntegrityException::class, Exceptions.GenericCryptoException::class)
|
||||||
|
fun testCryptoV1() {
|
||||||
|
val cryptoManager = Crypto.CryptoManager(1, Helpers.keyBase64, "TestSaltShouldBeJournalId")
|
||||||
|
|
||||||
|
val clearText = "This Is Some Test Cleartext."
|
||||||
|
val cipher = cryptoManager.encrypt(clearText.toByteArray(Charsets.UTF_8))
|
||||||
|
assertEquals(clearText, String(cryptoManager.decrypt(cipher!!)!!, Charsets.UTF_8))
|
||||||
|
|
||||||
|
val expected = "Lz+HUFzh1HdjxuGdQrBwBG1IzHT0ug6mO8fwePSbXtc="
|
||||||
|
assertEquals(expected, Base64.encodeToString(cryptoManager.hmac("Some test data".toByteArray(Charsets.UTF_8)), Base64.NO_WRAP))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Throws(Exceptions.IntegrityException::class, Exceptions.GenericCryptoException::class)
|
||||||
|
fun testCryptoV2() {
|
||||||
|
val cryptoManager = Crypto.CryptoManager(2, Helpers.keyBase64, "TestSaltShouldBeJournalId")
|
||||||
|
|
||||||
|
val clearText = "This Is Some Test Cleartext."
|
||||||
|
val cipher = cryptoManager.encrypt(clearText.toByteArray(Charsets.UTF_8))
|
||||||
|
assertEquals(clearText, String(cryptoManager.decrypt(cipher!!)!!, Charsets.UTF_8))
|
||||||
|
|
||||||
|
val expected = "XQ/A0gentOaE98R9wzf3zEIAHj4OH1GF8J4C6JiJupo="
|
||||||
|
assertEquals(expected, Base64.encodeToString(cryptoManager.hmac("Some test data".toByteArray(Charsets.UTF_8)), Base64.NO_WRAP))
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = Exceptions.VersionTooNewException::class)
|
||||||
|
@Throws(Exceptions.IntegrityException::class, Exceptions.VersionTooNewException::class)
|
||||||
|
fun testCryptoVersionTooNew() {
|
||||||
|
Crypto.CryptoManager(120, Helpers.keyBase64, "TestSaltShouldBeJournalId")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = Exceptions.IntegrityException::class)
|
||||||
|
@Throws(Exceptions.IntegrityException::class, Exceptions.VersionTooNewException::class)
|
||||||
|
fun testCryptoVersionOutOfRange() {
|
||||||
|
Crypto.CryptoManager(999, Helpers.keyBase64, "TestSaltShouldBeJournalId")
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Throws(Exceptions.IntegrityException::class, Exceptions.GenericCryptoException::class)
|
||||||
|
fun testAsymCrypto() {
|
||||||
|
val keyPair = Crypto.generateKeyPair()
|
||||||
|
val cryptoManager = Crypto.AsymmetricCryptoManager(keyPair!!)
|
||||||
|
|
||||||
|
val clearText = "This Is Some Test Cleartext.".toByteArray(Charsets.UTF_8)
|
||||||
|
val cipher = cryptoManager.encrypt(keyPair.publicKey, clearText)
|
||||||
|
val clearText2 = cryptoManager.decrypt(cipher!!)
|
||||||
|
assertArrayEquals(clearText, clearText2)
|
||||||
|
|
||||||
|
// Mostly for coverage. Make sure it's the expected sha256 value.
|
||||||
|
assertEquals("ca978112ca1bbdcafac231b39a23dc4da786eff8147c4e72b9807785afee48bb",
|
||||||
|
Hex.toHexString(Crypto.AsymmetricCryptoManager.getKeyFingerprint("a".toByteArray(Charsets.UTF_8))).toLowerCase())
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +0,0 @@
|
|||||||
package com.etesync.syncadapter.journalmanager;
|
|
||||||
|
|
||||||
class Helpers {
|
|
||||||
static final String USER = "test@localhost";
|
|
||||||
static final String USER2 = "test2@localhost";
|
|
||||||
static final String PASSWORD = "SomePassword";
|
|
||||||
static final String keyBase64 = "Gpn6j6WJ/9JJbVkWhmEfZjlqSps5rwEOzjUOO0rqufvb4vtT4UfRgx0uMivuGwjF7/8Y1z1glIASX7Oz/4l2jucgf+lAzg2oTZFodWkXRZCDmFa7c9a8/04xIs7koFmUH34Rl9XXW6V2/GDVigQhQU8uWnrGo795tupoNQMbtB8RgMX5GyuxR55FvcybHpYBbwrDIsKvXcBxWFEscdNU8zyeq3yjvDo/W/y24dApW3mnNo7vswoL2rpkZj3dqw==";
|
|
||||||
}
|
|
@ -0,0 +1,8 @@
|
|||||||
|
package com.etesync.syncadapter.journalmanager
|
||||||
|
|
||||||
|
internal object Helpers {
|
||||||
|
val USER = "test@localhost"
|
||||||
|
val USER2 = "test2@localhost"
|
||||||
|
val PASSWORD = "SomePassword"
|
||||||
|
val keyBase64 = "Gpn6j6WJ/9JJbVkWhmEfZjlqSps5rwEOzjUOO0rqufvb4vtT4UfRgx0uMivuGwjF7/8Y1z1glIASX7Oz/4l2jucgf+lAzg2oTZFodWkXRZCDmFa7c9a8/04xIs7koFmUH34Rl9XXW6V2/GDVigQhQU8uWnrGo795tupoNQMbtB8RgMX5GyuxR55FvcybHpYBbwrDIsKvXcBxWFEscdNU8zyeq3yjvDo/W/y24dApW3mnNo7vswoL2rpkZj3dqw=="
|
||||||
|
}
|
@ -1,271 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering).
|
|
||||||
* All rights reserved. This program and the accompanying materials
|
|
||||||
* are made available under the terms of the GNU Public License v3.0
|
|
||||||
* which accompanies this distribution, and is available at
|
|
||||||
* http://www.gnu.org/licenses/gpl.html
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.etesync.syncadapter.journalmanager;
|
|
||||||
|
|
||||||
import com.etesync.syncadapter.App;
|
|
||||||
import com.etesync.syncadapter.HttpClient;
|
|
||||||
import com.etesync.syncadapter.model.CollectionInfo;
|
|
||||||
|
|
||||||
import org.apache.commons.codec.Charsets;
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import okhttp3.HttpUrl;
|
|
||||||
import okhttp3.MediaType;
|
|
||||||
import okhttp3.OkHttpClient;
|
|
||||||
import okhttp3.Request;
|
|
||||||
import okhttp3.RequestBody;
|
|
||||||
import okhttp3.Response;
|
|
||||||
import okio.BufferedSink;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
|
|
||||||
public class ServiceTest {
|
|
||||||
private OkHttpClient httpClient;
|
|
||||||
private HttpUrl remote;
|
|
||||||
private String authToken;
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void setUp() throws Exception {
|
|
||||||
httpClient = HttpClient.create(null);
|
|
||||||
remote = HttpUrl.parse("http://localhost:8000"); // FIXME: hardcode for now, should make configureable
|
|
||||||
JournalAuthenticator journalAuthenticator = new JournalAuthenticator(httpClient, remote);
|
|
||||||
authToken = journalAuthenticator.getAuthToken(Helpers.USER, Helpers.PASSWORD);
|
|
||||||
|
|
||||||
httpClient = HttpClient.create(null, App.log, null, authToken);
|
|
||||||
|
|
||||||
/* Reset */
|
|
||||||
Request request = new Request.Builder()
|
|
||||||
.post(new RequestBody() {
|
|
||||||
@Override
|
|
||||||
public MediaType contentType() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void writeTo(BufferedSink sink) throws IOException {
|
|
||||||
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.url(remote.newBuilder().addEncodedPathSegments("reset/").build())
|
|
||||||
.build();
|
|
||||||
Response response = httpClient.newCall(request).execute();
|
|
||||||
if (!response.isSuccessful()) {
|
|
||||||
throw new Exception("Failed resetting");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() throws IOException {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSyncSimple() throws IOException, Exceptions.HttpException, Exceptions.GenericCryptoException, Exceptions.IntegrityException {
|
|
||||||
Exception caught;
|
|
||||||
JournalManager journalManager = new JournalManager(httpClient, remote);
|
|
||||||
CollectionInfo info = CollectionInfo.defaultForServiceType(CollectionInfo.Type.ADDRESS_BOOK);
|
|
||||||
info.uid = JournalManager.Journal.genUid();
|
|
||||||
info.displayName = "Test";
|
|
||||||
Crypto.CryptoManager crypto = new Crypto.CryptoManager(info.version, Helpers.keyBase64, info.uid);
|
|
||||||
JournalManager.Journal journal = new JournalManager.Journal(crypto, info.toJson(), info.uid);
|
|
||||||
journalManager.create(journal);
|
|
||||||
|
|
||||||
// Try pushing the same journal (uid clash)
|
|
||||||
try {
|
|
||||||
caught = null;
|
|
||||||
journalManager.create(journal);
|
|
||||||
} catch (Exceptions.HttpException e) {
|
|
||||||
caught = e;
|
|
||||||
}
|
|
||||||
assertNotNull(caught);
|
|
||||||
|
|
||||||
List<JournalManager.Journal> journals = journalManager.list();
|
|
||||||
assertEquals(journals.size(), 1);
|
|
||||||
CollectionInfo info2 = CollectionInfo.fromJson(journals.get(0).getContent(crypto));
|
|
||||||
assertEquals(info2.displayName, info.displayName);
|
|
||||||
|
|
||||||
// Update journal
|
|
||||||
info.displayName = "Test 2";
|
|
||||||
journal = new JournalManager.Journal(crypto, info.toJson(), info.uid);
|
|
||||||
journalManager.update(journal);
|
|
||||||
|
|
||||||
journals = journalManager.list();
|
|
||||||
assertEquals(journals.size(), 1);
|
|
||||||
info2 = CollectionInfo.fromJson(journals.get(0).getContent(crypto));
|
|
||||||
assertEquals(info2.displayName, info.displayName);
|
|
||||||
|
|
||||||
// Delete journal
|
|
||||||
journalManager.delete(journal);
|
|
||||||
|
|
||||||
journals = journalManager.list();
|
|
||||||
assertEquals(journals.size(), 0);
|
|
||||||
|
|
||||||
// Bad HMAC
|
|
||||||
info.uid = JournalManager.Journal.genUid();
|
|
||||||
journal = new JournalManager.Journal(crypto, info.toJson(), info.uid);
|
|
||||||
info.displayName = "Test 3";
|
|
||||||
//// We assume this doesn't update the hmac.
|
|
||||||
journal.setContent(crypto, info.toJson());
|
|
||||||
journalManager.create(journal);
|
|
||||||
|
|
||||||
try {
|
|
||||||
caught = null;
|
|
||||||
for (JournalManager.Journal journal1 : journalManager.list()) {
|
|
||||||
Crypto.CryptoManager crypto1 = new Crypto.CryptoManager(info.version, Helpers.keyBase64, journal1.getUid());
|
|
||||||
journal1.verify(crypto1);
|
|
||||||
}
|
|
||||||
} catch (Exceptions.IntegrityException e) {
|
|
||||||
caught = e;
|
|
||||||
}
|
|
||||||
assertNotNull(caught);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSyncEntry() throws IOException, Exceptions.HttpException, Exceptions.GenericCryptoException, Exceptions.IntegrityException {
|
|
||||||
Exception caught;
|
|
||||||
JournalManager journalManager = new JournalManager(httpClient, remote);
|
|
||||||
CollectionInfo info = CollectionInfo.defaultForServiceType(CollectionInfo.Type.ADDRESS_BOOK);
|
|
||||||
info.uid = JournalManager.Journal.genUid();
|
|
||||||
info.displayName = "Test";
|
|
||||||
Crypto.CryptoManager crypto = new Crypto.CryptoManager(info.version, Helpers.keyBase64, info.uid);
|
|
||||||
JournalManager.Journal journal = new JournalManager.Journal(crypto, info.toJson(), info.uid);
|
|
||||||
journalManager.create(journal);
|
|
||||||
|
|
||||||
JournalEntryManager journalEntryManager = new JournalEntryManager(httpClient, remote, info.uid);
|
|
||||||
JournalEntryManager.Entry previousEntry = null;
|
|
||||||
JournalEntryManager.Entry entry = new JournalEntryManager.Entry();
|
|
||||||
entry.update(crypto, "Content", previousEntry);
|
|
||||||
|
|
||||||
List<JournalEntryManager.Entry> entries = new LinkedList<>();
|
|
||||||
|
|
||||||
entries.add(entry);
|
|
||||||
journalEntryManager.create(entries, null);
|
|
||||||
previousEntry = entry;
|
|
||||||
|
|
||||||
entries.clear();
|
|
||||||
JournalEntryManager.Entry entry2 = new JournalEntryManager.Entry();
|
|
||||||
entry2.update(crypto, "Content", previousEntry);
|
|
||||||
entries.add(entry2);
|
|
||||||
|
|
||||||
// Pushing a correct entries without the last parameter
|
|
||||||
try {
|
|
||||||
caught = null;
|
|
||||||
journalEntryManager.create(entries, null);
|
|
||||||
} catch (Exceptions.HttpException e) {
|
|
||||||
caught = e;
|
|
||||||
}
|
|
||||||
assertNotNull(caught);
|
|
||||||
|
|
||||||
// Adding a second entry
|
|
||||||
journalEntryManager.create(entries, previousEntry.getUid());
|
|
||||||
previousEntry = entry2;
|
|
||||||
|
|
||||||
entries.clear();
|
|
||||||
entries.add(entry);
|
|
||||||
entries.add(entry2);
|
|
||||||
|
|
||||||
// Check last works:
|
|
||||||
entries = journalEntryManager.list(crypto, entry.getUid(), 0);
|
|
||||||
assertEquals(entries.size(), 1);
|
|
||||||
entries = journalEntryManager.list(crypto, entry2.getUid(), 0);
|
|
||||||
assertEquals(entries.size(), 0);
|
|
||||||
|
|
||||||
// Corrupt the journal and verify we catch it
|
|
||||||
entries.clear();
|
|
||||||
entry2 = new JournalEntryManager.Entry();
|
|
||||||
entry2.update(crypto, "Content", null);
|
|
||||||
entries.add(entry2);
|
|
||||||
|
|
||||||
journalEntryManager.create(entries, previousEntry.getUid());
|
|
||||||
|
|
||||||
try {
|
|
||||||
caught = null;
|
|
||||||
journalEntryManager.list(crypto, null, 0);
|
|
||||||
} catch (Exceptions.IntegrityException e) {
|
|
||||||
caught = e;
|
|
||||||
}
|
|
||||||
assertNotNull(caught);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUserInfo() throws IOException, Exceptions.HttpException, Exceptions.GenericCryptoException, Exceptions.IntegrityException {
|
|
||||||
Crypto.CryptoManager cryptoManager = new Crypto.CryptoManager(Constants.CURRENT_VERSION, Helpers.keyBase64, "userInfo");
|
|
||||||
UserInfoManager.UserInfo userInfo, userInfo2;
|
|
||||||
UserInfoManager manager = new UserInfoManager(httpClient, remote);
|
|
||||||
|
|
||||||
// Get when there's nothing
|
|
||||||
userInfo = manager.get(Helpers.USER);
|
|
||||||
assertNull(userInfo);
|
|
||||||
|
|
||||||
// Create
|
|
||||||
userInfo = UserInfoManager.UserInfo.generate(cryptoManager, Helpers.USER);
|
|
||||||
manager.create(userInfo);
|
|
||||||
|
|
||||||
// Get
|
|
||||||
userInfo2 = manager.get(Helpers.USER);
|
|
||||||
assertNotNull(userInfo2);
|
|
||||||
assertArrayEquals(userInfo.getContent(cryptoManager), userInfo2.getContent(cryptoManager));
|
|
||||||
|
|
||||||
// Update
|
|
||||||
userInfo.setContent(cryptoManager, "test".getBytes(Charsets.UTF_8));
|
|
||||||
manager.update(userInfo);
|
|
||||||
userInfo2 = manager.get(Helpers.USER);
|
|
||||||
assertNotNull(userInfo2);
|
|
||||||
assertArrayEquals(userInfo.getContent(cryptoManager), userInfo2.getContent(cryptoManager));
|
|
||||||
|
|
||||||
// Delete
|
|
||||||
manager.delete(userInfo);
|
|
||||||
userInfo = manager.get(Helpers.USER);
|
|
||||||
assertNull(userInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testJournalMember() throws IOException, Exceptions.HttpException, Exceptions.GenericCryptoException, Exceptions.IntegrityException {
|
|
||||||
Exception caught;
|
|
||||||
JournalManager journalManager = new JournalManager(httpClient, remote);
|
|
||||||
CollectionInfo info = CollectionInfo.defaultForServiceType(CollectionInfo.Type.ADDRESS_BOOK);
|
|
||||||
info.uid = JournalManager.Journal.genUid();
|
|
||||||
info.displayName = "Test";
|
|
||||||
Crypto.CryptoManager crypto = new Crypto.CryptoManager(info.version, Helpers.keyBase64, info.uid);
|
|
||||||
JournalManager.Journal journal = new JournalManager.Journal(crypto, info.toJson(), info.uid);
|
|
||||||
journalManager.create(journal);
|
|
||||||
|
|
||||||
assertEquals(journalManager.listMembers(journal).size(), 0);
|
|
||||||
|
|
||||||
// Test inviting ourselves
|
|
||||||
JournalManager.Member member = new JournalManager.Member(Helpers.USER, "test".getBytes(Charsets.UTF_8));
|
|
||||||
try {
|
|
||||||
caught = null;
|
|
||||||
journalManager.addMember(journal, member);
|
|
||||||
} catch (Exceptions.HttpException e) {
|
|
||||||
caught = e;
|
|
||||||
}
|
|
||||||
assertNotNull(caught);
|
|
||||||
|
|
||||||
JournalManager.Member member2 = new JournalManager.Member(Helpers.USER2, "test".getBytes(Charsets.UTF_8));
|
|
||||||
journalManager.addMember(journal, member2);
|
|
||||||
assertEquals(journalManager.listMembers(journal).size(), 1);
|
|
||||||
|
|
||||||
// Uninviting user
|
|
||||||
journalManager.deleteMember(journal, member2);
|
|
||||||
|
|
||||||
assertEquals(journalManager.listMembers(journal).size(), 0);
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,282 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2013 – 2015 Ricki Hirner (bitfire web engineering).
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the GNU Public License v3.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.gnu.org/licenses/gpl.html
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.etesync.syncadapter.journalmanager
|
||||||
|
|
||||||
|
import com.etesync.syncadapter.App
|
||||||
|
import com.etesync.syncadapter.HttpClient
|
||||||
|
import com.etesync.syncadapter.model.CollectionInfo
|
||||||
|
|
||||||
|
import org.apache.commons.codec.Charsets
|
||||||
|
import org.junit.After
|
||||||
|
import org.junit.Before
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
import java.io.IOException
|
||||||
|
import java.util.LinkedList
|
||||||
|
|
||||||
|
import okhttp3.HttpUrl
|
||||||
|
import okhttp3.MediaType
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.Request
|
||||||
|
import okhttp3.RequestBody
|
||||||
|
import okhttp3.Response
|
||||||
|
import okio.BufferedSink
|
||||||
|
|
||||||
|
import org.junit.Assert.assertArrayEquals
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Assert.assertNotNull
|
||||||
|
import org.junit.Assert.assertNull
|
||||||
|
|
||||||
|
class ServiceTest {
|
||||||
|
private var httpClient: OkHttpClient? = null
|
||||||
|
private var remote: HttpUrl? = null
|
||||||
|
private var authToken: String? = null
|
||||||
|
|
||||||
|
@Before
|
||||||
|
@Throws(Exception::class)
|
||||||
|
fun setUp() {
|
||||||
|
httpClient = HttpClient.create(null)
|
||||||
|
remote = HttpUrl.parse("http://localhost:8000") // FIXME: hardcode for now, should make configureable
|
||||||
|
val journalAuthenticator = JournalAuthenticator(httpClient!!, remote!!)
|
||||||
|
authToken = journalAuthenticator.getAuthToken(Helpers.USER, Helpers.PASSWORD)
|
||||||
|
|
||||||
|
httpClient = HttpClient.create(null, App.log, null, authToken!!)
|
||||||
|
|
||||||
|
/* Reset */
|
||||||
|
val request = Request.Builder()
|
||||||
|
.post(object : RequestBody() {
|
||||||
|
override fun contentType(): MediaType? {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
@Throws(IOException::class)
|
||||||
|
override fun writeTo(sink: BufferedSink) {
|
||||||
|
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.url(remote!!.newBuilder().addEncodedPathSegments("reset/").build())
|
||||||
|
.build()
|
||||||
|
val response = httpClient!!.newCall(request).execute()
|
||||||
|
if (!response.isSuccessful) {
|
||||||
|
throw Exception("Failed resetting")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
@Throws(IOException::class)
|
||||||
|
fun tearDown() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Throws(IOException::class, Exceptions.HttpException::class, Exceptions.GenericCryptoException::class, Exceptions.IntegrityException::class)
|
||||||
|
fun testSyncSimple() {
|
||||||
|
var caught: Exception?
|
||||||
|
val journalManager = JournalManager(httpClient!!, remote!!)
|
||||||
|
val info = CollectionInfo.defaultForServiceType(CollectionInfo.Type.ADDRESS_BOOK)
|
||||||
|
info.uid = JournalManager.Journal.genUid()
|
||||||
|
info.displayName = "Test"
|
||||||
|
val crypto = Crypto.CryptoManager(info.version, Helpers.keyBase64, info.uid)
|
||||||
|
var journal = JournalManager.Journal(crypto, info.toJson(), info.uid)
|
||||||
|
journalManager.create(journal)
|
||||||
|
|
||||||
|
// Try pushing the same journal (uid clash)
|
||||||
|
try {
|
||||||
|
caught = null
|
||||||
|
journalManager.create(journal)
|
||||||
|
} catch (e: Exceptions.HttpException) {
|
||||||
|
caught = e
|
||||||
|
}
|
||||||
|
|
||||||
|
assertNotNull(caught)
|
||||||
|
|
||||||
|
var journals: List<JournalManager.Journal> = journalManager.list()
|
||||||
|
assertEquals(journals.size.toLong(), 1)
|
||||||
|
var info2 = CollectionInfo.fromJson(journals[0].getContent(crypto))
|
||||||
|
assertEquals(info2.displayName, info.displayName)
|
||||||
|
|
||||||
|
// Update journal
|
||||||
|
info.displayName = "Test 2"
|
||||||
|
journal = JournalManager.Journal(crypto, info.toJson(), info.uid)
|
||||||
|
journalManager.update(journal)
|
||||||
|
|
||||||
|
journals = journalManager.list()
|
||||||
|
assertEquals(journals.size.toLong(), 1)
|
||||||
|
info2 = CollectionInfo.fromJson(journals[0].getContent(crypto))
|
||||||
|
assertEquals(info2.displayName, info.displayName)
|
||||||
|
|
||||||
|
// Delete journal
|
||||||
|
journalManager.delete(journal)
|
||||||
|
|
||||||
|
journals = journalManager.list()
|
||||||
|
assertEquals(journals.size.toLong(), 0)
|
||||||
|
|
||||||
|
// Bad HMAC
|
||||||
|
info.uid = JournalManager.Journal.genUid()
|
||||||
|
journal = JournalManager.Journal(crypto, info.toJson(), info.uid)
|
||||||
|
info.displayName = "Test 3"
|
||||||
|
//// We assume this doesn't update the hmac.
|
||||||
|
journal.setContent(crypto, info.toJson())
|
||||||
|
journalManager.create(journal)
|
||||||
|
|
||||||
|
try {
|
||||||
|
caught = null
|
||||||
|
for (journal1 in journalManager.list()) {
|
||||||
|
val crypto1 = Crypto.CryptoManager(info.version, Helpers.keyBase64, journal1.uid!!)
|
||||||
|
journal1.verify(crypto1)
|
||||||
|
}
|
||||||
|
} catch (e: Exceptions.IntegrityException) {
|
||||||
|
caught = e
|
||||||
|
}
|
||||||
|
|
||||||
|
assertNotNull(caught)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Throws(IOException::class, Exceptions.HttpException::class, Exceptions.GenericCryptoException::class, Exceptions.IntegrityException::class)
|
||||||
|
fun testSyncEntry() {
|
||||||
|
var caught: Exception?
|
||||||
|
val journalManager = JournalManager(httpClient!!, remote!!)
|
||||||
|
val info = CollectionInfo.defaultForServiceType(CollectionInfo.Type.ADDRESS_BOOK)
|
||||||
|
info.uid = JournalManager.Journal.genUid()
|
||||||
|
info.displayName = "Test"
|
||||||
|
val crypto = Crypto.CryptoManager(info.version, Helpers.keyBase64, info.uid)
|
||||||
|
val journal = JournalManager.Journal(crypto, info.toJson(), info.uid)
|
||||||
|
journalManager.create(journal)
|
||||||
|
|
||||||
|
val journalEntryManager = JournalEntryManager(httpClient!!, remote!!, info.uid)
|
||||||
|
var previousEntry: JournalEntryManager.Entry? = null
|
||||||
|
val entry = JournalEntryManager.Entry()
|
||||||
|
entry.update(crypto, "Content", previousEntry)
|
||||||
|
|
||||||
|
var entries: MutableList<JournalEntryManager.Entry> = LinkedList()
|
||||||
|
var retEntries: List<JournalEntryManager.Entry>
|
||||||
|
|
||||||
|
entries.add(entry)
|
||||||
|
journalEntryManager.create(entries, null)
|
||||||
|
previousEntry = entry
|
||||||
|
|
||||||
|
entries.clear()
|
||||||
|
var entry2 = JournalEntryManager.Entry()
|
||||||
|
entry2.update(crypto, "Content", previousEntry)
|
||||||
|
entries.add(entry2)
|
||||||
|
|
||||||
|
// Pushing a correct entries without the last parameter
|
||||||
|
try {
|
||||||
|
caught = null
|
||||||
|
journalEntryManager.create(entries, null)
|
||||||
|
} catch (e: Exceptions.HttpException) {
|
||||||
|
caught = e
|
||||||
|
}
|
||||||
|
|
||||||
|
assertNotNull(caught)
|
||||||
|
|
||||||
|
// Adding a second entry
|
||||||
|
journalEntryManager.create(entries, previousEntry.uid)
|
||||||
|
previousEntry = entry2
|
||||||
|
|
||||||
|
entries.clear()
|
||||||
|
entries.add(entry)
|
||||||
|
entries.add(entry2)
|
||||||
|
|
||||||
|
// Check last works:
|
||||||
|
retEntries = journalEntryManager.list(crypto, entry.uid, 0)
|
||||||
|
assertEquals(retEntries.size.toLong(), 1)
|
||||||
|
retEntries = journalEntryManager.list(crypto, entry2.uid, 0)
|
||||||
|
assertEquals(retEntries.size.toLong(), 0)
|
||||||
|
|
||||||
|
// Corrupt the journal and verify we catch it
|
||||||
|
entries.clear()
|
||||||
|
entry2 = JournalEntryManager.Entry()
|
||||||
|
entry2.update(crypto, "Content", null)
|
||||||
|
entries.add(entry2)
|
||||||
|
|
||||||
|
journalEntryManager.create(entries, previousEntry.uid)
|
||||||
|
|
||||||
|
try {
|
||||||
|
caught = null
|
||||||
|
journalEntryManager.list(crypto, null, 0)
|
||||||
|
} catch (e: Exceptions.IntegrityException) {
|
||||||
|
caught = e
|
||||||
|
}
|
||||||
|
|
||||||
|
assertNotNull(caught)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Throws(IOException::class, Exceptions.HttpException::class, Exceptions.GenericCryptoException::class, Exceptions.IntegrityException::class)
|
||||||
|
fun testUserInfo() {
|
||||||
|
val cryptoManager = Crypto.CryptoManager(Constants.CURRENT_VERSION, Helpers.keyBase64, "userInfo")
|
||||||
|
var userInfo: UserInfoManager.UserInfo?
|
||||||
|
var userInfo2: UserInfoManager.UserInfo?
|
||||||
|
val manager = UserInfoManager(httpClient!!, remote!!)
|
||||||
|
|
||||||
|
// Get when there's nothing
|
||||||
|
userInfo = manager[Helpers.USER]
|
||||||
|
assertNull(userInfo)
|
||||||
|
|
||||||
|
// Create
|
||||||
|
userInfo = UserInfoManager.UserInfo.generate(cryptoManager, Helpers.USER)
|
||||||
|
manager.create(userInfo)
|
||||||
|
|
||||||
|
// Get
|
||||||
|
userInfo2 = manager[Helpers.USER]
|
||||||
|
assertNotNull(userInfo2)
|
||||||
|
assertArrayEquals(userInfo.getContent(cryptoManager), userInfo2!!.getContent(cryptoManager))
|
||||||
|
|
||||||
|
// Update
|
||||||
|
userInfo.setContent(cryptoManager, "test".toByteArray(Charsets.UTF_8))
|
||||||
|
manager.update(userInfo)
|
||||||
|
userInfo2 = manager[Helpers.USER]
|
||||||
|
assertNotNull(userInfo2)
|
||||||
|
assertArrayEquals(userInfo.getContent(cryptoManager), userInfo2!!.getContent(cryptoManager))
|
||||||
|
|
||||||
|
// Delete
|
||||||
|
manager.delete(userInfo)
|
||||||
|
userInfo = manager[Helpers.USER]
|
||||||
|
assertNull(userInfo)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Throws(IOException::class, Exceptions.HttpException::class, Exceptions.GenericCryptoException::class, Exceptions.IntegrityException::class)
|
||||||
|
fun testJournalMember() {
|
||||||
|
var caught: Exception?
|
||||||
|
val journalManager = JournalManager(httpClient!!, remote!!)
|
||||||
|
val info = CollectionInfo.defaultForServiceType(CollectionInfo.Type.ADDRESS_BOOK)
|
||||||
|
info.uid = JournalManager.Journal.genUid()
|
||||||
|
info.displayName = "Test"
|
||||||
|
val crypto = Crypto.CryptoManager(info.version, Helpers.keyBase64, info.uid)
|
||||||
|
val journal = JournalManager.Journal(crypto, info.toJson(), info.uid)
|
||||||
|
journalManager.create(journal)
|
||||||
|
|
||||||
|
assertEquals(journalManager.listMembers(journal).size.toLong(), 0)
|
||||||
|
|
||||||
|
// Test inviting ourselves
|
||||||
|
val member = JournalManager.Member(Helpers.USER, "test".toByteArray(Charsets.UTF_8))
|
||||||
|
try {
|
||||||
|
caught = null
|
||||||
|
journalManager.addMember(journal, member)
|
||||||
|
} catch (e: Exceptions.HttpException) {
|
||||||
|
caught = e
|
||||||
|
}
|
||||||
|
|
||||||
|
assertNotNull(caught)
|
||||||
|
|
||||||
|
val member2 = JournalManager.Member(Helpers.USER2, "test".toByteArray(Charsets.UTF_8))
|
||||||
|
journalManager.addMember(journal, member2)
|
||||||
|
assertEquals(journalManager.listMembers(journal).size.toLong(), 1)
|
||||||
|
|
||||||
|
// Uninviting user
|
||||||
|
journalManager.deleteMember(journal, member2)
|
||||||
|
|
||||||
|
assertEquals(journalManager.listMembers(journal).size.toLong(), 0)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user