From c1dd356bf41503a0e84f091fed80f7465b6718ff Mon Sep 17 00:00:00 2001 From: Zofia Abramowska Date: Wed, 21 Jun 2017 16:38:59 +0200 Subject: [PATCH] Update service side to new requirements * No more toasts - remove datagram socket * Popup request passes only privilege as argument * Add credentials to service callbacks Change-Id: I86ef7253490dcd2c063943f9225dacc6b0f626bc --- packaging/askuser-notification.spec | 2 - src/agent/notification-daemon/Logic.cpp | 28 +++++++- src/agent/notification-daemon/Logic.h | 14 +++- src/agent/notification-daemon/ServerCallbacks.cpp | 25 +++---- src/agent/notification-daemon/ServerCallbacks.h | 12 ++-- .../askuser-notification/ask-user-service.h | 43 +++++++---- src/common/protocol/channel.cpp | 83 ++++++++++------------ src/common/protocol/channel.h | 6 +- src/common/protocol/main.cpp | 35 +++------ systemd/CMakeLists.txt | 1 - systemd/askuser-notification-datagram.socket | 8 --- 11 files changed, 126 insertions(+), 131 deletions(-) delete mode 100644 systemd/askuser-notification-datagram.socket diff --git a/packaging/askuser-notification.spec b/packaging/askuser-notification.spec index 6582d20..25abc25 100644 --- a/packaging/askuser-notification.spec +++ b/packaging/askuser-notification.spec @@ -83,7 +83,6 @@ rm -rf %{buildroot} %if %{with_systemd_daemon} mkdir -p %{buildroot}/%{_unitdir_user}/sockets.target.wants ln -s ../askuser-notification-stream.socket %{buildroot}/%{_unitdir_user}/sockets.target.wants/askuser-notification-stream.socket -ln -s ../askuser-notification-datagram.socket %{buildroot}/%{_unitdir_user}/sockets.target.wants/askuser-notification-datagram.socket %endif %post @@ -106,7 +105,6 @@ systemctl daemon-reload %if %{with_systemd_daemon} %{_unitdir_user}/askuser-notification.service %{_unitdir_user}/askuser-notification-stream.socket -%{_unitdir_user}/askuser-notification-datagram.socket %{_unitdir_user}/sockets.target.wants/* %endif %{_datadir}/askuser-notification/res/* diff --git a/src/agent/notification-daemon/Logic.cpp b/src/agent/notification-daemon/Logic.cpp index e55730e..d333e0e 100644 --- a/src/agent/notification-daemon/Logic.cpp +++ b/src/agent/notification-daemon/Logic.cpp @@ -36,7 +36,21 @@ namespace AskUser { namespace Notification { -void Logic::addChannelFd(int fd, Ecore_Fd_Handler_Flags flags) { +void Logic::addChannelFd(Protocol::ConnectionFd fd, const Protocol::Credentials &creds) { + // TODO check if doesn't already exist + // TODO translate to appId, pkgId and appIds from package + auto it = m_connToInfo.find(fd); + if (it != m_connToInfo.end()) { + ALOGE("Connection with fd : " << fd << " already exists. Closing connection"); + m_clientChannel->process(fd, 0); + return; + } + (void)creds; + ConnectionInfo connInfo; + m_connToInfo.insert(it, std::make_pair(fd, connInfo)); +} + +void Logic::updateChannelFd(Protocol::ConnectionFd fd, Ecore_Fd_Handler_Flags flags) { auto it = m_fdInfo.find(fd); if (it != m_fdInfo.end()) { m_fdInfo[fd].status = FdChange::CHANGE; @@ -52,7 +66,8 @@ void Logic::addChannelFd(int fd, Ecore_Fd_Handler_Flags flags) { m_fdInfo[fd].status = FdChange::NONE; } -void Logic::removeChannelFd(int fd) { +void Logic::removeChannelFd(Protocol::ConnectionFd fd) { + m_connToInfo.erase(fd); auto it = m_fdInfo.find(fd); if (it == m_fdInfo.end()) { return; @@ -111,6 +126,12 @@ void Logic::addEvent(IUIEvent *event) { processEvents(); } +void Logic::popup(Protocol::ConnectionFd fd, Protocol::RequestId id, std::string &&privilege) { + (void)fd; + (void)id; + (void)privilege; +} + bool Logic::isEventProcessed() { return m_currentEventId != -1; } @@ -227,7 +248,8 @@ void Logic::popupResponse(int popupId, NResponseType response) { default: clientResponse = -255; // error } - m_clientChannel->popupResponse(popupId, clientResponse); + // TODO create popup ids containing fd and request id + m_clientChannel->popupResponse(-1, popupId, clientResponse); finishCurrentEvent(); processEvents(); } diff --git a/src/agent/notification-daemon/Logic.h b/src/agent/notification-daemon/Logic.h index 95fe8bc..9bb0c8b 100644 --- a/src/agent/notification-daemon/Logic.h +++ b/src/agent/notification-daemon/Logic.h @@ -46,10 +46,12 @@ public: void run(); void stop(); - void addChannelFd(int fd, Ecore_Fd_Handler_Flags flags); - void removeChannelFd(int fd); + void addChannelFd(Protocol::ConnectionFd fd, const Protocol::Credentials &creds); + void updateChannelFd(Protocol::ConnectionFd fd, Ecore_Fd_Handler_Flags flags); + void removeChannelFd(Protocol::ConnectionFd fd); void addEvent(IUIEvent *event); + void popup(Protocol::ConnectionFd fd, Protocol::RequestId id, std::string &&privilege); ~Logic() {} private: @@ -96,6 +98,14 @@ private: }; std::map m_fdInfo; + + struct ConnectionInfo { + std::string appId; + std::string pkgId; + std::vector apps; + }; + + std::map m_connToInfo; }; } // namespace Notification diff --git a/src/agent/notification-daemon/ServerCallbacks.cpp b/src/agent/notification-daemon/ServerCallbacks.cpp index 97ac799..b8c7825 100644 --- a/src/agent/notification-daemon/ServerCallbacks.cpp +++ b/src/agent/notification-daemon/ServerCallbacks.cpp @@ -37,28 +37,19 @@ Ecore_Fd_Handler_Flags maskToFlags(int mask) { namespace AskUser { namespace Protocol { -void ServerCallbacks::updateFd(int fd, int mask) { +void ServerCallbacks::newConnection(ConnectionFd fd, const Credentials &creds) { + m_service->addChannelFd(fd, creds); +} + +void ServerCallbacks::updateConnection(ConnectionFd fd, int mask) { if (mask == 0) m_service->removeChannelFd(fd); else - m_service->addChannelFd(fd, maskToFlags(mask)); + m_service->updateChannelFd(fd, maskToFlags(mask)); } -void ServerCallbacks::popup_launch(int requestId, const std::string &pkgName, - const std::string &appName, uid_t, - const AskUser::Protocol::PrivilegeVector &privileges) -{ - m_service->addEvent(new AskUser::Notification::EventPopupLaunch(m_popupper, requestId, appName, pkgName, privileges)); -} -void ServerCallbacks::toast_deny(const std::string &pkgName, const std::string &appName, - uid_t, const AskUser::Protocol::Privilege &privilege) -{ - m_service->addEvent(new AskUser::Notification::EventToastDeny(m_popupper, 0, appName, pkgName, privilege)); -} -void ServerCallbacks::toast_fail_launch(const std::string &pkgName, const std::string &appName, - uid_t) -{ - m_service->addEvent(new AskUser::Notification::EventToastFail(m_popupper, 0, appName, pkgName)); +void ServerCallbacks::popup(ConnectionFd fd, RequestId id, std::string &&privilege) { + m_service->popup(fd, id, std::move(privilege)); } } /* namespace Notification */ diff --git a/src/agent/notification-daemon/ServerCallbacks.h b/src/agent/notification-daemon/ServerCallbacks.h index f8ca6fb..d2f9101 100644 --- a/src/agent/notification-daemon/ServerCallbacks.h +++ b/src/agent/notification-daemon/ServerCallbacks.h @@ -35,14 +35,10 @@ public: ServerCallbacks(AskUser::Notification::Logic *logic, AskUser::Notification::Popupper *popupper) : m_service(logic), m_popupper(popupper) {} - virtual void updateFd(int fd, int mask); - virtual void popup_launch(int requestId, const std::string &pkgName, - const std::string &appName, uid_t uid, - const AskUser::Protocol::PrivilegeVector &privileges); - virtual void toast_deny(const std::string &pkgName, const std::string &appName, - uid_t uid, const AskUser::Protocol::Privilege &privilege); - virtual void toast_fail_launch(const std::string &pkgName, const std::string &appName, - uid_t uid); + virtual void newConnection(ConnectionFd fd, const Credentials &creds); + virtual void updateConnection(ConnectionFd fd, int mask); + virtual void popup(ConnectionFd fd, RequestId id, std::string &&privilege); + virtual ~ServerCallbacks() {} private: AskUser::Notification::Logic *m_service; diff --git a/src/common/protocol/askuser-notification/ask-user-service.h b/src/common/protocol/askuser-notification/ask-user-service.h index 3761d07..8fb5b93 100644 --- a/src/common/protocol/askuser-notification/ask-user-service.h +++ b/src/common/protocol/askuser-notification/ask-user-service.h @@ -31,11 +31,19 @@ namespace AskUser { namespace Protocol { +typedef int ConnectionFd; +typedef int RequestId; + enum FdMask { READ = 1, WRITE = 2, }; +struct Credentials { + std::string label; + uid_t uid; +}; + /** * IServiceCallbacks defines set of callbacks that must be implemented in service. */ @@ -44,28 +52,33 @@ struct IServerCallbacks { virtual ~IServerCallbacks(){} /** + * This function is called when new peer connection is established. + * Fd is file descriptor for this new peer connection. + * + * \param[in] fd Connection file descriptor + */ + virtual void newConnection(ConnectionFd fd, const Credentials &creds) = 0; + + /** * This function gives you number of descriptor that should be watched by poll/select. * - * \param[in] fd Number of opened descriptor. + * \param[in] fd Connection file descriptor * \param[in] mask Type of acction that is required on this descriptor. * mask == 0 remove descriptor fd from watched pool * mask == 1 watch descriptor for READ * mask == 2 watch descriptor for WRITE * maks == 3 watch descriptor for READ and WRITE */ - virtual void updateFd(int fd, int mask) = 0; - /** - * some client called popup function with parameters. - */ - virtual void popup_launch(int requestId, const std::string &pkgName, const std::string &appName, uid_t uid, const PrivilegeVector &privileges) = 0; - /** - * some client called test_deny function with parameters. - */ - virtual void toast_deny(const std::string &pkgName, const std::string &appName, uid_t uid, const Privilege &privilege) = 0; + virtual void updateConnection(ConnectionFd fd, int mask) = 0; + /** - * some client called toast_fail_launch function with parameters. + * This function is called when popup request is received. + * + * \param[in] fd Connection file descriptor + * \param[in] id Request identifier + * \param[in] privilege Privilege for which permission is asked for */ - virtual void toast_fail_launch(const std::string &pkgName, const std::string &appName, uid_t uid) = 0; + virtual void popup(ConnectionFd fd, RequestId id, std::string &&privilege) = 0; }; struct IChannel { @@ -84,12 +97,12 @@ struct IChannel { virtual void process(int fd, int mask) = 0; /** - * Information about action that was choosed by user. + * Information about action that was chosen by user. * * \param[in] requestId Request number. - * \param[in] response Information about action choosed by user. + * \param[in] response Information about action chosen by user. */ - virtual void popupResponse(int requestId, int response) = 0; + virtual void popupResponse(ConnectionFd fd, RequestId id, int response) = 0; }; typedef std::unique_ptr ChannelPtr; diff --git a/src/common/protocol/channel.cpp b/src/common/protocol/channel.cpp index 3b9c46d..f05f038 100644 --- a/src/common/protocol/channel.cpp +++ b/src/common/protocol/channel.cpp @@ -18,7 +18,10 @@ * @author Bartlomiej Grzelewski * @brief */ + +#include #include +#include #include @@ -31,19 +34,12 @@ namespace Protocol { void Channel::init() { Sock stream(Sock::SRV_STREAM); - Sock datagram(Sock::SRV_DGRAM); - stream.connect(getStreamSocketPath(getuid())); - datagram.connect(getDatagramSocketPath(getuid())); - - int fd1 = stream.getFd(); - int fd2 = datagram.getFd(); - m_socket[fd1] = SockDesc(std::move(stream)); - m_socket[fd2] = SockDesc(std::move(datagram)); + int fd = stream.getFd(); + m_sockets[fd] = SockDesc(std::move(stream)); - m_callbacks->updateFd(fd1, FdMask::READ); - m_callbacks->updateFd(fd2, FdMask::READ); + m_callbacks->updateConnection(fd, FdMask::READ); } void Channel::parse(const std::string &data, std::vector &parsedData) @@ -65,13 +61,13 @@ void Channel::parse(const std::string &data, std::vector &parsedDat void Channel::process(int fd, int mask) { try { - auto it = m_socket.find(fd); - if (it == m_socket.end()) + auto it = m_sockets.find(fd); + if (it == m_sockets.end()) return; if (0 == mask) { - m_callbacks->updateFd(fd, 0); - m_socket.erase(it); + m_callbacks->updateConnection(fd, 0); + m_sockets.erase(it); return; } @@ -82,8 +78,9 @@ void Channel::process(int fd, int mask) { int fd = client.getFd(); if (fd < 0) return; - m_socket[fd] = SockDesc(std::move(client)); - m_callbacks->updateFd(fd, FdMask::READ); + m_sockets[fd] = SockDesc(std::move(client)); + m_callbacks->newConnection(fd, Credentials()); + m_callbacks->updateConnection(fd, FdMask::READ); return; } @@ -91,8 +88,8 @@ void Channel::process(int fd, int mask) { int ret = desc.sock.recv(desc.input); if (ret <= 0) { - m_callbacks->updateFd(fd, 0); - m_socket.erase(fd); + m_callbacks->updateConnection(fd, 0); + m_sockets.erase(fd); return; } @@ -101,28 +98,20 @@ void Channel::process(int fd, int mask) { desc.input.clear(); int command = std::stoi(params[0]); - std::string &pkgName = params[1]; - std::string &appName = params[2]; - uid_t uid = std::stoi(params[3]); + switch (command) { case MSGID_POPUP: { - PrivilegeVector vect(params.begin() + 4, params.end()); - m_callbacks->popup_launch(fd, pkgName, appName, uid, vect); - break; - } - case MSGID_TOAST1: - { - std::string &privilege = params[4]; - m_callbacks->toast_deny(pkgName, appName, uid, privilege); - break; - } - case MSGID_TOAST2: - { - m_callbacks->toast_fail_launch(pkgName, appName, uid); + std::string &privilege = params[1]; + RequestId id = std::strtol(params[2].c_str(), nullptr, 10); + m_callbacks->popup(fd, id, std::move(privilege)); break; } + default : + // TODO log the error + m_callbacks->updateConnection(fd, 0); + m_sockets.erase(fd); } } @@ -130,40 +119,44 @@ void Channel::process(int fd, int mask) { int size = static_cast(desc.output.size()); int result = desc.sock.send(desc.output); if (result < 0) { - m_callbacks->updateFd(fd, 0); - m_socket.erase(fd); + m_callbacks->updateConnection(fd, 0); + m_sockets.erase(fd); return; } if (result == size) { desc.output.clear(); - m_callbacks->updateFd(fd, FdMask::READ); + m_callbacks->updateConnection(fd, FdMask::READ); } if (result < size) { desc.output.erase(desc.output.begin(), desc.output.begin()+result); } } - } catch (const std::exception &){} + } catch (const std::exception &){ + // TODO handle error + } } -void Channel::popupResponse(int requestId, int response) { +void Channel::popupResponse(ConnectionFd fd, RequestId id, int response) { try { - auto it = m_socket.find(requestId); - if (it == m_socket.end()) + auto it = m_sockets.find(fd); + if (it == m_sockets.end()) return; auto &desc = it->second; - std::string o = std::to_string(response); + std::stringstream ss; + ss << id << " " << response; + std::string o = ss.str(); std::copy(o.begin(), o.end(), std::back_inserter(desc.output)); - m_callbacks->updateFd(requestId, FdMask::READ | FdMask::WRITE); + m_callbacks->updateConnection(fd, FdMask::READ | FdMask::WRITE); } catch (const std::exception &){} } Channel::~Channel() { - for (auto &e : m_socket) - m_callbacks->updateFd(e.first, 0); + for (auto &e : m_sockets) + m_callbacks->updateConnection(e.first, 0); } ChannelPtr createChannel(ServerCallbacksPtr ptr) { diff --git a/src/common/protocol/channel.h b/src/common/protocol/channel.h index 9ed90aa..86cac71 100644 --- a/src/common/protocol/channel.h +++ b/src/common/protocol/channel.h @@ -53,15 +53,15 @@ public: {} void init(); - virtual void process(int fd, int mask); - virtual void popupResponse(int requestId, int response); + virtual void process(ConnectionFd fd, int mask); + virtual void popupResponse(ConnectionFd fd, RequestId id, int response); virtual ~Channel(); private: virtual void parse(const std::string &data, std::vector &parsedData); ServerCallbacksPtr m_callbacks; - SocketMap m_socket; + SocketMap m_sockets; }; } // namespace Protocol diff --git a/src/common/protocol/main.cpp b/src/common/protocol/main.cpp index 5d2f31f..f3d6965 100644 --- a/src/common/protocol/main.cpp +++ b/src/common/protocol/main.cpp @@ -35,7 +35,11 @@ using namespace AskUser::Protocol; struct Callbacks : public IServerCallbacks { Callbacks() : m_channel(nullptr) {} - virtual void updateFd(int fd, int mask) { + virtual void newConnection(ConnectionFd fd, const Credentials &creds) { + (void)fd; + (void)creds; + } + virtual void updateConnection(ConnectionFd fd, int mask) { printf("call updateFd %d %d\n", fd, mask); if (mask == 0) { m_sockets.erase(fd); @@ -44,18 +48,10 @@ struct Callbacks : public IServerCallbacks { m_sockets[fd] = mask; } - virtual void popup_launch(int requestId, const std::string &pkgName, const std::string &appName, uid_t uid, UNUSED const PrivilegeVector &priv) { - printf("call popup %s %s %d\n", pkgName.c_str(), appName.c_str(), uid); + virtual void popup(ConnectionFd fd, RequestId id, Privilege &&priv) { + printf("call popup %s \n", priv.c_str()); if (m_channel) - m_channel->popupResponse(requestId, 0xdeadbeef); - } - - virtual void toast_deny(const std::string &pkgName, const std::string &appName, uid_t uid, UNUSED const Privilege &privilege) { - printf("call toast_deny %s %s %d\n", pkgName.c_str(), appName.c_str(), uid); - } - - virtual void toast_fail_launch(const std::string &pkgName, const std::string &appName, uid_t uid) { - printf("call toast_fail_launch %s %s %d\n", pkgName.c_str(), appName.c_str(), uid); + m_channel->popupResponse(fd, id, 0xdeadbeef); } void setChannel(IChannel *ptr) { @@ -101,15 +97,6 @@ void stream() { printf("Sended stream. Result: %x\n", result); } -void toust1() { - toast_deny("org.tizen.memo", "org.tizen.memo", getuid(), "http://tizen.org/privilege/camera"); - printf("sended\n"); -} - -void toust2() { - toast_fail_launch("org.tizen.memo", "org.tizen.memo", getuid()); - printf("sended\n"); -} int main(){ int com; @@ -123,12 +110,6 @@ int main(){ case 1: stream(); break; - case 2: - toust1(); - break; - case 3: - toust2(); - break; } return 0; diff --git a/systemd/CMakeLists.txt b/systemd/CMakeLists.txt index 334c3c7..638b14c 100644 --- a/systemd/CMakeLists.txt +++ b/systemd/CMakeLists.txt @@ -28,7 +28,6 @@ IF (BUILD_ASKUSER_NOTIFICATION) INSTALL(FILES ${CMAKE_SOURCE_DIR}/systemd/askuser-notification.service ${CMAKE_SOURCE_DIR}/systemd/askuser-notification-stream.socket - ${CMAKE_SOURCE_DIR}/systemd/askuser-notification-datagram.socket DESTINATION lib/systemd/user ) diff --git a/systemd/askuser-notification-datagram.socket b/systemd/askuser-notification-datagram.socket deleted file mode 100644 index 924250c..0000000 --- a/systemd/askuser-notification-datagram.socket +++ /dev/null @@ -1,8 +0,0 @@ -[Socket] -ListenDatagram=/run/user_ext/%U/askuser-notification-datagram.socket -SocketMode=0777 - -Service=askuser-notification.service - -[Install] -WantedBy=sockets.target -- 2.7.4