defuze.me  Client
doorman.cpp
00001 /**************************************************************************
00002 ** defuze.me Epitech Innovative Project
00003 **
00004 ** Copyright 2010-2011
00005 **   Athena Calmettes - Jocelyn De La Rosa - Francois Gaillard
00006 **   Adrien Jarthon - Alexandre Moore - Luc Peres - Arnaud Sellier
00007 **
00008 ** All rights reserved.
00009 **************************************************************************/
00010 
00011 #include <QDebug>
00012 #include "doorman.hpp"
00013 #include "remotesock.hpp"
00014 #include "remoteevent.hpp"
00015 #include "logger.hpp"
00016 #include "status.hpp"
00017 
00018 using namespace Network;
00019 
00020 Doorman::Doorman(QTcpServer *rcServer) : rcServer(rcServer)
00021 {
00022     connect(rcServer, SIGNAL(newConnection()), SLOT(newConnection()));
00023     setParamsName("doorman");
00024 }
00025 
00026 void    Doorman::loadKnownDevices()
00027 {
00028     knownDevices = getParameter("known-devices", QVariantMap()).toMap();
00029 }
00030 
00031 void    Doorman::storeKnownDevices()
00032 {
00033     setParameter("known-devices", knownDevices);
00034     commitParameters();
00035 }
00036 
00037 void    Doorman::defineParams()
00038 {
00039 }
00040 
00041 void    Doorman::newConnection()
00042 {
00043     QTcpSocket  *socket;
00044 
00045     while ((socket = rcServer->nextPendingConnection()))
00046     {
00047         RemoteSock  *client = new RemoteSock(socket);
00048         RemoteEvent &event = client->newEvent("authenticationRequest");
00049 
00050         Logger::log(QString("Remote: connection received from %1:%2").arg(client->ip()).arg(client->port()));
00051         event.sendWithReply(this, SLOT(authentication(const RemoteEvent&)));
00052     }
00053 }
00054 
00055 void    Doorman::authentication(const RemoteEvent& event)
00056 {
00057     if (event.getEvent() == "authentication")
00058     {
00059         QString token = event["token"].toString();
00060         event.remote->token = token;
00061         event.remote->device = event["deviceName"].toString();
00062         event.remote->version = event["appVersion"].toString();
00063         Logger::log(QString("Remote: authentication token received from %2: %1").arg(token, event.getRemote()->ip()));
00064         // Check for already autorized (or not) devices
00065         loadKnownDevices();
00066         if (knownDevices.contains(token))
00067         {
00068             const QVariantMap &info = knownDevices[token].toMap();
00069             if (info.contains("accepted"))
00070             {
00071                 answered(event.remote, event.uid, info["accepted"].toBool(), true);
00072                 Notification::Status::gMessage(tr("Remote device %1 has been %2").arg(
00073                                                    event.remote->device, (info["accepted"].toBool() ? tr("accepted") : tr("rejected"))), Notification::DEVICE);
00074             }
00075             else
00076                 emit needAuthorization(event);
00077         }
00078         else
00079         {
00080             Notification::Status::gMessage(tr("Remote device %1 is requesting remote control").arg(event.remote->device), Notification::DEVICE);
00081             emit needAuthorization(event);
00082         }
00083     }
00084     else
00085     {
00086         Logger::log(QString("Remote: bad authentication reply: %1").arg(event.getEvent()));
00087     }
00088 }
00089 
00090 void    Doorman::answered(RemoteSock* remote, unsigned msgid, bool accepted, bool permanent)
00091 {
00092     if (accepted)
00093     {
00094         RemoteEvent &reply = remote->newEvent("authenticated");
00095         reply.replyTo = msgid;
00096         Logger::log(QString("Remote: user accepted client %1, permanent = %2").arg(remote->ip()).arg(permanent));
00097         reply.send();
00098         emit authenticatedRemote(remote);
00099     }
00100     else
00101     {
00102         Logger::log(QString("Remote: user rejected client %1, permanent = %2").arg(remote->ip()).arg(permanent));
00103         RemoteEvent &reply = remote->newEvent("authenticationFailed");
00104         reply.replyTo = msgid;
00105         reply["msg"] = "Sorry, you've been rejected by the client software";
00106         reply.send();
00107     }
00108     if (permanent)
00109     {
00110         // Store choice to database
00111         QVariantMap info;
00112         info["accepted"] = accepted;
00113         info["last-ip"] = remote->ip();
00114         info["device-name"] = remote->getDevice();
00115         info["app-version"] = remote->getVersion();
00116         Logger::log(QString("Remote: store choice to database for %1").arg(remote->getToken()));
00117         knownDevices[remote->getToken()] = info;
00118         storeKnownDevices();
00119     }
00120 }
00121