summaryrefslogtreecommitdiff
path: root/src/components/policy/src/policy/src/policy_helper.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/policy/src/policy/src/policy_helper.cc')
-rw-r--r--src/components/policy/src/policy/src/policy_helper.cc375
1 files changed, 223 insertions, 152 deletions
diff --git a/src/components/policy/src/policy/src/policy_helper.cc b/src/components/policy/src/policy/src/policy_helper.cc
index 71f91aea6..efae9164b 100644
--- a/src/components/policy/src/policy/src/policy_helper.cc
+++ b/src/components/policy/src/policy/src/policy_helper.cc
@@ -43,21 +43,53 @@ namespace {
CREATE_LOGGERPTR_GLOBAL(logger_, "PolicyManagerImpl")
-bool Match(const StringsValueType& first_name,
- const StringsValueType& second_name) {
- const std::string& first = first_name;
- const std::string& second = second_name;
- return (strcasecmp(first.c_str(), second.c_str()) == 0);
-}
-
bool Compare(const StringsValueType& first, const StringsValueType& second) {
const std::string& first_str = first;
const std::string& second_str = second;
return (strcasecmp(first_str.c_str(), second_str.c_str()) < 0);
}
+struct CheckGroupName {
+ CheckGroupName(const policy::StringsValueType& value)
+ : value_(value) {
+ }
+
+ bool operator()(const FunctionalGroupNames::value_type& value) {
+ return value.second.second == std::string(value_);
+ }
+
+private:
+ const policy::StringsValueType& value_;
+};
+
+struct CopyAttributes{
+ CopyAttributes(const FunctionalGroupNames& groups_attributes,
+ std::vector<FunctionalGroupPermission>& groups_permissions)
+ : groups_attributes_(groups_attributes),
+ groups_permissions_(groups_permissions) {
+ }
+
+bool operator()(const policy::StringsValueType& value) {
+ CheckGroupName checker(value);
+ FunctionalGroupNames::const_iterator it =
+ std::find_if(groups_attributes_.begin(), groups_attributes_.end(),
+ checker);
+ if (groups_attributes_.end() == it) {
+ return false;
+ }
+ FunctionalGroupPermission group;
+ group.group_alias = it->second.first;
+ group.group_id = it->first;
+ groups_permissions_.push_back(group);
+ return true;
}
+private:
+ const FunctionalGroupNames& groups_attributes_;
+ std::vector<FunctionalGroupPermission>& groups_permissions_;
+};
+} // namespace
+
CompareGroupName::CompareGroupName(const StringsValueType& group_name)
: group_name_(group_name) {
}
@@ -71,7 +103,6 @@ bool CompareGroupName::operator()(
bool operator!=(const policy_table::ApplicationParams& first,
const policy_table::ApplicationParams& second) {
- // TODO(AOleynik): Add comparing of Ford-specific and other parameters
if (first.groups.size() != second.groups.size()) {
return true;
}
@@ -98,17 +129,42 @@ CheckAppPolicy::CheckAppPolicy(
snapshot_(snapshot) {
}
-bool CheckAppPolicy::HasSameGroups(const AppPoliciesValueType& app_policy,
- AppPermissions* perms) const {
- const std::string app_id = app_policy.first;
- AppPoliciesConstItr it = snapshot_->policy_table.app_policies.find(app_id);
+bool policy::CheckAppPolicy::HasRevokedGroups(
+ const policy::AppPoliciesValueType& app_policy,
+ policy_table::Strings* revoked_groups) const {
+ AppPoliciesConstItr it =
+ snapshot_->policy_table.app_policies.find(app_policy.first);
+
+ policy_table::Strings groups_new = app_policy.second.groups;
+ std::sort(groups_new.begin(), groups_new.end(), Compare);
+
+ policy_table::Strings groups_curr = (*it).second.groups;
+ std::sort(groups_curr.begin(), groups_curr.end(), Compare);
+
+ StringsConstItr it_groups_new = groups_new.begin();
+ StringsConstItr it_groups_new_end = groups_new.end();
+
+ StringsConstItr it_groups_curr = groups_curr.begin();
+ StringsConstItr it_groups_curr_end = groups_curr.end();
+
+ policy_table::Strings revoked_group_list;
+ std::set_difference(it_groups_curr, it_groups_curr_end,
+ it_groups_new, it_groups_new_end,
+ std::back_inserter(revoked_group_list), Compare);
- if (app_policy.second.is_string()) {
- return (it->second.is_string() &&
- app_policy.second.get_string().compare(it->second.get_string())
- == 0);
+ if (revoked_groups) {
+ *revoked_groups = revoked_group_list;
}
+ return !revoked_group_list.empty();
+}
+
+bool policy::CheckAppPolicy::HasNewGroups(
+ const policy::AppPoliciesValueType& app_policy,
+ policy_table::Strings* new_groups) const {
+ AppPoliciesConstItr it =
+ snapshot_->policy_table.app_policies.find(app_policy.first);
+
policy_table::Strings groups_new = app_policy.second.groups;
std::sort(groups_new.begin(), groups_new.end(), Compare);
@@ -121,137 +177,118 @@ bool CheckAppPolicy::HasSameGroups(const AppPoliciesValueType& app_policy,
StringsConstItr it_groups_curr = groups_curr.begin();
StringsConstItr it_groups_curr_end = groups_curr.end();
- StringsConstItr new_it = it_groups_new;
- StringsConstItr old_it = it_groups_curr;
+ policy_table::Strings new_group_list;
+ std::set_difference(it_groups_new, it_groups_new_end,
+ it_groups_curr, it_groups_curr_end,
+ std::back_inserter(new_group_list), Compare);
- std::pair<StringsConstItr, StringsConstItr> diff;
+ if (new_groups) {
+ *new_groups = new_group_list;
+ }
- while (it_groups_new_end != new_it && it_groups_curr_end != old_it) {
- size_t size = ((it_groups_new_end - new_it) > (it_groups_curr_end - old_it))
- ? it_groups_curr_end - old_it : it_groups_new_end - new_it;
- diff = std::mismatch(old_it, old_it + size, new_it, Match);
- if (it_groups_curr_end == diff.first || it_groups_new_end == diff.second) {
- new_it = diff.second;
- old_it = diff.first;
- break;
- }
- if (Compare(*diff.first, *diff.second) &&
- IsConsentRequired(*(diff.first))) {
- perms->isAppPermissionsRevoked = true;
- FunctionalGroupPermission group;
- group.group_name = *(diff.first);
- perms->appRevokedPermissions.push_back(group);
- old_it = ++diff.first;
- new_it = diff.second;
- } else {
- // according to the SDLAQ-CRS-2757 we have to set
- // appPermissionsConsentNeeded should not be set to true
- // in case if this group is auto-allowed
- perms->appPermissionsConsentNeeded = IsConsentRequired(*new_it);
- old_it = diff.first;
- new_it = ++diff.second;
- }
+ return !new_group_list.empty();
+}
+
+bool policy::CheckAppPolicy::HasConsentNeededGroups(
+ const policy::AppPoliciesValueType& app_policy) const {
+ policy_table::Strings new_groups;
+ if (!HasNewGroups(app_policy, &new_groups)) {
+ return false;
}
- for (StringsConstItr it = old_it; it != it_groups_curr_end; ++it) {
- if (!IsConsentRequired(*it)) {
- continue;
+ StringsConstItr it_new = new_groups.begin();
+ StringsConstItr it_new_end = new_groups.end();
+ for (; it_new != it_new_end; ++it_new) {
+ if (IsConsentRequired(app_policy.first, *it_new)) {
+ return true;
}
- perms->isAppPermissionsRevoked = true;
- FunctionalGroupPermission group;
- group.group_name = *it;
- perms->appRevokedPermissions.push_back(group);
}
- if (it_groups_new_end != new_it) {
- perms->appPermissionsConsentNeeded = true;
- }
+ return false;
+}
- if (perms->isAppPermissionsRevoked) {
+std::vector<FunctionalGroupPermission>
+policy::CheckAppPolicy::GetRevokedGroups(
+ const policy::AppPoliciesValueType& app_policy) const {
+ policy_table::Strings revoked_groups_names;
+ if (!HasRevokedGroups(app_policy, &revoked_groups_names)) {
+ return std::vector<FunctionalGroupPermission>();
+ }
- std::vector<policy::FunctionalGroupPermission>::const_iterator it =
- perms->appRevokedPermissions.begin();
- std::vector<policy::FunctionalGroupPermission>::const_iterator it_end =
- perms->appRevokedPermissions.end();
- for (;it != it_end; ++it) {
- pm_->RemoveAppConsentForGroup(perms->application_id, it->group_name);
- }
+ FunctionalGroupNames groups_attributes;
+ if (!pm_->cache_->GetFunctionalGroupNames(groups_attributes)) {
+ LOG4CXX_WARN(logger_, "Can't get functional group names");
+ return std::vector<FunctionalGroupPermission>();
}
+ std::vector<FunctionalGroupPermission> revoked_groups_permissions;
+ CopyAttributes copier(groups_attributes, revoked_groups_permissions);
+ std::for_each(revoked_groups_names.begin(), revoked_groups_names.end(),
+ copier);
+
+ return revoked_groups_permissions;
+}
- return !(perms->appRevokedPermissions.size() > 0
- || perms->appPermissionsConsentNeeded);
+void policy::CheckAppPolicy::RemoveRevokedConsents(
+ const AppPoliciesValueType& app_policy,
+ const std::vector<FunctionalGroupPermission>& revoked_groups) const {
+ std::vector<policy::FunctionalGroupPermission>::const_iterator it =
+ revoked_groups.begin();
+ std::vector<policy::FunctionalGroupPermission>::const_iterator it_end =
+ revoked_groups.end();
+ for (;it != it_end; ++it) {
+ pm_->RemoveAppConsentForGroup(app_policy.first, it->group_name);
+ }
}
-bool CheckAppPolicy::IsNewAppication(const std::string& application_id) const {
+bool CheckAppPolicy::IsKnownAppication(
+ const std::string& application_id) const {
const policy_table::ApplicationPolicies& current_policies =
snapshot_->policy_table.app_policies;
- AppPoliciesConstItr it_app_policies_curr = current_policies.begin();
- AppPoliciesConstItr it_app_policies_curr_end = current_policies.end();
- for (; it_app_policies_curr != it_app_policies_curr_end;
- ++it_app_policies_curr) {
+ return !(current_policies.end() == current_policies.find(application_id));
+}
- // Find necessary application in current snapshot
- const std::string application_id_curr = (*it_app_policies_curr).first;
- if (application_id == application_id_curr) {
- return false;
- }
- }
- return true;
+void policy::CheckAppPolicy::NotifySystem(
+ const policy::AppPoliciesValueType& app_policy) const {
+ pm_->listener()->OnPendingPermissionChange(app_policy.first);
}
-void CheckAppPolicy::SendNotification(
+void CheckAppPolicy::SendPermissionsToApp(
const AppPoliciesValueType& app_policy) const {
- // Collecting all available rpcs and their parameters from updated
- // policies and fill notification data struct
- Permissions notification_data;
+ const std::string app_id = app_policy.first;
- // Get current user permissions for groups from DB
- std::vector<FunctionalGroupPermission> group_permissons;
- // Get current device_id from application id
- const std::string device_id = pm_->GetCurrentDeviceId(app_policy.first);
+ const std::string device_id = pm_->GetCurrentDeviceId(app_id);
if (device_id.empty()) {
- LOG4CXX_WARN(logger_, "Couldn't find device info for application id "
- "'" << app_policy.first << "'");
+ LOG4CXX_WARN(logger_, "Couldn't find device info for application id: "
+ << app_id);
return;
}
- pm_->GetPermissionsForApp(device_id, app_policy.first, group_permissons);
+ std::vector<FunctionalGroupPermission> group_permissons;
+ pm_->GetPermissionsForApp(device_id, app_id, group_permissons);
+ Permissions notification_data;
pm_->PrepareNotificationData(update_->policy_table.functional_groupings,
app_policy.second.groups,
group_permissons, notification_data);
- const std::string app_id = app_policy.first;
- LOG4CXX_INFO(logger_, "Send notification for application_id:" << app_id);
+ LOG4CXX_INFO(logger_, "Send notification for application_id: " << app_id);
// Default_hmi is Ford-specific and should not be used with basic policy
const std::string default_hmi;
pm_->listener()->OnPermissionsUpdated(app_id, notification_data, default_hmi);
}
-void CheckAppPolicy::SendOnPendingPermissions(
- const AppPoliciesValueType& app_policy, AppPermissions permissions) const {
- // TODO(AOleynik): Exclude default group(s)
- if (permissions.appPermissionsConsentNeeded) {
- }
- // TODO(AOleynik): Seems, it is unused part?
- if (permissions.isAppPermissionsRevoked) {
- pm_->app_permissions_diff_.insert(
- std::make_pair(app_policy.first, permissions));
- pm_->listener()->OnPendingPermissionChange(app_policy.first);
- }
-}
-
bool CheckAppPolicy::IsAppRevoked(
const AppPoliciesValueType& app_policy) const {
+ LOG4CXX_AUTO_TRACE(logger_);
// Application params are not initialized = application revoked
// i.e. "123":null
return app_policy.second.is_null();
}
bool CheckAppPolicy::NicknamesMatch(
- const std::string app_id,
const AppPoliciesValueType& app_policy) const {
+ const std::string& app_id = app_policy.first;
std::string app_name = pm_->listener()->GetAppName(app_id);
if (!app_name.empty() &&
app_policy.second.nicknames &&
@@ -270,58 +307,28 @@ bool CheckAppPolicy::NicknamesMatch(
}
bool CheckAppPolicy::operator()(const AppPoliciesValueType& app_policy) {
- policy_table::ApplicationPolicies& current_policies =
- snapshot_->policy_table.app_policies;
-
const std::string app_id = app_policy.first;
- AppPermissions permissions_diff(app_id);
- permissions_diff.priority = policy_table::EnumToJsonString(
- app_policy.second.priority);
-
- // Check revocation
- if (!IsPredefinedApp(app_policy) && IsAppRevoked(app_policy)) {
- permissions_diff.appRevoked = true;
- pm_->app_permissions_diff_.insert(std::make_pair(app_id, permissions_diff));
- pm_->listener()->OnAppRevoked(app_id);
- policy_table::ApplicationPolicies::iterator it = current_policies.find(
- app_id);
- // Update snapshot with new policies for application
- if (it != current_policies.end()) {
- // Update
- (*it).second = app_policy.second;
- it->second.set_to_null();
- } else {
- // Add
- current_policies[app_policy.first] = app_policy.second;
- }
+ if (!IsKnownAppication(app_id)) {
+ LOG4CXX_WARN(logger_, "Application:" << app_id <<
+ " is not present in snapshot.");
return true;
}
- // TODO(PV): do we really need this check?
- if (IsNewAppication(app_id)) {
- // Update snapshot with policies for new application
- current_policies[app_id] = app_policy.second;
- SendNotification(app_policy);
- SendOnPendingPermissions(app_policy, permissions_diff);
+ if (!IsPredefinedApp(app_policy) && IsAppRevoked(app_policy)) {
+ SetPendingPermissions(app_policy, RESULT_APP_REVOKED);
+ NotifySystem(app_policy);
return true;
}
- if (!IsPredefinedApp(app_policy) && !NicknamesMatch(app_id, app_policy)) {
- permissions_diff.appUnauthorized = true;
- pm_->app_permissions_diff_.insert(std::make_pair(app_id, permissions_diff));
- pm_->listener()->OnPendingPermissionChange(app_policy.first);
- policy_table::ApplicationPolicies::iterator it = current_policies.find(
- app_id);
- // Update snapshot with new policies for application
- if (it != current_policies.end()) {
- (*it).second = app_policy.second;
- it->second.set_to_null();
- }
+ if (!IsPredefinedApp(app_policy) && !NicknamesMatch(app_policy)) {
+ SetPendingPermissions(app_policy, RESULT_NICKNAME_MISMATCH);
+ NotifySystem(app_policy);
return true;
}
- if (HasSameGroups(app_policy, &permissions_diff)) {
+ PermissionsCheckResult result = CheckPermissionsChanges(app_policy);
+ if (RESULT_NO_CHANGES == result) {
LOG4CXX_INFO(logger_, "Permissions for application:" << app_id <<
" wasn't changed.");
return true;
@@ -330,28 +337,92 @@ bool CheckAppPolicy::operator()(const AppPoliciesValueType& app_policy) {
LOG4CXX_INFO(logger_, "Permissions for application:" << app_id <<
" have been changed.");
- policy_table::ApplicationPolicies::iterator it = current_policies.find(
- app_id);
- // Update snapshot with new policies for application
- (*it).second = app_policy.second;
+ if (!IsPredefinedApp(app_policy) && RESULT_CONSENT_NOT_REQIURED != result) {
+ SetPendingPermissions(app_policy, result);
+ NotifySystem(app_policy);
+ }
// Don't sent notification for predefined apps (e.g. default, device etc.)
if (!IsPredefinedApp(app_policy)) {
- SendNotification(app_policy);
- SendOnPendingPermissions(app_policy, permissions_diff);
+ SendPermissionsToApp(app_policy);
}
return true;
}
-bool CheckAppPolicy::IsConsentRequired(const std::string& group_name) const {
+void policy::CheckAppPolicy::SetPendingPermissions(
+ const AppPoliciesValueType& app_policy,
+ PermissionsCheckResult result) const {
+ const std::string app_id = app_policy.first;
+ AppPermissions permissions_diff(app_id);
+ permissions_diff.priority = policy_table::EnumToJsonString(
+ app_policy.second.priority);
+
+ switch (result) {
+ case RESULT_APP_REVOKED:
+ permissions_diff.appRevoked = true;
+ break;
+ case RESULT_NICKNAME_MISMATCH:
+ permissions_diff.appUnauthorized = true;
+ break;
+ case RESULT_PERMISSIONS_REVOKED:
+ permissions_diff.isAppPermissionsRevoked = true;
+ permissions_diff.appRevokedPermissions = GetRevokedGroups(app_policy);
+ RemoveRevokedConsents(app_policy, permissions_diff.appRevokedPermissions);
+ break;
+ case RESULT_CONSENT_NEEDED:
+ permissions_diff.appPermissionsConsentNeeded = true;
+ break;
+ case RESULT_PERMISSIONS_REVOKED_AND_CONSENT_NEEDED:
+ permissions_diff.isAppPermissionsRevoked = true;
+ permissions_diff.appPermissionsConsentNeeded = true;
+ permissions_diff.appRevokedPermissions = GetRevokedGroups(app_policy);
+ RemoveRevokedConsents(app_policy, permissions_diff.appRevokedPermissions);
+ break;
+ default:
+ return;
+ }
+ pm_->app_permissions_diff_lock_.Acquire();
+ pm_->app_permissions_diff_.insert(std::make_pair(app_id, permissions_diff));
+ pm_->app_permissions_diff_lock_.Release();
+}
+
+policy::CheckAppPolicy::PermissionsCheckResult
+policy::CheckAppPolicy::CheckPermissionsChanges(
+ const policy::AppPoliciesValueType& app_policy) const {
+
+ bool has_revoked_groups = HasRevokedGroups(app_policy);
+
+ bool has_consent_needed_groups = HasConsentNeededGroups(app_policy);
+
+ bool has_new_groups = HasNewGroups(app_policy);
+
+ if (has_revoked_groups && has_consent_needed_groups) {
+ return RESULT_PERMISSIONS_REVOKED_AND_CONSENT_NEEDED;
+ } else if (has_revoked_groups) {
+ return RESULT_PERMISSIONS_REVOKED;
+ } else if (has_consent_needed_groups) {
+ return RESULT_CONSENT_NEEDED;
+ } else if (has_new_groups) {
+ return RESULT_CONSENT_NOT_REQIURED;
+ }
+
+ return RESULT_NO_CHANGES;
+}
+
+bool CheckAppPolicy::IsConsentRequired(const std::string& app_id,
+ const std::string& group_name) const {
const policy_table::FunctionalGroupings& functional_groupings =
snapshot_->policy_table.functional_groupings;
+
FuncGroupConstItr it = functional_groupings.find(group_name);
+
if (functional_groupings.end() == it) {
return false;
}
- return it->second.user_consent_prompt.is_initialized();
+ bool is_preconsented = false;
+
+ return it->second.user_consent_prompt.is_initialized() && !is_preconsented;
}
FillNotificationData::FillNotificationData(Permissions& data,