| /* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying | 
 |    file LICENSE.rst or https://cmake.org/licensing for details.  */ | 
 | #include "cmWIXAccessControlList.h" | 
 |  | 
 | #include <cm/string_view> | 
 |  | 
 | #include "cmCPackGenerator.h" | 
 | #include "cmStringAlgorithms.h" | 
 | #include "cmSystemTools.h" | 
 |  | 
 | cmWIXAccessControlList::cmWIXAccessControlList( | 
 |   cmCPackLog* logger, cmInstalledFile const& installedFile, | 
 |   cmWIXSourceWriter& sourceWriter) | 
 |   : Logger(logger) | 
 |   , InstalledFile(installedFile) | 
 |   , SourceWriter(sourceWriter) | 
 | { | 
 | } | 
 |  | 
 | bool cmWIXAccessControlList::Apply() | 
 | { | 
 |   auto entries = this->InstalledFile.GetPropertyAsList("CPACK_WIX_ACL"); | 
 |  | 
 |   for (auto const& entry : entries) { | 
 |     this->CreatePermissionElement(entry); | 
 |   } | 
 |  | 
 |   return true; | 
 | } | 
 |  | 
 | void cmWIXAccessControlList::CreatePermissionElement(std::string const& entry) | 
 | { | 
 |   std::string::size_type pos = entry.find('='); | 
 |   if (pos == std::string::npos) { | 
 |     this->ReportError(entry, "Did not find mandatory '='"); | 
 |     return; | 
 |   } | 
 |  | 
 |   cm::string_view enview(entry); | 
 |   cm::string_view user_and_domain = enview.substr(0, pos); | 
 |   cm::string_view permission_string = enview.substr(pos + 1); | 
 |  | 
 |   pos = user_and_domain.find('@'); | 
 |   cm::string_view user; | 
 |   cm::string_view domain; | 
 |   if (pos != std::string::npos) { | 
 |     user = user_and_domain.substr(0, pos); | 
 |     domain = user_and_domain.substr(pos + 1); | 
 |   } else { | 
 |     user = user_and_domain; | 
 |   } | 
 |  | 
 |   this->SourceWriter.BeginElement("Permission"); | 
 |   this->SourceWriter.AddAttribute("User", std::string(user)); | 
 |   if (!domain.empty()) { | 
 |     this->SourceWriter.AddAttribute("Domain", std::string(domain)); | 
 |   } | 
 |   for (auto permission : | 
 |        cmTokenizedView(permission_string, ',', cmTokenizerMode::New)) { | 
 |     this->EmitBooleanAttribute(entry, cmTrimWhitespace(permission)); | 
 |   } | 
 |   this->SourceWriter.EndElement("Permission"); | 
 | } | 
 |  | 
 | void cmWIXAccessControlList::ReportError(std::string const& entry, | 
 |                                          std::string const& message) | 
 | { | 
 |   cmCPackLogger(cmCPackLog::LOG_ERROR, | 
 |                 "Failed processing ACL entry '" << entry << "': " << message | 
 |                                                 << std::endl); | 
 | } | 
 |  | 
 | bool cmWIXAccessControlList::IsBooleanAttribute(std::string const& name) | 
 | { | 
 |   static char const* validAttributes[] = { | 
 |     /* clang-format needs this comment to break after the opening brace */ | 
 |     "Append", | 
 |     "ChangePermission", | 
 |     "CreateChild", | 
 |     "CreateFile", | 
 |     "CreateLink", | 
 |     "CreateSubkeys", | 
 |     "Delete", | 
 |     "DeleteChild", | 
 |     "EnumerateSubkeys", | 
 |     "Execute", | 
 |     "FileAllRights", | 
 |     "GenericAll", | 
 |     "GenericExecute", | 
 |     "GenericRead", | 
 |     "GenericWrite", | 
 |     "Notify", | 
 |     "Read", | 
 |     "ReadAttributes", | 
 |     "ReadExtendedAttributes", | 
 |     "ReadPermission", | 
 |     "SpecificRightsAll", | 
 |     "Synchronize", | 
 |     "TakeOwnership", | 
 |     "Traverse", | 
 |     "Write", | 
 |     "WriteAttributes", | 
 |     "WriteExtendedAttributes", | 
 |     nullptr | 
 |   }; | 
 |  | 
 |   size_t i = 0; | 
 |   while (validAttributes[i]) { | 
 |     if (name == validAttributes[i++]) { | 
 |       return true; | 
 |     } | 
 |   } | 
 |  | 
 |   return false; | 
 | } | 
 |  | 
 | void cmWIXAccessControlList::EmitBooleanAttribute(std::string const& entry, | 
 |                                                   std::string const& name) | 
 | { | 
 |   if (!this->IsBooleanAttribute(name)) { | 
 |     this->ReportError(entry, | 
 |                       cmStrCat("Unknown boolean attribute '", name, '\'')); | 
 |   } | 
 |  | 
 |   this->SourceWriter.AddAttribute(name, "yes"); | 
 | } |