File indexing completed on 2024-05-26 05:14:35
0001 /*************************************************************************** 0002 * SPDX-FileCopyrightText: 2006 Till Adam <adam@kde.org> * 0003 * * 0004 * SPDX-License-Identifier: LGPL-2.0-or-later * 0005 ***************************************************************************/ 0006 #include "handler.h" 0007 0008 #include "private/scope_p.h" 0009 0010 #include "handler/collectioncopyhandler.h" 0011 #include "handler/collectioncreatehandler.h" 0012 #include "handler/collectiondeletehandler.h" 0013 #include "handler/collectionfetchhandler.h" 0014 #include "handler/collectionmodifyhandler.h" 0015 #include "handler/collectionmovehandler.h" 0016 #include "handler/collectionstatsfetchhandler.h" 0017 #include "handler/itemcopyhandler.h" 0018 #include "handler/itemcreatehandler.h" 0019 #include "handler/itemdeletehandler.h" 0020 #include "handler/itemfetchhandler.h" 0021 #include "handler/itemlinkhandler.h" 0022 #include "handler/itemmodifyhandler.h" 0023 #include "handler/itemmovehandler.h" 0024 #include "handler/loginhandler.h" 0025 #include "handler/logouthandler.h" 0026 #include "handler/relationfetchhandler.h" 0027 #include "handler/relationmodifyhandler.h" 0028 #include "handler/relationremovehandler.h" 0029 #include "handler/resourceselecthandler.h" 0030 #include "handler/searchcreatehandler.h" 0031 #include "handler/searchhandler.h" 0032 #include "handler/searchresulthandler.h" 0033 #include "handler/tagcreatehandler.h" 0034 #include "handler/tagdeletehandler.h" 0035 #include "handler/tagfetchhandler.h" 0036 #include "handler/tagmodifyhandler.h" 0037 #include "handler/transactionhandler.h" 0038 #include "storage/querybuilder.h" 0039 0040 using namespace Akonadi; 0041 using namespace Akonadi::Server; 0042 0043 std::unique_ptr<Handler> Handler::findHandlerForCommandNonAuthenticated(Protocol::Command::Type cmd, AkonadiServer &akonadi) 0044 { 0045 // allowed are LOGIN 0046 if (cmd == Protocol::Command::Login) { 0047 return std::make_unique<LoginHandler>(akonadi); 0048 } 0049 0050 return {}; 0051 } 0052 0053 std::unique_ptr<Handler> Handler::findHandlerForCommandAlwaysAllowed(Protocol::Command::Type cmd, AkonadiServer &akonadi) 0054 { 0055 // allowed is LOGOUT 0056 if (cmd == Protocol::Command::Logout) { 0057 return std::make_unique<LogoutHandler>(akonadi); 0058 } 0059 return nullptr; 0060 } 0061 0062 std::unique_ptr<Handler> Handler::findHandlerForCommandAuthenticated(Protocol::Command::Type cmd, AkonadiServer &akonadi) 0063 { 0064 switch (cmd) { 0065 case Protocol::Command::Invalid: 0066 Q_ASSERT_X(cmd != Protocol::Command::Invalid, __FUNCTION__, "Invalid command is not allowed"); 0067 return {}; 0068 case Protocol::Command::Hello: 0069 Q_ASSERT_X(cmd != Protocol::Command::Hello, __FUNCTION__, "Hello command is not allowed in this context"); 0070 return {}; 0071 case Protocol::Command::Login: 0072 case Protocol::Command::Logout: 0073 return {}; 0074 case Protocol::Command::_ResponseBit: 0075 Q_ASSERT_X(cmd != Protocol::Command::_ResponseBit, __FUNCTION__, "ResponseBit is not a valid command type"); 0076 return {}; 0077 0078 case Protocol::Command::Transaction: 0079 return std::make_unique<TransactionHandler>(akonadi); 0080 0081 case Protocol::Command::CreateItem: 0082 return std::make_unique<ItemCreateHandler>(akonadi); 0083 case Protocol::Command::CopyItems: 0084 return std::make_unique<ItemCopyHandler>(akonadi); 0085 case Protocol::Command::DeleteItems: 0086 return std::make_unique<ItemDeleteHandler>(akonadi); 0087 case Protocol::Command::FetchItems: 0088 return std::make_unique<ItemFetchHandler>(akonadi); 0089 case Protocol::Command::LinkItems: 0090 return std::make_unique<ItemLinkHandler>(akonadi); 0091 case Protocol::Command::ModifyItems: 0092 return std::make_unique<ItemModifyHandler>(akonadi); 0093 case Protocol::Command::MoveItems: 0094 return std::make_unique<ItemMoveHandler>(akonadi); 0095 0096 case Protocol::Command::CreateCollection: 0097 return std::make_unique<CollectionCreateHandler>(akonadi); 0098 case Protocol::Command::CopyCollection: 0099 return std::make_unique<CollectionCopyHandler>(akonadi); 0100 case Protocol::Command::DeleteCollection: 0101 return std::make_unique<CollectionDeleteHandler>(akonadi); 0102 case Protocol::Command::FetchCollections: 0103 return std::make_unique<CollectionFetchHandler>(akonadi); 0104 case Protocol::Command::FetchCollectionStats: 0105 return std::make_unique<CollectionStatsFetchHandler>(akonadi); 0106 case Protocol::Command::ModifyCollection: 0107 return std::make_unique<CollectionModifyHandler>(akonadi); 0108 case Protocol::Command::MoveCollection: 0109 return std::make_unique<CollectionMoveHandler>(akonadi); 0110 0111 case Protocol::Command::Search: 0112 return std::make_unique<SearchHandler>(akonadi); 0113 case Protocol::Command::SearchResult: 0114 return std::make_unique<SearchResultHandler>(akonadi); 0115 case Protocol::Command::StoreSearch: 0116 return std::make_unique<SearchCreateHandler>(akonadi); 0117 0118 case Protocol::Command::CreateTag: 0119 return std::make_unique<TagCreateHandler>(akonadi); 0120 case Protocol::Command::DeleteTag: 0121 return std::make_unique<TagDeleteHandler>(akonadi); 0122 case Protocol::Command::FetchTags: 0123 return std::make_unique<TagFetchHandler>(akonadi); 0124 case Protocol::Command::ModifyTag: 0125 return std::make_unique<TagModifyHandler>(akonadi); 0126 0127 case Protocol::Command::FetchRelations: 0128 return std::make_unique<RelationFetchHandler>(akonadi); 0129 case Protocol::Command::ModifyRelation: 0130 return std::make_unique<RelationModifyHandler>(akonadi); 0131 case Protocol::Command::RemoveRelations: 0132 return std::make_unique<RelationRemoveHandler>(akonadi); 0133 0134 case Protocol::Command::SelectResource: 0135 return std::make_unique<ResourceSelectHandler>(akonadi); 0136 0137 case Protocol::Command::StreamPayload: 0138 Q_ASSERT_X(cmd != Protocol::Command::StreamPayload, __FUNCTION__, "StreamPayload command is not allowed in this context"); 0139 return {}; 0140 0141 case Protocol::Command::ItemChangeNotification: 0142 Q_ASSERT_X(cmd != Protocol::Command::ItemChangeNotification, __FUNCTION__, "ItemChangeNotification command is not allowed on this connection"); 0143 return {}; 0144 case Protocol::Command::CollectionChangeNotification: 0145 Q_ASSERT_X(cmd != Protocol::Command::CollectionChangeNotification, 0146 __FUNCTION__, 0147 "CollectionChangeNotification command is not allowed on this connection"); 0148 return {}; 0149 case Protocol::Command::TagChangeNotification: 0150 Q_ASSERT_X(cmd != Protocol::Command::TagChangeNotification, __FUNCTION__, "TagChangeNotification command is not allowed on this connection"); 0151 return {}; 0152 case Protocol::Command::RelationChangeNotification: 0153 Q_ASSERT_X(cmd != Protocol::Command::RelationChangeNotification, __FUNCTION__, "RelationChangeNotification command is not allowed on this connection"); 0154 return {}; 0155 case Protocol::Command::SubscriptionChangeNotification: 0156 Q_ASSERT_X(cmd != Protocol::Command::SubscriptionChangeNotification, 0157 __FUNCTION__, 0158 "SubscriptionChangeNotification command is not allowed on this connection"); 0159 return {}; 0160 case Protocol::Command::DebugChangeNotification: 0161 Q_ASSERT_X(cmd != Protocol::Command::DebugChangeNotification, __FUNCTION__, "DebugChangeNotification command is not allowed on this connection"); 0162 return {}; 0163 case Protocol::Command::ModifySubscription: 0164 Q_ASSERT_X(cmd != Protocol::Command::ModifySubscription, __FUNCTION__, "ModifySubscription command is not allowed on this connection"); 0165 return {}; 0166 case Protocol::Command::CreateSubscription: 0167 Q_ASSERT_X(cmd != Protocol::Command::CreateSubscription, __FUNCTION__, "CreateSubscription command is not allowed on this connection"); 0168 return {}; 0169 } 0170 0171 return {}; 0172 } 0173 0174 Handler::Handler(AkonadiServer &akonadi) 0175 : m_akonadi(akonadi) 0176 { 0177 } 0178 0179 void Handler::setTag(quint64 tag) 0180 { 0181 m_tag = tag; 0182 } 0183 0184 quint64 Handler::tag() const 0185 { 0186 return m_tag; 0187 } 0188 0189 void Handler::setCommand(const Protocol::CommandPtr &cmd) 0190 { 0191 m_command = cmd; 0192 } 0193 0194 Protocol::CommandPtr Handler::command() const 0195 { 0196 return m_command; 0197 } 0198 0199 void Handler::setConnection(Connection *connection) 0200 { 0201 m_connection = connection; 0202 } 0203 0204 Connection *Handler::connection() const 0205 { 0206 return m_connection; 0207 } 0208 0209 DataStore *Handler::storageBackend() const 0210 { 0211 return m_connection->storageBackend(); 0212 } 0213 0214 AkonadiServer &Handler::akonadi() const 0215 { 0216 return m_akonadi; 0217 } 0218 0219 bool Handler::failureResponse(const QByteArray &failureMessage) 0220 { 0221 return failureResponse(QString::fromUtf8(failureMessage)); 0222 } 0223 0224 bool Handler::failureResponse(const char *failureMessage) 0225 { 0226 return failureResponse(QString::fromUtf8(failureMessage)); 0227 } 0228 0229 bool Handler::failureResponse(const QString &failureMessage) 0230 { 0231 // Prevent sending multiple error responses from a single handler (or from 0232 // a handler and then from Connection, since clients only expect a single 0233 // error response 0234 if (!m_sentFailureResponse) { 0235 m_sentFailureResponse = true; 0236 Protocol::ResponsePtr r = Protocol::Factory::response(m_command->type()); 0237 // FIXME: Error enums? 0238 r->setError(1, failureMessage); 0239 0240 m_connection->sendResponse(m_tag, r); 0241 } 0242 0243 return false; 0244 } 0245 0246 bool Handler::checkScopeConstraints(const Akonadi::Scope &scope, int permittedScopes) 0247 { 0248 return scope.scope() & permittedScopes; 0249 }