package org.witness.informacam.transport;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.net.HttpURLConnection;
import org.witness.informacam.InformaCam;
import org.witness.informacam.informa.InformaService;
import org.witness.informacam.json.JSONException;
import org.witness.informacam.json.JSONObject;
import org.witness.informacam.json.JSONTokener;
import org.witness.informacam.models.Model;
import org.witness.informacam.models.organizations.IOrganization;
import org.witness.informacam.utils.Constants.Actions;
import org.witness.informacam.utils.Constants.Logger;
import org.witness.informacam.utils.Constants.Models;
import org.witness.informacam.utils.Constants.Models.ITransportStub.GoogleDrive;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.accounts.AuthenticatorException;
import android.accounts.OperationCanceledException;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.UserRecoverableNotifiedException;
public class GoogleDriveTransport extends Transport {
GDSubmissionPermission permission;
String fileId = null;
AuthToken authToken = null;
int auth_attempts = 0;
private final static String SIMPLE_API_KEY = "AIzaSyDjCiTp3cof1vqTdurVWN4XVncWSn-dm-Q"; //making this loaded from assets file at some point
public GoogleDriveTransport() {
super(Models.ITransportStub.GoogleDrive.TAG);
}
@Override
protected boolean init() {
//Following lines make debugging Google permission easier. Make sure that
//the service account permission is revoked (on your google account "security"
//settings page) and then uncomment the following lines to remove the local
//cached token.
//authToken = new AuthToken(AccountManager.get(informaCam).getAccounts()[0]);
//if(authToken.token != null)
// GoogleAuthUtil.invalidateToken(getApplicationContext(), authToken.token);
// authenticate google drive
AccountManager am =AccountManager.get(informaCam);
Account[] accounts = am.getAccountsByType("com.google");
if (accounts == null || accounts.length == 0)
{
Logger.d(LOG,"No Google Accounts configured on the device");
finishUnsuccessfully();
return false;
}
Logger.d(LOG, "Retrieved google accounts from device; found " + accounts.length);
Logger.d(LOG, "Using account: " + accounts[0].name);
if (authToken == null)
authToken = new AuthToken(am,accounts[0]);
try
{
authToken.doAuth();
} catch (Exception e) {
Logger.e(LOG, e);
auth_attempts++;
finishUnsuccessfully();
return false;
}
if(authToken.token != null) {
// TODO: if user uses tor
if(!super.init(false)) {
return false;
}
// upload to drive, on success: file id is in there
mBuilder.setProgress(100, 0, false);
mNotifyManager.notify(NOTIFY_ID, mBuilder.build());
try {
JSONObject subResponse = (JSONObject) doPost(new GDSubmissionMetadata(), transportStub.asset, GoogleDrive.Urls.UPLOAD);
if(subResponse != null) {
fileId = subResponse.getString("id");
// share to our google drive person
subResponse = (JSONObject) doPost(new GDSubmissionPermission(), String.format(GoogleDrive.Urls.SHARE, fileId));
Logger.d(LOG, "CONFIRM:\n" + transportStub.lastResult);
mBuilder.setProgress(100, 60, false);
mNotifyManager.notify(NOTIFY_ID, mBuilder.build());
if(subResponse != null) {
Logger.d(LOG, "CONFIRM:\n" + transportStub.lastResult);
mBuilder
.setContentText("Successful upload to: " + repository.asset_root)
.setTicker("Successful upload to: " + repository.asset_root);
mBuilder.setAutoCancel(true);
mBuilder.setProgress(0, 0, false);
mNotifyManager.notify(NOTIFY_ID, mBuilder.build());
finishSuccessfully();
}
}
} catch (Exception e) {
Logger.e(LOG, e);
auth_attempts++;
finishUnsuccessfully();
return false;
}
} else {
Logger.d(LOG, "AUTH TOKEN NULL-- WHAT TO DO?");
GoogleAuthUtil.invalidateToken(getApplicationContext(), authToken.token);
auth_attempts++;
if(auth_attempts >= 10) {
return false;
}
return init();
}
return true;
}
@Override
public Object parseResponse(InputStream response) {
super.parseResponse(response);
try {
response.close();
} catch (IOException e) {
Logger.e(LOG, e);
}
try {
return (JSONObject) new JSONTokener(transportStub.lastResult).nextValue();
} catch (JSONException e) {
Logger.e(LOG, e);
}
Logger.d(LOG, "THIS POST DID NOT WORK");
return null;
}
@Override
protected HttpURLConnection buildConnection(String urlString, boolean useTorProxy) throws IOException {
StringBuilder sbUrl = new StringBuilder();
sbUrl.append(urlString);
/*
if (urlString.contains("?"))
sbUrl.append("&");
else
sbUrl.append("?");
sbUrl.append("key=");
sbUrl.append(apiKey);
*/
HttpURLConnection http = super.buildConnection(sbUrl.toString(), useTorProxy);
http.setRequestProperty("Authorization", "Bearer " + authToken.token);
http.setRequestProperty("key", SIMPLE_API_KEY);
Logger.d(LOG, "Authenticating Google Access with token: " + authToken.token);
return http;
}
public static class GoogleDriveEventBroadcaster extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Logger.d(LOG, intent.getAction());
Bundle b = intent.getExtras();
if (b != null)
{
for(String k : b.keySet()) {
Logger.d(LOG, k);
if(k.equals(Actions.USER_ACCEPT_ACTION)) {
for(IOrganization organization : InformaCam.getInstance().installedOrganizations.organizations) {
InformaCam.getInstance().resendCredentials(organization);
}
}
}
}
}
}
public class GDSubmissionMetadata extends Model implements Serializable {
private static final long serialVersionUID = -5854206953634303757L;
public String title;
public GDSubmissionMetadata() {
super();
title = GoogleDriveTransport.this.transportStub.asset.assetName;
}
public GDSubmissionMetadata(GDSubmissionMetadata metadata) throws InstantiationException, IllegalAccessException {
super();
inflate(metadata);
}
}
public class GDSubmissionPermission extends Model implements Serializable {
private static final long serialVersionUID = 2781623454711408251L;
public String type;
public String role;
public String value;
public GDSubmissionPermission() {
super();
role = Models.ITransportStub.GoogleDrive.Roles.WRITER;
type = Models.ITransportStub.GoogleDrive.Permissions.USER;
value = GoogleDriveTransport.this.transportStub.getRepository(Models.ITransportStub.GoogleDrive.TAG).asset_id;
}
public GDSubmissionPermission(GDSubmissionPermission permission) throws InstantiationException, IllegalAccessException {
super();
inflate(permission);
}
}
public class AuthToken {
public Account account;
public String token = null;
private AccountManager am = null;
public Intent userAcceptCallback = new Intent().setAction(Actions.USER_ACCEPT_ACTION);
@SuppressWarnings("deprecation")
public AuthToken(AccountManager am, Account account) {
this.account = account;
this.am = am;
}
public void doAuth () throws OperationCanceledException, AuthenticatorException, IOException, UserRecoverableNotifiedException, GoogleAuthException
{
Bundle bund = new Bundle();
token = GoogleAuthUtil.getTokenWithNotification(InformaService.getInstance().getApplicationContext(), account.name, Models.ITransportStub.GoogleDrive.SCOPE,bund);
if (bund.containsKey(AccountManager.KEY_AUTHTOKEN))
token = bund.getString(AccountManager.KEY_AUTHTOKEN);
/**
if (token != null)
am.invalidateAuthToken(Models.ITransportStub.GoogleDrive.SCOPE, token);
AccountManagerFuture<Bundle> response = am.getAuthToken(account, Models.ITransportStub.GoogleDrive.SCOPE, true, new AccountManagerCallback<Bundle> () {
@Override
public void run(AccountManagerFuture<Bundle> result) {
try {
token = result.getResult().getString(AccountManager.KEY_AUTHTOKEN);
} catch (OperationCanceledException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (AuthenticatorException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}, null);
Bundle b;
b = response.getResult();
token = b.getString(AccountManager.KEY_AUTHTOKEN);
*/
}
}
}