/* ================================================ */ void SystemMessageUnit::StartEventAction() { // 積まれたイベントをこのタイミングでpush for( uint32_t i = 0; i < m_nextEventVec.size() ; ++i ){ m_eventVec.push_back( m_nextEventVec.at(i) ); } m_nextEventVec.clear(); auto it = m_eventVec.begin(); for( uint32_t i = 0; it != m_eventVec.end() ; ++i ){ if( (*it).m_delayTime == 0 ){ EventUpdate( (*it) ); it = m_eventVec.erase(it); } else{ --(*it).m_delayTime; ++it; } } }
//======================= // PRIVATE SLOTS //======================= //GENERIC SERVER SIGNALS // New Connection Signals void WebServer::NewSocketConnection(){ WebSocket *sock = 0; if(WSServer!=0){ if(WSServer->hasPendingConnections()){ QWebSocket *ws = WSServer->nextPendingConnection(); if( !allowConnection(ws->peerAddress()) ){ ws->close(); } else{ sock = new WebSocket( ws, generateID(), AUTH); } } }else if(TCPServer!=0){ if(TCPServer->hasPendingConnections()){ QSslSocket *ss = TCPServer->nextPendingConnection(); if( !allowConnection(ss->peerAddress()) ){ ss->close(); } else{ sock = new WebSocket( ss, generateID(), AUTH); } } } if(sock==0){ return; } //no new connection //qDebug() << "New Socket Connection"; connect(sock, SIGNAL(SocketClosed(QString)), this, SLOT(SocketClosed(QString)) ); connect(EVENTS, SIGNAL(NewEvent(EventWatcher::EVENT_TYPE, QJsonValue)), sock, SLOT(EventUpdate(EventWatcher::EVENT_TYPE, QJsonValue)) ); OpenSockets << sock; }
/** * @brief * Update layout hints */ void LayoutHints::Update() { // Call event EventUpdate(); }
void WebSocket::EvaluateRequest(const RestInputStruct &REQ){ RestOutputStruct out; out.in_struct = REQ; QHostAddress host; if(SOCKET!=0){ host = SOCKET->peerAddress(); } else if(TSOCKET!=0){ host = TSOCKET->peerAddress(); } if(!REQ.VERB.isEmpty() && REQ.VERB != "GET" && REQ.VERB!="POST" && REQ.VERB!="PUT"){ //Non-supported request (at the moment) - return an error message out.CODE = RestOutputStruct::BADREQUEST; }else if(out.in_struct.name.isEmpty() || out.in_struct.namesp.isEmpty() ){ //Invalid JSON structure validity //Note: id and args are optional at this stage - let the subsystems handle those inputs out.CODE = RestOutputStruct::BADREQUEST; }else{ //First check for a REST authorization (not stand-alone request) if(!out.in_struct.auth.isEmpty()){ AUTHSYSTEM->clearAuth(SockAuthToken); //new auth requested - clear any old token SockAuthToken = AUTHSYSTEM->LoginUP(host, out.in_struct.auth.section(":",0,0), out.in_struct.auth.section(":",1,1)); } //Now check the body of the message and do what it needs if(out.in_struct.namesp.toLower() == "rpc"){ if(out.in_struct.name.startsWith("auth")){ //Now perform authentication based on type of auth given //Note: This sets/changes the current SockAuthToken AUTHSYSTEM->clearAuth(SockAuthToken); //new auth requested - clear any old token if(DEBUG){ qDebug() << "Authenticate Peer:" << SOCKET->peerAddress().toString(); } //Now do the auth if(out.in_struct.name=="auth" && out.in_struct.args.isObject() ){ //username/[password/cert] authentication QString user, pass; if(out.in_struct.args.toObject().contains("username")){ user = JsonValueToString(out.in_struct.args.toObject().value("username")); } if(out.in_struct.args.toObject().contains("password")){ pass = JsonValueToString(out.in_struct.args.toObject().value("password")); } if(!pass.isEmpty()){ //Use the given password SockAuthToken = AUTHSYSTEM->LoginUP(host, user, pass); }else{ //No password - use the current SSL certificates instead QList<QSslCertificate> certs; if(SOCKET!=0){ certs = SOCKET->sslConfiguration().peerCertificateChain(); } else if(TSOCKET!=0){ certs = TSOCKET->peerCertificateChain(); } SockAuthToken = AUTHSYSTEM->LoginUC(host, user, certs); } }else if(out.in_struct.name == "auth_token" && out.in_struct.args.isObject()){ SockAuthToken = JsonValueToString(out.in_struct.args.toObject().value("token")); }else if(out.in_struct.name == "auth_clear"){ return; //don't send a return message after clearing an auth (already done) } //Now check the auth and respond appropriately if(AUTHSYSTEM->checkAuth(SockAuthToken)){ //Good Authentication - return the new token QJsonArray array; array.append(SockAuthToken); array.append(AUTHSYSTEM->checkAuthTimeoutSecs(SockAuthToken)); out.out_args = array; out.CODE = RestOutputStruct::OK; }else{ if(SockAuthToken=="REFUSED"){ out.CODE = RestOutputStruct::FORBIDDEN; } SockAuthToken.clear(); //invalid token //Bad Authentication - return error out.CODE = RestOutputStruct::UNAUTHORIZED; } }else if( AUTHSYSTEM->checkAuth(SockAuthToken) ){ //validate current Authentication token //Now provide access to the various subsystems // First get/set the permissions flag into the input structure out.in_struct.fullaccess = AUTHSYSTEM->hasFullAccess(SockAuthToken); //Pre-set any output fields QJsonObject outargs; out.CODE = EvaluateBackendRequest(out.in_struct, &outargs); out.out_args = outargs; }else{ //Bad/No authentication out.CODE = RestOutputStruct::UNAUTHORIZED; } }else if(out.in_struct.namesp.toLower() == "events"){ if( AUTHSYSTEM->checkAuth(SockAuthToken) ){ //validate current Authentication token //Pre-set any output fields QJsonObject outargs; //Assemble the list of input events QStringList evlist; if(out.in_struct.args.isObject()){ evlist << JsonValueToString(out.in_struct.args); } else if(out.in_struct.args.isArray()){ evlist = JsonArrayToStringList(out.in_struct.args.toArray()); } //Now subscribe/unsubscribe to these events int sub = -1; //bad input if(out.in_struct.name=="subscribe"){ sub = 1; } else if(out.in_struct.name=="unsubscribe"){ sub = 0; } //qDebug() << "Got Client Event Modification:" << sub << evlist; if(sub>=0 && !evlist.isEmpty() ){ for(int i=0; i<evlist.length(); i++){ EventWatcher::EVENT_TYPE type = EventWatcher::typeFromString(evlist[i]); if(type==EventWatcher::BADEVENT){ continue; } outargs.insert(out.in_struct.name,QJsonValue(evlist[i])); if(sub==1){ ForwardEvents << type; EventUpdate(type); }else{ ForwardEvents.removeAll(type); } } out.out_args = outargs; out.CODE = RestOutputStruct::OK; }else{ //Bad/No authentication out.CODE = RestOutputStruct::BADREQUEST; } }else{ //Bad/No authentication out.CODE = RestOutputStruct::UNAUTHORIZED; } //Other namespace - check whether auth has already been established before continuing }else if( AUTHSYSTEM->checkAuth(SockAuthToken) ){ //validate current Authentication token //Now provide access to the various subsystems // First get/set the permissions flag into the input structure out.in_struct.fullaccess = AUTHSYSTEM->hasFullAccess(SockAuthToken); //Pre-set any output fields QJsonObject outargs; out.CODE = EvaluateBackendRequest(out.in_struct, &outargs); out.out_args = outargs; }else{ //Error in inputs - assemble the return error message out.CODE = RestOutputStruct::UNAUTHORIZED; } //If this is a REST input - go ahead and format the output header if(out.CODE == RestOutputStruct::OK){ out.Header << "Content-Type: text/json; charset=utf-8"; } } //Return any information this->sendReply(out.assembleMessage()); if(out.CODE == RestOutputStruct::FORBIDDEN && SOCKET!=0){ SOCKET->close(QWebSocketProtocol::CloseCodeNormal, "Too Many Authorization Failures - Try again later"); } }