protection.py 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. from __future__ import absolute_import
  2. # Copyright (c) 2010-2019 openpyxl
  3. from openpyxl.descriptors.serialisable import Serialisable
  4. from openpyxl.descriptors import (
  5. Alias,
  6. Typed,
  7. String,
  8. Float,
  9. Integer,
  10. Bool,
  11. NoneSet,
  12. Set,
  13. )
  14. from openpyxl.descriptors.excel import (
  15. ExtensionList,
  16. HexBinary,
  17. Guid,
  18. Relation,
  19. Base64Binary,
  20. )
  21. from openpyxl.utils.protection import hash_password
  22. class WorkbookProtection(Serialisable):
  23. _workbook_password, _revisions_password = None, None
  24. tagname = "workbookPr"
  25. workbook_password = Alias("workbookPassword")
  26. workbookPasswordCharacterSet = String(allow_none=True)
  27. revision_password = Alias("revisionsPassword")
  28. revisionsPasswordCharacterSet = String(allow_none=True)
  29. lockStructure = Bool(allow_none=True)
  30. lock_structure = Alias("lockStructure")
  31. lockWindows = Bool(allow_none=True)
  32. lock_windows = Alias("lockWindows")
  33. lockRevision = Bool(allow_none=True)
  34. lock_revision = Alias("lockRevision")
  35. revisionsAlgorithmName = String(allow_none=True)
  36. revisionsHashValue = Base64Binary(allow_none=True)
  37. revisionsSaltValue = Base64Binary(allow_none=True)
  38. revisionsSpinCount = Integer(allow_none=True)
  39. workbookAlgorithmName = String(allow_none=True)
  40. workbookHashValue = Base64Binary(allow_none=True)
  41. workbookSaltValue = Base64Binary(allow_none=True)
  42. workbookSpinCount = Integer(allow_none=True)
  43. __attrs__ = ('workbookPassword', 'workbookPasswordCharacterSet', 'revisionsPassword',
  44. 'revisionsPasswordCharacterSet', 'lockStructure', 'lockWindows', 'lockRevision',
  45. 'revisionsAlgorithmName', 'revisionsHashValue', 'revisionsSaltValue',
  46. 'revisionsSpinCount', 'workbookAlgorithmName', 'workbookHashValue',
  47. 'workbookSaltValue', 'workbookSpinCount')
  48. def __init__(self,
  49. workbookPassword=None,
  50. workbookPasswordCharacterSet=None,
  51. revisionsPassword=None,
  52. revisionsPasswordCharacterSet=None,
  53. lockStructure=None,
  54. lockWindows=None,
  55. lockRevision=None,
  56. revisionsAlgorithmName=None,
  57. revisionsHashValue=None,
  58. revisionsSaltValue=None,
  59. revisionsSpinCount=None,
  60. workbookAlgorithmName=None,
  61. workbookHashValue=None,
  62. workbookSaltValue=None,
  63. workbookSpinCount=None,
  64. ):
  65. if workbookPassword is not None:
  66. self.workbookPassword = workbookPassword
  67. self.workbookPasswordCharacterSet = workbookPasswordCharacterSet
  68. if revisionsPassword is not None:
  69. self.revisionsPassword = revisionsPassword
  70. self.revisionsPasswordCharacterSet = revisionsPasswordCharacterSet
  71. self.lockStructure = lockStructure
  72. self.lockWindows = lockWindows
  73. self.lockRevision = lockRevision
  74. self.revisionsAlgorithmName = revisionsAlgorithmName
  75. self.revisionsHashValue = revisionsHashValue
  76. self.revisionsSaltValue = revisionsSaltValue
  77. self.revisionsSpinCount = revisionsSpinCount
  78. self.workbookAlgorithmName = workbookAlgorithmName
  79. self.workbookHashValue = workbookHashValue
  80. self.workbookSaltValue = workbookSaltValue
  81. self.workbookSpinCount = workbookSpinCount
  82. def set_workbook_password(self, value='', already_hashed=False):
  83. """Set a password on this workbook."""
  84. if not already_hashed:
  85. value = hash_password(value)
  86. self._workbook_password = value
  87. @property
  88. def workbookPassword(self):
  89. """Return the workbook password value, regardless of hash."""
  90. return self._workbook_password
  91. @workbookPassword.setter
  92. def workbookPassword(self, value):
  93. """Set a workbook password directly, forcing a hash step."""
  94. self.set_workbook_password(value)
  95. def set_revisions_password(self, value='', already_hashed=False):
  96. """Set a revision password on this workbook."""
  97. if not already_hashed:
  98. value = hash_password(value)
  99. self._revisions_password = value
  100. @property
  101. def revisionsPassword(self):
  102. """Return the revisions password value, regardless of hash."""
  103. return self._revisions_password
  104. @revisionsPassword.setter
  105. def revisionsPassword(self, value):
  106. """Set a revisions password directly, forcing a hash step."""
  107. self.set_revisions_password(value)
  108. @classmethod
  109. def from_tree(cls, node):
  110. """Don't hash passwords when deserialising from XML"""
  111. self = super(WorkbookProtection, cls).from_tree(node)
  112. if self.workbookPassword:
  113. self.set_workbook_password(node.get('workbookPassword'), already_hashed=True)
  114. if self.revisionsPassword:
  115. self.set_revisions_password(node.get('revisionsPassword'), already_hashed=True)
  116. return self
  117. # Backwards compatibility
  118. DocumentSecurity = WorkbookProtection
  119. class FileSharing(Serialisable):
  120. tagname = "fileSharing"
  121. readOnlyRecommended = Bool(allow_none=True)
  122. userName = String(allow_none=True)
  123. reservationPassword = HexBinary(allow_none=True)
  124. algorithmName = String(allow_none=True)
  125. hashValue = Base64Binary(allow_none=True)
  126. saltValue = Base64Binary(allow_none=True)
  127. spinCount = Integer(allow_none=True)
  128. def __init__(self,
  129. readOnlyRecommended=None,
  130. userName=None,
  131. reservationPassword=None,
  132. algorithmName=None,
  133. hashValue=None,
  134. saltValue=None,
  135. spinCount=None,
  136. ):
  137. self.readOnlyRecommended = readOnlyRecommended
  138. self.userName = userName
  139. self.reservationPassword = reservationPassword
  140. self.algorithmName = algorithmName
  141. self.hashValue = hashValue
  142. self.saltValue = saltValue
  143. self.spinCount = spinCount