/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set et sw=2 ts=2: */ /*************************************************************************** * messagehandler.cc * * Mon Mar 26 15:35:24 CEST 2012 * Copyright 2012 Jonas Suhr Christensen * jsc@umbraculum.org ****************************************************************************/ /* * This file is part of Munia. * * Munia is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Munia 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Munia; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "messagehandler.h" #include "hugin.hpp" // Defines global node_manager object #include "nodemanager.h" #include "messageparser.h" #include "errorcodes.h" MessageList handle_msg(MessageList msgList, clientid_t wsi) { MessageList outmsgs; MessageList::iterator it; for(it = msgList.begin(); it != msgList.end(); it++) { message_t &m = *it; if(m.cmd == cmd::login) { connection_handler.login(wsi, m.login.user, m.login.password); if(!connection_handler.authenticated(wsi)) { outmsgs.push_back(create_msg_error(ErrorCode::LoginFailed, "Bad username or password.", wsi)); continue; } } // If client is not authenticated; do not continue beyond this point... if(!connection_handler.authenticated(wsi)) { outmsgs.push_back(create_msg_error(ErrorCode::Unauthorized, "Not authorized.", wsi)); continue; } switch(m.cmd) { case cmd::login: // Already handled, before this switch ... case INFO(messagehandler, "Handling login command\n"); break; case cmd::logout: INFO(messagehandler, "Handling logout command\n"); connection_handler.logout(wsi); break; case cmd::create_with_attributes: // Never sent to the server INFO(messagehandler, "Handling create_with_attributes command\n"); break; case cmd::create: { INFO(messagehandler, "Handling create command\n"); try { m.nodes = node_manager.createNode(m.create.parentid, m.create.id, m.create.insertbeforeid); outmsgs.push_back(m); } catch (const ErrorMessage& e) { // Set client id (wsi) and forward upstream outmsgs.push_back(create_msg_error(e, wsi)); } catch (...) { outmsgs.push_back(create_msg_error(ErrorCode::Unknown, "Unknown create error", wsi)); } } break; case cmd::remove: { INFO(messagehandler, "Handling remove command\n"); try { NodeIdList ids = node_manager.subNodes(m.remove.id); NodeIdList::reverse_iterator id = ids.rbegin(); while(id != ids.rend()) { node_t node = node_manager.node(*id); message_t m = create_msg_remove(node); m.nodes = node_manager.removeNode(node.id); outmsgs.push_back(m); id++; } } catch (const ErrorMessage& e) { // Set client id (wsi) and forward upstream outmsgs.push_back(create_msg_error(e, wsi)); } catch (...) { outmsgs.push_back(create_msg_error(ErrorCode::Unknown, "Unknown remove error", wsi)); } } break; case cmd::move: { INFO(messagehandler, "Handling move command\n"); try { node_t removenode = node_manager.node(m.move.id); NodeIdListPair tilpair = node_manager.moveNode(m.move.id, m.move.parentid, m.move.insertbeforeid); node_t createnode = node_manager.node(m.move.id); message_t removemsg = create_msg_remove(removenode); removemsg.nodes = tilpair.first; message_t createmsg = create_msg_create_with_attributes(createnode, m.move.insertbeforeid); createmsg.create.attributes = createnode.attributes; for(const auto& child_node_id : node_manager.subNodes(m.move.id)) { if(child_node_id == m.move.id) { continue; } auto child_node = node_manager.node(child_node_id); create_t child; child.id = child_node.id; child.parentid = child_node.parentid; child.insertbeforeid = -1; child.attributes = child_node.attributes; createmsg.create.children.push_back(child); } createmsg.nodes = tilpair.second; outmsgs.push_back(removemsg); outmsgs.push_back(createmsg); } catch (const ErrorMessage& e) { // Set client id (wsi) and forward upstream outmsgs.push_back(create_msg_error(e, wsi)); } catch (...) { outmsgs.push_back(create_msg_error(ErrorCode::Unknown, "Unknown move error", wsi)); } } break; case cmd::subscribe: INFO(messagehandler, "Handling subscribe command\n"); outmsgs.push_back(m); break; case cmd::unsubscribe: INFO(messagehandler, "Handling unsubscribe command\n"); outmsgs.push_back(m); break; case cmd::update: { INFO(messagehandler, "Handling update command\n"); try { m.nodes = node_manager.updateNode(m.update.id, m.update.attribute, m.update.value); outmsgs.push_back(m); } catch (const ErrorMessage& e) { // Set client id (wsi) and forward upstream outmsgs.push_back(create_msg_error(e, wsi)); } catch (...) { outmsgs.push_back(create_msg_error(ErrorCode::Unknown, "Unknown update error", wsi)); } } break; case cmd::error: INFO(messagehandler, "Handling error command\n"); outmsgs.push_back(m); // Just forward the error message break; } } return outmsgs; }