Server signature verification working

This commit is contained in:
Sylvain Berfini 2015-04-22 14:59:40 +02:00
parent 940b67221b
commit 081d12a571
3 changed files with 61 additions and 21 deletions

View file

@ -33,4 +33,4 @@ log_collection_upload_server_url=https://www.linphone.org:444/lft.php
user_certificates_path=/data/data/org.linphone/files user_certificates_path=/data/data/org.linphone/files
[in-app-purchase] [in-app-purchase]
server_url=https://www.linphone.org/wizard2.php server_url=https://www.linphone.org/inapp.php

View file

@ -32,14 +32,14 @@ import android.view.View.OnClickListener;
import android.widget.ImageView; import android.widget.ImageView;
import android.widget.LinearLayout; import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast;
/** /**
* @author Sylvain Berfini * @author Sylvain Berfini
*/ */
public class InAppPurchaseActivity extends Activity implements InAppPurchaseListener, OnClickListener { public class InAppPurchaseActivity extends Activity implements InAppPurchaseListener, OnClickListener {
private InAppPurchaseHelper inAppPurchaseHelper; private InAppPurchaseHelper inAppPurchaseHelper;
private LinearLayout purchasableItems; private LinearLayout purchasableItemsLayout;
private ArrayList<Purchasable> purchasedItems;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
@ -48,7 +48,7 @@ public class InAppPurchaseActivity extends Activity implements InAppPurchaseList
inAppPurchaseHelper = new InAppPurchaseHelper(this, this); inAppPurchaseHelper = new InAppPurchaseHelper(this, this);
setContentView(R.layout.in_app_store); setContentView(R.layout.in_app_store);
purchasableItems = (LinearLayout) findViewById(R.id.purchasable_items); purchasableItemsLayout = (LinearLayout) findViewById(R.id.purchasable_items);
} }
@Override @Override
@ -59,29 +59,35 @@ public class InAppPurchaseActivity extends Activity implements InAppPurchaseList
@Override @Override
public void onServiceAvailableForQueries() { public void onServiceAvailableForQueries() {
inAppPurchaseHelper.getAvailableItemsForPurchaseAsync();
inAppPurchaseHelper.getPurchasedItemsAsync(); inAppPurchaseHelper.getPurchasedItemsAsync();
} }
@Override @Override
public void onAvailableItemsForPurchaseQueryFinished(ArrayList<Purchasable> items) { public void onAvailableItemsForPurchaseQueryFinished(ArrayList<Purchasable> items) {
purchasableItems.removeAllViews(); purchasableItemsLayout.removeAllViews();
for (Purchasable item : items) { for (Purchasable item : items) {
View layout = LayoutInflater.from(this).inflate(R.layout.in_app_purchasable, purchasableItems); View layout = LayoutInflater.from(this).inflate(R.layout.in_app_purchasable, purchasableItemsLayout);
TextView text = (TextView) layout.findViewById(R.id.text); TextView text = (TextView) layout.findViewById(R.id.text);
text.setText(item.getTitle() + " (" + item.getPrice() + ")"); text.setText(item.getTitle() + " " + item.getPrice());
ImageView image = (ImageView) layout.findViewById(R.id.image); ImageView image = (ImageView) layout.findViewById(R.id.image);
image.setTag(item); image.setTag(item);
image.setOnClickListener(this); image.setOnClickListener(this);
for (Purchasable purchasedItem : purchasedItems) {
Log.d("[In-app purchase] Found already bought item");
if (purchasedItem.getId().equals(item.getId())) {
image.setEnabled(false);
text.setEnabled(false);
}
}
} }
} }
@Override @Override
public void onPurchasedItemsQueryFinished(ArrayList<Purchasable> items) { public void onPurchasedItemsQueryFinished(ArrayList<Purchasable> items) {
for (Purchasable item : items) { purchasedItems = items;
Log.d("[In-app] Item " + item.getTitle() + " is already bought"); inAppPurchaseHelper.getAvailableItemsForPurchaseAsync();
}
} }
@Override @Override

View file

@ -245,12 +245,10 @@ public class InAppPurchaseHelper {
String signature = signatureList.get(i); String signature = signatureList.get(i);
Log.d("[In-app purchase] Found purchase data: " + purchaseData); Log.d("[In-app purchase] Found purchase data: " + purchaseData);
verifySignatureAsync(new VerifiedSignatureListener() { Purchasable item = verifySignature(purchaseData, signature);
@Override if (item != null) {
public void onParsedAndVerifiedSignatureQueryFinished(Purchasable item) {
items.add(item); items.add(item);
} }
}, purchaseData, signature);
} }
} else { } else {
Log.e("[In-app purchase] Error: responde code is not ok: " + responseCodeToErrorMessage(response)); Log.e("[In-app purchase] Error: responde code is not ok: " + responseCodeToErrorMessage(response));
@ -303,7 +301,7 @@ public class InAppPurchaseHelper {
if (resultCode == Activity.RESULT_OK && responseCode == RESPONSE_RESULT_OK) { if (resultCode == Activity.RESULT_OK && responseCode == RESPONSE_RESULT_OK) {
Log.d("[In-app purchase] response is OK"); Log.d("[In-app purchase] response is OK");
verifySignatureAsync(new VerifiedSignatureListener() { verifySignatureAndCreateAccountAsync(new VerifiedSignatureListener() {
@Override @Override
public void onParsedAndVerifiedSignatureQueryFinished(Purchasable item) { public void onParsedAndVerifiedSignatureQueryFinished(Purchasable item) {
mListener.onPurchasedItemConfirmationQueryFinished(item); mListener.onPurchasedItemConfirmationQueryFinished(item);
@ -319,7 +317,7 @@ public class InAppPurchaseHelper {
mContext.unbindService(mServiceConn); mContext.unbindService(mServiceConn);
} }
private void verifySignatureAsync(final VerifiedSignatureListener listener, String purchasedData, String signature) { private Purchasable verifySignature(String purchasedData, String signature) {
XMLRPCClient client = null; XMLRPCClient client = null;
try { try {
client = new XMLRPCClient(new URL(LinphonePreferences.instance().getInAppPurchaseValidatingServerUrl())); client = new XMLRPCClient(new URL(LinphonePreferences.instance().getInAppPurchaseValidatingServerUrl()));
@ -328,29 +326,65 @@ public class InAppPurchaseHelper {
} }
if (client != null) { if (client != null) {
client.callAsync(new XMLRPCCallback() {
@Override
public void onServerError(long id, XMLRPCServerException error) {
Log.e(error);
}
@Override
public void onResponse(long id, Object result) {
try { try {
JSONObject object = new JSONObject((String)result); Object result = client.call("check_signature", purchasedData, signature, "google");
String productId = object.getString(PURCHASE_DETAILS_PRODUCT_ID); String object = (String)result;
JSONObject json = new JSONObject(object);
Log.d("[In-app purchase] JSON received is " + json);
String productId = json.getString(PURCHASE_DETAILS_PRODUCT_ID);
Log.d("[In-app purchase] Purchasable verified by server: " + productId); Log.d("[In-app purchase] Purchasable verified by server: " + productId);
Purchasable item = new Purchasable(productId); Purchasable item = new Purchasable(productId);
//TODO parse JSON result to get the purchasable in it //TODO parse JSON result to get the purchasable in it
listener.onParsedAndVerifiedSignatureQueryFinished(item); return item;
} catch (XMLRPCException e) {
Log.e(e);
} catch (JSONException e) { } catch (JSONException e) {
Log.e(e); Log.e(e);
} }
} }
return null;
}
private void verifySignatureAndCreateAccountAsync(final VerifiedSignatureListener listener, String purchasedData, String signature) {
XMLRPCClient client = null;
try {
client = new XMLRPCClient(new URL(LinphonePreferences.instance().getInAppPurchaseValidatingServerUrl()));
} catch (MalformedURLException e) {
Log.e(e);
Log.e("[In-app purchase] Can't reach the server !");
}
if (client != null) {
client.callAsync(new XMLRPCCallback() {
@Override
public void onServerError(long id, XMLRPCServerException error) {
Log.e(error);
Log.e("[In-app purchase] Server can't validate the payload and it's signature !");
}
@Override
public void onResponse(long id, Object result) {
try {
String object = (String)result;
JSONObject json = new JSONObject(object);
Log.d("[In-app purchase] JSON received is " + json);
String productId = json.getString(PURCHASE_DETAILS_PRODUCT_ID);
Log.d("[In-app purchase] Purchasable verified by server: " + productId);
Purchasable item = new Purchasable(productId);
//TODO parse JSON result to get the purchasable in it
listener.onParsedAndVerifiedSignatureQueryFinished(item);
return;
} catch (JSONException e) {
Log.e(e);
}
Log.e("[In-app purchase] Server can't validate the payload and it's signature !");
}
@Override @Override
public void onError(long id, XMLRPCException error) { public void onError(long id, XMLRPCException error) {
Log.e(error); Log.e(error);
Log.e("[In-app purchase] Server can't validate the payload and it's signature !");
} }
}, "create_account_from_in_app_purchase", "sylvain@sip.linphone.org", "toto", purchasedData, signature, "google"); }, "create_account_from_in_app_purchase", "sylvain@sip.linphone.org", "toto", purchasedData, signature, "google");
} }