/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.devicepolicy.cts;

import static com.android.bedstead.remotedpc.RemoteDpc.DPC_COMPONENT_NAME;

import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.assertThrows;

import static java.util.Collections.singleton;

import android.content.Context;
import android.net.Uri;
import android.os.Process;
import android.security.KeyChain;
import android.security.KeyChainException;

import com.android.activitycontext.ActivityContext;
import com.android.bedstead.harrier.BedsteadJUnit4;
import com.android.bedstead.harrier.DeviceState;
import com.android.bedstead.harrier.annotations.Postsubmit;
import com.android.bedstead.harrier.annotations.enterprise.CanSetPolicyTest;
import com.android.bedstead.harrier.annotations.enterprise.PositivePolicyTest;
import com.android.bedstead.harrier.policies.KeyManagement;
import com.android.bedstead.nene.TestApis;
import com.android.compatibility.common.util.BlockingCallback;
import com.android.compatibility.common.util.FakeKeys;

import org.junit.ClassRule;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.testng.Assert;

import java.io.ByteArrayInputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Test that a DPC can manage keys and certificate on a device by installing, generating and
 * removing key pairs via DevicePolicyManager APIs. The instrumented test app can use the installed
 * keys by requesting access to them and retrieving them via KeyChain APIs.
 */
@RunWith(BedsteadJUnit4.class)
public final class KeyManagementTest {

    @ClassRule
    @Rule
    public static final DeviceState sDeviceState = new DeviceState();
    private static final int KEYCHAIN_CALLBACK_TIMEOUT_SECONDS = 600;
    private static final String RSA = "RSA";
    private static final String RSA_ALIAS = "com.android.test.valid-rsa-key-1";
    private static final PrivateKey PRIVATE_KEY =
            generatePrivateKey(FakeKeys.FAKE_RSA_1.privateKey, RSA);
    private static final Certificate CERTIFICATE =
            generateCertificate(FakeKeys.FAKE_RSA_1.caCertificate);
    private static final Certificate[] CERTIFICATES = new Certificate[]{CERTIFICATE};
    private static final String NON_EXISTENT_ALIAS = "KeyManagementTest-nonexistent";
    private static final Context sContext = TestApis.context().instrumentedContext();

    private static Uri getUri(String alias) {
        try {
            return Uri.parse("https://example.org/?alias=" + URLEncoder.encode(alias, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            throw new AssertionError("Unable to parse URI." + e);
        }
    }

    private static void choosePrivateKeyAlias(KeyChainAliasCallback callback, String alias) {
        /* Pass the alias as a GET to an imaginary server instead of explicitly asking for it,
         * to make sure the DPC actually has to do some work to grant the cert.
         */
        try {
            ActivityContext.runWithContext(
                    (activity) -> KeyChain.choosePrivateKeyAlias(activity, callback, /* keyTypes= */
                            null, /* issuers= */ null, getUri(alias), /* alias = */ null)
            );
        } catch (InterruptedException e) {
            throw new AssertionError("Unable to choose private key alias." + e);
        }
    }

    private static PrivateKey getPrivateKey(Context context, String alias) {
        try {
            return KeyChain.getPrivateKey(context, alias);
        } catch (KeyChainException | InterruptedException e) {
            throw new AssertionError("Failed to get private key." + e);
        }
    }

    private static PrivateKey generatePrivateKey(final byte[] key, String type) {
        try {
            return KeyFactory.getInstance(type).generatePrivate(
                    new PKCS8EncodedKeySpec(key));
        } catch (InvalidKeySpecException | NoSuchAlgorithmException e) {
            throw new AssertionError("Unable to get private key." + e);
        }
    }

    private static Certificate generateCertificate(byte[] cert) {
        try {
            return CertificateFactory.getInstance("X.509").generateCertificate(
                    new ByteArrayInputStream(cert));
        } catch (CertificateException e) {
            throw new AssertionError("Unable to get certificate." + e);
        }
    }

    @Test
    @Postsubmit(reason = "new test")
    @CanSetPolicyTest(policy = KeyManagement.class)
    public void installKeyPair_validRsaKeyPair_success() {
        try {
            // Install keypair
            assertThat(sDeviceState.dpc().devicePolicyManager()
                    .installKeyPair(DPC_COMPONENT_NAME, PRIVATE_KEY, CERTIFICATE,
                            RSA_ALIAS)).isTrue();
        } finally {
            // Remove keypair
            sDeviceState.dpc().devicePolicyManager().removeKeyPair(DPC_COMPONENT_NAME, RSA_ALIAS);
        }
    }

    @Test
    @Postsubmit(reason = "new test")
    @CanSetPolicyTest(policy = KeyManagement.class, singleTestOnly = true)
    public void installKeyPair_nullPrivateKey_throwException() {
        assertThrows(NullPointerException.class,
                () -> sDeviceState.dpc().devicePolicyManager().installKeyPair(
                        DPC_COMPONENT_NAME, /* privKey = */ null, CERTIFICATE, RSA_ALIAS));
    }

    @Test
    @Postsubmit(reason = "new test")
    @CanSetPolicyTest(policy = KeyManagement.class, singleTestOnly = true)
    public void installKeyPair_nullCertificate_throwException() {
        assertThrows(NullPointerException.class,
                () -> sDeviceState.dpc().devicePolicyManager().installKeyPair(
                        DPC_COMPONENT_NAME, PRIVATE_KEY, /* cert = */ null, RSA_ALIAS));
    }

    @Test
    @Postsubmit(reason = "new test")
    @CanSetPolicyTest(policy = KeyManagement.class, singleTestOnly = true)
    public void installKeyPair_nullAdminComponent_throwException() {
        assertThrows(SecurityException.class,
                () -> sDeviceState.dpc().devicePolicyManager().installKeyPair(
                        /* admin = */ null, PRIVATE_KEY, CERTIFICATE, RSA_ALIAS));
    }

    @Test
    @Ignore("TODO(b/204544463): Enable when the key can be serialized")
    @Postsubmit(reason = "new test")
    @CanSetPolicyTest(policy = KeyManagement.class)
    public void installKeyPair_withAutomatedAccess_aliasIsGranted() throws Exception {
        try {
            // Install keypair with automated access
            sDeviceState.dpc().devicePolicyManager().installKeyPair(DPC_COMPONENT_NAME, PRIVATE_KEY,
                    CERTIFICATES, RSA_ALIAS, /* requestAccess = */ true);

            // TODO(b/204544478): Remove the null context
            assertThat(sDeviceState.dpc().keyChain().getPrivateKey(/* context= */ null, RSA_ALIAS))
                    .isNotNull();
        } finally {
            // Remove keypair
            sDeviceState.dpc().devicePolicyManager().removeKeyPair(DPC_COMPONENT_NAME, RSA_ALIAS);
        }
    }

    @Test
    @Postsubmit(reason = "new test")
    @CanSetPolicyTest(policy = KeyManagement.class)
    public void installKeyPair_withoutAutomatedAccess_aliasIsNotGranted() throws Exception {
        try {
            // Install keypair with automated access
            sDeviceState.dpc().devicePolicyManager().installKeyPair(DPC_COMPONENT_NAME, PRIVATE_KEY,
                    CERTIFICATES, RSA_ALIAS, /* requestAccess = */ false);

            // TODO(b/204544478): Remove the null context
            assertThat(sDeviceState.dpc().keyChain().getPrivateKey(/* context= */ null, RSA_ALIAS))
                    .isNull();
        } finally {
            // Remove keypair
            sDeviceState.dpc().devicePolicyManager().removeKeyPair(DPC_COMPONENT_NAME, RSA_ALIAS);
        }
    }

    @Test
    @Postsubmit(reason = "new test")
    @CanSetPolicyTest(policy = KeyManagement.class)
    public void removeKeyPair_validRsaKeyPair_success() {
        try {
            // Install keypair
            sDeviceState.dpc().devicePolicyManager()
                    .installKeyPair(DPC_COMPONENT_NAME, PRIVATE_KEY, CERTIFICATE, RSA_ALIAS);
        } finally {
            // Remove keypair
            assertThat(sDeviceState.dpc().devicePolicyManager()
                    .removeKeyPair(DPC_COMPONENT_NAME, RSA_ALIAS)).isTrue();
        }
    }

    @Test
    @Postsubmit(reason = "new test")
    @CanSetPolicyTest(policy = KeyManagement.class)
    public void hasKeyPair_nonExistentAlias_false() {
        assertThat(
                sDeviceState.dpc().devicePolicyManager().hasKeyPair(NON_EXISTENT_ALIAS)).isFalse();
    }

    @Test
    @Postsubmit(reason = "new test")
    @CanSetPolicyTest(policy = KeyManagement.class)
    public void hasKeyPair_installedAlias_true() {
        try {
            // Install keypair
            sDeviceState.dpc().devicePolicyManager()
                    .installKeyPair(DPC_COMPONENT_NAME, PRIVATE_KEY, CERTIFICATE, RSA_ALIAS);

            assertThat(sDeviceState.dpc().devicePolicyManager().hasKeyPair(RSA_ALIAS)).isTrue();
        } finally {
            // Remove keypair
            sDeviceState.dpc().devicePolicyManager().removeKeyPair(DPC_COMPONENT_NAME, RSA_ALIAS);
        }
    }

    @Test
    @Postsubmit(reason = "new test")
    @CanSetPolicyTest(policy = KeyManagement.class)
    public void hasKeyPair_removedAlias_false() {
        try {
            // Install keypair
            sDeviceState.dpc().devicePolicyManager()
                    .installKeyPair(DPC_COMPONENT_NAME, PRIVATE_KEY, CERTIFICATE, RSA_ALIAS);
            sDeviceState.dpc().devicePolicyManager().removeKeyPair(DPC_COMPONENT_NAME, RSA_ALIAS);

            assertThat(sDeviceState.dpc().devicePolicyManager().hasKeyPair(RSA_ALIAS)).isFalse();
        } finally {
            // Remove keypair
            sDeviceState.dpc().devicePolicyManager().removeKeyPair(DPC_COMPONENT_NAME, RSA_ALIAS);
        }
    }

    @Test
    @Postsubmit(reason = "new test")
    @PositivePolicyTest(policy = KeyManagement.class)
    public void choosePrivateKeyAlias_aliasIsSelectedByAdmin_returnAlias() throws Exception {
        try {
            // Install keypair
            sDeviceState.dpc().devicePolicyManager()
                    .installKeyPair(DPC_COMPONENT_NAME, PRIVATE_KEY, CERTIFICATE, RSA_ALIAS);
            KeyChainAliasCallback callback = new KeyChainAliasCallback();

            choosePrivateKeyAlias(callback, RSA_ALIAS);

            assertThat(callback.await(KEYCHAIN_CALLBACK_TIMEOUT_SECONDS, TimeUnit.SECONDS))
                    .isEqualTo(RSA_ALIAS);
        } finally {
            // Remove keypair
            sDeviceState.dpc().devicePolicyManager().removeKeyPair(DPC_COMPONENT_NAME, RSA_ALIAS);
        }
    }

    @Test
    @Postsubmit(reason = "new test")
    @PositivePolicyTest(policy = KeyManagement.class)
    public void choosePrivateKeyAlias_nonUserSelectedAliasIsSelectedByAdmin_returnAlias()
            throws Exception {
        try {
            // Install keypair which is not user selectable
            sDeviceState.dpc().devicePolicyManager().installKeyPair(DPC_COMPONENT_NAME, PRIVATE_KEY,
                    CERTIFICATES, RSA_ALIAS, /* flags = */ 0);
            KeyChainAliasCallback callback = new KeyChainAliasCallback();

            choosePrivateKeyAlias(callback, RSA_ALIAS);

            assertThat(callback.await(KEYCHAIN_CALLBACK_TIMEOUT_SECONDS, TimeUnit.SECONDS))
                    .isEqualTo(RSA_ALIAS);
        } finally {
            // Remove keypair
            sDeviceState.dpc().devicePolicyManager().removeKeyPair(DPC_COMPONENT_NAME, RSA_ALIAS);
        }
    }

    @Test
    @Postsubmit(reason = "new test")
    @PositivePolicyTest(policy = KeyManagement.class)
    public void getPrivateKey_aliasIsGranted_returnPrivateKey() throws Exception {
        try {
            // Install keypair
            sDeviceState.dpc().devicePolicyManager()
                    .installKeyPair(DPC_COMPONENT_NAME, PRIVATE_KEY, CERTIFICATE, RSA_ALIAS);
            // Grant alias via {@code KeyChain.choosePrivateKeyAlias}
            KeyChainAliasCallback callback = new KeyChainAliasCallback();
            choosePrivateKeyAlias(callback, RSA_ALIAS);
            callback.await(KEYCHAIN_CALLBACK_TIMEOUT_SECONDS, TimeUnit.SECONDS);

            // Get private key for the granted alias
            final PrivateKey privateKey =
                    getPrivateKey(TestApis.context().instrumentedContext(), RSA_ALIAS);

            assertThat(privateKey).isNotNull();
            assertThat(privateKey.getAlgorithm()).isEqualTo(RSA);

        } finally {
            // Remove keypair
            sDeviceState.dpc().devicePolicyManager().removeKeyPair(DPC_COMPONENT_NAME, RSA_ALIAS);
        }
    }

    @Test
    @Postsubmit(reason = "new test")
    @CanSetPolicyTest(policy = KeyManagement.class)
    public void install_wasPreviouslyGrantedOnPreviousInstall_grantDoesNotPersist()
            throws Exception {
        try {
            sDeviceState.dpc().devicePolicyManager()
                    .installKeyPair(DPC_COMPONENT_NAME, PRIVATE_KEY, CERTIFICATES, RSA_ALIAS, true);
            sDeviceState.dpc().devicePolicyManager().removeKeyPair(DPC_COMPONENT_NAME, RSA_ALIAS);

            sDeviceState.dpc().devicePolicyManager()
                    .installKeyPair(DPC_COMPONENT_NAME, PRIVATE_KEY, CERTIFICATES, RSA_ALIAS,
                            false);

            assertThat(sDeviceState.dpc().keyChain().getPrivateKey(
                    TestApis.context().instrumentedContext(), RSA_ALIAS))
                    .isNull();
        } finally {
            // Remove keypair
            sDeviceState.dpc().devicePolicyManager().removeKeyPair(DPC_COMPONENT_NAME, RSA_ALIAS);
        }
    }

    @Test
    @Postsubmit(reason = "new test")
    @CanSetPolicyTest(policy = KeyManagement.class, singleTestOnly = true)
    public void getKeyPairGrants_nonExistent_throwsIllegalArgumentException() {
        Assert.assertThrows(IllegalArgumentException.class,
                () -> sDeviceState.dpc().devicePolicyManager()
                        .getKeyPairGrants(NON_EXISTENT_ALIAS));
    }

    @Test
    @Postsubmit(reason = "new test")
    @CanSetPolicyTest(policy = KeyManagement.class)
    public void getKeyPairGrants_doesNotIncludeNotGranted() {
        try {
            sDeviceState.dpc().devicePolicyManager().installKeyPair(
                    DPC_COMPONENT_NAME, PRIVATE_KEY, CERTIFICATES,
                    RSA_ALIAS, /* requestAccess= */ false);

            assertThat(
                    sDeviceState.dpc().devicePolicyManager().getKeyPairGrants(RSA_ALIAS)).isEmpty();
        } finally {
            // Remove keypair
            sDeviceState.dpc().devicePolicyManager().removeKeyPair(DPC_COMPONENT_NAME, RSA_ALIAS);
        }
    }

    @Test
    @Postsubmit(reason = "new test")
    @CanSetPolicyTest(policy = KeyManagement.class)
    public void getKeyPairGrants_includesGrantedAtInstall() {
        try {
            sDeviceState.dpc().devicePolicyManager().installKeyPair(
                    DPC_COMPONENT_NAME, PRIVATE_KEY, CERTIFICATES,
                    RSA_ALIAS, /* requestAccess= */ true);

            assertThat(sDeviceState.dpc().devicePolicyManager().getKeyPairGrants(RSA_ALIAS))
                    .isEqualTo(Map.of(sDeviceState.dpc().process().uid(),
                            singleton(sDeviceState.dpc().componentName().getPackageName())));
        } finally {
            // Remove keypair
            sDeviceState.dpc().devicePolicyManager().removeKeyPair(DPC_COMPONENT_NAME, RSA_ALIAS);
        }
    }

    @Test
    @Postsubmit(reason = "new test")
    @PositivePolicyTest(policy = KeyManagement.class)
    public void getKeyPairGrants_includesGrantedExplicitly() {
        try {
            sDeviceState.dpc().devicePolicyManager().installKeyPair(
                    DPC_COMPONENT_NAME, PRIVATE_KEY, CERTIFICATES,
                    RSA_ALIAS, /* requestAccess= */ false);
            sDeviceState.dpc().devicePolicyManager().grantKeyPairToApp(
                    DPC_COMPONENT_NAME, RSA_ALIAS,
                    sContext.getPackageName());

            assertThat(sDeviceState.dpc().devicePolicyManager().getKeyPairGrants(RSA_ALIAS))
                    .isEqualTo(Map.of(Process.myUid(),
                            singleton(sContext.getPackageName())));
        } finally {
            // Remove keypair
            sDeviceState.dpc().devicePolicyManager().removeKeyPair(DPC_COMPONENT_NAME, RSA_ALIAS);
        }
    }

    @Test
    @Postsubmit(reason = "new test")
    @CanSetPolicyTest(policy = KeyManagement.class)
    public void getKeyPairGrants_doesNotIncludeRevoked() {
        try {
            sDeviceState.dpc().devicePolicyManager().installKeyPair(
                    DPC_COMPONENT_NAME, PRIVATE_KEY, CERTIFICATES,
                    RSA_ALIAS, /* requestAccess= */ true);
            sDeviceState.dpc().devicePolicyManager().revokeKeyPairFromApp(
                    DPC_COMPONENT_NAME, RSA_ALIAS,
                    sDeviceState.dpc().componentName().getPackageName());

            assertThat(
                    sDeviceState.dpc().devicePolicyManager().getKeyPairGrants(RSA_ALIAS)).isEmpty();
        } finally {
            // Remove keypair
            sDeviceState.dpc().devicePolicyManager().removeKeyPair(DPC_COMPONENT_NAME, RSA_ALIAS);
        }
    }

    @Test
    @Postsubmit(reason = "new test")
    @CanSetPolicyTest(policy = KeyManagement.class)
    public void isKeyPairGrantedToWifiAuth_default_returnsFalse() {
        try {
            sDeviceState.dpc().devicePolicyManager().installKeyPair(
                    DPC_COMPONENT_NAME, PRIVATE_KEY, CERTIFICATES,
                    RSA_ALIAS, /* requestAccess= */ false);

            assertThat(
                    sDeviceState.dpc().devicePolicyManager().isKeyPairGrantedToWifiAuth(RSA_ALIAS))
                    .isFalse();
        } finally {
            // Remove keypair
            sDeviceState.dpc().devicePolicyManager().removeKeyPair(DPC_COMPONENT_NAME, RSA_ALIAS);
        }
    }

    @Test
    @Postsubmit(reason = "new test")
    @CanSetPolicyTest(policy = KeyManagement.class)
    public void isKeyPairGrantedToWifiAuth_granted_returnsTrue() {
        try {
            sDeviceState.dpc().devicePolicyManager().installKeyPair(
                    DPC_COMPONENT_NAME, PRIVATE_KEY, CERTIFICATES,
                    RSA_ALIAS, /* requestAccess= */ false);
            sDeviceState.dpc().devicePolicyManager().grantKeyPairToWifiAuth(RSA_ALIAS);

            assertThat(
                    sDeviceState.dpc().devicePolicyManager().isKeyPairGrantedToWifiAuth(RSA_ALIAS))
                    .isTrue();
        } finally {
            // Remove keypair
            sDeviceState.dpc().devicePolicyManager().removeKeyPair(DPC_COMPONENT_NAME, RSA_ALIAS);
        }
    }

    @Test
    @Postsubmit(reason = "new test")
    @CanSetPolicyTest(policy = KeyManagement.class)
    public void isKeyPairGrantedToWifiAuth_revoked_returnsFalse() {
        try {
            sDeviceState.dpc().devicePolicyManager().installKeyPair(
                    DPC_COMPONENT_NAME, PRIVATE_KEY, CERTIFICATES,
                    RSA_ALIAS, /* requestAccess= */ false);
            sDeviceState.dpc().devicePolicyManager().grantKeyPairToWifiAuth(RSA_ALIAS);
            sDeviceState.dpc().devicePolicyManager().revokeKeyPairFromWifiAuth(RSA_ALIAS);

            assertThat(
                    sDeviceState.dpc().devicePolicyManager().isKeyPairGrantedToWifiAuth(RSA_ALIAS))
                    .isFalse();
        } finally {
            // Remove keypair
            sDeviceState.dpc().devicePolicyManager().removeKeyPair(DPC_COMPONENT_NAME, RSA_ALIAS);
        }
    }

    @Test
    @Postsubmit(reason = "new test")
    @PositivePolicyTest(policy = KeyManagement.class)
    public void grantKeyPair_keyUsable() throws Exception {
        try {
            sDeviceState.dpc().devicePolicyManager().installKeyPair(
                    DPC_COMPONENT_NAME, PRIVATE_KEY, CERTIFICATES,
                    RSA_ALIAS, /* requestAccess= */ false);
            sDeviceState.dpc().devicePolicyManager().grantKeyPairToApp(
                    DPC_COMPONENT_NAME, RSA_ALIAS, sContext.getPackageName()
            );

            PrivateKey key = KeyChain.getPrivateKey(sContext, RSA_ALIAS);

            signDataWithKey("SHA256withRSA", key); // Doesn't throw exception
        } finally {
            // Remove keypair
            sDeviceState.dpc().devicePolicyManager().removeKeyPair(DPC_COMPONENT_NAME, RSA_ALIAS);
        }
    }

    @Test
    @Postsubmit(reason = "new test")
    @PositivePolicyTest(policy = KeyManagement.class)
    public void revokeKeyPairFromApp_keyNotUsable() throws Exception {
        try {
            sDeviceState.dpc().devicePolicyManager().installKeyPair(
                    DPC_COMPONENT_NAME, PRIVATE_KEY, CERTIFICATES,
                    RSA_ALIAS, /* requestAccess= */ false);
            sDeviceState.dpc().devicePolicyManager().grantKeyPairToApp(
                    DPC_COMPONENT_NAME, RSA_ALIAS, sContext.getPackageName()
            );
            // Key is requested from KeyChain prior to revoking the grant.
            PrivateKey key = KeyChain.getPrivateKey(sContext, RSA_ALIAS);

            sDeviceState.dpc().devicePolicyManager().revokeKeyPairFromApp(
                    DPC_COMPONENT_NAME, RSA_ALIAS, sContext.getPackageName());

            // Key shouldn't be valid after the grant is revoked.
            Assert.assertThrows(
                    InvalidKeyException.class, () -> signDataWithKey("SHA256withRSA", key));
        } finally {
            // Remove keypair
            sDeviceState.dpc().devicePolicyManager().removeKeyPair(DPC_COMPONENT_NAME, RSA_ALIAS);
        }
    }

    private byte[] signDataWithKey(String algoIdentifier, PrivateKey privateKey) throws Exception {
        byte[] data = "hello".getBytes();
        Signature sign = Signature.getInstance(algoIdentifier);
        sign.initSign(privateKey);
        sign.update(data);
        return sign.sign();
    }

    private static class KeyChainAliasCallback extends BlockingCallback<String> implements
            android.security.KeyChainAliasCallback {

        @Override
        public void alias(final String chosenAlias) {
            callbackTriggered(chosenAlias);
        }
    }
}
