diff --git a/last_commit.txt b/last_commit.txt index 5c400eff78..8bd09aed02 100644 --- a/last_commit.txt +++ b/last_commit.txt @@ -1,59 +1,44 @@ -Repository: plone.session - - -Branch: refs/heads/master -Date: 2023-09-04T12:22:31+02:00 -Author: Maurits van Rees (mauritsvanrees) -Commit: https://github.com/plone/plone.session/commit/a093d48b1ff81e715e6836170c1f87a3f8da284a - -Do not set an auth cookie after password reset, unless the user is authenticated. - -Otherwise anonymous users will be logged in immediately, even when autologin after password reset is false. -Fixes https://github.com/plone/Products.CMFPlone/issues/3835. - -Files changed: -A news/3835.bugfix -M plone/session/plugins/session.py -M plone/session/tests/testPAS.py - -b'diff --git a/news/3835.bugfix b/news/3835.bugfix\nnew file mode 100644\nindex 0000000..28a7ddc\n--- /dev/null\n+++ b/news/3835.bugfix\n@@ -0,0 +1,4 @@\n+Do not set an auth cookie after password reset, unless the user is authenticated.\n+Otherwise anonymous users will be logged in immediately, even when autologin after password reset is false.\n+Fixes `issue 3835 `_.\n+[maurits]\ndiff --git a/plone/session/plugins/session.py b/plone/session/plugins/session.py\nindex 803087c..bd49f83 100644\n--- a/plone/session/plugins/session.py\n+++ b/plone/session/plugins/session.py\n@@ -281,8 +281,14 @@ def updateCredentials(self, request, response, login, new_password):\n authenticated_user = getSecurityManager().getUser()\n if authenticated_user is not None:\n authenticated_id = authenticated_user.getId()\n- # For anonymous, the id is empty\n- if authenticated_id and authenticated_id != user_id:\n+ # For anonymous, the id is empty.\n+ if not authenticated_id:\n+ # We should not update credentials when there are none currently.\n+ # Otherwise for example you are logged in after a password reset,\n+ # even when autologin after password reset is false.\n+ # See https://github.com/plone/Products.CMFPlone/issues/3835\n+ return\n+ if authenticated_id != user_id:\n return\n self._setupSession(user_id, response)\n \ndiff --git a/plone/session/tests/testPAS.py b/plone/session/tests/testPAS.py\nindex 8872042..9e9b2d1 100644\n--- a/plone/session/tests/testPAS.py\n+++ b/plone/session/tests/testPAS.py\n@@ -117,7 +117,10 @@ def testCredentialsUpdateAnonymous(self):\n session = self.folder.pas.session\n request = self.makeRequest("test string")\n session.updateCredentials(request, request.response, "our_user", "password")\n- self.assertIsNotNone(\n+ # The anonymous user should not get a cookie: resetCredentials should\n+ # not do anything when there are no current credentials.\n+ # See https://github.com/plone/Products.CMFPlone/issues/3835\n+ self.assertIsNone(\n request.response.getCookie(session.cookie_name),\n )\n \n@@ -133,7 +136,7 @@ def testRefresh(self):\n logout()\n session = self.folder.pas.session\n request = self.makeRequest("test string")\n- session.updateCredentials(request, request.response, "our_user", "password")\n+ session._setupSession(self.userid, request.response)\n cookie = request.response.getCookie(session.cookie_name)["value"]\n request2 = self.makeRequest(cookie)\n request2.form["type"] = "gif"\n' - -Repository: plone.session - - -Branch: refs/heads/master -Date: 2023-09-06T16:25:43+02:00 -Author: Maurits van Rees (mauritsvanrees) -Commit: https://github.com/plone/plone.session/commit/2c9213c69edc3b5f08e33c167458e7283d071276 - -testRefresh: no need to logout first. - -Also, fix/clarify a few comments in the tests. - -Also, check that calling updateCredentials for ourselves *does* set a cookie. -This seems the most obvious test to do, but we seem to have missed this. - -Files changed: -M plone/session/tests/testPAS.py - -b'diff --git a/plone/session/tests/testPAS.py b/plone/session/tests/testPAS.py\nindex 9e9b2d1..c3cf6ec 100644\n--- a/plone/session/tests/testPAS.py\n+++ b/plone/session/tests/testPAS.py\n@@ -102,7 +102,9 @@ def testExtraction(self):\n self.assertEqual(creds, {})\n \n def testCredentialsUpdateUnknownUser(self):\n- # We are logged in as test user, which we do not want.\n+ # Check that calling updateCredentials for an *unknown* user does not set a\n+ # cookie if there is no cookie with credentials yet (you are anonymous).\n+ # So first logout.\n logout()\n session = self.folder.pas.session\n request = self.makeRequest("test string")\n@@ -112,12 +114,14 @@ def testCredentialsUpdateUnknownUser(self):\n self.assertIsNone(request.response.getCookie(session.cookie_name))\n \n def testCredentialsUpdateAnonymous(self):\n- # We are logged in as test user, which we do not want.\n+ # Check that calling updateCredentials for a *known* user does not set a\n+ # cookie if there is no cookie with credentials yet (you are anonymous).\n+ # So first logout.\n logout()\n session = self.folder.pas.session\n request = self.makeRequest("test string")\n session.updateCredentials(request, request.response, "our_user", "password")\n- # The anonymous user should not get a cookie: resetCredentials should\n+ # The anonymous user should not get a cookie: updateCredentials should\n # not do anything when there are no current credentials.\n # See https://github.com/plone/Products.CMFPlone/issues/3835\n self.assertIsNone(\n@@ -125,15 +129,21 @@ def testCredentialsUpdateAnonymous(self):\n )\n \n def testCredentialsUpdateOtherUser(self):\n- # We are logged in as test user, which we DO want in this test.\n- # The session should not be updated then.\n+ # Check that calling updateCredentials for someone other than the logged in\n+ # user does not set a cookie.\n session = self.folder.pas.session\n request = self.makeRequest("test string")\n session.updateCredentials(request, request.response, "our_user", "password")\n self.assertIsNone(request.response.getCookie(session.cookie_name))\n \n+ def testCredentialsUpdateSameUser(self):\n+ # Check that calling updateCredentials for ourselves *does* set a cookie.\n+ session = self.folder.pas.session\n+ request = self.makeRequest("test string")\n+ session.updateCredentials(request, request.response, self.userid, "password")\n+ self.assertIsNone(request.response.getCookie(session.cookie_name))\n+\n def testRefresh(self):\n- logout()\n session = self.folder.pas.session\n request = self.makeRequest("test string")\n session._setupSession(self.userid, request.response)\n@@ -146,14 +156,14 @@ def testRefresh(self):\n def testUnicodeUserid(self):\n response = MockResponse()\n session = self.folder.pas.session\n- # This step would fail.\n+ # The main thing we test, is that the next call does not give a traceback:\n session._setupSession(self.userid, response)\n \n def testSpecialCharUserid(self):\n unicode_userid = "\xc3\xa3bcd\xc3\xa9fghijk"\n response = MockResponse()\n session = self.folder.pas.session\n- # This step would fail.\n+ # The main thing we test, is that the next call does not give a traceback:\n session._setupSession(unicode_userid, response)\n \n def testCookieInvalidAfterLogout(self):\n' - -Repository: plone.session - - -Branch: refs/heads/master -Date: 2023-09-06T21:44:09-07:00 -Author: David Glick (davisagli) -Commit: https://github.com/plone/plone.session/commit/991f77bf5d4e33f12016234570b6ff6f6da56641 - -Merge pull request #44 from plone/maurits-do-not-update-credentials-for-anonymous-issue-3835 - -Do not set auth cookie after password reset, unless user is authenticated +Repository: plone.restapi + + +Branch: refs/heads/main +Date: 2023-09-06T21:51:28-07:00 +Author: Leonardo J. Caballero G (macagua) +Commit: https://github.com/plone/plone.restapi/commit/ed192208499989b379de8534a3aa12d037316db4 + +Add Spanish translation #1684 (#1685) + +* Add Spanish translation #1684 + +* Updated Spanish translation + +* Fixed some typos from Spanish translation + +* Update Spanish translation + +* Add Spanish translation #1684 + +* Updated Spanish translation + +* Fixed some typos from Spanish translation + +* Update Spanish translation + +* maintenance: Added change log entry that missing + +* maintenance: Added change log entry that missing + +* Update news/1684.feature + +--------- + +Co-authored-by: Mikel Larreategi <mlarreategi@codesyntax.com> +Co-authored-by: David Glick <david@glicksoftware.com> Files changed: -A news/3835.bugfix -M plone/session/plugins/session.py -M plone/session/tests/testPAS.py +A news/1684.feature +A src/plone/restapi/locales/es/LC_MESSAGES/plone.restapi.po +M CONTRIBUTORS.rst -b'diff --git a/news/3835.bugfix b/news/3835.bugfix\nnew file mode 100644\nindex 0000000..28a7ddc\n--- /dev/null\n+++ b/news/3835.bugfix\n@@ -0,0 +1,4 @@\n+Do not set an auth cookie after password reset, unless the user is authenticated.\n+Otherwise anonymous users will be logged in immediately, even when autologin after password reset is false.\n+Fixes `issue 3835 `_.\n+[maurits]\ndiff --git a/plone/session/plugins/session.py b/plone/session/plugins/session.py\nindex 803087c..bd49f83 100644\n--- a/plone/session/plugins/session.py\n+++ b/plone/session/plugins/session.py\n@@ -281,8 +281,14 @@ def updateCredentials(self, request, response, login, new_password):\n authenticated_user = getSecurityManager().getUser()\n if authenticated_user is not None:\n authenticated_id = authenticated_user.getId()\n- # For anonymous, the id is empty\n- if authenticated_id and authenticated_id != user_id:\n+ # For anonymous, the id is empty.\n+ if not authenticated_id:\n+ # We should not update credentials when there are none currently.\n+ # Otherwise for example you are logged in after a password reset,\n+ # even when autologin after password reset is false.\n+ # See https://github.com/plone/Products.CMFPlone/issues/3835\n+ return\n+ if authenticated_id != user_id:\n return\n self._setupSession(user_id, response)\n \ndiff --git a/plone/session/tests/testPAS.py b/plone/session/tests/testPAS.py\nindex 8872042..c3cf6ec 100644\n--- a/plone/session/tests/testPAS.py\n+++ b/plone/session/tests/testPAS.py\n@@ -102,7 +102,9 @@ def testExtraction(self):\n self.assertEqual(creds, {})\n \n def testCredentialsUpdateUnknownUser(self):\n- # We are logged in as test user, which we do not want.\n+ # Check that calling updateCredentials for an *unknown* user does not set a\n+ # cookie if there is no cookie with credentials yet (you are anonymous).\n+ # So first logout.\n logout()\n session = self.folder.pas.session\n request = self.makeRequest("test string")\n@@ -112,28 +114,39 @@ def testCredentialsUpdateUnknownUser(self):\n self.assertIsNone(request.response.getCookie(session.cookie_name))\n \n def testCredentialsUpdateAnonymous(self):\n- # We are logged in as test user, which we do not want.\n+ # Check that calling updateCredentials for a *known* user does not set a\n+ # cookie if there is no cookie with credentials yet (you are anonymous).\n+ # So first logout.\n logout()\n session = self.folder.pas.session\n request = self.makeRequest("test string")\n session.updateCredentials(request, request.response, "our_user", "password")\n- self.assertIsNotNone(\n+ # The anonymous user should not get a cookie: updateCredentials should\n+ # not do anything when there are no current credentials.\n+ # See https://github.com/plone/Products.CMFPlone/issues/3835\n+ self.assertIsNone(\n request.response.getCookie(session.cookie_name),\n )\n \n def testCredentialsUpdateOtherUser(self):\n- # We are logged in as test user, which we DO want in this test.\n- # The session should not be updated then.\n+ # Check that calling updateCredentials for someone other than the logged in\n+ # user does not set a cookie.\n session = self.folder.pas.session\n request = self.makeRequest("test string")\n session.updateCredentials(request, request.response, "our_user", "password")\n self.assertIsNone(request.response.getCookie(session.cookie_name))\n \n+ def testCredentialsUpdateSameUser(self):\n+ # Check that calling updateCredentials for ourselves *does* set a cookie.\n+ session = self.folder.pas.session\n+ request = self.makeRequest("test string")\n+ session.updateCredentials(request, request.response, self.userid, "password")\n+ self.assertIsNone(request.response.getCookie(session.cookie_name))\n+\n def testRefresh(self):\n- logout()\n session = self.folder.pas.session\n request = self.makeRequest("test string")\n- session.updateCredentials(request, request.response, "our_user", "password")\n+ session._setupSession(self.userid, request.response)\n cookie = request.response.getCookie(session.cookie_name)["value"]\n request2 = self.makeRequest(cookie)\n request2.form["type"] = "gif"\n@@ -143,14 +156,14 @@ def testRefresh(self):\n def testUnicodeUserid(self):\n response = MockResponse()\n session = self.folder.pas.session\n- # This step would fail.\n+ # The main thing we test, is that the next call does not give a traceback:\n session._setupSession(self.userid, response)\n \n def testSpecialCharUserid(self):\n unicode_userid = "\xc3\xa3bcd\xc3\xa9fghijk"\n response = MockResponse()\n session = self.folder.pas.session\n- # This step would fail.\n+ # The main thing we test, is that the next call does not give a traceback:\n session._setupSession(unicode_userid, response)\n \n def testCookieInvalidAfterLogout(self):\n' +b'diff --git a/CONTRIBUTORS.rst b/CONTRIBUTORS.rst\nindex 35fb75b10b..4af50c3c97 100644\n--- a/CONTRIBUTORS.rst\n+++ b/CONTRIBUTORS.rst\n@@ -38,4 +38,4 @@\n - Gauthier Bastien\n - Katja S\xc3\xbcss\n - Jon Pentland\n- \n\\ No newline at end of file\n+- Leonardo J. Caballero G.\ndiff --git a/news/1684.feature b/news/1684.feature\nnew file mode 100644\nindex 0000000000..61ece574fb\n--- /dev/null\n+++ b/news/1684.feature\n@@ -0,0 +1 @@\n+Add Spanish translation @macagua\n\\ No newline at end of file\ndiff --git a/src/plone/restapi/locales/es/LC_MESSAGES/plone.restapi.po b/src/plone/restapi/locales/es/LC_MESSAGES/plone.restapi.po\nnew file mode 100644\nindex 0000000000..b957833eec\n--- /dev/null\n+++ b/src/plone/restapi/locales/es/LC_MESSAGES/plone.restapi.po\n@@ -0,0 +1,279 @@\n+# --- PLEASE EDIT THE LINES BELOW CORRECTLY ---\n+# SOME DESCRIPTIVE TITLE.\n+# Leonardo J. Caballero G. , 2019, 2023.\n+msgid ""\n+msgstr ""\n+"Project-Id-Version: Plone\\n"\n+"POT-Creation-Date: 2019-12-09 10:14+0000\\n"\n+"PO-Revision-Date: 2023-08-23 21:19-0400\\n"\n+"Last-Translator: Leonardo J. Caballero G. \\n"\n+"Language-Team: ES \\n"\n+"Language: es\\n"\n+"MIME-Version: 1.0\\n"\n+"Content-Type: text/plain; charset=UTF-8\\n"\n+"Content-Transfer-Encoding: 8bit\\n"\n+"Plural-Forms: nplurals=2; plural=(n != 1);\\n"\n+"Language-Code: es\\n"\n+"Language-Name: Espa\xc3\xb1ol\\n"\n+"Preferred-Encodings: utf-8 latin1\\n"\n+"Domain: plone.restapi\\n"\n+"X-Generator: Poedit 3.3.2\\n"\n+"X-Is-Fallback-For: es-ar es-bo es-cl es-co es-cr es-do es-ec es-es es-sv es-gt es-hn es-mx es-ni es-pa es-py es-pe es-pr es-us es-uy es-ve\\n"\n+\n+#: plone/restapi/services/email_send/post.py:81\n+msgid "${sender_fullname} via ${portal_title}"\n+msgstr "${sender_fullname} v\xc3\xada ${portal_title}"\n+\n+#: plone/restapi/services/email_send/post.py:74\n+msgid "A portal user via ${portal_title}"\n+msgstr "Un usuario de portal user v\xc3\xada ${portal_title}"\n+\n+#: plone/restapi/configure.zcml:73\n+msgid "Adds sample content for performance testing"\n+msgstr "A\xc3\xb1adir contenido de ejemplo para efectuar pruebas"\n+\n+#: plone/restapi/configure.zcml:56\n+msgid "Adds sample content types for testing"\n+msgstr "A\xc3\xb1adir tipos de contenido de ejemplo para pruebas"\n+\n+#: plone/restapi/configure.zcml:65\n+msgid "Adds sample workflows for testing"\n+msgstr "A\xc3\xb1adir flujos de trabajo de muestra para realizar pruebas"\n+\n+#: plone/restapi/services/aliases/add.py:106\n+msgid "Alternative urls that point to themselves will cause an endless cycle of redirects."\n+msgstr "Las URL alternativas que apuntan a s\xc3\xad mismas provocar\xc3\xa1n un bucle interminable de redireccionamientos."\n+\n+#: plone/restapi/configure.zcml:115\n+msgid "Blocks"\n+msgstr "Bloques"\n+\n+#: plone/restapi/configure.zcml:122\n+msgid "Blocks (Editable Layout)"\n+msgstr "Bloques (Dise\xc3\xb1o editable)"\n+\n+#: plone/restapi/configure.zcml:122\n+msgid "Enables Volto Blocks (editable layout) support"\n+msgstr "Habilita el soporte para bloques Volto (dise\xc3\xb1o editable)"\n+\n+#: plone/restapi/configure.zcml:115\n+msgid "Enables Volto Blocks support"\n+msgstr "Habilitar soporte a Bloques Volto"\n+\n+#: plone/restapi/configure.zcml:81\n+msgid "Enables blocks on the Document content type"\n+msgstr "Habilitar bloques en el tipo de contenido Documento"\n+\n+#: plone/restapi/services/contextnavigation/get.py:133\n+msgid "Enter a valid scale name (see \'Image Handling\' control panel) to override (e.g. icon, tile, thumb, mini, preview, ... ). Leave empty to use default (see \'Site\' control panel)."\n+msgstr "Introducir un nombre de escala v\xc3\xa1lido (consulte \'Manipulaci\xc3\xb3n de im\xc3\xa1genes\' en el panel de control) para anular (por ejemplo, icon, tile, thumb, mini, preview...). D\xc3\xa9jelo en blanco para usar el valor predeterminado (consulte \'Sitio\' en el panel de control)."\n+\n+#: plone/restapi/services/users/add.py:163\n+msgid "Error in fields. ${errors_to_string}"\n+msgstr "Errores en los campos. ${errors_to_string}"\n+\n+#. Default: "The reset_token is expired."\n+#: plone/restapi/services/users/add.py:312\n+msgid "Expired Token"\n+msgstr "Token caducado"\n+\n+#: plone/restapi/services/contextnavigation/get.py:126\n+msgid "If enabled, the portlet will not show document type icons."\n+msgstr "Si est\xc3\xa1 habilitado, el portlet no mostrar\xc3\xa1 los iconos de tipo de contenido."\n+\n+#: plone/restapi/services/contextnavigation/get.py:145\n+msgid "If enabled, the portlet will not show thumbs."\n+msgstr "Si est\xc3\xa1 habilitado, el portlet no mostrar\xc3\xa1 miniaturas."\n+\n+#: plone/restapi/services/users/add.py:296\n+msgid "If you pass \'old_password\' you have to pass \'new_password\'"\n+msgstr "Si introduce \'Contrase\xc3\xb1a anterior\', debe ingresar \'Contrase\xc3\xb1a nueva\'"\n+\n+#: plone/restapi/services/users/add.py:290\n+msgid "If you pass \'reset_token\' you have to pass \'new_password\'"\n+msgstr "Si introduce \'Restablecer token\' debe ingresar \'Nueva contrase\xc3\xb1a\'"\n+\n+#: plone/restapi/behaviors.py:23\n+msgid "Layout"\n+msgstr "Dise\xc3\xb1o"\n+\n+#: plone/restapi/services/contextnavigation/get.py:195\n+msgid "Navigation"\n+msgstr "Navegaci\xc3\xb3n"\n+\n+#: plone/restapi/services/contextnavigation/get.py:132\n+msgid "Override thumb scale"\n+msgstr "Anular escala de miniaturas"\n+\n+#: plone/restapi/services/users/add.py:97\n+msgid "Property \'${fieldname}\' is not allowed."\n+msgstr "El campo \'${fieldname}\' no est\xc3\xa1 permitido."\n+\n+#: plone/restapi/services/users/add.py:87\n+msgid "Property \'${fieldname}\' is required."\n+msgstr "El campo \'${fieldname}\' es obligatorio."\n+\n+#: plone/restapi/configure.zcml:89\n+msgid "RESTful hypermedia API for Plone - Uninstall"\n+msgstr "API hipermedia RESTful para Plone - Desinstalar"\n+\n+#: plone/restapi/configure.zcml:47\n+msgid "RESTful hypermedia API for Plone."\n+msgstr "API hipermedia RESTful para Plone."\n+\n+#: plone/restapi/services/history/patch.py:28\n+msgid "Reverted to revision ${version}"\n+msgstr "Revertido para revisi\xc3\xb3n ${version}"\n+\n+#: plone/restapi/services/users/add.py:48\n+msgid "Roles"\n+msgstr "Roles"\n+\n+#: plone/restapi/services/users/add.py:350\n+msgid "See the user endpoint documentation for the valid parameters."\n+msgstr "Consulte la documentaci\xc3\xb3n del usuario del terminal para conocer los par\xc3\xa1metros v\xc3\xa1lidos."\n+\n+#: plone/restapi/services/contextnavigation/get.py:125\n+msgid "Suppress Icons"\n+msgstr "Suprimir iconos"\n+\n+#: plone/restapi/services/contextnavigation/get.py:144\n+msgid "Suppress thumbs"\n+msgstr "Suprimir miniaturas"\n+\n+#: plone/restapi/services/users/add.py:342\n+msgid "The password passed as \'old_password\' is wrong."\n+msgstr "La contrase\xc3\xb1a pasada como \\"Contrase\xc3\xb1a anterior\\" no es v\xc3\xa1lida."\n+\n+#: plone/restapi/services/users/add.py:307\n+msgid "The reset_token is unknown/not valid."\n+msgstr "El reset_token es desconocido/no v\xc3\xa1lido."\n+\n+#: plone/restapi/configure.zcml:81\n+msgid "Volto Blocks"\n+msgstr "Bloques Volto"\n+\n+#: plone/restapi/services/users/update.py:119\n+msgid "You are not authorized to perform this action"\n+msgstr "No est\xc3\xa1 autorizado a realizar esta acci\xc3\xb3n."\n+\n+#: plone/restapi/services/email_send/post.py:91\n+msgid "You are receiving this mail because ${sender_fullname} sent this message via the site ${portal_title}:"\n+msgstr "Est\xc3\xa1 recibiendo este correo porque ${sender_fullname} envi\xc3\xb3 este mensaje a trav\xc3\xa9s del sitio ${portal_title}:"\n+\n+#: plone/restapi/services/users/add.py:114\n+msgid "You can\'t send both password and sendPasswordReset."\n+msgstr "No puede enviar la contrase\xc3\xb1a y \'Enviar un correo electr\xc3\xb3nico de confirmaci\xc3\xb3n con un enlace para establecer la contrase\xc3\xb1a\'."\n+\n+#: plone/restapi/services/users/add.py:322\n+msgid "You can\'t set a password without a password reset token."\n+msgstr "No puede establecer una contrase\xc3\xb1a sin un token de restablecimiento de contrase\xc3\xb1a."\n+\n+#: plone/restapi/services/users/update.py:125\n+msgid "You can\'t update the properties of this user"\n+msgstr "No puede actualizar las propiedades de este usuario."\n+\n+#: plone/restapi/services/users/add.py:284\n+msgid "You can\'t use \'reset_token\' and \'old_password\' together."\n+msgstr "No puede utilizar \'Restablecer token\' y \'Contrase\xc3\xb1a anterior\' juntas."\n+\n+#: plone/restapi/services/users/add.py:109\n+msgid "You have to either send a password or sendPasswordReset."\n+msgstr "Debe enviar una contrase\xc3\xb1a o \'Enviar un correo electr\xc3\xb3nico de confirmaci\xc3\xb3n con un enlace para establecer la contrase\xc3\xb1a\'."\n+\n+#: plone/restapi/services/users/add.py:154\n+msgid "You need AddPortalMember permission."\n+msgstr "Necesita el permiso AddPortalMember."\n+\n+#: plone/restapi/services/users/add.py:329\n+msgid "You need to be logged in as the user \'${username}\' to set the password."\n+msgstr "Debe iniciar sesi\xc3\xb3n como usuario \'${username}\' para poder establecer la contrase\xc3\xb1a."\n+\n+#. Default: "Missing dependency"\n+#: plone/restapi/services/addons/addons.py:207\n+msgid "dependency_missing"\n+msgstr "Dependencia faltante"\n+\n+#. Default: "If selected, the navigation tree will only show the current folder and its children at all times."\n+#: plone/restapi/services/contextnavigation/get.py:84\n+msgid "help_current_folder_only"\n+msgstr "Si se selecciona, el \xc3\xa1rbol de navegaci\xc3\xb3n siempre mostrar\xc3\xa1 solo la carpeta actual y sus hijos."\n+\n+#. Default: "Whether or not to show the top, or \'root\', node in the navigation tree. This is affected by the \'Start level\' setting."\n+#: plone/restapi/services/contextnavigation/get.py:69\n+msgid "help_include_top_node"\n+msgstr "Si el nodo superior, o \'ra\xc3\xadz\', debe mostrarse o no en el \xc3\xa1rbol de navegaci\xc3\xb3n. Esto se ve afectado por la configuraci\xc3\xb3n del \'Nivel inicial\'."\n+\n+#. Default: "You may search for and choose a folder to act as the root of the navigation tree. Leave blank to use the Plone site root."\n+#: plone/restapi/services/contextnavigation/get.py:58\n+msgid "help_navigation_root"\n+msgstr "Puede buscar y seleccionar una carpeta para que act\xc3\xbae como ra\xc3\xadz del \xc3\xa1rbol de navegaci\xc3\xb3n. D\xc3\xa9jelo en blanco para usar la ra\xc3\xadz del sitio Plone."\n+\n+#. Default: "An integer value that specifies the number of folder levels below the site root that must be exceeded before the navigation tree will display. 0 means that the navigation tree should be displayed everywhere including pages in the root of the site. 1 means the tree only shows up inside folders located in the root and downwards, never showing at the top level."\n+#: plone/restapi/services/contextnavigation/get.py:96\n+msgid "help_navigation_start_level"\n+msgstr "Un valor entero que especifica el n\xc3\xbamero de niveles de carpeta debajo de la ra\xc3\xadz del sitio que se deben exceder antes de que se muestre el \xc3\xa1rbol de navegaci\xc3\xb3n. 0 significa que el \xc3\xa1rbol de navegaci\xc3\xb3n debe mostrarse en cualquier lugar, incluidas las p\xc3\xa1ginas en la ra\xc3\xadz del sitio. 1 significa que el \xc3\xa1rbol solo aparecer\xc3\xa1 dentro de las carpetas ubicadas en la ra\xc3\xadz y debajo de ella, y nunca aparecer\xc3\xa1 en el nivel ra\xc3\xadz."\n+\n+#. Default: "The title of the navigation tree."\n+#: plone/restapi/services/contextnavigation/get.py:49\n+msgid "help_navigation_title"\n+msgstr "El t\xc3\xadtulo del \xc3\xa1rbol de navegaci\xc3\xb3n."\n+\n+#. Default: "How many folders should be included before the navigation tree stops. 0 means no limit. 1 only includes the root folder."\n+#: plone/restapi/services/contextnavigation/get.py:113\n+msgid "help_navigation_tree_depth"\n+msgstr "Cu\xc3\xa1ntas carpetas se deben incluir antes de que se detenga el \xc3\xa1rbol de navegaci\xc3\xb3n. 0 significa sin l\xc3\xadmite. 1 significa incluir solo la carpeta ra\xc3\xadz."\n+\n+#. Default: "Only show the contents of the current folder."\n+#: plone/restapi/services/contextnavigation/get.py:80\n+msgid "label_current_folder_only"\n+msgstr "Muestra solo el contenido de la carpeta actual."\n+\n+#. Default: "Include top node"\n+#: plone/restapi/services/contextnavigation/get.py:68\n+msgid "label_include_top_node"\n+msgstr "Incluir nodo superior"\n+\n+#. Default: "Root node"\n+#: plone/restapi/services/contextnavigation/get.py:57\n+msgid "label_navigation_root_path"\n+msgstr "Nodo ra\xc3\xadz"\n+\n+#. Default: "Start level"\n+#: plone/restapi/services/contextnavigation/get.py:95\n+msgid "label_navigation_startlevel"\n+msgstr "Nivel inicial"\n+\n+#. Default: "Title"\n+#: plone/restapi/services/contextnavigation/get.py:48\n+msgid "label_navigation_title"\n+msgstr "T\xc3\xadtulo"\n+\n+#. Default: "Navigation tree depth"\n+#: plone/restapi/services/contextnavigation/get.py:112\n+msgid "label_navigation_tree_depth"\n+msgstr "Profundidad del \xc3\xa1rbol de navegaci\xc3\xb3n"\n+\n+#: plone/restapi/configure.zcml:47\n+msgid "plone.restapi"\n+msgstr "plone.restapi"\n+\n+#: plone/restapi/configure.zcml:73\n+msgid "plone.restapi performance testing"\n+msgstr "plone.restapi - prueba de rendimiento"\n+\n+#: plone/restapi/configure.zcml:56\n+msgid "plone.restapi testing"\n+msgstr "plone.restapi - pruebas"\n+\n+#: plone/restapi/configure.zcml:65\n+msgid "plone.restapi testing-workflows"\n+msgstr "plone.restapi - pruebas de flujos de trabajo"\n+\n+#: plone/restapi/upgrades/configure.zcml:33\n+msgid "plone.restapi.upgrades.0002"\n+msgstr "plone.restapi.upgrades.0002"\n+\n+#: plone/restapi/upgrades/configure.zcml:52\n+msgid "plone.restapi.upgrades.0004"\n+msgstr "plone.restapi.upgrades.0004"\n'