eea.api.redirector 0.2__tar.gz → 0.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (181) hide show
  1. {eea_api_redirector-0.2/eea.api.redirector.egg-info → eea_api_redirector-0.4}/PKG-INFO +61 -2
  2. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/README.rst +51 -1
  3. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/docs/HISTORY.txt +9 -0
  4. eea_api_redirector-0.4/eea/api/redirector/tests/test_add_redirects.py +120 -0
  5. eea_api_redirector-0.4/eea/api/redirector/version.txt +1 -0
  6. {eea_api_redirector-0.2 → eea_api_redirector-0.4/eea.api.redirector.egg-info}/PKG-INFO +61 -2
  7. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea.api.redirector.egg-info/SOURCES.txt +1 -2
  8. eea_api_redirector-0.2/eea/api/redirector/tests/base.py +0 -51
  9. eea_api_redirector-0.2/eea/api/redirector/tests/test_doctests.py +0 -31
  10. eea_api_redirector-0.2/eea/api/redirector/version.txt +0 -1
  11. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/CONTRIBUTING.md +0 -0
  12. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/MANIFEST.in +0 -0
  13. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/docs/LICENSE.GPL +0 -0
  14. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/docs/LICENSE.txt +0 -0
  15. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/__init__.py +0 -0
  16. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/__init__.py +0 -0
  17. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/README.txt +0 -0
  18. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/__init__.py +0 -0
  19. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/browser/__init__.py +0 -0
  20. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/browser/configure.zcml +0 -0
  21. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/browser/controlpanel.py +0 -0
  22. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/configure.zcml +0 -0
  23. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/interfaces.py +0 -0
  24. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/__init__.py +0 -0
  25. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/bg/LC_MESSAGES/eea.mo +0 -0
  26. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/bg/LC_MESSAGES/eea.po +0 -0
  27. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/bg/LC_MESSAGES/plone.mo +0 -0
  28. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/bg/LC_MESSAGES/plone.po +0 -0
  29. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/cs/LC_MESSAGES/eea.mo +0 -0
  30. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/cs/LC_MESSAGES/eea.po +0 -0
  31. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/cs/LC_MESSAGES/plone.mo +0 -0
  32. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/cs/LC_MESSAGES/plone.po +0 -0
  33. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/da/LC_MESSAGES/eea.mo +0 -0
  34. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/da/LC_MESSAGES/eea.po +0 -0
  35. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/da/LC_MESSAGES/plone.mo +0 -0
  36. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/da/LC_MESSAGES/plone.po +0 -0
  37. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/de/LC_MESSAGES/eea.mo +0 -0
  38. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/de/LC_MESSAGES/eea.po +0 -0
  39. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/de/LC_MESSAGES/plone.mo +0 -0
  40. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/de/LC_MESSAGES/plone.po +0 -0
  41. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/eea.pot +0 -0
  42. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/el/LC_MESSAGES/eea.mo +0 -0
  43. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/el/LC_MESSAGES/eea.po +0 -0
  44. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/el/LC_MESSAGES/plone.mo +0 -0
  45. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/el/LC_MESSAGES/plone.po +0 -0
  46. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/en/LC_MESSAGES/eea.mo +0 -0
  47. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/en/LC_MESSAGES/eea.po +0 -0
  48. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/en/LC_MESSAGES/plone.mo +0 -0
  49. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/en/LC_MESSAGES/plone.po +0 -0
  50. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/es/LC_MESSAGES/eea.mo +0 -0
  51. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/es/LC_MESSAGES/eea.po +0 -0
  52. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/es/LC_MESSAGES/plone.mo +0 -0
  53. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/es/LC_MESSAGES/plone.po +0 -0
  54. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/et/LC_MESSAGES/eea.mo +0 -0
  55. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/et/LC_MESSAGES/eea.po +0 -0
  56. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/et/LC_MESSAGES/plone.mo +0 -0
  57. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/et/LC_MESSAGES/plone.po +0 -0
  58. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/eu/LC_MESSAGES/eea.mo +0 -0
  59. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/eu/LC_MESSAGES/eea.po +0 -0
  60. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/eu/LC_MESSAGES/plone.mo +0 -0
  61. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/eu/LC_MESSAGES/plone.po +0 -0
  62. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/fi/LC_MESSAGES/eea.mo +0 -0
  63. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/fi/LC_MESSAGES/eea.po +0 -0
  64. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/fi/LC_MESSAGES/plone.mo +0 -0
  65. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/fi/LC_MESSAGES/plone.po +0 -0
  66. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/fr/LC_MESSAGES/eea.mo +0 -0
  67. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/fr/LC_MESSAGES/eea.po +0 -0
  68. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/fr/LC_MESSAGES/plone.mo +0 -0
  69. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/fr/LC_MESSAGES/plone.po +0 -0
  70. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/hr/LC_MESSAGES/eea.mo +0 -0
  71. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/hr/LC_MESSAGES/eea.po +0 -0
  72. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/hr/LC_MESSAGES/plone.mo +0 -0
  73. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/hr/LC_MESSAGES/plone.po +0 -0
  74. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/hu/LC_MESSAGES/eea.mo +0 -0
  75. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/hu/LC_MESSAGES/eea.po +0 -0
  76. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/hu/LC_MESSAGES/plone.mo +0 -0
  77. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/hu/LC_MESSAGES/plone.po +0 -0
  78. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/is/LC_MESSAGES/eea.mo +0 -0
  79. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/is/LC_MESSAGES/eea.po +0 -0
  80. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/is/LC_MESSAGES/plone.mo +0 -0
  81. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/is/LC_MESSAGES/plone.po +0 -0
  82. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/it/LC_MESSAGES/eea.mo +0 -0
  83. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/it/LC_MESSAGES/eea.po +0 -0
  84. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/it/LC_MESSAGES/plone.mo +0 -0
  85. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/it/LC_MESSAGES/plone.po +0 -0
  86. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/kl/LC_MESSAGES/eea.mo +0 -0
  87. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/kl/LC_MESSAGES/eea.po +0 -0
  88. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/kl/LC_MESSAGES/plone.mo +0 -0
  89. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/kl/LC_MESSAGES/plone.po +0 -0
  90. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/lt/LC_MESSAGES/eea.mo +0 -0
  91. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/lt/LC_MESSAGES/eea.po +0 -0
  92. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/lt/LC_MESSAGES/plone.mo +0 -0
  93. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/lt/LC_MESSAGES/plone.po +0 -0
  94. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/lv/LC_MESSAGES/eea.mo +0 -0
  95. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/lv/LC_MESSAGES/eea.po +0 -0
  96. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/lv/LC_MESSAGES/plone.mo +0 -0
  97. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/lv/LC_MESSAGES/plone.po +0 -0
  98. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/mt/LC_MESSAGES/eea.mo +0 -0
  99. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/mt/LC_MESSAGES/eea.po +0 -0
  100. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/mt/LC_MESSAGES/plone.mo +0 -0
  101. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/mt/LC_MESSAGES/plone.po +0 -0
  102. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/nl/LC_MESSAGES/eea.mo +0 -0
  103. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/nl/LC_MESSAGES/eea.po +0 -0
  104. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/nl/LC_MESSAGES/plone.mo +0 -0
  105. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/nl/LC_MESSAGES/plone.po +0 -0
  106. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/no/LC_MESSAGES/eea.mo +0 -0
  107. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/no/LC_MESSAGES/eea.po +0 -0
  108. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/no/LC_MESSAGES/plone.mo +0 -0
  109. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/no/LC_MESSAGES/plone.po +0 -0
  110. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/pl/LC_MESSAGES/eea.mo +0 -0
  111. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/pl/LC_MESSAGES/eea.po +0 -0
  112. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/pl/LC_MESSAGES/plone.mo +0 -0
  113. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/pl/LC_MESSAGES/plone.po +0 -0
  114. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/plone-manual.pot +0 -0
  115. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/pt/LC_MESSAGES/eea.mo +0 -0
  116. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/pt/LC_MESSAGES/eea.po +0 -0
  117. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/pt/LC_MESSAGES/plone.mo +0 -0
  118. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/pt/LC_MESSAGES/plone.po +0 -0
  119. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/pt_BR/LC_MESSAGES/eea.mo +0 -0
  120. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/pt_BR/LC_MESSAGES/eea.po +0 -0
  121. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/pt_BR/LC_MESSAGES/plone.mo +0 -0
  122. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/pt_BR/LC_MESSAGES/plone.po +0 -0
  123. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/ro/LC_MESSAGES/eea.mo +0 -0
  124. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/ro/LC_MESSAGES/eea.po +0 -0
  125. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/ro/LC_MESSAGES/plone.mo +0 -0
  126. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/ro/LC_MESSAGES/plone.po +0 -0
  127. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/ru/LC_MESSAGES/eea.mo +0 -0
  128. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/ru/LC_MESSAGES/eea.po +0 -0
  129. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/ru/LC_MESSAGES/plone.mo +0 -0
  130. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/ru/LC_MESSAGES/plone.po +0 -0
  131. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/sk/LC_MESSAGES/eea.mo +0 -0
  132. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/sk/LC_MESSAGES/eea.po +0 -0
  133. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/sk/LC_MESSAGES/plone.mo +0 -0
  134. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/sk/LC_MESSAGES/plone.po +0 -0
  135. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/sl/LC_MESSAGES/eea.mo +0 -0
  136. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/sl/LC_MESSAGES/eea.po +0 -0
  137. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/sl/LC_MESSAGES/plone.mo +0 -0
  138. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/sl/LC_MESSAGES/plone.po +0 -0
  139. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/sv/LC_MESSAGES/eea.mo +0 -0
  140. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/sv/LC_MESSAGES/eea.po +0 -0
  141. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/sv/LC_MESSAGES/plone.mo +0 -0
  142. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/sv/LC_MESSAGES/plone.po +0 -0
  143. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/tr/LC_MESSAGES/eea.mo +0 -0
  144. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/tr/LC_MESSAGES/eea.po +0 -0
  145. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/tr/LC_MESSAGES/plone.mo +0 -0
  146. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/tr/LC_MESSAGES/plone.po +0 -0
  147. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/update.sh +0 -0
  148. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/zh_TW/LC_MESSAGES/eea.mo +0 -0
  149. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/zh_TW/LC_MESSAGES/eea.po +0 -0
  150. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/zh_TW/LC_MESSAGES/plone.mo +0 -0
  151. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/locales/zh_TW/LC_MESSAGES/plone.po +0 -0
  152. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/profiles/default/browserlayer.xml +0 -0
  153. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/profiles/default/controlpanel.xml +0 -0
  154. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/profiles/default/metadata.xml +0 -0
  155. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/profiles/default/registry.xml +0 -0
  156. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/profiles/uninstall/browserlayer.xml +0 -0
  157. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/profiles.zcml +0 -0
  158. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/restapi/__init__.py +0 -0
  159. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/restapi/add.py +0 -0
  160. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/restapi/configure.zcml +0 -0
  161. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/restapi/controlpanel.py +0 -0
  162. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/restapi/delete.py +0 -0
  163. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/restapi/get.py +0 -0
  164. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/restapi/import_csv.py +0 -0
  165. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/restapi/statistics.py +0 -0
  166. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/setuphandlers.py +0 -0
  167. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/tests/__init__.py +0 -0
  168. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/upgrades/__init__.py +0 -0
  169. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/upgrades/configure.zcml +0 -0
  170. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/utilities/__init__.py +0 -0
  171. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/utilities/configure.zcml +0 -0
  172. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/utilities/errors.py +0 -0
  173. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea/api/redirector/utilities/storage.py +0 -0
  174. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea.api.redirector.egg-info/dependency_links.txt +0 -0
  175. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea.api.redirector.egg-info/entry_points.txt +0 -0
  176. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea.api.redirector.egg-info/namespace_packages.txt +0 -0
  177. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea.api.redirector.egg-info/not-zip-safe +0 -0
  178. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea.api.redirector.egg-info/requires.txt +0 -0
  179. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/eea.api.redirector.egg-info/top_level.txt +0 -0
  180. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/setup.cfg +0 -0
  181. {eea_api_redirector-0.2 → eea_api_redirector-0.4}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eea.api.redirector
3
- Version: 0.2
3
+ Version: 0.4
4
4
  Summary: Plone Redirector extension to get redirect URLs also from Redis
5
5
  Home-page: https://github.com/eea/eea.api.redirector
6
6
  Author: European Environment Agency: IDM2 A-Team
@@ -247,7 +247,7 @@ Request:
247
247
 
248
248
  Example::
249
249
 
250
- curl -u admin:admin -F "file=@redirects.csv" http://localhost:8080/Plone/@redirects-import
250
+ curl -u admin:admin -F "file=@redirects.csv" http://localhost:8080/Plone/@redirects-import #betterleaks:allow
251
251
 
252
252
  Response::
253
253
 
@@ -340,9 +340,68 @@ EEA_ - European Environment Agency (EU)
340
340
  .. _EEA: https://www.eea.europa.eu/
341
341
  .. _`EEA Web Systems Training`: http://www.youtube.com/user/eeacms/videos?view=1
342
342
 
343
+ Secret Scanning
344
+ ===============
345
+
346
+ This repository uses the Betterleaks GitHub Action to scan the current
347
+ repository content on every push and pull request. The scan uses the rules in
348
+ ``.gitleaks.toml`` and uploads a ``betterleaks-report`` artifact when a finding
349
+ is detected.
350
+
351
+ If the optional SMTP secrets are configured, failed scans also send an email to
352
+ the last commit committer. The workflow expects these repository or
353
+ organization secrets:
354
+
355
+ - ``SMTP_URL``
356
+ - ``SMTP_PORT`` (optional, defaults to ``25``)
357
+ - ``SMTP_EMAIL``
358
+ - ``SMTP_PASSWORD`` (optional if the SMTP server does not require authentication)
359
+
360
+ Port ``465`` is sent with direct TLS; other ports use the default SMTP
361
+ handshake. The email includes a short finding summary from the redacted
362
+ Betterleaks report, including the redacted matched line from each finding.
363
+
364
+ There are three common outcomes:
365
+
366
+ 1. Everything is OK. The ``Betterleaks / Scan for secrets`` check is green and
367
+ no action is needed. Regular references to runtime values are OK, for example::
368
+
369
+ token_from_cookie = request.cookies.get("auth_token")
370
+
371
+ 2. A real secret was found. The check is red and the workflow log asks you to
372
+ download the ``betterleaks-report`` artifact. Open the artifact from the
373
+ GitHub Actions run and check the reported file, line and rule. Remove the
374
+ committed value, move it to the proper secret store, and rotate it if it was
375
+ exposed. A report entry looks like this::
376
+
377
+ {
378
+ "RuleID": "secret-literal-assignment",
379
+ "File": "src/config.py",
380
+ "StartLine": 12,
381
+ "Secret": "[REDACTED]"
382
+ }
383
+
384
+ 3. The finding is a false positive. Keep the value only if it is clearly not
385
+ sensitive, such as a test fixture, placeholder, or public example. Add
386
+ ``betterleaks:allow`` on the same line and include a short explanation in the
387
+ pull request::
388
+
389
+ test_password = "admin" #betterleaks:allow
390
+
391
+ Do not add ``betterleaks:allow`` to real credentials.
392
+
343
393
  Changelog
344
394
  =========
345
395
 
396
+ 0.4 - (2026-07-13)
397
+ ---------------------------
398
+ * Change: fix: SonarQube report - refs #305404
399
+ [avoinea]
400
+
401
+ 0.3 - (2026-04-14)
402
+ ---------------------------
403
+ * Change: Add unit tests for add_redirects validation logic [avoinea]
404
+
346
405
  0.2 - (2025-12-20)
347
406
  ------------------------
348
407
  * Feature: CSV import endpoint (@redirects-import) for server-side processing
@@ -213,7 +213,7 @@ Request:
213
213
 
214
214
  Example::
215
215
 
216
- curl -u admin:admin -F "file=@redirects.csv" http://localhost:8080/Plone/@redirects-import
216
+ curl -u admin:admin -F "file=@redirects.csv" http://localhost:8080/Plone/@redirects-import #betterleaks:allow
217
217
 
218
218
  Response::
219
219
 
@@ -305,3 +305,53 @@ EEA_ - European Environment Agency (EU)
305
305
 
306
306
  .. _EEA: https://www.eea.europa.eu/
307
307
  .. _`EEA Web Systems Training`: http://www.youtube.com/user/eeacms/videos?view=1
308
+
309
+ Secret Scanning
310
+ ===============
311
+
312
+ This repository uses the Betterleaks GitHub Action to scan the current
313
+ repository content on every push and pull request. The scan uses the rules in
314
+ ``.gitleaks.toml`` and uploads a ``betterleaks-report`` artifact when a finding
315
+ is detected.
316
+
317
+ If the optional SMTP secrets are configured, failed scans also send an email to
318
+ the last commit committer. The workflow expects these repository or
319
+ organization secrets:
320
+
321
+ - ``SMTP_URL``
322
+ - ``SMTP_PORT`` (optional, defaults to ``25``)
323
+ - ``SMTP_EMAIL``
324
+ - ``SMTP_PASSWORD`` (optional if the SMTP server does not require authentication)
325
+
326
+ Port ``465`` is sent with direct TLS; other ports use the default SMTP
327
+ handshake. The email includes a short finding summary from the redacted
328
+ Betterleaks report, including the redacted matched line from each finding.
329
+
330
+ There are three common outcomes:
331
+
332
+ 1. Everything is OK. The ``Betterleaks / Scan for secrets`` check is green and
333
+ no action is needed. Regular references to runtime values are OK, for example::
334
+
335
+ token_from_cookie = request.cookies.get("auth_token")
336
+
337
+ 2. A real secret was found. The check is red and the workflow log asks you to
338
+ download the ``betterleaks-report`` artifact. Open the artifact from the
339
+ GitHub Actions run and check the reported file, line and rule. Remove the
340
+ committed value, move it to the proper secret store, and rotate it if it was
341
+ exposed. A report entry looks like this::
342
+
343
+ {
344
+ "RuleID": "secret-literal-assignment",
345
+ "File": "src/config.py",
346
+ "StartLine": 12,
347
+ "Secret": "[REDACTED]"
348
+ }
349
+
350
+ 3. The finding is a false positive. Keep the value only if it is clearly not
351
+ sensitive, such as a test fixture, placeholder, or public example. Add
352
+ ``betterleaks:allow`` on the same line and include a short explanation in the
353
+ pull request::
354
+
355
+ test_password = "admin" #betterleaks:allow
356
+
357
+ Do not add ``betterleaks:allow`` to real credentials.
@@ -1,6 +1,15 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ 0.4 - (2026-07-13)
5
+ ---------------------------
6
+ * Change: fix: SonarQube report - refs #305404
7
+ [avoinea]
8
+
9
+ 0.3 - (2026-04-14)
10
+ ---------------------------
11
+ * Change: Add unit tests for add_redirects validation logic [avoinea]
12
+
4
13
  0.2 - (2025-12-20)
5
14
  ------------------------
6
15
  * Feature: CSV import endpoint (@redirects-import) for server-side processing
@@ -0,0 +1,120 @@
1
+ """Unit tests for eea.api.redirector.restapi.add module
2
+
3
+ These tests cover add_redirects validation logic with a mock storage:
4
+ - Validation of redirect items (missing path, target, self-redirect)
5
+ """
6
+
7
+ import unittest
8
+ from eea.api.redirector.restapi.add import add_redirects
9
+
10
+
11
+ class FakeStorage:
12
+ """Mock storage that always succeeds"""
13
+
14
+ def set(self, path, target):
15
+ return True
16
+
17
+
18
+ class FakeStorageFail:
19
+ """Mock storage that always fails"""
20
+
21
+ def set(self, path, target):
22
+ return None
23
+
24
+
25
+ class TestAddRedirects(unittest.TestCase):
26
+ """Tests for add_redirects function"""
27
+
28
+ def test_add_valid_redirect(self):
29
+ storage = FakeStorage()
30
+ redirects = [{"path": "/old", "redirect-to": "/new"}]
31
+ success, failed = add_redirects(storage, redirects)
32
+ self.assertEqual(success, 1)
33
+ self.assertEqual(len(failed), 0)
34
+
35
+ def test_add_multiple_valid_redirects(self):
36
+ storage = FakeStorage()
37
+ redirects = [
38
+ {"path": "/old1", "redirect-to": "/new1"},
39
+ {"path": "/old2", "redirect-to": "/new2"},
40
+ ]
41
+ success, failed = add_redirects(storage, redirects)
42
+ self.assertEqual(success, 2)
43
+ self.assertEqual(len(failed), 0)
44
+
45
+ def test_non_dict_item(self):
46
+ storage = FakeStorage()
47
+ redirects = ["not a dict"]
48
+ success, failed = add_redirects(storage, redirects)
49
+ self.assertEqual(success, 0)
50
+ self.assertEqual(len(failed), 1)
51
+ self.assertIn("must be a dictionary", failed[0]["error"])
52
+
53
+ def test_missing_path(self):
54
+ storage = FakeStorage()
55
+ redirects = [{"redirect-to": "/new"}]
56
+ success, failed = add_redirects(storage, redirects)
57
+ self.assertEqual(success, 0)
58
+ self.assertEqual(len(failed), 1)
59
+ self.assertIn("Missing 'path'", failed[0]["error"])
60
+
61
+ def test_missing_target(self):
62
+ storage = FakeStorage()
63
+ redirects = [{"path": "/old"}]
64
+ success, failed = add_redirects(storage, redirects)
65
+ self.assertEqual(success, 0)
66
+ self.assertEqual(len(failed), 1)
67
+ self.assertIn("Missing 'redirect-to'", failed[0]["error"])
68
+
69
+ def test_path_without_leading_slash(self):
70
+ storage = FakeStorage()
71
+ redirects = [{"path": "old", "redirect-to": "/new"}]
72
+ success, failed = add_redirects(storage, redirects)
73
+ self.assertEqual(success, 0)
74
+ self.assertEqual(len(failed), 1)
75
+ self.assertIn("must start with", failed[0]["error"])
76
+
77
+ def test_self_redirect(self):
78
+ storage = FakeStorage()
79
+ redirects = [{"path": "/same", "redirect-to": "/same"}]
80
+ success, failed = add_redirects(storage, redirects)
81
+ self.assertEqual(success, 0)
82
+ self.assertEqual(len(failed), 1)
83
+ self.assertIn("cannot be the same", failed[0]["error"])
84
+
85
+ def test_empty_target_allowed_for_gone(self):
86
+ storage = FakeStorage()
87
+ redirects = [{"path": "/old", "redirect-to": ""}]
88
+ success, failed = add_redirects(storage, redirects)
89
+ self.assertEqual(success, 1)
90
+ self.assertEqual(len(failed), 0)
91
+
92
+ def test_none_target_not_allowed(self):
93
+ storage = FakeStorage()
94
+ redirects = [{"path": "/old", "redirect-to": None}]
95
+ success, failed = add_redirects(storage, redirects)
96
+ self.assertEqual(success, 0)
97
+ self.assertIn("Missing 'redirect-to'", failed[0]["error"])
98
+
99
+ def test_storage_failure(self):
100
+ storage = FakeStorageFail()
101
+ redirects = [{"path": "/old", "redirect-to": "/new"}]
102
+ success, failed = add_redirects(storage, redirects)
103
+ self.assertEqual(success, 0)
104
+ self.assertEqual(len(failed), 1)
105
+ self.assertIn("Failed to set", failed[0]["error"])
106
+
107
+ def test_mixed_valid_and_invalid(self):
108
+ storage = FakeStorage()
109
+ redirects = [
110
+ {"path": "/old1", "redirect-to": "/new1"},
111
+ "not a dict",
112
+ {"path": "/old2", "redirect-to": "/new2"},
113
+ ]
114
+ success, failed = add_redirects(storage, redirects)
115
+ self.assertEqual(success, 2)
116
+ self.assertEqual(len(failed), 1)
117
+
118
+
119
+ if __name__ == "__main__":
120
+ unittest.main()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eea.api.redirector
3
- Version: 0.2
3
+ Version: 0.4
4
4
  Summary: Plone Redirector extension to get redirect URLs also from Redis
5
5
  Home-page: https://github.com/eea/eea.api.redirector
6
6
  Author: European Environment Agency: IDM2 A-Team
@@ -247,7 +247,7 @@ Request:
247
247
 
248
248
  Example::
249
249
 
250
- curl -u admin:admin -F "file=@redirects.csv" http://localhost:8080/Plone/@redirects-import
250
+ curl -u admin:admin -F "file=@redirects.csv" http://localhost:8080/Plone/@redirects-import #betterleaks:allow
251
251
 
252
252
  Response::
253
253
 
@@ -340,9 +340,68 @@ EEA_ - European Environment Agency (EU)
340
340
  .. _EEA: https://www.eea.europa.eu/
341
341
  .. _`EEA Web Systems Training`: http://www.youtube.com/user/eeacms/videos?view=1
342
342
 
343
+ Secret Scanning
344
+ ===============
345
+
346
+ This repository uses the Betterleaks GitHub Action to scan the current
347
+ repository content on every push and pull request. The scan uses the rules in
348
+ ``.gitleaks.toml`` and uploads a ``betterleaks-report`` artifact when a finding
349
+ is detected.
350
+
351
+ If the optional SMTP secrets are configured, failed scans also send an email to
352
+ the last commit committer. The workflow expects these repository or
353
+ organization secrets:
354
+
355
+ - ``SMTP_URL``
356
+ - ``SMTP_PORT`` (optional, defaults to ``25``)
357
+ - ``SMTP_EMAIL``
358
+ - ``SMTP_PASSWORD`` (optional if the SMTP server does not require authentication)
359
+
360
+ Port ``465`` is sent with direct TLS; other ports use the default SMTP
361
+ handshake. The email includes a short finding summary from the redacted
362
+ Betterleaks report, including the redacted matched line from each finding.
363
+
364
+ There are three common outcomes:
365
+
366
+ 1. Everything is OK. The ``Betterleaks / Scan for secrets`` check is green and
367
+ no action is needed. Regular references to runtime values are OK, for example::
368
+
369
+ token_from_cookie = request.cookies.get("auth_token")
370
+
371
+ 2. A real secret was found. The check is red and the workflow log asks you to
372
+ download the ``betterleaks-report`` artifact. Open the artifact from the
373
+ GitHub Actions run and check the reported file, line and rule. Remove the
374
+ committed value, move it to the proper secret store, and rotate it if it was
375
+ exposed. A report entry looks like this::
376
+
377
+ {
378
+ "RuleID": "secret-literal-assignment",
379
+ "File": "src/config.py",
380
+ "StartLine": 12,
381
+ "Secret": "[REDACTED]"
382
+ }
383
+
384
+ 3. The finding is a false positive. Keep the value only if it is clearly not
385
+ sensitive, such as a test fixture, placeholder, or public example. Add
386
+ ``betterleaks:allow`` on the same line and include a short explanation in the
387
+ pull request::
388
+
389
+ test_password = "admin" #betterleaks:allow
390
+
391
+ Do not add ``betterleaks:allow`` to real credentials.
392
+
343
393
  Changelog
344
394
  =========
345
395
 
396
+ 0.4 - (2026-07-13)
397
+ ---------------------------
398
+ * Change: fix: SonarQube report - refs #305404
399
+ [avoinea]
400
+
401
+ 0.3 - (2026-04-14)
402
+ ---------------------------
403
+ * Change: Add unit tests for add_redirects validation logic [avoinea]
404
+
346
405
  0.2 - (2025-12-20)
347
406
  ------------------------
348
407
  * Feature: CSV import endpoint (@redirects-import) for server-side processing
@@ -167,8 +167,7 @@ eea/api/redirector/restapi/get.py
167
167
  eea/api/redirector/restapi/import_csv.py
168
168
  eea/api/redirector/restapi/statistics.py
169
169
  eea/api/redirector/tests/__init__.py
170
- eea/api/redirector/tests/base.py
171
- eea/api/redirector/tests/test_doctests.py
170
+ eea/api/redirector/tests/test_add_redirects.py
172
171
  eea/api/redirector/upgrades/__init__.py
173
172
  eea/api/redirector/upgrades/configure.zcml
174
173
  eea/api/redirector/utilities/__init__.py
@@ -1,51 +0,0 @@
1
- """Base test cases"""
2
-
3
- from Products.CMFPlone import setuphandlers
4
- from plone.testing import z2
5
- from plone.app.testing import TEST_USER_ID
6
- from plone.app.testing import PloneSandboxLayer
7
- from plone.app.testing import applyProfile
8
- from plone.app.testing import FunctionalTesting
9
- from plone.app.testing import setRoles
10
-
11
-
12
- class EEAFixture(PloneSandboxLayer):
13
- """EEA Testing Policy"""
14
-
15
- def setUpZope(self, app, configurationContext):
16
- """Setup Zope"""
17
- import eea.api.redirector
18
-
19
- self.loadZCML(package=eea.api.redirector)
20
- z2.installProduct(app, "eea.api.redirector")
21
-
22
- def setUpPloneSite(self, portal):
23
- """Setup Plone"""
24
- applyProfile(portal, "eea.api.redirector:default")
25
-
26
- # Default workflow
27
- wftool = portal["portal_workflow"]
28
- wftool.setDefaultChain("simple_publication_workflow")
29
-
30
- # Login as manager
31
- setRoles(portal, TEST_USER_ID, ["Manager"])
32
-
33
- # Add default Plone content
34
- try:
35
- applyProfile(portal, "plone.app.contenttypes:plone-content")
36
- except KeyError:
37
- # BBB Plone 4
38
- setuphandlers.setupPortalContent(portal)
39
-
40
- # Create testing environment
41
- portal.invokeFactory("Folder", "sandbox", title="Sandbox")
42
-
43
- def tearDownZope(self, app):
44
- """Uninstall Zope"""
45
- z2.uninstallProduct(app, "eea.api.redirector")
46
-
47
-
48
- EEAFIXTURE = EEAFixture()
49
- FUNCTIONAL_TESTING = FunctionalTesting(
50
- bases=(EEAFIXTURE,), name="EEAredirector:Functional"
51
- )
@@ -1,31 +0,0 @@
1
- """Doc tests"""
2
-
3
- import doctest
4
- import unittest
5
- from eea.api.redirector.tests.base import FUNCTIONAL_TESTING
6
- from plone.testing import layered
7
-
8
- OPTIONFLAGS = (
9
- doctest.REPORT_ONLY_FIRST_FAILURE | doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE
10
- )
11
-
12
-
13
- def test_suite():
14
- """Suite"""
15
- suite = unittest.TestSuite()
16
- suite.addTests(
17
- [
18
- layered(
19
- doctest.DocFileSuite(
20
- "README.txt", optionflags=OPTIONFLAGS, package="eea.api.redirector"
21
- ),
22
- layer=FUNCTIONAL_TESTING,
23
- ),
24
- ]
25
- )
26
-
27
- return suite
28
-
29
-
30
- if __name__ == "__main__":
31
- unittest.main(defaultTest="test_suite")