Make get scannable files credential-aware 55/68255/1
authorKyungwook Tak <k.tak@samsung.com>
Tue, 3 May 2016 06:48:17 +0000 (15:48 +0900)
committerKyungwook Tak <k.tak@samsung.com>
Tue, 3 May 2016 06:48:17 +0000 (15:48 +0900)
For files which are readable by server...
  - and removable by client
    -> list given to client
  - and unremovable by client
    -> list not given to client but scanning task of them
       is submitted to workqueue so as to perform in background

Change-Id: I94d358f16d6781cc002e96c844b45e4d7fe59fd4
Signed-off-by: Kyungwook Tak <k.tak@samsung.com>
src/framework/db/manager.cpp
src/framework/db/manager.h
src/framework/service/logic.cpp
src/framework/service/logic.h
src/framework/service/server-service.cpp
src/framework/service/server-service.h

index 784b5ca..4275c09 100644 (file)
@@ -190,7 +190,7 @@ time_t Manager::getLastScanTime(const std::string &dir,
        return stmt.step() ? static_cast<time_t>(stmt.getInt64()) : -1;
 }
 
-void Manager::insertLastScanTime(const std::string &dir, long scanTime,
+void Manager::insertLastScanTime(const std::string &dir, time_t scanTime,
                                                                 const std::string &dataVersion)
 {
        Statement stmt(m_conn, Query::INS_SCAN_REQUEST);
index 4ad4c65..ae2fb75 100644 (file)
@@ -46,7 +46,7 @@ public:
 
        // SCAN_REQUEST
        time_t getLastScanTime(const std::string &dir, const std::string &dataVersion);
-       void insertLastScanTime(const std::string &dir, long scanTime,
+       void insertLastScanTime(const std::string &dir, time_t scanTime,
                                                        const std::string &dataVersion);
        void deleteLastScanTime(const std::string &dir);
        void cleanLastScanTime();
index fe025af..af0264a 100644 (file)
 #include <string>
 #include <utility>
 #include <algorithm>
+#include <ctime>
 #include <climits>
 
 #include "common/audit/logger.h"
 #include "common/exception.h"
 #include "service/type-converter.h"
 #include "service/file-system.h"
+#include "service/access-control.h"
 #include "ui/askuser.h"
 #include "csr/error.h"
 
 namespace Csr {
 
-Logic::Logic() :
+Logic::Logic(ThreadPool &pool) :
+       m_workqueue(pool),
        m_cs(new CsLoader(CS_ENGINE_PATH)),
        m_wp(new WpLoader(WP_ENGINE_PATH)),
        m_db(new Db::Manager(RW_DBSPACE "/.csr.db", RO_DBSPACE))
@@ -239,11 +242,12 @@ RawBuffer Logic::scanFile(const CsContext &context, const std::string &filepath)
        return BinaryQueue::Serialize(CSR_ERROR_NONE, history).pop();
 }
 
-RawBuffer Logic::getScannableFiles(const std::string &dir)
+RawBuffer Logic::getScannableFiles(const Credential &cred, const std::string &dir)
 {
        auto lastScanTime = m_db->getLastScanTime(dir, m_csDataVersion);
 
-       StrSet fileset;
+       StrSet filesetForClient;
+       auto filesetForServer = std::make_shared<StrSet>();
        try {
                auto visitor = FsVisitor::create(dir, lastScanTime);
 
@@ -252,7 +256,10 @@ RawBuffer Logic::getScannableFiles(const std::string &dir)
 
                while (auto file = visitor->next()) {
                        DEBUG("In dir[" << dir << "], Scannable file[" << file->getPath() << "]");
-                       fileset.insert(file->getPath());
+                       if (hasPermToRemove(cred, file->getPath()))
+                               filesetForClient.insert(file->getPath());
+                       else
+                               filesetForServer->insert(file->getPath());
                }
        } catch (const FileDoNotExist &) {
                WARN("Directory isn't exist: " << dir << " return success with empty file set "
@@ -267,10 +274,44 @@ RawBuffer Logic::getScannableFiles(const std::string &dir)
        if (lastScanTime != -1) {
                // for case: scan history exist and not modified.
                for (auto &row : m_db->getDetectedMalwares(dir))
-                       fileset.insert(row->targetName);
+                       filesetForClient.insert(row->targetName);
        }
 
-       return BinaryQueue::Serialize(CSR_ERROR_NONE, fileset).pop();
+       // no fileset for server-only or dir is scanning in background already.. just skip
+       if (filesetForServer->empty() || m_scanningDirs.count(dir) != 0)
+               return BinaryQueue::Serialize(CSR_ERROR_NONE, filesetForClient).pop();
+
+       // update last scan time before start.
+       // to set scan time early is safe because file which is modified between
+       // scan start time and end time will be traversed by FsVisitor and re-scanned
+       // being compared to start time as modified since.
+       m_db->insertLastScanTime(dir, time(nullptr), m_csDataVersion);
+
+       m_workqueue.submit([this, dir, filesetForServer]() {
+               {
+                       std::lock_guard<std::mutex> l(this->m_mutex);
+                       this->m_scanningDirs.insert(dir);
+               }
+
+               // TODO: how to set default option of scan on cloud?
+               // ask user -> not ask user
+               // message -> none because not ask user
+               // core usage -> default
+               CsContext context;
+
+               for (auto file : *filesetForServer) {
+                       // results are registered to db automatically
+                       // so need not to handle returned data
+                       this->scanFileHelper(context, file);
+               }
+
+               {
+                       std::lock_guard<std::mutex> l(this->m_mutex);
+                       this->m_scanningDirs.erase(dir);
+               }
+       });
+
+       return BinaryQueue::Serialize(CSR_ERROR_NONE, filesetForClient).pop();
 }
 
 RawBuffer Logic::judgeStatus(const std::string &filepath, csr_cs_action_e action)
index 54159c5..a4264d5 100644 (file)
 #include <string>
 #include <utility>
 #include <memory>
+#include <mutex>
 
 #include "common/types.h"
+#include "common/credential.h"
 #include "common/cs-context.h"
 #include "common/wp-context.h"
 #include "common/cs-detected.h"
 #include "common/wp-result.h"
 #include "db/manager.h"
+#include "service/thread-pool.h"
 #include "service/cs-loader.h"
 #include "service/wp-loader.h"
 
@@ -40,12 +43,14 @@ namespace Csr {
 
 class Logic {
 public:
-       Logic();
+       Logic(ThreadPool &);
        virtual ~Logic();
 
+       void submit(std::function<void()> &&task);
+
        RawBuffer scanData(const CsContext &context, const RawBuffer &data);
        RawBuffer scanFile(const CsContext &context, const std::string &filepath);
-       RawBuffer getScannableFiles(const std::string &dir);
+       RawBuffer getScannableFiles(const Credential &cred, const std::string &dir);
        RawBuffer judgeStatus(const std::string &filepath, csr_cs_action_e action);
        RawBuffer getDetected(const std::string &filepath);
        RawBuffer getDetectedList(const StrSet &dirSet);
@@ -64,6 +69,11 @@ private:
        static csr_wp_user_response_e getUserResponse(const WpContext &,
                        const std::string &url, const WpResult &);
 
+       // internal task submit to thread pool for background scanning
+       ThreadPool &m_workqueue;
+       std::mutex m_mutex;
+       StrSet m_scanningDirs;
+
        std::shared_ptr<CsLoader> m_cs;
        std::shared_ptr<WpLoader> m_wp;
        std::unique_ptr<Db::Manager> m_db;
index ef89551..9970371 100644 (file)
@@ -36,7 +36,8 @@ namespace Csr {
 
 ServerService::ServerService(const std::string &address) :
        Service(address),
-       m_workqueue(2, 10)
+       m_workqueue(2, 10),
+       m_logic(m_workqueue)
 {
 }
 
@@ -44,7 +45,7 @@ ServerService::~ServerService()
 {
 }
 
-RawBuffer ServerService::process(const ConnShPtr &, RawBuffer &data)
+RawBuffer ServerService::process(const ConnShPtr &conn, RawBuffer &data)
 {
        CommandId id;
 
@@ -73,7 +74,7 @@ RawBuffer ServerService::process(const ConnShPtr &, RawBuffer &data)
                std::string dir;
                q.Deserialize(dir);
 
-               return m_logic.getScannableFiles(dir);
+               return m_logic.getScannableFiles(conn->getCredential(), dir);
        }
 
        case CommandId::JUDGE_STATUS: {
index 8a99928..a7ad9ec 100644 (file)
@@ -38,8 +38,8 @@ private:
 
        RawBuffer process(const ConnShPtr &, RawBuffer &);
 
-       Logic m_logic;
        ThreadPool m_workqueue;
+       Logic m_logic;
 };
 
 }