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 }