ECACL.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. /*
  2. * Copyright 2005 - 2016 Zarafa and its licensors
  3. *
  4. * This program is free software: you can redistribute it and/or modify
  5. * it under the terms of the GNU Affero General Public License, version 3,
  6. * as published by the Free Software Foundation.
  7. *
  8. * This program is distributed in the hope that it will be useful,
  9. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. * GNU Affero General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU Affero General Public License
  14. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. *
  16. */
  17. #include <kopano/platform.h>
  18. #include "ECACL.h"
  19. #include <kopano/CommonUtil.h>
  20. #include <kopano/stringutil.h>
  21. #include <sstream>
  22. #include <algorithm>
  23. namespace KC {
  24. // The data in this array must be sorted on the ulRights field.
  25. struct AclRightName {
  26. unsigned ulRight;
  27. const char *szRight;
  28. };
  29. static const AclRightName g_rights[] = {
  30. {RIGHTS_READ_ITEMS, "item read"},
  31. {RIGHTS_CREATE_ITEMS, "item create"},
  32. {RIGHTS_EDIT_OWN, "edit own"},
  33. {RIGHTS_DELETE_OWN, "delete own"},
  34. {RIGHTS_EDIT_ALL, "edit all"},
  35. {RIGHTS_DELETE_ALL, "delete all"},
  36. {RIGHTS_CREATE_SUBFOLDERS, "create sub"},
  37. {RIGHTS_FOLDER_OWNER, "own"},
  38. {RIGHTS_FOLDER_CONTACT, "contact"},
  39. {RIGHTS_FOLDER_VISIBLE, "view"}
  40. };
  41. // The data in this array must be sorted on the ulRights field.
  42. struct AclRoleName {
  43. unsigned ulRights;
  44. const char *szRole;
  45. };
  46. static const AclRoleName g_roles[] = {
  47. {RIGHTS_NONE, "none"}, // Actually a right, but not seen as such by IsRight
  48. {ROLE_NONE, "none"}, // This might be confusing
  49. {ROLE_REVIEWER, "reviewer"},
  50. {ROLE_CONTRIBUTOR, "contributor"},
  51. {ROLE_NONEDITING_AUTHOR, "non-editting author"},
  52. {ROLE_AUTHOR, "author"},
  53. {ROLE_EDITOR, "editor"},
  54. {ROLE_PUBLISH_EDITOR, "publish editor"},
  55. {ROLE_PUBLISH_AUTHOR, "publish author"},
  56. {ROLE_OWNER, "owner"}
  57. };
  58. static inline bool IsRight(unsigned ulRights) {
  59. // A right has exactly 1 bit set. Otherwise it's a role
  60. return (ulRights ^ (ulRights - 1)) == 0;
  61. }
  62. static inline bool operator<(const AclRightName &lhs, const AclRightName &rhs) {
  63. return lhs.ulRight < rhs.ulRight;
  64. }
  65. static inline bool operator<(const AclRoleName &lhs, const AclRoleName &rhs) {
  66. return lhs.ulRights < rhs.ulRights;
  67. }
  68. static const AclRightName *FindAclRight(unsigned ulRights) {
  69. const AclRightName rn = {ulRights, NULL};
  70. const AclRightName *lpRightName = std::lower_bound(g_rights, ARRAY_END(g_rights), rn);
  71. if (lpRightName != ARRAY_END(g_rights) && lpRightName->ulRight == ulRights)
  72. return lpRightName;
  73. return NULL;
  74. }
  75. static const AclRoleName *FindAclRole(unsigned ulRights) {
  76. const AclRoleName rn = {ulRights, NULL};
  77. const AclRoleName *lpRoleName = std::lower_bound(g_roles, ARRAY_END(g_roles), rn);
  78. if (lpRoleName != ARRAY_END(g_roles) && lpRoleName->ulRights == ulRights)
  79. return lpRoleName;
  80. return NULL;
  81. }
  82. std::string AclRightsToString(unsigned ulRights)
  83. {
  84. if (ulRights == unsigned(-1))
  85. return "missing or invalid";
  86. if (IsRight(ulRights)) {
  87. const AclRightName *lpRightName = FindAclRight(ulRights);
  88. if (lpRightName == NULL)
  89. return stringify(ulRights, true);
  90. return lpRightName->szRight;
  91. }
  92. const AclRoleName *lpRoleName = FindAclRole(ulRights);
  93. if (lpRoleName != NULL)
  94. return lpRoleName->szRole;
  95. std::ostringstream ostr;
  96. bool empty = true;
  97. for (unsigned bit = 0, mask = 1; bit < 32; ++bit, mask <<= 1) {
  98. if (ulRights & mask) {
  99. if (!empty)
  100. ostr << ",";
  101. empty = false;
  102. ostr << AclRightsToString(mask);
  103. }
  104. }
  105. return ostr.str();
  106. }
  107. } /* namespace */