Commit 9f6ec5ba authored by Lukas Gehrke's avatar Lukas Gehrke
Browse files

Make Fake In work with custom checkin data.

parent 2524e4ac
......@@ -2,6 +2,7 @@ package de.culture4life.luca.fake;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.util.Pair;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
......@@ -68,7 +69,7 @@ public class FakeManager extends Manager {
}
public static final MediaType JSON
= MediaType.parse("application/json");
= MediaType.parse("application/json; charset=utf-8");
@Override
protected Completable doInitialize(@NonNull Context context) {
......@@ -140,85 +141,100 @@ public class FakeManager extends Manager {
VenueData venueData = new VenueData(cryptoManager, checkInManager, scannerId, deviceData);
CheckinData checkinData = new CheckinData(deviceData, venueData);
CheckInRequestData checkInRequestData = CheckinData.map(checkinData);
String json = serializeToJson(checkInRequestData).blockingGet();
// Try with custom POST
// String json = serializeToJson(checkInRequestData).blockingGet();
// postCheckIn(json);
UUID userId = doFakeRegistration();
handleCheckin(scannerId, userId);
// Try with NetworkManager
// networkManager.getLucaEndpointsV3().blockingGet().checkIn(checkInRequestData);
handleCheckinDirectly(checkInRequestData);
// Try with CheckinManager and NetworkManager - persistence alarm
// UUID userId = doFakeRegistration();
// handleCheckin(scannerId, userId);
}
private void handleCheckin(UUID scannerId, UUID userId) {
modelDisposable.add(performSelfCheckIn(scannerId, userId)
private void handleCheckinDirectly(CheckInRequestData checkInRequestData) {
modelDisposable.add(networkManager.getLucaEndpointsV3().blockingGet().checkIn(checkInRequestData)
.subscribe(
() -> Timber.d("Successfully checked in"),
throwable -> Timber.w("Unable to check in: %s", throwable.toString())
));
}
private Completable performSelfCheckIn(UUID scannerId, UUID userId) {
return generateQrCodeData(userId)
.flatMapCompletable(qrCodeData -> checkInManager.checkInLean(scannerId, qrCodeData));
}
// What the heck do these people write terrible code
public Single<QrCodeData> generateQrCodeData(UUID userId) {
return Single.just(new QrCodeData())
.flatMap(qrCodeData -> cryptoManager.getTraceIdWrapper(userId)
.flatMapCompletable(userTraceIdWrapper -> Completable.mergeArray(
cryptoManager.getDailyKeyPairPublicKeyWrapper()
.map(DailyKeyPairPublicKeyWrapper::getId)
.doOnSuccess(qrCodeData::setKeyId)
.ignoreElement(),
cryptoManager.getUserEphemeralKeyPair(userTraceIdWrapper.getTraceId())
.observeOn(Schedulers.computation())
.flatMapCompletable(keyPair -> Completable.mergeArray(
encryptUserIdAndSecret(userId, keyPair)
.doOnSuccess(encryptedDataAndIv -> qrCodeData.setEncryptedData(encryptedDataAndIv.first))
.flatMap(encryptedDataAndIv -> generateVerificationTag(encryptedDataAndIv.first, userTraceIdWrapper.getTimestamp())
.doOnSuccess(qrCodeData::setVerificationTag))
.ignoreElement(),
Single.just(keyPair.getPublic())
.cast(ECPublicKey.class)
.flatMap(publicKey -> AsymmetricCipherProvider.encode(publicKey, true))
.doOnSuccess(qrCodeData::setUserEphemeralPublicKey)
.ignoreElement()
)),
TimeUtil.encodeUnixTimestamp(userTraceIdWrapper.getTimestamp())
.doOnSuccess(qrCodeData::setTimestamp)
.ignoreElement(),
Completable.fromAction(() -> qrCodeData.setTraceId(userTraceIdWrapper.getTraceId()))))
.andThen(Single.just(qrCodeData)));
}
private Single<android.util.Pair<byte[], byte[]>> encryptUserIdAndSecret(@NonNull UUID userId, @NonNull KeyPair userEphemeralKeyPair) {
return Single.just(userEphemeralKeyPair.getPublic())
.cast(ECPublicKey.class)
.flatMap(publicKey -> AsymmetricCipherProvider.encode(publicKey, true))
.flatMap(encodedPublicKey -> CryptoManager.trim(encodedPublicKey, 16))
.flatMap(iv -> encryptUserIdAndSecret(userId, userEphemeralKeyPair.getPrivate(), iv)
.map(bytes -> new android.util.Pair<>(bytes, iv)));
}
private Single<byte[]> encryptUserIdAndSecret(@NonNull UUID userId, @NonNull PrivateKey userEphemeralPrivateKey, @NonNull byte[] iv) {
return cryptoManager.getDataSecret()
.flatMap(userDataSecret -> CryptoManager.encode(userId)
.flatMap(encodedUserId -> CryptoManager.concatenate(encodedUserId, userDataSecret)))
.flatMap(encodedData -> cryptoManager.generateEphemeralDiffieHellmanSecret(userEphemeralPrivateKey)
.flatMap(cryptoManager::generateDataEncryptionSecret)
.flatMap(CryptoManager::createKeyFromSecret)
.flatMap(encodingKey -> cryptoManager.getSymmetricCipherProvider().encrypt(encodedData, iv, encodingKey)));
}
private Single<byte[]> generateVerificationTag(@NonNull byte[] encryptedUserIdAndSecret, long roundedUnixTimestamp) {
return TimeUtil.encodeUnixTimestamp(roundedUnixTimestamp)
.flatMap(encodedTimestamp -> CryptoManager.concatenate(encodedTimestamp, encryptedUserIdAndSecret))
.flatMap(encodedData -> cryptoManager.getDataSecret()
.flatMap(cryptoManager::generateDataAuthenticationSecret)
.flatMap(CryptoManager::createKeyFromSecret)
.flatMap(dataAuthenticationKey -> cryptoManager.getMacProvider().sign(encodedData, dataAuthenticationKey)))
.flatMap(verificationTag -> CryptoManager.trim(verificationTag, 8))
.doOnSuccess(verificationTag -> Timber.d("Generated new verification tag: %s", SerializationUtil.serializeToBase64(verificationTag).blockingGet()));
}
// private void handleCheckin(UUID scannerId, UUID userId) {
// modelDisposable.add(performSelfCheckIn(scannerId, userId)
// .subscribe(
// () -> Timber.d("Successfully checked in"),
// throwable -> Timber.w("Unable to check in: %s", throwable.toString())
// ));
// }
//
// private Completable performSelfCheckIn(UUID scannerId, UUID userId) {
// return generateQrCodeData(userId)
// .flatMapCompletable(qrCodeData -> checkInManager.checkInLean(scannerId, qrCodeData));
// }
//
// // What the heck do these people write terrible code
// public Single<QrCodeData> generateQrCodeData(UUID userId) {
// return Single.just(new QrCodeData())
// .flatMap(qrCodeData -> cryptoManager.getTraceIdWrapper(userId)
// .flatMapCompletable(userTraceIdWrapper -> Completable.mergeArray(
// cryptoManager.getDailyKeyPairPublicKeyWrapper()
// .map(DailyKeyPairPublicKeyWrapper::getId)
// .doOnSuccess(qrCodeData::setKeyId)
// .ignoreElement(),
// cryptoManager.getUserEphemeralKeyPair(userTraceIdWrapper.getTraceId())
// .observeOn(Schedulers.computation())
// .flatMapCompletable(keyPair -> Completable.mergeArray(
// encryptUserIdAndSecret(userId, keyPair)
// .doOnSuccess(encryptedDataAndIv -> qrCodeData.setEncryptedData(encryptedDataAndIv.first))
// .flatMap(encryptedDataAndIv -> generateVerificationTag(encryptedDataAndIv.first, userTraceIdWrapper.getTimestamp())
// .doOnSuccess(qrCodeData::setVerificationTag))
// .ignoreElement(),
// Single.just(keyPair.getPublic())
// .cast(ECPublicKey.class)
// .flatMap(publicKey -> AsymmetricCipherProvider.encode(publicKey, true))
// .doOnSuccess(qrCodeData::setUserEphemeralPublicKey)
// .ignoreElement()
// )),
// TimeUtil.encodeUnixTimestamp(userTraceIdWrapper.getTimestamp())
// .doOnSuccess(qrCodeData::setTimestamp)
// .ignoreElement(),
// Completable.fromAction(() -> qrCodeData.setTraceId(userTraceIdWrapper.getTraceId()))))
// .andThen(Single.just(qrCodeData)));
// }
//
// private Single<android.util.Pair<byte[], byte[]>> encryptUserIdAndSecret(@NonNull UUID userId, @NonNull KeyPair userEphemeralKeyPair) {
// return Single.just(userEphemeralKeyPair.getPublic())
// .cast(ECPublicKey.class)
// .flatMap(publicKey -> AsymmetricCipherProvider.encode(publicKey, true))
// .flatMap(encodedPublicKey -> CryptoManager.trim(encodedPublicKey, 16))
// .flatMap(iv -> encryptUserIdAndSecret(userId, userEphemeralKeyPair.getPrivate(), iv)
// .map(bytes -> new android.util.Pair<>(bytes, iv)));
// }
//
// private Single<byte[]> encryptUserIdAndSecret(@NonNull UUID userId, @NonNull PrivateKey userEphemeralPrivateKey, @NonNull byte[] iv) {
// return cryptoManager.getDataSecret()
// .flatMap(userDataSecret -> CryptoManager.encode(userId)
// .flatMap(encodedUserId -> CryptoManager.concatenate(encodedUserId, userDataSecret)))
// .flatMap(encodedData -> cryptoManager.generateEphemeralDiffieHellmanSecret(userEphemeralPrivateKey)
// .flatMap(cryptoManager::generateDataEncryptionSecret)
// .flatMap(CryptoManager::createKeyFromSecret)
// .flatMap(encodingKey -> cryptoManager.getSymmetricCipherProvider().encrypt(encodedData, iv, encodingKey)));
// }
//
// private Single<byte[]> generateVerificationTag(@NonNull byte[] encryptedUserIdAndSecret, long roundedUnixTimestamp) {
// return TimeUtil.encodeUnixTimestamp(roundedUnixTimestamp)
// .flatMap(encodedTimestamp -> CryptoManager.concatenate(encodedTimestamp, encryptedUserIdAndSecret))
// .flatMap(encodedData -> cryptoManager.getDataSecret()
// .flatMap(cryptoManager::generateDataAuthenticationSecret)
// .flatMap(CryptoManager::createKeyFromSecret)
// .flatMap(dataAuthenticationKey -> cryptoManager.getMacProvider().sign(encodedData, dataAuthenticationKey)))
// .flatMap(verificationTag -> CryptoManager.trim(verificationTag, 8))
// .doOnSuccess(verificationTag -> Timber.d("Generated new verification tag: %s", SerializationUtil.serializeToBase64(verificationTag).blockingGet()));
// }
public static byte[] generateRandomData(Integer length) {
SecureRandom random = new SecureRandom();
......@@ -244,27 +260,28 @@ public class FakeManager extends Manager {
}
// Not working, may delete later
private void postCheckIn(String json) throws IOException {
try {
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(json, JSON);
Request request = new Request.Builder()
.url("https://10.0.2.2/api/v3/traces/checkin")
.post(body)
.build();
System.out.println("Request Body:");
System.out.println(request.body().toString());
Call call = client.newCall(request);
Response response = call.execute();
} catch (IOException e) {
e.printStackTrace();
}
}
// https://square.github.io/okhttp/
// https://stackoverflow.com/questions/6343166/how-can-i-fix-android-os-networkonmainthreadexception
// private void postCheckIn(String json) throws IOException {
//
// try {
// OkHttpClient client = new OkHttpClient();
//
// RequestBody body = RequestBody.create(json, JSON);
//
// Request request = new Request.Builder()
// .url("https://10.0.2.2/api/v3/traces/checkin")
// .post(body)
// .build();
//
// System.out.println("Request Body:");
// System.out.println(request.body().toString());
// Call call = client.newCall(request);
// Response response = call.execute();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
}
class CheckinData {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment