blob: 8634bc0b380eb74e78e28f4001959ba61d428a70 [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package io.v.android.apps.account_manager;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import com.google.common.base.Joiner;
import java.security.interfaces.ECPublicKey;
import java.util.Map;
import io.v.android.v23.V;
import io.v.android.v23.services.blessing.BlessingService;
import io.v.v23.context.VContext;
import io.v.v23.security.BlessingPattern;
import io.v.v23.security.Blessings;
import io.v.v23.verror.VException;
import io.v.v23.vom.VomUtil;
/**
* Mints a new set of Vanadium {@link Blessings} for the invoking application.
*/
public class LocalBlessingActivity extends Activity {
public static final String TAG = "LocalBlessingActivity";
private static final int REQUEST_CODE_BLESS = 1000;
private static final int REQUEST_CODE_CREATE_ACCOUNT = 1001;
private VContext mBaseContext;
private String mBlesseePkgName;
private ECPublicKey mBlesseePubKey;
private String mGoogleAccount;
private byte[] mBlessWithVom = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mBaseContext = V.init(this);
// Get the name of the application invoking this activity.
Intent intent = getIntent();
if (intent == null || intent.getExtras() == null) {
replyWithError("No extras provided.");
return;
}
// Get blessee package name.
mBlesseePkgName = getCallingActivity().getPackageName();
if (mBlesseePkgName == null || mBlesseePkgName.isEmpty()) {
replyWithError("Empty blessee package name.");
return;
}
// Get blessee public key.
mBlesseePubKey =
(ECPublicKey) intent.getSerializableExtra(BlessingService.EXTRA_PUBLIC_KEY);
if (mBlesseePubKey == null) {
replyWithError("Empty blessee public key.");
return;
}
// See if the user wants to base the blessings on the specific google account.
// If so, we will try to look for it in the list of existing blessings and mint a new
// set of blessings if necessary.
mGoogleAccount = intent.getStringExtra(BlessingService.EXTRA_GOOGLE_ACCOUNT);
if (mGoogleAccount != null && !mGoogleAccount.isEmpty()) {
handleWithBlessings(false);
return;
}
bless();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CODE_CREATE_ACCOUNT:
if (resultCode != RESULT_OK) {
replyWithError("Couldn't create a Vanadium blessing.");
return;
}
handleWithBlessings(true);
break;
case REQUEST_CODE_BLESS:
if (resultCode != RESULT_OK) {
replyWithError("Blessing error: " + data.getStringExtra(Constants.ERROR));
return;
}
replyWithSuccess(data.getByteArrayExtra(Constants.REPLY));
break;
default:
super.onActivityResult(requestCode, resultCode, data);
}
}
private void handleWithBlessings(boolean postCreation) {
// Attempt to find the blessing matching the specified google account name.
String blessingName = Joiner.on(
io.v.v23.security.Constants.CHAIN_SEPARATOR).join(
"dev.v.io", "u", mGoogleAccount, "android");
Map<BlessingPattern, Blessings> allBlessings =
V.getPrincipal(mBaseContext).blessingStore().peerBlessings();
Blessings blessings = allBlessings.get(new BlessingPattern(blessingName));
if (blessings == null) {
// Blessings with the given name don't exist: create them.
if (postCreation) { // to avoid the infinite creation loop
replyWithError(
"Couldn't find already created blessings with name: " + blessingName);
return;
}
Intent intent = new Intent(this, AccountActivity.class);
intent.putExtra(AccountActivity.GOOGLE_ACCOUNT, mGoogleAccount);
startActivityForResult(intent, REQUEST_CODE_CREATE_ACCOUNT);
return;
}
try {
mBlessWithVom = VomUtil.encode(blessings, Blessings.class);
bless();
} catch (VException e) {
replyWithError("Couldn't encode blessings: " + e.getMessage());
return;
}
}
private void bless() {
Intent i = new Intent(this, BlessActivity.class);
i.putExtra(BlessActivity.BLESSEE_PUBLIC_KEY, mBlesseePubKey);
i.putExtra(BlessActivity.BLESSEE_NAMES, new String[]{mBlesseePkgName});
i.putExtra(BlessActivity.BLESSEE_EXTENSION, mBlesseePkgName);
i.putExtra(BlessActivity.BLESSEE_EXTENSION_MUTABLE, false);
i.putExtra(BlessActivity.BLESS_WITH, mBlessWithVom);
startActivityForResult(i, REQUEST_CODE_BLESS);
}
private void replyWithError(String error) {
android.util.Log.e(TAG, "Blessing error: " + error);
Intent intent = new Intent();
intent.putExtra(BlessingService.EXTRA_ERROR, error);
setResult(RESULT_CANCELED, intent);
finish();
}
private void replyWithSuccess(byte[] blessingsVom) {
Intent intent = new Intent();
intent.putExtra(BlessingService.EXTRA_REPLY, blessingsVom);
setResult(RESULT_OK, intent);
finish();
}
}