Modification for dynamic speed sign (not activated)
[staging/HomeScreen.git] / HomeScreen / src2 / usermanagement.cpp
1 #include "usermanagement.h"
2 #include <QDebug>
3 #include <QtCore/QJsonDocument>
4 #include <QByteArray>
5 UserManagement::UserManagement(QObject *root) : QObject()
6 {
7     home = root->findChild<QObject *>("Home");
8     QObject::connect(home, SIGNAL(disconnect()),
9                          this, SLOT(slot_disconnect()));
10     logo = root->findChild<QObject *>("Logo_colour");
11     shortcutArea = root->findChild<QObject *>("ShortcutArea");
12     statusArea = root->findChild<QObject *>("StatusArea");
13     this->appModel = home->findChild<ApplicationModel *>("ApplicationModel");
14     sequence = 0;
15     isRed = false;
16     connect(&timerRed, SIGNAL(timeout()), this, SLOT(slot_turnOffRed()));
17     timerRed.setSingleShot(true);
18     timerRed.setInterval(3000);
19 #ifdef REAL_SERVER
20     connectWebsockets();
21 #else
22     pSocket = NULL;
23     connect(&timerTest, SIGNAL(timeout()), this, SLOT(slot_timerTest()));
24     timerTest.setSingleShot(false);
25     timerTest.start(5000);
26     launchServer();
27 #endif
28 }
29 void UserManagement::slot_disconnect()
30 {
31     appModel->changeOrder(-1);
32     timerRed.stop();
33     slot_turnOffRed();
34     QMetaObject::invokeMethod(home, "languageChanged");
35     QMetaObject::invokeMethod(shortcutArea, "languageChanged", Q_ARG(QVariant, "en"));
36     QMetaObject::invokeMethod(statusArea, "languageChanged", Q_ARG(QVariant, "en"));
37     QMetaObject::invokeMethod(home, "showSign90", Q_ARG(QVariant, false));
38     QMetaObject::invokeMethod(home, "showVisa", Q_ARG(QVariant, false), Q_ARG(QVariant, ""));
39     QMetaObject::invokeMethod(home, "changeFlag", Q_ARG(QVariant, "./images/us_flag.png"));
40     QMetaObject::invokeMethod(home, "setUser", Q_ARG(QVariant, ""), Q_ARG(QVariant, ""));
41     QVariantList list;
42     list << 2 << QString().setNum(++sequence) << "agl-identity-agent/logout" << true;
43     listToJson(list, &data);
44     slot_sendData();
45 }
46
47 void UserManagement::setUser(const User &user)
48 {
49     int hash = qHash(user.name + user.first_name);
50     timerRed.stop();
51     appModel->changeLanguage(user.graphPreferredLanguage);
52     appModel->changeOrder(hash);
53     slot_turnOffRed();
54     QMetaObject::invokeMethod(home, "languageChanged");
55     QMetaObject::invokeMethod(shortcutArea, "languageChanged", Q_ARG(QVariant, user.graphPreferredLanguage));
56     QMetaObject::invokeMethod(statusArea, "languageChanged", Q_ARG(QVariant, user.graphPreferredLanguage));
57     QStringList t;
58     bool noSpeedLimit = true;
59     foreach(const QString &s, user.graphActions) {
60         if(!s.contains("Exceed")) {
61             t.append(s);
62         } else {
63             noSpeedLimit = false;
64             QStringList speed = s.split(" ");
65             if(speed.size() == 3)
66                 QMetaObject::invokeMethod(home, "showSign90", Q_ARG(QVariant, true),
67                                           Q_ARG(QVariant, speed.at(1)), Q_ARG(QVariant, speed.at(2)));
68         }
69     }
70     if(noSpeedLimit)
71         QMetaObject::invokeMethod(home, "showSign90", Q_ARG(QVariant, false),
72                                   Q_ARG(QVariant, QString()), Q_ARG(QVariant, QString()));
73     QString type = user.policy;
74     if(user.graphPreferredLanguage == "fr") {
75         if(type == "Owner")
76             type = "Propriétaire";
77         else if(type == "Driver")
78             type = "Conducteur";
79         else if(type == "Maintainer")
80             type = "Maintenance";
81     }
82     QMetaObject::invokeMethod(home, "setUser", Q_ARG(QVariant, type), Q_ARG(QVariant, QVariant::fromValue(t)));
83     if(user.ccNumberMasked.isEmpty())
84         QMetaObject::invokeMethod(home, "showVisa", Q_ARG(QVariant, false), Q_ARG(QVariant, ""));
85     else
86         QMetaObject::invokeMethod(home, "showVisa", Q_ARG(QVariant, true), Q_ARG(QVariant, user.ccNumberMasked));
87     const QString welcome = QString("%1").arg(user.graphPreferredLanguage == "fr" ? "Bonjour " : "Hello") + " ";
88     QMetaObject::invokeMethod(home, "showHello", Q_ARG(QVariant, welcome + user.first_name));
89     QMetaObject::invokeMethod(home, "changeFlag", Q_ARG(QVariant, user.graphPreferredLanguage == "fr" ? "./images/french_flag.png" : "./images/us_flag.png"));
90 }
91 void UserManagement::slot_turnOffRed()
92 {
93     if(!isRed)
94         return;
95     QMetaObject::invokeMethod(logo, "setImage", Q_ARG(QVariant, "./images/Utility_Logo_Colour-01.png"));
96     isRed = false;
97 }
98
99 void UserManagement::connectWebsockets()
100 {
101 #ifdef REAL_SERVER
102     const QUrl url(REAL_SERVER);
103 #else
104     const QUrl url(QStringLiteral("ws://localhost:1234"));
105 #endif
106     QSslConfiguration config = QSslConfiguration::defaultConfiguration();
107     config.setProtocol(QSsl::SecureProtocols);
108     webSocket.setSslConfiguration(config);
109     connect(&webSocket, &QWebSocket::connected, this, &UserManagement::onConnected);
110     connect(&webSocket, &QWebSocket::disconnected, this, &UserManagement::onClosed);
111     if(!connect(&webSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(onWebSocketError(QAbstractSocket::SocketError)))) {
112         qWarning() << "Failed to connect to QWebSocket::error";
113     }
114     webSocket.open(QUrl(url));
115 }
116 void UserManagement::onWebSocketError(QAbstractSocket::SocketError)
117 {
118     qWarning()<<"Websocket error:" << webSocket.errorString();
119 }
120
121 void UserManagement::onConnected()
122 {
123     connect(&webSocket, &QWebSocket::textMessageReceived,
124             this, &UserManagement::onTextMessageReceived);
125     QVariantList list;
126     QByteArray json;
127     list << 2 << QString().setNum(++sequence) << "agl-identity-agent/subscribe" << true;
128     listToJson(list, &json);
129     webSocket.sendTextMessage(QString(json));
130     list .clear();
131     list << 2 << QString().setNum(++sequence) << "agl-identity-agent/scan" << true;
132     listToJson(list, &json);
133     webSocket.sendTextMessage(QString(json));
134 }
135 void UserManagement::onTextMessageReceived(QString message)
136 {
137     QVariantList list;
138     const bool ok = jsonToList(message.toUtf8(), &list);
139     if(!ok || list.size() < 3) {
140         qWarning()<<"error 1 decoding json"<<list.size()<<message;
141         return;
142     }
143     QVariantMap map  = list.at(2).toMap();
144     if(list.first().toInt() == 5) {
145         if(!isRed)
146             QMetaObject::invokeMethod(logo, "setImage", Q_ARG(QVariant, "./images/Utility_Logo_Red-01.png"));
147         isRed = true;
148         timerRed.start();
149         map = map["data"].toMap();
150         if(map["eventName"].toString() == "login") {
151             //qWarning()<<"login received in client";
152             list.clear();
153             list << 2 << QString().setNum(++sequence) << "agl-identity-agent/get" << true;
154             listToJson(list, &data);
155             QTimer::singleShot(300, this, SLOT(slot_sendData()));
156         }
157         return;
158     }
159     if(list.first().toInt() == 3) {
160         if(!map.contains("response")) {
161             return;
162         }
163         map = map["response"].toMap();
164         User user;
165         user.postal_address = map["postal_address"].toString();
166         QStringList temp  = map["loc"].toString().split(",");
167         if(temp.size() == 2) {
168             user.loc.setX(temp.at(0).toDouble());
169             user.loc.setY(temp.at(1).toDouble());
170         }
171         user.graphActions = map["graphActions"].toString().split(",");
172         user.country = map["country"].toString();
173         user.mail = map["mail"].toString();
174         user.city = map["city"].toString();
175         user.graphEmail = map["graphEmail"].toString();
176         user.graphPreferredLanguage = map["graphPreferredLanguage"].toString();
177         user.ccNumberMasked = map["ccNumberMasked"].toString();
178         user.ccExpYear = map["ccExpYear"].toString();
179         user.ccExpMonth = map["ccExpMonth"].toString();
180         user.description = map["description"].toString();
181         user.groups = map["groups"].toStringList();
182         user.last_name = map["last_name"].toString();
183         user.ccNumber = map["ccNumber"].toString();
184         user.house_identifier = map["house_identifier"].toString();
185         user.phone = map["phone"].toString();
186         user.name = map["name"].toString();
187         user.state = map["state"].toString();
188         user.common_name = map["common_name"].toString();
189         user.fax = map["fax"].toString();
190         user.postal_code = map["postal_code"].toString();
191         user.first_name = map["first_name"].toString();
192         user.keytoken = map["keytoken"].toString();
193         user.policy = map["graphPolicies"].toString();
194         setUser(user);
195     }
196 }
197 void UserManagement::slot_sendData()
198 {
199     webSocket.sendTextMessage(QString(data));
200 }
201
202 void UserManagement::onClosed()
203 {
204     qWarning()<<"webSocket closed";
205 }
206 bool UserManagement::listToJson(const QList<QVariant> &list, QByteArray *json) const
207 {
208     QVariant v(list);
209     *json = QJsonDocument::fromVariant(v).toJson(QJsonDocument::Compact);
210     return true;
211 }
212 bool UserManagement::jsonToList(const QByteArray &buf, QList<QVariant> *list) const
213 {
214     if(!list)
215         return false;
216     QJsonParseError err;
217     QVariant v = QJsonDocument::fromJson(buf, &err).toVariant();
218     if(err.error != 0) {
219         qWarning() << "Error parsing json data" << err.errorString() << buf;
220         *list = QList<QVariant>();
221         return false;
222     }
223     *list = v.toList();
224     return true;
225 }
226 bool UserManagement::mapToJson( const QVariantMap &map, QByteArray *json) const
227 {
228     if(!json)
229         return false;
230     QVariant v(map);
231     *json = QJsonDocument::fromVariant(v).toJson(QJsonDocument::Compact);
232     return true;
233 }
234 bool UserManagement::jsonToMap(const QByteArray &buf, QVariantMap *map) const
235 {
236     if(!map)
237         return false;
238     QJsonParseError err;
239     QVariant v = QJsonDocument::fromJson(buf, &err).toVariant();
240     if(err.error != 0) {
241         qWarning() << "Error parsing json data" << err.errorString() << buf;
242         *map = QVariantMap();
243         return false;
244     }
245     *map = v.toMap();
246     return true;
247 }
248 #ifndef REAL_SERVER
249 void UserManagement::launchServer()
250 {
251       webSocketServer = new QWebSocketServer(QStringLiteral("My Server"),
252                                               QWebSocketServer::NonSecureMode, this);
253       if(webSocketServer->listen(QHostAddress::Any, 1234)) {
254           connect(webSocketServer, &QWebSocketServer::newConnection,
255                   this, &UserManagement::onServerNewConnection);
256           connect(webSocketServer, &QWebSocketServer::closed, this, &UserManagement::onServerClosed);
257           QTimer::singleShot(100, this, SLOT(connectWebsockets()));
258       } else {
259           qWarning()<<"unable to launch webSocket server";
260       }
261 }
262 void UserManagement::onServerNewConnection()
263 {
264     pSocket = webSocketServer->nextPendingConnection();
265     connect(pSocket, &QWebSocket::textMessageReceived, this, &UserManagement::processTextMessage, Qt::UniqueConnection);
266     connect(pSocket, &QWebSocket::binaryMessageReceived, this, &UserManagement::processBinaryMessage, Qt::UniqueConnection);
267     connect(pSocket, &QWebSocket::disconnected, this, &UserManagement::serverSocketDisconnected, Qt::UniqueConnection);
268 }
269 void UserManagement::processTextMessage(QString message)
270 {
271     QString clientDetails_1 = "{\"postal_address\":\"201 Mission Street\",\"loc\":\"37.7914374,-122.3950694\",\"graphActions\":\"Install App,Update Software,Exceed 100 Kph,Open Trunk,View Online\""
272                               ",\"country\":\"USA\",\"mail\":\"bjensen@example.com\",\"city\":\"San Francisco\",\"graphEmail\":"
273                               "\"bjensen@example.com\",\"graphPreferredLanguage\":\"en\",\"ccNumberMasked\":\"-111\",\"ccExpYear\""
274                               ":\"19\",\"ccExpMonth\":\"01\",\"description\":\"Original description\",\"groups\":[],\"last_name\":\""
275                               "Jensen\",\"ccNumber\":\"111-2343-1121-111\",\"house_identifier\":\"ForgeRock\",\"phone\":\""
276                               "+1 408 555 1862\",\"name\":\"bjensen\",\"state\":\"CA\",\"common_name\":\"Barbara Jensen\",\"fax\":\""
277                               "+1 408 555 1862\",\"postal_code\":\"94105\",\"first_name\":\"Barbara\",\"keytoken\":\"a123456\",\"graphPolicies\":\"Driver\"}";
278     QString clientDetails_2 = "{\"postal_address\":\"201 Mission Street\",\"loc\":\"37.7914374,-122.3950694\""
279                               ",\"country\":\"USA\",\"mail\":\"bjensen@example.com\",\"city\":\"San Francisco\",\"graphEmail\":"
280                               "\"bjensen@example.com\",\"graphPreferredLanguage\":\"fr\",\"ccNumberMasked\":\"-222\",\"ccExpYear\""
281                               ":\"19\",\"ccExpMonth\":\"01\",\"description\":\"Original description\",\"groups\":[],\"last_name\":\""
282                               "Jensen\",\"ccNumber\":\"111-2343-1121-111\",\"house_identifier\":\"ForgeRock\",\"phone\":\""
283                               "+1 408 555 1862\",\"name\":\"bjensen\",\"state\":\"CA\",\"common_name\":\"Barbara Jensen\",\"fax\":\""
284                               "+1 408 555 1862\",\"postal_code\":\"94105\",\"first_name\":\"José\",\"keytoken\":\"a123456\",\"graphPolicies\":\"Maintainer\"}";
285     QString clientDetails = clientDetails_1;
286     if(sequence % 2 == 1)
287         clientDetails = clientDetails_2;
288     QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
289     //qDebug() << "message received in server:" << message;
290     if (!pClient)
291         return;
292     QVariantList list;
293     if(!jsonToList(message.toUtf8(), &list))
294         return;
295     if(list.size() < 2)
296         return;
297     const int messType = list.at(0).toInt();
298     const QString messId = list.at(1).toString();
299     const QString cmd = list.at(2).toString();
300     list.clear();
301     QString reply;
302     switch(messType) {
303     case 2:
304         if(cmd == "agl-identity-agent/subscribe") {
305             reply = "[3,\"999maitai999\",{\"jtype\":\"afb-reply\",\"request\":{\"status\":\"success\",\"uuid\":\"1f2f7678-6f2e-4f54-b7b5-d0d4dcbf2e41\"}}]";
306         } else if (cmd == "agl-identity-agent/get") {
307             reply = "[3,\"999maitai99\",{\"jtype\":\"afb-reply\",\"request\":{\"status\":\"success\"},\"response\":....}]";
308             reply = reply.replace("....", clientDetails);
309         } else {
310             qWarning()<<"invalid cmd received:"<<cmd;
311             return;
312         }
313         break;
314     default:
315         qWarning()<<"invalid message type"<<messType;
316         return;
317         break;
318     }
319     reply = reply.replace("999maitai999", messId);
320     pClient->sendTextMessage(reply);
321 }
322 void UserManagement::processBinaryMessage(QByteArray message)
323 {
324     QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
325     qDebug() << "Binary Message received ????:" << message;
326     if (pClient) {
327        // pClient->sendBinaryMessage(message);
328     }
329 }
330 void UserManagement::serverSocketDisconnected()
331 {
332     QWebSocket *pClient = qobject_cast<QWebSocket *>(sender());
333     qDebug() << "socketDisconnected:" << pClient;
334     if (pClient) {
335         pClient->deleteLater();
336     }
337 }
338 void UserManagement::slot_timerTest()
339 {
340     if(!pSocket)
341         return;
342     if(sequence > 3) {
343         timerTest.stop();
344         return;
345     }
346     pSocket->sendTextMessage("[5,\"agl-identity-agent/event\",{\"event\":\"agl-identity-agent\/event\",\"data\":{\"eventName\":\"incoming\",\"accountid\":\"D2:D4:71:0D:B5:F1\",\"nickname\":\"D2:D4:71:0D:B5:F1\"},\"jtype\":\"afb-event\"}]");
347     pSocket->sendTextMessage("[5,\"agl-identity-agent/event\",{\"event\":\"agl-identity-agent\/event\",\"data\":{\"eventName\":\"login\",\"accountid\":\"null\"},\"jtype\":\"afb-event\"}]");
348 }
349 void UserManagement::onServerClosed()
350 {
351     qWarning()<<"websocket server closed";
352 }
353 #endif