/*
* Copyright 2012 The Stanford MobiSocial Laboratory
*
* 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 mobisocial.musubi.objects;
import java.util.Iterator;
import mobisocial.crypto.IBHashedIdentity;
import mobisocial.crypto.IBHashedIdentity.Authority;
import mobisocial.musubi.App;
import mobisocial.musubi.feed.iface.DbEntryHandler;
import mobisocial.musubi.model.MFeed;
import mobisocial.musubi.model.MIdentity;
import mobisocial.musubi.model.MObject;
import mobisocial.musubi.model.helpers.IdentitiesManager;
import mobisocial.socialkit.obj.MemObj;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Context;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Base64;
import android.util.Log;
/**
* An object that provides minimal information about introduced participants to a group.
* This ensures the minimum latency in a person being able to tell who is participating
* in a feed. Other approaches, such as sending profile to people we discover (which we still do),
* have one round-trip of latency.
*
*/
public class OutOfBandInvitedObj extends DbEntryHandler {
public static final String TYPE = "oobinvited";
public static final String IDENTITIES = "identities";
public static final String ID_AUTHORITY = "authority";
public static final String ID_PRINCIPAL_HASH = "hash";
@Override
public String getType() {
return TYPE;
}
public static MemObj from(Iterator<MIdentity> iterator) {
return new MemObj(TYPE, json(iterator));
}
public static JSONObject json(Iterator<MIdentity> iterator){
JSONArray array = new JSONArray();
JSONObject obj = new JSONObject();
try{
while(iterator.hasNext()) {
MIdentity id = iterator.next();
JSONObject identity = new JSONObject();
identity.put(ID_AUTHORITY, id.type_.ordinal());
identity.put(ID_PRINCIPAL_HASH, Base64.encodeToString(id.principalHash_, Base64.DEFAULT));
array.put(identity);
}
obj.put(IDENTITIES, array);
}catch(JSONException e){}
return obj;
}
@Override
public boolean processObject(Context context, MFeed feed, MIdentity sender,
MObject object) {
SQLiteOpenHelper databaseSource = App.getDatabaseSource(context);
IdentitiesManager identitiesManager = new IdentitiesManager(databaseSource);
if (object.json_ == null) {
Log.w(TAG, "bad introduction format");
return false;
}
JSONObject json;
try {
json = new JSONObject(object.json_);
} catch (JSONException e) {
Log.e(TAG, "Bad json in database", e);
return false;
}
JSONArray array;
try {
array = json.getJSONArray(IDENTITIES);
} catch (JSONException e) {
Log.e(TAG, "json identity array missing", e);
return false;
}
for(int i = 0; i < array.length(); ++i) {
JSONObject identity;
try {
identity = array.getJSONObject(i);
} catch (JSONException e) {
Log.e(TAG, "identity entry in introduction access error", e);
continue;
}
int authority = -1;
String principalHashString = null;
try {
authority = identity.getInt(ID_AUTHORITY);
principalHashString = identity.getString(ID_PRINCIPAL_HASH);
} catch (JSONException e) {
Log.e(TAG, "identity entry in introduction missing key fields", e);
continue;
}
byte[] principalHash = Base64.decode(principalHashString, Base64.DEFAULT);
IBHashedIdentity hid = new IBHashedIdentity(Authority.values()[authority], principalHash, 0);
MIdentity ident = identitiesManager.getIdentityForIBHashedIdentity(hid);
if(ident == null) {
//this introduction has to be sent to both participants, so the low leve
//will already have added the identity
Log.e(TAG, "identity introduction for totally unseen identities");
continue;
}
if(!ident.hasSentEmail_) {
ident.hasSentEmail_ = true;
identitiesManager.updateIdentity(ident);
}
}
return false;
}
}