Skip to content

Commit

Permalink
Merge pull request #166 from apptentive/branch_5.3.0
Browse files Browse the repository at this point in the history
Release 5.3.0
  • Loading branch information
weeeBox authored Aug 31, 2018
2 parents 95e4932 + 2d39b8d commit f3e8898
Show file tree
Hide file tree
Showing 47 changed files with 1,873 additions and 750 deletions.
3 changes: 3 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,18 @@ android:
- platform-tools
- tools # not a mistakenly duplicated line: used above api 25.x
- build-tools-27.0.3
- build-tools-28.0.2
- android-19
- android-27
- android-28
- extra-google-google_play_services
- extra-google-m2repository
- extra-android-m2repository
- addon-google_apis-google-26
- sys-img-armeabi-v7a-android-19
before_install:
- yes | sdkmanager "platforms;android-27"
- yes | sdkmanager "platforms;android-28"
install: true
before_script:
- echo no | android create avd --force -n test -t android-19 --abi armeabi-v7a
Expand Down
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# 2018-08-30 - v5.3.0

#### Improvements

* Improved SDK security with encryption and KeyStore.

# 2018-08-23 - v5.2.0

#### Improvements
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use your app, to talk to them at the right time, and in the right way.

##### [Release Notes](https://learn.apptentive.com/knowledge-base/android-sdk-release-notes/)

##### Binary releases are hosted for Maven [here](http://search.maven.org/#artifactdetails|com.apptentive|apptentive-android|5.2.0|aar)
##### Binary releases are hosted for Maven [here](http://search.maven.org/#artifactdetails|com.apptentive|apptentive-android|5.3.0|aar)

#### Reporting Bugs

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import com.apptentive.android.sdk.ApptentiveInternal;
import com.apptentive.android.sdk.TestCaseBase;
import com.apptentive.android.sdk.encryption.EncryptionKey;
import com.apptentive.android.sdk.model.ApptentiveMessage;
import com.apptentive.android.sdk.model.CompoundMessage;
import com.apptentive.android.sdk.util.StringUtils;
Expand Down Expand Up @@ -37,11 +38,13 @@ public class FileMessageStoreTest extends TestCaseBase {

@Rule
public TemporaryFolder tempFolder = new TemporaryFolder();
private EncryptionKey encryptionKey;

@Before
public void setUp() throws Exception {
super.setUp();
ApptentiveInternal.setInstance(new ApptentiveInternal(InstrumentationRegistry.getTargetContext()));
encryptionKey = EncryptionKey.NULL; // FIXME: generate key
}

@After
Expand All @@ -55,13 +58,13 @@ public void testAddingAndLoadingMessages() throws Exception {
File file = getTempFile();

// create a few messages and add them to the store
FileMessageStore store = new FileMessageStore(file);
FileMessageStore store = new FileMessageStore(file, encryptionKey);
store.addOrUpdateMessages(createMessage("1", State.sending, READ, 10.0));
store.addOrUpdateMessages(createMessage("2", State.sent, UNREAD, 20.0));
store.addOrUpdateMessages(createMessage("3", State.saved, READ, 30.0));

// reload store and check saved messages
store = new FileMessageStore(file);
store = new FileMessageStore(file, encryptionKey);
addResult(store.getAllMessages());

assertResult(
Expand All @@ -70,7 +73,7 @@ public void testAddingAndLoadingMessages() throws Exception {
"{'nonce':'3','client_created_at':'30','state':'saved','read':'true'}");

// reload the store again and add another message
store = new FileMessageStore(file);
store = new FileMessageStore(file, encryptionKey);
store.addOrUpdateMessages(createMessage("4", State.sent, UNREAD, 40.0));
addResult(store.getAllMessages());

Expand All @@ -87,13 +90,13 @@ public void updateMessage() throws Exception {
File file = getTempFile();

// create a few messages and add them to the store
FileMessageStore store = new FileMessageStore(file);
FileMessageStore store = new FileMessageStore(file, encryptionKey);
store.addOrUpdateMessages(createMessage("1", State.sending, READ, 10.0));
store.addOrUpdateMessages(createMessage("2", State.sent, UNREAD, 20.0));
store.addOrUpdateMessages(createMessage("3", State.saved, READ, 30.0));

// reload the store and change a single message
store = new FileMessageStore(file);
store = new FileMessageStore(file, encryptionKey);
store.updateMessage(createMessage("2", State.saved, READ, 40.0));
addResult(store.getAllMessages());

Expand All @@ -104,7 +107,7 @@ public void updateMessage() throws Exception {


// reload the store and check the stored messages
store = new FileMessageStore(file);
store = new FileMessageStore(file, encryptionKey);
addResult(store.getAllMessages());

assertResult(
Expand All @@ -118,7 +121,7 @@ public void getLastReceivedMessageId() throws Exception {
File file = getTempFile();

// create a few messages and add them to the store
FileMessageStore store = new FileMessageStore(file);
FileMessageStore store = new FileMessageStore(file, encryptionKey);
store.addOrUpdateMessages(createMessage("1", State.saved, READ, 10.0, "111"));
store.addOrUpdateMessages(createMessage("2", State.saved, UNREAD, 20.0, "222"));
store.addOrUpdateMessages(createMessage("3", State.sending, READ, 30.0, "333"));
Expand All @@ -127,7 +130,7 @@ public void getLastReceivedMessageId() throws Exception {
assertEquals("222", store.getLastReceivedMessageId());

// reload the store and check again
store = new FileMessageStore(file);
store = new FileMessageStore(file, encryptionKey);
assertEquals("222", store.getLastReceivedMessageId());
}

Expand All @@ -136,7 +139,7 @@ public void getUnreadMessageCount() throws Exception {
File file = getTempFile();

// create a few messages and add them to the store
FileMessageStore store = new FileMessageStore(file);
FileMessageStore store = new FileMessageStore(file, encryptionKey);
store.addOrUpdateMessages(createMessage("1", State.sending, READ, 10.0));
store.addOrUpdateMessages(createMessage("2", State.sent, UNREAD, 20.0));
store.addOrUpdateMessages(createMessage("3", State.saved, READ, 30.0));
Expand All @@ -145,7 +148,7 @@ public void getUnreadMessageCount() throws Exception {
assertEquals(2, store.getUnreadMessageCount());

// reload store and check saved messages
store = new FileMessageStore(file);
store = new FileMessageStore(file, encryptionKey);
assertEquals(2, store.getUnreadMessageCount());
}

Expand All @@ -154,7 +157,7 @@ public void deleteAllMessages() throws Exception {
File file = getTempFile();

// create a few messages and add them to the store
FileMessageStore store = new FileMessageStore(file);
FileMessageStore store = new FileMessageStore(file, encryptionKey);
store.addOrUpdateMessages(createMessage("1", State.sending, READ, 10.0));
store.addOrUpdateMessages(createMessage("2", State.sent, UNREAD, 20.0));
store.addOrUpdateMessages(createMessage("3", State.saved, READ, 30.0));
Expand All @@ -168,7 +171,7 @@ public void deleteAllMessages() throws Exception {
assertResult();

// reload the store and check for messages
store = new FileMessageStore(file);
store = new FileMessageStore(file, encryptionKey);
addResult(store.getAllMessages());
assertResult();
}
Expand All @@ -178,7 +181,7 @@ public void deleteAllMessagesAfterReload() throws Exception {
File file = getTempFile();

// create a few messages and add them to the store
FileMessageStore store = new FileMessageStore(file);
FileMessageStore store = new FileMessageStore(file, encryptionKey);
store.addOrUpdateMessages(createMessage("1", State.sending, READ, 10.0));
store.addOrUpdateMessages(createMessage("2", State.sent, UNREAD, 20.0));
store.addOrUpdateMessages(createMessage("3", State.saved, READ, 30.0));
Expand All @@ -188,7 +191,7 @@ public void deleteAllMessagesAfterReload() throws Exception {
store.deleteAllMessages();

// reload the store and check for messages
store = new FileMessageStore(file);
store = new FileMessageStore(file, encryptionKey);
addResult(store.getAllMessages());
assertResult();
}
Expand All @@ -198,7 +201,7 @@ public void deleteMessage() throws Exception {
File file = getTempFile();

// create a few messages and add them to the store
FileMessageStore store = new FileMessageStore(file);
FileMessageStore store = new FileMessageStore(file, encryptionKey);
store.addOrUpdateMessages(createMessage("1", State.sending, READ, 10.0));
store.addOrUpdateMessages(createMessage("2", State.sent, UNREAD, 20.0));
store.addOrUpdateMessages(createMessage("3", State.saved, READ, 30.0));
Expand All @@ -219,7 +222,7 @@ public void deleteMessageAndReload() throws Exception {
File file = getTempFile();

// create a few messages and add them to the store
FileMessageStore store = new FileMessageStore(file);
FileMessageStore store = new FileMessageStore(file, encryptionKey);
store.addOrUpdateMessages(createMessage("1", State.sending, READ, 10.0));
store.addOrUpdateMessages(createMessage("2", State.sent, UNREAD, 20.0));
store.addOrUpdateMessages(createMessage("3", State.saved, READ, 30.0));
Expand All @@ -229,7 +232,7 @@ public void deleteMessageAndReload() throws Exception {
store.deleteMessage("4");

// reload store
store = new FileMessageStore(file);
store = new FileMessageStore(file, encryptionKey);
addResult(store.getAllMessages());

assertResult(
Expand All @@ -243,7 +246,7 @@ public void deleteMessageAndReload() throws Exception {
assertResult("{'nonce':'3','client_created_at':'30','state':'saved','read':'true'}");

// reload store
store = new FileMessageStore(file);
store = new FileMessageStore(file, encryptionKey);
addResult(store.getAllMessages());

assertResult("{'nonce':'3','client_created_at':'30','state':'saved','read':'true'}");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@
* under which redistribution and use of this file is permitted.
*/

package com.apptentive.android.sdk.storage;
package com.apptentive.android.sdk.encryption;

import com.apptentive.android.sdk.TestCaseBase;
import com.apptentive.android.sdk.encryption.Encryptor;
import com.apptentive.android.sdk.model.EventPayload;

import org.json.JSONObject;
Expand All @@ -25,21 +24,16 @@ public class EncryptedPayloadSenderTest extends TestCaseBase {
@Test
public void testEncryptedPayload() throws Exception {

EncryptionKey encryptionKey = new EncryptionKey(ENCRYPTION_KEY);

final EventPayload original = new EventPayload(EVENT_LABEL, "trigger");
original.setToken(AUTH_TOKEN);
original.setEncryptionKey(ENCRYPTION_KEY);
original.setEncryptionKey(encryptionKey);

byte[] cipherText = original.renderData();

Encryptor encryptor = new Encryptor(ENCRYPTION_KEY);

try {
byte[] plainText = encryptor.decrypt(cipherText);
JSONObject result = new JSONObject(new String(plainText));
String label = result.getJSONObject("event").getString("label");
assertEquals(label, EVENT_LABEL);
} catch (Exception e) {
fail(e.getMessage());
}
byte[] plainText = Encryptor.decrypt(encryptionKey, cipherText);
JSONObject result = new JSONObject(new String(plainText));
String label = result.getJSONObject("event").getString("label");
assertEquals(label, EVENT_LABEL);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@

package com.apptentive.android.sdk.encryption;

import org.junit.Before;
import org.junit.Test;

import java.util.Arrays;
Expand All @@ -15,34 +14,30 @@
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;

import static com.apptentive.android.sdk.encryption.EncryptionKey.DEFAULT_TRANSFORMATION;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

public class EncryptorTest {

private static final int TEST_DATA_SIZE = 8096;
private Encryptor encryptor;
private byte[] testData;

@Before
public void setupEncryptor() throws Exception {
@Test
public void testRoundTripEncryption() throws Exception {
// Generate a key and setup the crypto
KeyGenerator keyGen = KeyGenerator.getInstance("AES");
keyGen.init(256);
SecretKey secretKey = keyGen.generateKey();
encryptor = new Encryptor(secretKey.getEncoded());

// Set up the test data
testData = new byte[TEST_DATA_SIZE];
byte[] testData = new byte[TEST_DATA_SIZE];
new Random().nextBytes(testData);
}

@Test
public void testRoundTripEncryption() throws Exception {
long start = System.currentTimeMillis();
byte[] cipherText = encryptor.encrypt(testData);
EncryptionKey key = new EncryptionKey(secretKey, DEFAULT_TRANSFORMATION);
byte[] cipherText = Encryptor.encrypt(key, testData);
assertNotNull(cipherText);
byte[] plainText = encryptor.decrypt(cipherText);
byte[] plainText = Encryptor.decrypt(key, cipherText);
long stop = System.currentTimeMillis();
System.out.println(String.format("Round trip encryption took: %dms", stop - start));
assertNotNull(plainText);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package com.apptentive.android.sdk.encryption;

import com.apptentive.android.sdk.InstrumentationTestCaseBase;

import org.junit.Before;
import org.junit.Test;

import java.util.Arrays;
import java.util.Random;

import static org.junit.Assert.*;

public class SecurityManagerTest extends InstrumentationTestCaseBase {
private static final int TEST_DATA_SIZE = 8096;

@Before
public void setup() {
SecurityManager.clear(getContext());
SecurityManager.init(getContext());
}

@Test
public void testDataEncryptionDecryption() throws Exception {
EncryptionKey key = SecurityManager.getMasterKey();

// Set up the test data
byte[] testData = new byte[TEST_DATA_SIZE];
new Random().nextBytes(testData);

byte[] cipherText = Encryptor.encrypt(key, testData);
assertNotNull(cipherText);

byte[] plainText = Encryptor.decrypt(key, cipherText);
assertNotNull(plainText);

assertTrue(Arrays.equals(plainText, testData));
}

@Test
public void testStringEncryptionDecryption() throws Exception {
EncryptionKey key = SecurityManager.getMasterKey();

// Set up the test data
String testData = "Test data";

byte[] cipherText = Encryptor.encrypt(key, testData);
assertNotNull(cipherText);

String plainText = Encryptor.decryptString(key, cipherText);
assertNotNull(plainText);

assertEquals(plainText, testData);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;

import com.apptentive.android.sdk.encryption.EncryptionKey;
import com.apptentive.android.sdk.model.AppReleasePayload;
import com.apptentive.android.sdk.model.DevicePayload;
import com.apptentive.android.sdk.model.EventPayload;
Expand Down Expand Up @@ -88,7 +89,7 @@ class ApptentiveDatabaseMockHelper extends ApptentiveDatabaseHelper {
" ORDER BY " + PayloadEntry.COLUMN_PRIMARY_KEY;

ApptentiveDatabaseMockHelper(Context context) {
super(context);
super(context, EncryptionKey.NULL);
}

List<Payload> listPayloads(SQLiteDatabase db) throws JSONException {
Expand Down
Loading

0 comments on commit f3e8898

Please sign in to comment.