package com.code44.finance.backend.utils;
import com.code44.finance.backend.endpoint.body.Body;
import com.code44.finance.backend.entity.DeviceEntity;
import com.code44.finance.backend.entity.UserAccount;
import com.code44.finance.common.utils.StringUtils;
import com.google.android.gcm.server.Constants;
import com.google.android.gcm.server.Message;
import com.google.android.gcm.server.Result;
import com.google.android.gcm.server.Sender;
import com.google.api.server.spi.response.BadRequestException;
import com.google.api.server.spi.response.ForbiddenException;
import com.google.api.server.spi.response.NotFoundException;
import com.google.appengine.api.oauth.OAuthRequestException;
import com.google.appengine.api.users.User;
import com.googlecode.objectify.Key;
import java.io.IOException;
import java.util.List;
import static com.code44.finance.backend.OfyService.ofy;
public class EndpointUtils {
private static final String API_KEY = System.getProperty("gcm.api.key");
public static void verifyUserNotNull(User user) throws OAuthRequestException {
if (user == null) {
throw new OAuthRequestException("Requires authentication.");
}
}
public static void verifyBodyNotNull(Body body) throws BadRequestException {
if (body == null) {
throw new BadRequestException("Body cannot be empty.");
}
}
public static void verifyIdNotEmpty(String id) throws BadRequestException {
if (StringUtils.isEmpty(id)) {
throw new BadRequestException("Id cannot be empty.");
}
}
public static UserAccount getUserAccount(User user) throws OAuthRequestException, NotFoundException {
verifyUserNotNull(user);
final UserAccount userAccount = UserAccount.find(user);
if (userAccount == null) {
throw new NotFoundException("User " + user.getEmail() + " is not registered");
}
return userAccount;
}
public static UserAccount getUserAccountAndVerifyPermissions(User user) throws OAuthRequestException, NotFoundException, ForbiddenException {
UserAccount userAccount = getUserAccount(user);
if (!userAccount.isPremium()) {
throw new ForbiddenException("User does not have permission to call this API because it's not a premium account.");
}
return userAccount;
}
public static void notifyOtherDevices(UserAccount userAccount, String senderDeviceRedId) throws IOException {
// Get list of user devices
final List<DeviceEntity> devices = ofy()
.load()
.type(DeviceEntity.class)
.filter("userAccount", Key.create(UserAccount.class, userAccount.getId()))
.list();
if (devices == null) {
return;
}
// Check if there are devices other than the sender
boolean hasOtherDevices = false;
DeviceEntity senderDevice = null;
for (DeviceEntity device : devices) {
if (!device.getId().equals(senderDeviceRedId)) {
hasOtherDevices = true;
break;
} else {
senderDevice = device;
}
}
if (!hasOtherDevices) {
return;
}
devices.remove(senderDevice);
final Sender sender = new Sender(API_KEY);
final Message message = new Message.Builder()
.collapseKey("notify")
.build();
for (DeviceEntity device : devices) {
final Result result = sender.send(message, device.getId(), 5);
if (result.getMessageId() != null) {
final String canonicalRegId = result.getCanonicalRegistrationId();
if (canonicalRegId != null) {
// The regId changed
device.setId(canonicalRegId);
ofy().save().entity(device).now();
}
} else {
final String error = result.getErrorCodeName();
if (error.equals(Constants.ERROR_NOT_REGISTERED)) {
// The device is no longer registered with Gcm
ofy().delete().entity(device).now();
}
}
}
}
}