Support privilege mapping to multiple privacies 04/161304/10
authorZofia Abramowska <z.abramowska@samsung.com>
Thu, 16 Nov 2017 16:54:17 +0000 (17:54 +0100)
committerZofia Grzelewska <z.abramowska@samsung.com>
Thu, 30 Nov 2017 12:35:11 +0000 (13:35 +0100)
Add different root types of application: EXTENDED and SKEL.
This is connected with new places, where application can put
its own files.

Change-Id: I9f3db1523d0121dc6d094713a992a71b490c1976

20 files changed:
src/client/impl/ApiInterfaceImpl.cpp
src/common/CMakeLists.txt
src/common/policy/AppInfo.h [new file with mode: 0644]
src/common/policy/Policy.cpp
src/common/policy/Policy.h
src/common/policy/PrivilegeInfo.cpp [new file with mode: 0644]
src/common/policy/PrivilegeInfo.h [moved from src/notification-daemon/policy/PrivilegeInfo.h with 70% similarity]
src/common/types/PolicyTypes.h [new file with mode: 0644]
src/notification-daemon/CMakeLists.txt
src/notification-daemon/Logic.cpp
src/notification-daemon/Logic.h
src/notification-daemon/PolicyUpdater.cpp
src/notification-daemon/PolicyUpdater.h
src/notification-daemon/PrivaciesSequence.cpp [new file with mode: 0644]
src/notification-daemon/PrivaciesSequence.h [new file with mode: 0644]
src/notification-daemon/event/Event.h
src/notification-daemon/policy/PrivilegeInfo.cpp [deleted file]
src/notification-daemon/ui/Po.cpp
src/notification-daemon/ui/Popupper.cpp
src/notification-daemon/ui/Popupper.h

index 12021ed..4ee3f27 100644 (file)
@@ -98,31 +98,17 @@ askuser_check_result ApiInterfaceImpl::checkPrivilege(const std::string &privile
 {
     std::string appId = getOwnAppId();
 
-    PolicyEntry filter;
-    filter.setApp(appId);
-    filter.setUser(std::to_string(geteuid()));
-    filter.setPrivilege(privilege);
+    auto policyLevel = getPrivilegePolicy(appId, privilege);
 
-    PolicyFetchRequest fetch(std::move(filter));
-    auto policies = fetch.fetchPolicy();
-
-    if (policies.size() != 1) {
-        ALOGE("Unusual situation, there are " << policies.size() <<
-              " policies for (" << appId << ", " << geteuid() << ", " << privilege << ")");
-        return ASKUSER_CHECK_RESULT_DENY;
-    }
-
-    auto level = policies.front().getLevel();
-
-    if (level == "Allow") {
+    if (policyLevel == "Allow") {
         return ASKUSER_CHECK_RESULT_ALLOW;
     }
 
-    if (level == "Deny") {
+    if (policyLevel == "Deny") {
         return ASKUSER_CHECK_RESULT_DENY;
     }
 
-    if (level == "Ask user") {
+    if (policyLevel == "Ask user") {
         return ASKUSER_CHECK_RESULT_ASK;
     }
 
index 6e3e8e6..4adb6f8 100644 (file)
@@ -38,6 +38,7 @@ INCLUDE_DIRECTORIES(
 SET(COMMON_SOURCES
     ${COMMON_PATH}/log/alog.cpp
     ${COMMON_PATH}/policy/Policy.cpp
+    ${COMMON_PATH}/policy/PrivilegeInfo.cpp
     ${COMMON_PATH}/types/AgentErrorMsg.cpp
     ${COMMON_PATH}/util/SafeFunction.cpp
     ${COMMON_PATH}/config/Limits.cpp
diff --git a/src/common/policy/AppInfo.h b/src/common/policy/AppInfo.h
new file mode 100644 (file)
index 0000000..68cf4ab
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ *  Copyright (c) 2017 Samsung Electronics Co.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/**
+ * @file        src/common/policy/AppInfo.h
+ * @author      Zofia Abramowska <z.abramowska@samsung.com>
+ * @brief       Definition of pkgmgr-info wrappers
+ */
+
+#pragma once
+
+#include <string>
+#include <sys/types.h>
+#include <pkgmgr-info.h>
+
+#include <log/alog.h>
+
+namespace AskUser {
+
+struct AppInfo {
+    AppInfo(const std::string &appId, uid_t uid) : m_handle(nullptr) {
+        int ret = pkgmgrinfo_appinfo_get_usr_appinfo(appId.c_str(), uid, &m_handle);
+        if (ret != PMINFO_R_OK) {
+            ALOGE("pkgmgrinfo_appinfo_get_usr_appinfo failed for " << appId  << " with " << ret);
+            m_handle = nullptr;
+        }
+    }
+    ~AppInfo() {
+        if (m_handle)
+            pkgmgrinfo_appinfo_destroy_appinfo(m_handle);
+    }
+    const std::string type() {
+        char *type = nullptr;
+        int ret = pkgmgrinfo_appinfo_get_apptype(m_handle, &type);
+        if (ret != PMINFO_R_OK) {
+            ALOGE("pkgmgrinfo_appinfo_get_apptype failed with " << ret);
+            return "";
+        }
+        return type ? type : "";
+    }
+
+    const std::string apiVersion() {
+        char *version = nullptr;
+        int ret = pkgmgrinfo_appinfo_get_api_version(m_handle, &version);
+        if (ret != PMINFO_R_OK) {
+            ALOGE("pkgmgrinfo_appinfo_get_api_version failed with " << ret);
+            return "";
+        }
+        return version ? version : "";
+    }
+
+    pkgmgrinfo_appinfo_h m_handle;
+};
+
+} // namespace AskUser
index fc48163..feb4867 100644 (file)
@@ -20,6 +20,7 @@
  */
 
 #include <memory>
+#include <vector>
 
 #include <security-manager.h>
 
@@ -28,6 +29,9 @@
 
 #include "PkgInfo.h"
 #include "Policy.h"
+#include "PrivilegeInfo.h"
+
+namespace AskUser {
 
 namespace {
 inline void throwOnSMError(std::string err, int ret)
@@ -41,9 +45,82 @@ inline void throwOnSMNullptr(std::string err, const char *ret)
     if (ret == nullptr)
         throw AskUser::Exception("SM returned null : " + err);
 }
+
+} // namespace anonymous
+
+PolicyEntryCopy::PolicyEntryCopy(policy_entry *entry) {
+    const char *app;
+    throwOnSMNullptr("security_manager_policy_entry_get_application",
+                     app = security_manager_policy_entry_get_application(entry));
+    m_appId = app;
+
+    const char *user;
+    throwOnSMNullptr("security_manager_policy_entry_get_user",
+                     user = security_manager_policy_entry_get_user(entry));
+    m_user = user;
+
+    const char *privilege;
+    throwOnSMNullptr("security_manager_policy_entry_get_privilege",
+                     privilege = security_manager_policy_entry_get_privilege(entry));
+    m_privilege = privilege;
+
+    const char *level;
+    throwOnSMNullptr("security_manager_policy_entry_get_level",
+            level = security_manager_policy_entry_get_level(entry));
+    m_level = level;
 }
 
-namespace AskUser {
+Policy getMinimumPolicy(const std::vector<Policy> &policies) {
+    Policy minimumPolicy = "Allow";
+
+    for (auto &policy : policies) {
+        if (policy == "Deny") {
+            minimumPolicy = "Deny";
+            break;
+        } else if (policy != minimumPolicy && policy == "Ask user") {
+            minimumPolicy = "Ask user";
+        }
+    }
+    return minimumPolicy;
+}
+
+Policy calculatePolicyForPrivacy(const std::string &appId, const Privacy &privacy) {
+    ALOGD("Calculating privacy " << privacy);
+    std::vector<Policy> privsPolicies;
+    auto privileges = PrivilegeInfo::getPrivacyPrivileges(privacy);
+    for (const auto &privilege : privileges) {
+        ALOGD("Calculating policy for privilege " << privilege);
+        PolicyEntry filter;
+        filter.setApp(appId);
+        filter.setUser(std::to_string(geteuid()));
+        filter.setPrivilege(privilege);
+
+        PolicyFetchRequest fetch(std::move(filter));
+        auto policies = fetch.fetchPolicy();
+        if (policies.size() == 0) {
+            ALOGD("No policy for given privilege " << privilege);
+            continue;
+        }
+        if (policies.size() > 1) {
+            ALOGW("Something went wrong, there should be no more than one policy for specific filter");
+            // FIXME : don't really know what to do with it. Lets ignore it for now.
+            continue;
+        }
+        std::string policyLevel = policies[0].getLevel();
+        ALOGD("Fetched policy level : " << policyLevel);
+
+        privsPolicies.push_back(std::move(policyLevel));
+    }
+    return getMinimumPolicy(privsPolicies);
+}
+
+Policy getPrivaciesPolicy(const std::string &appId, const std::vector<Privacy> &privacies) {
+    std::vector<Policy> policies;
+    for (auto &privacy : privacies) {
+        policies.push_back(calculatePolicyForPrivacy(appId, privacy));
+    }
+    return getMinimumPolicy(policies);
+}
 
 void identifyApp(const std::string &client, std::string &appId, std::string &pkgLabel)
 {
@@ -67,6 +144,16 @@ void identifyApp(const std::string &client, std::string &appId, std::string &pkg
     pkgLabel = pkgInfo.pkgLabel();
 }
 
+Policy getPrivilegePolicy(const std::string &appId, const std::string &privilege) {
+    std::vector<Privacy> privacies = PrivilegeInfo::getPrivilegePrivaciesMapping(appId, privilege);
+    if (privacies.empty()) {
+        ALOGE("Privilege doesn't map to any privacy");
+        return "";
+    }
+
+    return getPrivaciesPolicy(appId, privacies);
+}
+
 std::string getOwnAppId()
 {
     char *pkgName = nullptr;
@@ -84,7 +171,7 @@ std::string getOwnAppId()
     return std::string();
 }
 
-PolicyEntry::PolicyEntry() {
+PolicyEntry::PolicyEntry() : m_entry(nullptr) {
     throwOnSMError("security_manager_policy_entry_new",
                                   security_manager_policy_entry_new(&m_entry));
 }
@@ -142,6 +229,7 @@ std::string PolicyEntry::getLevel() {
     const char *level;
     throwOnSMNullptr("security_manager_policy_entry_get_level",
             level = security_manager_policy_entry_get_level(m_entry));
+    ALOGD("Level : " << level);
     return level;
 }
 
@@ -168,7 +256,7 @@ void PolicyRequest::updatePolicy() {
 }
 
 
-std::vector<PolicyEntry> PolicyFetchRequest::fetchPolicy() {
+std::vector<PolicyEntryCopy> PolicyFetchRequest::fetchPolicy() {
     policy_entry **pp_entries;
     size_t p_size;
     throwOnSMError("security_manager_get_configured_policy_for_self",
@@ -178,9 +266,9 @@ std::vector<PolicyEntry> PolicyFetchRequest::fetchPolicy() {
                 security_manager_policy_entries_free(*p, p_size);
             }
     );
-    std::vector<PolicyEntry> entries;
-    for(size_t i = 0; i < p_size; i++) {
-        entries.emplace_back(PolicyEntry(pp_entries[i]));
+    std::vector<PolicyEntryCopy> entries;
+    for (size_t i = 0; i < p_size; i++) {
+        entries.emplace_back(PolicyEntryCopy(pp_entries[i]));
     }
     ppPtr.release();
     return entries;
index 0f7aca1..5c6723d 100644 (file)
 #include <string>
 #include <vector>
 
+#include <types/PolicyTypes.h>
+
 struct policy_entry;
 struct policy_update_req;
 
 namespace AskUser {
 
-void identifyApp(const std::string &client, std::string &appId, std::string &pkgLabel);
 std::string getOwnAppId();
+void identifyApp(const std::string &client, std::string &appId, std::string &pkgLabel);
+
+Policy getPrivilegePolicy(const std::string &appId, const Privilege &privilege);
+Policy getPrivaciesPolicy(const std::string &appId, const std::vector<Privacy> &privacies);
+
 
 class PolicyEntry {
 public:
@@ -53,6 +59,24 @@ private:
     policy_entry *m_entry;
 };
 
+class PolicyEntryCopy {
+public:
+    PolicyEntryCopy() = default;
+    PolicyEntryCopy(PolicyEntryCopy &&other) = default;
+    PolicyEntryCopy(policy_entry *entry);
+    ~PolicyEntryCopy() = default;
+    std::string getAppId() { return m_appId; }
+    std::string getUser() { return m_user; }
+    std::string getPrivilege() { return m_privilege; }
+    std::string getLevel() { return m_level; }
+
+private:
+    std::string m_appId;
+    std::string m_user;
+    std::string m_privilege;
+    std::string m_level;
+};
+
 class PolicyRequest {
 public:
     PolicyRequest();
@@ -69,7 +93,7 @@ class PolicyFetchRequest {
 public:
     PolicyFetchRequest(PolicyEntry &&filter) : m_filter(std::move(filter)) {}
     ~PolicyFetchRequest() {}
-    std::vector<PolicyEntry> fetchPolicy();
+    std::vector<PolicyEntryCopy> fetchPolicy();
 private:
     PolicyEntry m_filter;
 };
diff --git a/src/common/policy/PrivilegeInfo.cpp b/src/common/policy/PrivilegeInfo.cpp
new file mode 100644 (file)
index 0000000..200e068
--- /dev/null
@@ -0,0 +1,195 @@
+/*
+ *  Copyright (c) 2016 Samsung Electronics Co.
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/**
+ * @file        src/agent/notification-daemon/Privilege.cpp
+ * @author      Zofia Abramowska <z.abramowska@samsung.com>
+ * @brief       Implementation of Privilege Info wrappers
+ */
+
+#include <cstdlib>
+#include <memory>
+#include <set>
+
+#include "PrivilegeInfo.h"
+
+#include <exception/Exception.h>
+#include <log/alog.h>
+#include <policy/AppInfo.h>
+
+#include <privilegemgr/privilege_info.h>
+#include <privilegemgr/privilege_db_manager.h>
+#include <pkgmgr-info.h>
+#include <glib.h>
+
+
+namespace AskUser {
+
+namespace PrivilegeInfo {
+
+namespace {
+
+class GListWrap {
+public:
+    GListWrap() : m_head(nullptr) {
+        m_head = g_list_alloc();
+        if (!m_head) {
+            ALOGE("Failed to allocate glib list");
+            // FIXME : throw
+        }
+    }
+
+    GListWrap(GList *_list) : m_head(_list) {}
+
+    ~GListWrap() { g_list_free(m_head);}
+
+    void append(gpointer data) {
+        GList *newHead = g_list_prepend(m_head, data);
+        if (newHead == nullptr) {
+            ALOGE("Failed to prepend the glib list");
+            return;
+        }
+        m_head = newHead;
+    }
+    GList * get() { return m_head; }
+
+private:
+    GList *m_head;
+};
+
+std::vector<Privacy> getPrivilegesPrivacies(const std::vector<std::string> &corePrivileges) {
+    std::set<Privacy> privaciesSet;
+    for (auto &privilege : corePrivileges) {
+        ALOGD("Getting privacy for privilege : " << privilege);
+        if (!isPrivacy(privilege)) {
+            ALOGD("Privilege " << privilege << " is not privacy, skipping");
+            continue;
+        }
+        Privacy privacy = getPrivacyName(privilege);
+        if (privacy.empty()) {
+            // FIXME: should we abort whole request or ignore privilege which cannot be mapped to privacy?
+            ALOGE("Something went wrong with fetching privacy name for " << privilege << ", aborting");
+            return {};
+        } else {
+            ALOGD("Privilege belongs to privacy " << privacy);
+        }
+        privaciesSet.insert(privacy);
+    }
+    return std::vector<Privacy>(privaciesSet.begin(), privaciesSet.end());
+}
+
+std::vector<Privilege> getPrivilegeMapping(const std::string &appId, const Privilege &privilege) {
+    ALOGD("Mapping privilege " << privilege);
+    AppInfo app(appId, geteuid());
+    std::string version = app.apiVersion();
+    std::string type = app.type();
+
+    if (version.empty() || type.empty()) {
+        ALOGE("Failed to fetch application version and type");
+        return {};
+    }
+    ALOGD("App " << appId << " is of type " << type << " and version " << version);
+
+    privilege_manager_package_type_e pkgType;
+    if (type == "c++app" || type == "capp") {
+        pkgType = PRVMGR_PACKAGE_TYPE_CORE;
+    } else if (type == "webapp") {
+        pkgType = PRVMGR_PACKAGE_TYPE_WRT;
+    } else {
+        ALOGD("Application type not supported by mapping : " << type);
+        return {privilege};
+    }
+
+    GListWrap privList;
+    privList.append(const_cast<void*>(static_cast<const void *>(privilege.c_str())));
+
+    GList *privMapped = nullptr;
+    int ret = privilege_db_manager_get_mapped_privilege_list(version.c_str(), pkgType, privList.get(), &privMapped);
+    if (ret != PRVMGR_ERR_NONE || !privMapped) {
+        ALOGE("Unable to get mapping of privilege " << privilege << "; err: <" << ret <<  ">");
+        return {};
+    }
+
+    GListWrap privMappedWrap(privMapped);
+    std::vector<std::string> privMappedVector;
+    for (GList *l = privMappedWrap.get(); l != NULL; l = l->next) {
+        std::string corePriv = static_cast<char*>(l->data);
+        ALOGD("Privilege mapps to " << corePriv);
+        privMappedVector.push_back(std::move(corePriv));
+    }
+
+    return privMappedVector;
+}
+
+
+} //namespace anonymous
+
+bool isPrivacy(const Privilege &privilege) {
+    return privilege_info_is_privacy(privilege.c_str()) == 1;
+}
+
+std::string getPrivacyDisplayName(const Privacy &privacy) {
+    char *displayName = nullptr;
+    int ret = privilege_info_get_privacy_display(privacy.c_str(), &displayName);
+    if (ret != PRVMGR_ERR_NONE || !displayName) {
+        ALOGE("Unable to get privacy display name for <" << privacy << ">, err: <" << ret << ">");
+        return privacy;
+    }
+    std::unique_ptr<char, decltype(free)*> displaNamePtr(displayName, free);
+    return std::string(displayName);
+}
+
+Privacy getPrivacyName(const Privilege &privilege) {
+    char* privacyName = nullptr;
+    int ret = privilege_info_get_privacy_by_privilege(privilege.c_str(), &privacyName);
+    if (ret != PRVMGR_ERR_NONE || !privacyName) {
+        ALOGE("Unable to get privacy group for privilege: <" << privilege << ">, err: <" << ret << ">");
+        return privilege;
+    }
+
+    std::unique_ptr<char, decltype(free) *> privacyNamePtr(privacyName, free);
+    return std::string(privacyName);
+}
+
+std::vector<Privilege> getPrivacyPrivileges(const Privacy &privacy) {
+    GList *privilegeList = nullptr;
+
+    int ret = privilege_info_get_privilege_list_by_privacy(privacy.c_str(), &privilegeList);
+    if (ret != PRVMGR_ERR_NONE || !privilegeList) {
+        ALOGE("Unable to get privacy group list of privileges; err: <" << ret <<  ">");
+        return {privacy};
+    }
+
+    GListWrap privList(privilegeList);
+    std::vector<Privilege> privVector;
+    for (GList *l = privList.get(); l != NULL; l = l->next) {
+        privVector.push_back(static_cast<char*>(l->data));
+    }
+    return privVector;
+}
+
+
+std::vector<Privacy> getPrivilegePrivaciesMapping(const std::string &appId, const std::string &privilege) {
+    std::vector<std::string> corePrivileges = PrivilegeInfo::getPrivilegeMapping(appId, privilege);
+    if (corePrivileges.empty()) {
+        ALOGE("Cannot fetch mapping for application " << appId << " and privilege " << privilege << ", aborting");
+        return {};
+    }
+
+    return getPrivilegesPrivacies(corePrivileges);
+}
+
+}
+} /* namespace AskUser */
similarity index 70%
rename from src/notification-daemon/policy/PrivilegeInfo.h
rename to src/common/policy/PrivilegeInfo.h
index 0249b4f..06d714e 100644 (file)
 #include <string>
 #include <vector>
 
+#include <types/PolicyTypes.h>
+
 namespace AskUser {
 
 namespace PrivilegeInfo {
-    std::string getPrivacyDisplayName(const std::string &privilege);
-    std::string getPrivacyName(const std::string &privilege);
-    std::vector<std::string> getPrivacyPrivileges(const std::string &privacy);
+    std::vector<Privacy> getPrivilegePrivaciesMapping(const std::string &appId, const std::string &privilege);
+    bool isPrivacy(const Privilege &privilege);
+    Privacy getPrivacyName(const Privacy &privilege);
+    std::string getPrivacyDisplayName(const Privacy &privacy);
+
+    std::vector<Privilege> getPrivacyPrivileges(const Privacy &privacy);
 };
 
 } /* namespace AskUser */
diff --git a/src/common/types/PolicyTypes.h b/src/common/types/PolicyTypes.h
new file mode 100644 (file)
index 0000000..c532671
--- /dev/null
@@ -0,0 +1,32 @@
+/*
+ *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+/**
+ * @file        PolicyTypes.h
+ * @author      Zofia Grzelewska <z.abramowska@samsung.com>
+ * @brief       The definition of Policy types
+ */
+
+#pragma once
+#include <string>
+
+namespace AskUser {
+
+typedef std::string Privilege;
+typedef std::string Privacy;
+typedef std::string Policy;
+
+} // namespace AskUser
index 89b330d..f69a298 100644 (file)
@@ -30,8 +30,8 @@ SET(ASKUSER_NOTIFICATION_SOURCES
     ${NOTIF_PATH}/main.cpp
     ${NOTIF_PATH}/Logic.cpp
     ${NOTIF_PATH}/PolicyUpdater.cpp
+    ${NOTIF_PATH}/PrivaciesSequence.cpp
     ${NOTIF_PATH}/ServerCallbacks.cpp
-    ${NOTIF_PATH}/policy/PrivilegeInfo.cpp
     ${NOTIF_PATH}/ui/Po.cpp
     ${NOTIF_PATH}/ui/Popupper.cpp
    )
index 9e6d1c0..b0eab3a 100644 (file)
 #include <policy/Policy.h>
 #include "PolicyUpdater.h"
 #include "ServerCallbacks.h"
+#include "policy/PrivilegeInfo.h"
+
 
 namespace AskUser {
 
 namespace Notification {
 
+namespace {
+
+int uiResponseToClientResponse(NResponseType response) {
+    int clientResponse;
+
+    switch (response) {
+    case NResponseType::Deny:
+        clientResponse = ASKUSER_DENY_ONCE;
+        break;
+    case NResponseType::DenyAlways:
+        clientResponse = ASKUSER_DENY_FOREVER;
+        break;
+    case NResponseType::Allow:
+    case NResponseType::AllowAlways:
+        clientResponse = ASKUSER_ALLOW_FOREVER;
+        break;
+    case NResponseType::None:
+        clientResponse = ASKUSER_NONE;
+        break;
+    case NResponseType::Error:
+        clientResponse = ASKUSER_UNKNOWN_ERROR;
+        break;
+    default:
+        clientResponse = ASKUSER_UNKNOWN_ERROR;
+    }
+
+    return clientResponse;
+}
+
+std::string clientResponseToPolicy(int clientResponse) {
+    std::string level;
+
+    switch (clientResponse) {
+    case ASKUSER_DENY_FOREVER:
+        level = "Deny";
+        break;
+    case ASKUSER_ALLOW_FOREVER:
+        level = "Allow";
+        break;
+    default :
+        level = "Ask user";
+    }
+
+    return level;
+}
+
+}
+
 void Logic::addChannelFd(Protocol::ConnectionFd fd, const Protocol::Credentials &creds) {
     auto it = m_connToInfo.find(fd);
     if (it != m_connToInfo.end()) {
@@ -46,6 +96,11 @@ void Logic::addChannelFd(Protocol::ConnectionFd fd, const Protocol::Credentials
         return;
     }
 
+    if (creds.uid != std::to_string(geteuid())) {
+        ALOGE("This is very unexpected, client with different uid connected : " << creds.uid);
+        m_serverChannel->process(fd, 0);
+    }
+
     std::string appId, pkgLabel;
     identifyApp(creds.label, appId, pkgLabel);
     ConnectionInfo connInfo{appId, pkgLabel, creds.uid};
@@ -71,8 +126,6 @@ void Logic::updateChannelFd(Protocol::ConnectionFd fd, Ecore_Fd_Handler_Flags fl
 }
 
 void Logic::removeChannelFd(Protocol::ConnectionFd fd) {
-    m_connToInfo.erase(fd);
-
     auto it = m_fdInfo.find(fd);
     if (it == m_fdInfo.end()) {
         return;
@@ -109,13 +162,17 @@ Eina_Bool Logic::processChannel(int fd, int mask) {
                 [fd](const FdEvent &fdEvent) {return fdEvent.id.fd == fd;});
         m_pendingEvents.erase(queueIt, m_pendingEvents.end());
 
+        // Ignore error in policy setting, we can't do anything about it nor we can inform user about error
+        (void)setPolicy(m_connToInfo[fd], "Ask user");
+        m_connToInfo.erase(fd);
+        m_fdInfo.erase(fd);
+        m_serverChannel->process(fd, 0);
+
         // Handle next event if removed active fd
         if (fd == m_currentEvent.fd) {
-            finishCurrentEvent();
+            finishCurrentRequest();
             processEvents();
         }
-        m_fdInfo.erase(fd);
-        m_serverChannel->process(fd, 0);
         return ECORE_CALLBACK_CANCEL;
     }
     case FdChange::CHANGE:
@@ -126,42 +183,40 @@ Eina_Bool Logic::processChannel(int fd, int mask) {
     }
 }
 
-void Logic::addEvent(EventId id, IUIEvent *event) {
-    FdEvent fdEvent{id, std::unique_ptr<IUIEvent>(event)};
+void Logic::addEvent(Protocol::ConnectionFd fd, Protocol::RequestId id, const std::vector<Privacy> &privacies) {
+    EventId eventId{fd, id};
+    PrivaciesSequence &seq = m_eventToPrivaciesSeq[eventId];
+    seq.setPrivacies(privacies);
+
+    ConnectionInfo &conn = m_connToInfo[fd];
+
+    Privacy currentPrivacy;
+    seq.getNextPrivacy(currentPrivacy);
+
+    FdEvent fdEvent{eventId, std::unique_ptr<IUIEvent>(new EventPopupCheck(&m_popupper, conn.pkgLabel, currentPrivacy))};
     m_pendingEvents.emplace_back(std::move(fdEvent));
-    processEvents();
 }
 
 void Logic::popup(Protocol::ConnectionFd fd, Protocol::RequestId id, const std::string &privilege) {
+    ALOGD("Request for privilege " << privilege);
+
     auto it = m_connToInfo.find(fd);
     if (it == m_connToInfo.end()) {
         ALOGE("Got request to non existing fd " << fd);
         return;
     }
+    ConnectionInfo &conn = it->second;
 
-    PolicyEntry filter;
-    filter.setApp(it->second.appId);
-    filter.setUser(it->second.user);
-    filter.setPrivilege(privilege);
-
-    PolicyFetchRequest fetch(std::move(filter));
-    auto policies = fetch.fetchPolicy();
-
-    if (policies.size() == 0) {
-        ALOGE("No policy for (" << it->second.appId << ", " << it->second.user << ", " << privilege << ")");
-        m_serverChannel->popupResponse(fd, id, ASKUSER_DENY_ONCE);
-        return;
-    }
-
-    if (policies.size() > 1) {
-        ALOGE("Something strange happened, more than one policy for (" << it->second.appId << ", "
-              << it->second.user << ", " << privilege << ") exists");
+    std::vector<Privacy> privacies = PrivilegeInfo::getPrivilegePrivaciesMapping(conn.appId, privilege);
+    if (privacies.empty()) {
+        ALOGE("Privilege " << privilege << " doesn't map to any privacy");
         m_serverChannel->popupResponse(fd, id, ASKUSER_DENY_ONCE);
         return;
     }
 
-    std::string policyLevel = policies.front().getLevel();
+    Policy policyLevel = getPrivaciesPolicy(conn.appId, privacies);
 
+    ALOGD("Privilege policy level calculated to : " << policyLevel);
     if (policyLevel == "Allow") {
         m_serverChannel->popupResponse(fd, id, ASKUSER_ALLOW_FOREVER);
         return;
@@ -171,14 +226,14 @@ void Logic::popup(Protocol::ConnectionFd fd, Protocol::RequestId id, const std::
         return;
     }
     if (policyLevel != "Ask user") {
-        ALOGE("Unknown policy set : " << policyLevel << " for (" << it->second.appId << ", " << it->second.user
-              << ", " << privilege << ")" );
+        ALOGE("Unknown policy set : " << policyLevel << " for (" << conn.appId << ", " << conn.user
+              << ", " << privilege << ")");
         m_serverChannel->popupResponse(fd, id, ASKUSER_DENY_ONCE);
         return;
     }
 
-    auto &pkgId = it->second.pkgLabel;
-    addEvent({fd, id}, new EventPopupCheck(&m_popupper, pkgId, privilege));
+    addEvent(fd, id, privacies);
+    processEvents();
 }
 
 Logic::~Logic()
@@ -190,8 +245,10 @@ bool Logic::isEventProcessed() {
     return m_currentEvent.fd != Protocol::INVALID_FD;
 }
 
-void Logic::finishCurrentEvent() {
+void Logic::finishCurrentRequest() {
+    m_eventToPrivaciesSeq.erase(m_currentEvent);
     m_popupper.popupClose();
+
     m_currentEvent = EventId();
     if (!m_pendingEvents.empty())
         m_pendingEvents.pop_front();
@@ -232,8 +289,11 @@ void Logic::registerSignalFd() {
 }
 
 void Logic::stop() {
-    if (isEventProcessed())
-        finishCurrentEvent();
+    if (isEventProcessed()) {
+        ConnectionInfo &conn = m_connToInfo[m_currentEvent.fd];
+        processResponse(conn, ASKUSER_DENY_ONCE, "Ask user");
+        finishCurrentRequest();
+    }
     m_popupper.stop();
 }
 
@@ -272,10 +332,48 @@ void Logic::run() {
     m_popupper.shutdown();
 }
 
-void Logic::respondAndContinue(int response) {
-    m_serverChannel->popupResponse(m_currentEvent.fd, m_currentEvent.id, response);
-    finishCurrentEvent();
-    processEvents();
+bool Logic::setPolicy(const ConnectionInfo &conn, const std::string &lastPolicy) {
+    std::string currentPrivacy;
+
+    PrivaciesSequence &privSeq = m_eventToPrivaciesSeq[m_currentEvent];
+    if (!privSeq.getCurrentPrivacy(currentPrivacy)) {
+        ALOGD("Privilege is allowed completely");
+    }
+
+    privSeq.rewind();
+
+    Privacy privacy;
+    while (privSeq.getNextPrivacy(privacy) && privacy != currentPrivacy) {
+        /*
+         * When privacy is not allowed with deny forever or deny once, then processing is stopped,
+         * so all privacies, which were already processed, are allowed.
+         */
+        if (!PolicyUpdater::update(conn.appId, privacy, "Allow")) {
+            // FIXME : Maybe ignore those errors and try to maintain the policy as consistent as we can?
+            ALOGE("Couldn't set policy for " << conn.appId << " privacy : " << privacy << " level : Allow");
+            return false;
+        }
+    }
+
+    if (!currentPrivacy.empty() && lastPolicy != "Ask user") {
+        /*
+         * setPolicy is called when privacy processing is either successfully finished or
+         * aborted due to error, so currentPrivacy will be empty in the first case and
+         * we don't set policy when user responds with "Deny once" (this translates to "Ask user")
+         */
+        if (!PolicyUpdater::update(conn.appId, currentPrivacy, lastPolicy)) {
+            ALOGE("Couldn't set policy for " <<  conn.appId << " privacy : " << privacy << " level : " << lastPolicy);
+        }
+    }
+    return true;
+}
+
+void Logic::processResponse(const ConnectionInfo &conn, int clientResponse, const Policy &level) {
+    if (!setPolicy(conn, level)) {
+        m_serverChannel->popupResponse(m_currentEvent.fd, m_currentEvent.id, ASKUSER_UNKNOWN_ERROR);
+    } else {
+        m_serverChannel->popupResponse(m_currentEvent.fd, m_currentEvent.id, clientResponse);
+    }
 }
 
 void Logic::popupResponse(NResponseType response) {
@@ -284,47 +382,33 @@ void Logic::popupResponse(NResponseType response) {
         ALOGE("Got response from inactive fd " << m_currentEvent.fd);
         return;
     }
-
-    EventPopupCheck *event = dynamic_cast<EventPopupCheck*>(m_pendingEvents.front().event.get());
-    if (!event) {
-        ALOGE("Something went really wrong - couldn't cast event to EventPopupCheck");
-        respondAndContinue(ASKUSER_UNKNOWN_ERROR);
-        return;
-    }
-
-    int clientResponse;
-    std::string level;
-    // TODO translate ui response to policy result
-    switch (response) {
-    case NResponseType::Deny:
-        clientResponse = ASKUSER_DENY_ONCE;
-        break;
-    case NResponseType::DenyAlways:
-        clientResponse = ASKUSER_DENY_FOREVER;
-        level = "Deny";
-        break;
-    case NResponseType::Allow:
-    case NResponseType::AllowAlways:
-        clientResponse = ASKUSER_ALLOW_FOREVER;
-        level = "Allow";
-        break;
-    case NResponseType::None:
-        clientResponse = ASKUSER_NONE;
-        break;
-    case NResponseType::Error:
-        clientResponse = ASKUSER_UNKNOWN_ERROR;
-        break;
-    default:
-        clientResponse = ASKUSER_UNKNOWN_ERROR;
-    }
-    if (!level.empty()) {
-        if (!PolicyUpdater::update(it->second.appId, event->getPrivilege(), level)) {
-            ALOGE("Failed to update policy, returning DENY_ONCE in this case");
-            clientResponse = ASKUSER_DENY_ONCE;
+    ConnectionInfo &conn = it->second;
+
+    int clientResponse = uiResponseToClientResponse(response);
+    std::string level = clientResponseToPolicy(clientResponse);
+    if (clientResponse != ASKUSER_ALLOW_FOREVER) {
+        // Privacy not allowed, request is denied
+        processResponse(conn, clientResponse, level);
+        finishCurrentRequest();
+        processEvents();
+    } else {
+        // Privacy allowed - check if more privacies are to process
+        PrivaciesSequence &seq = m_eventToPrivaciesSeq[m_currentEvent];
+        Privacy nextPrivacy;
+        if (seq.getNextPrivacy(nextPrivacy)) {
+            // More privacies to process - replace existing event with new privacy
+            FdEvent fdEvent{m_currentEvent, std::unique_ptr<IUIEvent>(new EventPopupCheck(&m_popupper, conn.pkgLabel, nextPrivacy))};
+            m_pendingEvents[0] = std::move(fdEvent);
+            // don't call finishCurrentRequest here, because it will pop event, which we replaced
+            m_currentEvent = EventId();
+            processEvents();
+        } else {
+            // No more privacies, request is allowed
+            processResponse(it->second, clientResponse, level);
+            finishCurrentRequest();
+            processEvents();
         }
     }
-
-    respondAndContinue(clientResponse);
 }
 
 } // namespace Notification
index 2c6ea82..6c502bb 100644 (file)
@@ -24,7 +24,9 @@
 #include <map>
 #include <deque>
 #include <server-channel.h>
-#include <event/Event.h>
+
+#include "event/Event.h"
+#include "PrivaciesSequence.h"
 
 namespace AskUser {
 
@@ -59,6 +61,16 @@ private:
         EventId(Protocol::ConnectionFd _fd, Protocol::RequestId _id) : fd(_fd), id(_id) {}
         Protocol::ConnectionFd fd;
         Protocol::RequestId id;
+
+        bool operator<(const EventId &rhs) const {
+            return (fd < rhs.fd) || ((fd == rhs.fd) && (id < rhs.id));
+        }
+    };
+
+    struct ConnectionInfo {
+        std::string appId;
+        std::string pkgLabel;
+        std::string user;
     };
 
     //Initialization
@@ -71,14 +83,17 @@ private:
     static Eina_Bool signalHandler(void *data, Ecore_Fd_Handler *handler);
     //static Eina_Bool signalHandler(void *data, int type, void *event);
 
-    void addEvent(EventId id, IUIEvent *event);
+    void addEvent(Protocol::ConnectionFd fd, Protocol::RequestId id, const std::vector<Privacy> &privacies);
     Eina_Bool processChannel(int fd, int mask);
     bool identifyClient(const std::string &label, std::string &appId, std::string &pkgId);
     void processEvents();
+    void processResponse(const ConnectionInfo &conn, int clientResponse, const Policy &level);
     bool isEventProcessed();
-    void finishCurrentEvent();
+    void finishCurrentRequest();
     void popupResponse(NResponseType response);
-    void respondAndContinue(int response);
+
+    bool processError(EventId id, int error);
+    bool setPolicy(const ConnectionInfo &conn, const std::string &lastPolicy);
 
     std::unique_ptr<AskUser::Protocol::ServerChannel> m_serverChannel;
     Popupper m_popupper;
@@ -105,13 +120,11 @@ private:
 
     std::map<Protocol::ConnectionFd, FdInfo> m_fdInfo;
 
-    struct ConnectionInfo {
-        std::string appId;
-        std::string pkgLabel;
-        std::string user;
-    };
+
 
     std::map<Protocol::ConnectionFd, ConnectionInfo> m_connToInfo;
+
+    std::map<EventId, PrivaciesSequence> m_eventToPrivaciesSeq;
 };
 
 } // namespace Notification
index 2319dd3..a4064e2 100644 (file)
@@ -34,29 +34,25 @@ namespace AskUser {
 namespace Notification {
 
 bool PolicyUpdater::update(const std::string &appId,
-                           const std::string &privilege, const std::string &level)
+                           const std::string &privacy, const std::string &level)
 {
     try {
-        ALOGD("Policy update for: app: " << appId << ", privilege: " << privilege
+        ALOGD("Generating policy update for: app: " << appId << ", privacy: " << privacy
               << ", user:" << geteuid() << ", level: " << level);
 
         static const std::string user = std::to_string(geteuid());
         PolicyRequest req;
 
-        std::string privacyName = PrivilegeInfo::getPrivacyName(privilege);
-        if (privacyName.empty()) {
-            ALOGE("Unable to get privacy name for privilege " << privilege);
-            throw Exception("Unable to get privacy name for " + privilege);
-        }
-        auto privacyPrivs = PrivilegeInfo::getPrivacyPrivileges(privacyName);
+        auto privacyPrivs = PrivilegeInfo::getPrivacyPrivileges(privacy);
         if (privacyPrivs.empty()) {
-            ALOGE("Unable to get privacy privileges for privacy " << privacyName);
-            throw Exception("Unable to get privacy privileges for privacy " + privacyName);
+            ALOGE("Unable to get privacy privileges for privacy " << privacy);
+            throw Exception("Unable to get privacy privileges for privacy " + privacy);
         }
-        ALOGD("Adding policy entry for : app: " << appId << ", privilege: "
-              << privilege  << ", user:" << user << ", level: "
-              << level);
+
         for (auto &priv : privacyPrivs) {
+            ALOGD("Adding policy entries for : app: " << appId << ", priv: "
+                  << priv  << ", user:" << user << ", level: "
+                  << level);
             PolicyEntry entry;
             entry.setApp(appId);
             entry.setUser(user);
index f91e88f..f821fe0 100644 (file)
@@ -33,7 +33,7 @@ namespace AskUser {
 namespace Notification {
 
 namespace PolicyUpdater {
-    bool update(const std::string &appId, const std::string &privilege,
+    bool update(const std::string &appId, const std::string &privacy,
                 const std::string &level);
 };
 
diff --git a/src/notification-daemon/PrivaciesSequence.cpp b/src/notification-daemon/PrivaciesSequence.cpp
new file mode 100644 (file)
index 0000000..8a4badd
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+/**
+ * @file        PrivaciesSequence.cpp
+ * @author      Zofia Grzelewska <z.abramowska@samsung.com>
+ * @brief       The implementation of PrivaciesSequence
+ */
+
+#include "PrivaciesSequence.h"
+
+namespace AskUser {
+
+namespace Notification {
+
+PrivaciesSequence::PrivaciesSequence() : m_currentPrivacy(m_privacies.begin()), m_nextPrivacy(m_privacies.begin())
+{}
+
+void PrivaciesSequence::rewind() {
+    m_currentPrivacy = m_privacies.begin();
+    m_nextPrivacy = m_privacies.begin();
+}
+
+void PrivaciesSequence::setPrivacies(const std::vector<Privacy> &privacies) {
+    m_privacies = privacies;
+    m_currentPrivacy = m_privacies.begin();
+    m_nextPrivacy = m_privacies.begin();
+}
+
+bool PrivaciesSequence::getCurrentPrivacy(Privacy &privacy) {
+    if (m_currentPrivacy == m_privacies.end())
+        return false;
+    privacy = *m_currentPrivacy;
+    return true;
+}
+
+bool PrivaciesSequence::getNextPrivacy(Privacy &privacy) {
+    m_currentPrivacy = m_nextPrivacy;
+    if (m_currentPrivacy == m_privacies.end())
+        return false;
+    privacy = *m_currentPrivacy;
+    m_nextPrivacy++;
+    return true;
+}
+
+} // namespace Notification
+
+} // namespace AskUser
diff --git a/src/notification-daemon/PrivaciesSequence.h b/src/notification-daemon/PrivaciesSequence.h
new file mode 100644 (file)
index 0000000..3782bc2
--- /dev/null
@@ -0,0 +1,65 @@
+/*
+ *  Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+
+/**
+ * @file        PrivaciesSequence.h
+ * @author      Zofia Grzelewska <z.abramowska@samsung.com>
+ * @brief       The definition of PrivaciesSequence
+ */
+#pragma once
+
+#include <string>
+#include <vector>
+
+#include <types/PolicyTypes.h>
+
+namespace AskUser {
+
+namespace Notification {
+
+/*
+ * Container allowing sequential access to privacy vector
+ */
+class PrivaciesSequence {
+public:
+    PrivaciesSequence();
+    void setPrivacies(const std::vector<Privacy> &privacies);
+    /*
+     * Get next privacy in sequence. Returns false, when there is no more privacies.
+     */
+    bool getNextPrivacy(Privacy &privacy);
+
+    /*
+     * Get current privacy in sequence.
+     */
+    bool getCurrentPrivacy(Privacy &privacy);
+
+    /*
+     * Rewind to the beginning of privacy sequence.
+     */
+    void rewind();
+
+    virtual ~PrivaciesSequence() {}
+private:
+    typedef std::vector<Privacy> PrivacyVector;
+    PrivacyVector m_privacies;
+    PrivacyVector::iterator m_currentPrivacy;
+    PrivacyVector::iterator m_nextPrivacy;
+};
+
+}
+
+}
index 239d91a..ab4a91a 100644 (file)
@@ -40,20 +40,16 @@ protected:
 
 class EventPopupCheck : public IUIEvent {
 public:
-    EventPopupCheck(Popupper *popupper, const std::string &pkgLabel, const std::string &privilege)
-        : IUIEvent(popupper), m_pkgLabel(pkgLabel), m_privilege(privilege)
+    EventPopupCheck(Popupper *popupper, const std::string &pkgLabel, const std::string &privacy)
+        : IUIEvent(popupper), m_pkgLabel(pkgLabel), m_privacy(privacy)
     {}
 
-    std::string getPrivilege() {
-        return m_privilege;
-    }
-
     virtual void process() {
-        m_popupper->popupCheck(m_pkgLabel, m_privilege);
+        m_popupper->popupCheck(m_pkgLabel, m_privacy);
     }
 private:
     std::string m_pkgLabel;
-    std::string m_privilege;
+    std::string m_privacy;
 };
 
 } //namespace AskUser
diff --git a/src/notification-daemon/policy/PrivilegeInfo.cpp b/src/notification-daemon/policy/PrivilegeInfo.cpp
deleted file mode 100644 (file)
index 06d65b7..0000000
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- *  Copyright (c) 2016 Samsung Electronics Co.
- *
- *  Licensed under the Apache License, Version 2.0 (the "License");
- *  you may not use this file except in compliance with the License.
- *  You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- *  Unless required by applicable law or agreed to in writing, software
- *  distributed under the License is distributed on an "AS IS" BASIS,
- *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- *  See the License for the specific language governing permissions and
- *  limitations under the License
- */
-/**
- * @file        src/agent/notification-daemon/Privilege.cpp
- * @author      Zofia Abramowska <z.abramowska@samsung.com>
- * @brief       Implementation of Privilege Info wrappers
- */
-
-#include <cstdlib>
-#include <memory>
-
-#include "PrivilegeInfo.h"
-
-#include <exception/Exception.h>
-#include <log/alog.h>
-
-#include <privilegemgr/privilege_info.h>
-#include <glib.h>
-
-namespace AskUser {
-
-struct GListWrap {
-    GListWrap(GList *_list) : list(_list) {}
-    ~GListWrap() { g_list_free_full(list, free);}
-    GList * get() { return list; }
-    GList *list;
-};
-
-namespace PrivilegeInfo {
-
-std::string getPrivacyDisplayName(const std::string &privilege) {
-    char *displayName = nullptr;
-    int ret = privilege_info_get_privacy_display(getPrivacyName(privilege).c_str(), &displayName);
-    if (ret != PRVMGR_ERR_NONE || !displayName) {
-        ALOGE("Unable to get privacy display name for <" << privilege << ">, err: <" << ret << ">");
-        return privilege;
-    }
-    std::unique_ptr<char, decltype(free)*> displaNamePtr(displayName, free);
-    return std::string(displayName);
-}
-
-std::string getPrivacyName(const std::string &privilege) {
-    char* privacyName = nullptr;
-    int ret = privilege_info_get_privacy_by_privilege(privilege.c_str(), &privacyName);
-    if (ret != PRVMGR_ERR_NONE || !privacyName) {
-        ALOGE("Unable to get privacy group for privilege: <" << privilege << ">, err: <" << ret << ">");
-        return privilege;
-    }
-
-    std::unique_ptr<char, decltype(free) *> privacyNamePtr(privacyName, free);
-    return std::string(privacyName);
-}
-
-std::vector<std::string> getPrivacyPrivileges(const std::string &privacy) {
-    GList *privilegeList = nullptr;
-
-    int ret = privilege_info_get_privilege_list_by_privacy(privacy.c_str(), &privilegeList);
-    if (ret != PRVMGR_ERR_NONE || !privilegeList) {
-        ALOGE("Unable to get privacy group list of privileges; err: <" << ret <<  ">" );
-        return {privacy};
-    }
-
-    GListWrap privList(privilegeList);
-    std::vector<std::string> privVector;
-    for (GList *l = privList.get(); l != NULL; l = l->next) {
-        privVector.push_back(static_cast<char*>(l->data));
-    }
-    return privVector;
-}
-
-}
-} /* namespace AskUser */
index 4da2d52..1707027 100644 (file)
@@ -57,7 +57,7 @@ std::map<MsgType, const char*> MSG_PO = {
         {MsgType::MSG_POPUP_TEXT, "IDS_IDLE_POP_ALLOW_P1SS_TO_ACCESS_YOUR_P2SS_Q"},
         {MsgType::MSG_POPUP_LAUNCH_TEXT, "IDS_IDLE_POP_PS_IS_REQUESTING_PERMISSION_TO_ACCESS_THE_FOLLOWING_ITEMS_C"},
         {MsgType::MSG_POPUP_CHECKBOX, "IDS_ST_OPT_DONT_SHOW_AGAIN"},
-        {MsgType::MSG_POPUP_ALLOW_BTN,"IDS_IDLE_BUTTON_ALLOW_ABB7"},
+        {MsgType::MSG_POPUP_ALLOW_BTN, "IDS_IDLE_BUTTON_ALLOW_ABB7"},
         {MsgType::MSG_POPUP_DENY_BTN, "IDS_IDLE_BUTTON_DENY"},
         {MsgType::MSG_TOAST_DENY_TEXT, "IDS_ST_TPOP_P1SS_NOT_ALLOWED_TO_USE_P2SS_SELECT_PRIVACY_SETTINGS_IN_SETTINGS_PRIVACY_AND_SECURITY"},
         {MsgType::MSG_TOAST_FAIL_TEXT, "IDS_IDLE_TPOP_TO_USE_APP_ALLOW_ALL_RELEVANT_PERMISSIONS"}
@@ -94,9 +94,9 @@ const char *getFormat(enum MsgType type) {
 
 namespace Notification {
 namespace Po {
-std::string createPopupCheckMsg(const std::string &pkgLabel, const std::string &priv) {
+std::string createPopupCheckMsg(const std::string &pkgLabel, const std::string &privacy) {
     return makeFromFormat(getFormat(MsgType::MSG_POPUP_TEXT), pkgLabel.c_str(),
-                          PrivilegeInfo::getPrivacyDisplayName(priv).c_str());
+                          PrivilegeInfo::getPrivacyDisplayName(privacy).c_str());
 }
 
 std::string getPopupTitleMsg() {
index bde4a20..ab7ed3f 100644 (file)
@@ -158,16 +158,16 @@ void Popupper::show() {
     evas_object_show(m_win);
 }
 
-void Popupper::popupCheck(const std::string &pkgLabel, const std::string &priv) {
+void Popupper::popupCheck(const std::string &pkgLabel, const std::string &privacy) {
     std::string profileName = getProfileName();
     PopupCheck *popup;
     try {
         if (profileName[0] != 'w' && profileName[0] != 'W') {
             // Not wearable
-            popup = new PopupCheckMobile(m_win, Po::createPopupCheckMsg(pkgLabel, priv));
+            popup = new PopupCheckMobile(m_win, Po::createPopupCheckMsg(pkgLabel, privacy));
         } else {
             // Wearable
-            popup = new PopupCheckWearable(m_win, Po::createPopupCheckMsg(pkgLabel, priv));
+            popup = new PopupCheckWearable(m_win, Po::createPopupCheckMsg(pkgLabel, privacy));
         }
         popup->create();
     } catch (const std::exception &e) {
index 067b746..c83ea81 100644 (file)
@@ -47,7 +47,7 @@ public:
     void registerPopupResponseHandler(PopupHandler handler);
     void start();
 
-    void popupCheck(const std::string &pkgLabel, const std::string &priv);
+    void popupCheck(const std::string &pkgLabel, const std::string &privacy);
 
     void popupClose();
     void stop();