/**
* Copyright 2010 The University of Nottingham
*
* This file is part of lobbyservice.
*
* lobbyservice is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* lobbyservice is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with lobbyservice. If not, see <http://www.gnu.org/licenses/>.
*
*/
package uk.ac.horizon.ug.lobby.browser;
import java.io.BufferedReader;
import java.io.IOException;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.json.JSONException;
import org.json.JSONObject;
import com.google.appengine.api.datastore.Key;
import uk.ac.horizon.ug.lobby.RequestException;
import uk.ac.horizon.ug.lobby.model.EMF;
import uk.ac.horizon.ug.lobby.model.GameClient;
import uk.ac.horizon.ug.lobby.model.GameClientStatus;
import uk.ac.horizon.ug.lobby.protocol.ClientRequest;
import uk.ac.horizon.ug.lobby.protocol.ClientResponse;
import uk.ac.horizon.ug.lobby.protocol.ClientResponseStatus;
import uk.ac.horizon.ug.lobby.protocol.JSONUtils;
import uk.ac.horizon.ug.lobby.protocol.RegisterClientRequest;
import uk.ac.horizon.ug.lobby.protocol.RegisterClientResponse;
import uk.ac.horizon.ug.lobby.protocol.RegisterClientResponseStatus;
/**
* @author cmg
*
*/
public class RegisterClientServlet extends HttpServlet {
static Logger logger = Logger.getLogger(RegisterClientServlet.class.getName());
/* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
// parse request
// NB this had BETTER be called over HTTPS
String line = null;
RegisterClientRequest rcreq = null;
try {
BufferedReader br = req.getReader();
line = br.readLine();
JSONObject json = new JSONObject(line);
rcreq = JSONUtils.parseRegisterClientRequest(json);
logger.info("RegisterClientRequest "+rcreq);
}
catch (JSONException e) {
logger.warning(e.toString());
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, e.toString());
return;
}
try {
// app logic...
RegisterClientResponse rcresp = handleRequest(rcreq);
JSONUtils.sendRegisterClientResponse(resp, rcresp);
} catch (RequestException e) {
resp.sendError(e.getErrorCode(), e.getMessage());
return;
}
}
/** test entry point */
public static RegisterClientResponse testHandleRequest(RegisterClientRequest rcreq) throws RequestException {
return handleRequest(rcreq);
}
/** handle Client registration request (esp. trying to set a sharedSecret for subsequent
* authentication).
*
* @param rcreq
* @return
* @throws RequestException
*/
private static RegisterClientResponse handleRequest(RegisterClientRequest rcreq) throws RequestException {
RegisterClientResponse rcresp = new RegisterClientResponse();
rcresp.setVersion(RegisterClientRequest.VERSION);
// validate request
String clientId = rcreq.getClientId();
if (clientId==null)
throw new RequestException(HttpServletResponse.SC_BAD_REQUEST,"clientId not specified");
String sharedSecret = rcreq.getSharedSecret();
if (sharedSecret==null || sharedSecret.length()==0)
throw new RequestException(HttpServletResponse.SC_BAD_REQUEST,"sharedSecret not specified");
// handle request
EntityManager em = EMF.get().createEntityManager();
EntityTransaction et = em.getTransaction();
try {
// prepare
Key clientKey = GameClient.idToKey(clientId);
et.begin();
GameClient gc = em.find(GameClient.class, clientKey);
if (gc==null) {
// create client
gc = new GameClient();
gc.setKey(clientKey);
gc.setCreatedTime(System.currentTimeMillis());
gc.setStatus(GameClientStatus.ANONYMOUS);
em.persist(gc);
logger.info("Creating GameClient "+clientId+" on RegisterClient");
}
if (gc.getSharedSecret()==null || gc.getSharedSecret().equals(sharedSecret)) {
// OK
gc.setSharedSecret(sharedSecret);
// update properties
if (rcreq.getCharacteristicsJson()!=null)
gc.setCharacteristicsJson(rcreq.getCharacteristicsJson());
if (rcreq.getNickname()!=null)
gc.setNickname(rcreq.getNickname());
et.commit();
logger.info("Set/updated GameClient on Register: "+gc);
rcresp.setStatus(RegisterClientResponseStatus.OK);
return rcresp;
}
// no...
et.rollback();
rcresp.setStatus(RegisterClientResponseStatus.ERROR_NOT_PERMITTED);
logger.info("Failed/Not permitted RegisterClient "+clientId);
}
finally {
if (et.isActive())
et.rollback();
em.close();
}
return rcresp;
}
}