diff --git a/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_doSvnLogin.xml b/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_doVcsLogin.xml similarity index 97% rename from bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_doSvnLogin.xml rename to bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_doVcsLogin.xml index d5f34c077612223330caa82f64e8d1991ed8ca8f..ee9fe9352e4498f4aeacbd1f346c033634aa1c23 100644 --- a/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_doSvnLogin.xml +++ b/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_doVcsLogin.xml @@ -66,7 +66,7 @@ return traverseName(context, caller)(**caller_kw)\n </item> <item> <key> <string>id</string> </key> - <value> <string>BusinessTemplate_doSvnLogin</string> </value> + <value> <string>BusinessTemplate_doVcsLogin</string> </value> </item> </dictionary> </pickle> diff --git a/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_handleException.xml b/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_handleException.xml index f1d2d59bf555ccffd5982aba16fdcfc2ad783d5b..5508468049e4f1b9457f18640d7aaac10dd614ea 100644 --- a/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_handleException.xml +++ b/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_handleException.xml @@ -50,7 +50,8 @@ </item> <item> <key> <string>_body</string> </key> - <value> <string>from Products.ERP5VCS.SubversionClient import SubversionSSLTrustError, SubversionLoginError\n + <value> <string>from Products.ERP5VCS.Git import GitLoginError\n +from Products.ERP5VCS.SubversionClient import SubversionSSLTrustError, SubversionLoginError\n \n try:\n raise exception\n @@ -62,6 +63,10 @@ except SubversionLoginError, e:\n message = \'Server needs authentication, no cookie found\'\n kw = dict(realm=e.getRealm(), username=context.getVcsTool().getPreferredUsername())\n method = \'BusinessTemplate_viewSvnLogin\'\n +except GitLoginError, e:\n + message = str(e)\n + kw = dict(remote_url=context.getVcsTool().getRemoteUrl())\n + method = \'BusinessTemplate_viewGitLogin\'\n \n context.REQUEST.set(\'portal_status_message\', message)\n return getattr(context.asContext(**kw), method)(caller=caller, caller_kw=caller_kw)\n diff --git a/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewGitLogin.xml b/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewGitLogin.xml new file mode 100644 index 0000000000000000000000000000000000000000..c3b2a6b11859bfd2f0513a29aba2530d4cf70c61 --- /dev/null +++ b/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewGitLogin.xml @@ -0,0 +1,155 @@ +<?xml version="1.0"?> +<ZopeData> + <record id="1" aka="AAAAAAAAAAE="> + <pickle> + <global name="ERP5Form" module="Products.ERP5Form.Form"/> + </pickle> + <pickle> + <dictionary> + <item> + <key> <string>_bind_names</string> </key> + <value> + <object> + <klass> + <global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/> + </klass> + <tuple/> + <state> + <dictionary> + <item> + <key> <string>_asgns</string> </key> + <value> + <dictionary/> + </value> + </item> + </dictionary> + </state> + </object> + </value> + </item> + <item> + <key> <string>_objects</string> </key> + <value> + <tuple/> + </value> + </item> + <item> + <key> <string>action</string> </key> + <value> <string>BusinessTemplate_doVcsLogin</string> </value> + </item> + <item> + <key> <string>description</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>edit_order</string> </key> + <value> + <list/> + </value> + </item> + <item> + <key> <string>encoding</string> </key> + <value> <string>UTF-8</string> </value> + </item> + <item> + <key> <string>enctype</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>group_list</string> </key> + <value> + <list> + <string>left</string> + <string>right</string> + <string>center</string> + <string>bottom</string> + <string>hidden</string> + </list> + </value> + </item> + <item> + <key> <string>groups</string> </key> + <value> + <dictionary> + <item> + <key> <string>bottom</string> </key> + <value> + <list/> + </value> + </item> + <item> + <key> <string>center</string> </key> + <value> + <list/> + </value> + </item> + <item> + <key> <string>hidden</string> </key> + <value> + <list/> + </value> + </item> + <item> + <key> <string>left</string> </key> + <value> + <list> + <string>remote_url</string> + <string>your_user</string> + <string>your_password</string> + <string>your_auth</string> + </list> + </value> + </item> + <item> + <key> <string>right</string> </key> + <value> + <list/> + </value> + </item> + </dictionary> + </value> + </item> + <item> + <key> <string>id</string> </key> + <value> <string>BusinessTemplate_viewGitLogin</string> </value> + </item> + <item> + <key> <string>method</string> </key> + <value> <string>POST</string> </value> + </item> + <item> + <key> <string>name</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>pt</string> </key> + <value> <string>vcs_dialog</string> </value> + </item> + <item> + <key> <string>row_length</string> </key> + <value> <int>4</int> </value> + </item> + <item> + <key> <string>stored_encoding</string> </key> + <value> <string>UTF-8</string> </value> + </item> + <item> + <key> <string>title</string> </key> + <value> <string>Login</string> </value> + </item> + <item> + <key> <string>unicode_mode</string> </key> + <value> <int>0</int> </value> + </item> + <item> + <key> <string>update_action</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>update_action_title</string> </key> + <value> <string></string> </value> + </item> + </dictionary> + </pickle> + </record> +</ZopeData> diff --git a/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewGitLogin/remote_url.xml b/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewGitLogin/remote_url.xml new file mode 100644 index 0000000000000000000000000000000000000000..b635e055a335be64739e41daeb54b0546d108f1e --- /dev/null +++ b/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewGitLogin/remote_url.xml @@ -0,0 +1,133 @@ +<?xml version="1.0"?> +<ZopeData> + <record id="1" aka="AAAAAAAAAAE="> + <pickle> + <global name="ProxyField" module="Products.ERP5Form.ProxyField"/> + </pickle> + <pickle> + <dictionary> + <item> + <key> <string>delegated_list</string> </key> + <value> + <list> + <string>default</string> + <string>editable</string> + <string>title</string> + </list> + </value> + </item> + <item> + <key> <string>id</string> </key> + <value> <string>remote_url</string> </value> + </item> + <item> + <key> <string>message_values</string> </key> + <value> + <dictionary> + <item> + <key> <string>external_validator_failed</string> </key> + <value> <string>The input failed the external validator.</string> </value> + </item> + </dictionary> + </value> + </item> + <item> + <key> <string>overrides</string> </key> + <value> + <dictionary> + <item> + <key> <string>field_id</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>form_id</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>target</string> </key> + <value> <string></string> </value> + </item> + </dictionary> + </value> + </item> + <item> + <key> <string>tales</string> </key> + <value> + <dictionary> + <item> + <key> <string>default</string> </key> + <value> + <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent> + </value> + </item> + <item> + <key> <string>editable</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>field_id</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>form_id</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>target</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>title</string> </key> + <value> <string></string> </value> + </item> + </dictionary> + </value> + </item> + <item> + <key> <string>values</string> </key> + <value> + <dictionary> + <item> + <key> <string>default</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>editable</string> </key> + <value> <int>0</int> </value> + </item> + <item> + <key> <string>field_id</string> </key> + <value> <string>my_string_field</string> </value> + </item> + <item> + <key> <string>form_id</string> </key> + <value> <string>Base_viewFieldLibrary</string> </value> + </item> + <item> + <key> <string>target</string> </key> + <value> <string>Click to edit the target</string> </value> + </item> + <item> + <key> <string>title</string> </key> + <value> <string>Remote URL</string> </value> + </item> + </dictionary> + </value> + </item> + </dictionary> + </pickle> + </record> + <record id="2" aka="AAAAAAAAAAI="> + <pickle> + <global name="TALESMethod" module="Products.Formulator.TALESField"/> + </pickle> + <pickle> + <dictionary> + <item> + <key> <string>_text</string> </key> + <value> <string>here/remote_url</string> </value> + </item> + </dictionary> + </pickle> + </record> +</ZopeData> diff --git a/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewGitLogin/your_auth.xml b/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewGitLogin/your_auth.xml new file mode 100644 index 0000000000000000000000000000000000000000..41aefc7bfa52d45ca3177422f7def41504e266f1 --- /dev/null +++ b/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewGitLogin/your_auth.xml @@ -0,0 +1,114 @@ +<?xml version="1.0"?> +<ZopeData> + <record id="1" aka="AAAAAAAAAAE="> + <pickle> + <global name="ProxyField" module="Products.ERP5Form.ProxyField"/> + </pickle> + <pickle> + <dictionary> + <item> + <key> <string>delegated_list</string> </key> + <value> + <list> + <string>editable</string> + <string>hidden</string> + <string>title</string> + </list> + </value> + </item> + <item> + <key> <string>id</string> </key> + <value> <string>your_auth</string> </value> + </item> + <item> + <key> <string>message_values</string> </key> + <value> + <dictionary> + <item> + <key> <string>external_validator_failed</string> </key> + <value> <string>The input failed the external validator.</string> </value> + </item> + </dictionary> + </value> + </item> + <item> + <key> <string>overrides</string> </key> + <value> + <dictionary> + <item> + <key> <string>field_id</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>form_id</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>target</string> </key> + <value> <string></string> </value> + </item> + </dictionary> + </value> + </item> + <item> + <key> <string>tales</string> </key> + <value> + <dictionary> + <item> + <key> <string>field_id</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>form_id</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>hidden</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>target</string> </key> + <value> <string></string> </value> + </item> + </dictionary> + </value> + </item> + <item> + <key> <string>values</string> </key> + <value> + <dictionary> + <item> + <key> <string>editable</string> </key> + <value> <int>1</int> </value> + </item> + <item> + <key> <string>field_id</string> </key> + <value> <string>remote_url</string> </value> + </item> + <item> + <key> <string>form_id</string> </key> + <value> <string>BusinessTemplate_viewGitLogin</string> </value> + </item> + <item> + <key> <string>hidden</string> </key> + <value> <int>1</int> </value> + </item> + <item> + <key> <string>target</string> </key> + <value> <string>Click to edit the target</string> </value> + </item> + <item> + <key> <string>title</string> </key> + <value> <string encoding="cdata"><![CDATA[ + + + +]]></string> </value> + </item> + </dictionary> + </value> + </item> + </dictionary> + </pickle> + </record> +</ZopeData> diff --git a/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewGitLogin/your_password.xml b/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewGitLogin/your_password.xml new file mode 100644 index 0000000000000000000000000000000000000000..c8e287029e0950ba4d7b0b040dea40b475f0b60d --- /dev/null +++ b/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewGitLogin/your_password.xml @@ -0,0 +1,275 @@ +<?xml version="1.0"?> +<ZopeData> + <record id="1" aka="AAAAAAAAAAE="> + <pickle> + <global name="PasswordField" module="Products.Formulator.StandardFields"/> + </pickle> + <pickle> + <dictionary> + <item> + <key> <string>id</string> </key> + <value> <string>your_password</string> </value> + </item> + <item> + <key> <string>message_values</string> </key> + <value> + <dictionary> + <item> + <key> <string>external_validator_failed</string> </key> + <value> <string>The input failed the external validator.</string> </value> + </item> + <item> + <key> <string>required_not_found</string> </key> + <value> <string>Input is required but no input given.</string> </value> + </item> + <item> + <key> <string>too_long</string> </key> + <value> <string>Too much input was given.</string> </value> + </item> + </dictionary> + </value> + </item> + <item> + <key> <string>overrides</string> </key> + <value> + <dictionary> + <item> + <key> <string>alternate_name</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>css_class</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>default</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>description</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>display_maxwidth</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>display_width</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>editable</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>enabled</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>external_validator</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>extra</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>hidden</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>max_length</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>required</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>title</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>truncate</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>unicode</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>whitespace_preserve</string> </key> + <value> <string></string> </value> + </item> + </dictionary> + </value> + </item> + <item> + <key> <string>tales</string> </key> + <value> + <dictionary> + <item> + <key> <string>alternate_name</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>css_class</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>default</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>description</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>display_maxwidth</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>display_width</string> </key> + <value> + <persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent> + </value> + </item> + <item> + <key> <string>editable</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>enabled</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>external_validator</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>extra</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>hidden</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>max_length</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>required</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>title</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>truncate</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>unicode</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>whitespace_preserve</string> </key> + <value> <string></string> </value> + </item> + </dictionary> + </value> + </item> + <item> + <key> <string>values</string> </key> + <value> + <dictionary> + <item> + <key> <string>alternate_name</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>css_class</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>default</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>description</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>display_maxwidth</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>display_width</string> </key> + <value> <int>50</int> </value> + </item> + <item> + <key> <string>editable</string> </key> + <value> <int>1</int> </value> + </item> + <item> + <key> <string>enabled</string> </key> + <value> <int>1</int> </value> + </item> + <item> + <key> <string>external_validator</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>extra</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>hidden</string> </key> + <value> <int>0</int> </value> + </item> + <item> + <key> <string>max_length</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>required</string> </key> + <value> <int>0</int> </value> + </item> + <item> + <key> <string>title</string> </key> + <value> <string>Password</string> </value> + </item> + <item> + <key> <string>truncate</string> </key> + <value> <int>0</int> </value> + </item> + <item> + <key> <string>unicode</string> </key> + <value> <int>0</int> </value> + </item> + <item> + <key> <string>whitespace_preserve</string> </key> + <value> <int>0</int> </value> + </item> + </dictionary> + </value> + </item> + </dictionary> + </pickle> + </record> + <record id="2" aka="AAAAAAAAAAI="> + <pickle> + <global name="TALESMethod" module="Products.Formulator.TALESField"/> + </pickle> + <pickle> + <dictionary> + <item> + <key> <string>_text</string> </key> + <value> <string>python: preferences.getPreference(\'preferred_string_field_width\', 30)</string> </value> + </item> + </dictionary> + </pickle> + </record> +</ZopeData> diff --git a/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewGitLogin/your_user.xml b/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewGitLogin/your_user.xml new file mode 100644 index 0000000000000000000000000000000000000000..528b3418a26ab1bfcb33be5fc68494e924c7bf56 --- /dev/null +++ b/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewGitLogin/your_user.xml @@ -0,0 +1,100 @@ +<?xml version="1.0"?> +<ZopeData> + <record id="1" aka="AAAAAAAAAAE="> + <pickle> + <global name="ProxyField" module="Products.ERP5Form.ProxyField"/> + </pickle> + <pickle> + <dictionary> + <item> + <key> <string>delegated_list</string> </key> + <value> + <list> + <string>title</string> + </list> + </value> + </item> + <item> + <key> <string>id</string> </key> + <value> <string>your_user</string> </value> + </item> + <item> + <key> <string>message_values</string> </key> + <value> + <dictionary> + <item> + <key> <string>external_validator_failed</string> </key> + <value> <string>The input failed the external validator.</string> </value> + </item> + </dictionary> + </value> + </item> + <item> + <key> <string>overrides</string> </key> + <value> + <dictionary> + <item> + <key> <string>field_id</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>form_id</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>target</string> </key> + <value> <string></string> </value> + </item> + </dictionary> + </value> + </item> + <item> + <key> <string>tales</string> </key> + <value> + <dictionary> + <item> + <key> <string>field_id</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>form_id</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>target</string> </key> + <value> <string></string> </value> + </item> + <item> + <key> <string>title</string> </key> + <value> <string></string> </value> + </item> + </dictionary> + </value> + </item> + <item> + <key> <string>values</string> </key> + <value> + <dictionary> + <item> + <key> <string>field_id</string> </key> + <value> <string>my_string_field</string> </value> + </item> + <item> + <key> <string>form_id</string> </key> + <value> <string>Base_viewFieldLibrary</string> </value> + </item> + <item> + <key> <string>target</string> </key> + <value> <string>Click to edit the target</string> </value> + </item> + <item> + <key> <string>title</string> </key> + <value> <string>User Name</string> </value> + </item> + </dictionary> + </value> + </item> + </dictionary> + </pickle> + </record> +</ZopeData> diff --git a/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewSvnLogin.xml b/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewSvnLogin.xml index 33e16a2e5fca00b6c72d83fd65cbab74854f7547..71960c03e41f839ec85354562b3f004c1bf118b2 100644 --- a/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewSvnLogin.xml +++ b/bt5/erp5_forge/SkinTemplateItem/portal_skins/erp5_vcs/BusinessTemplate_viewSvnLogin.xml @@ -35,7 +35,7 @@ </item> <item> <key> <string>action</string> </key> - <value> <string>BusinessTemplate_doSvnLogin</string> </value> + <value> <string>BusinessTemplate_doVcsLogin</string> </value> </item> <item> <key> <string>description</string> </key> @@ -98,7 +98,7 @@ </item> <item> <key> <string>name</string> </key> - <value> <string>BusinessTemplate_viewSvnLogin2</string> </value> + <value> <string></string> </value> </item> <item> <key> <string>pt</string> </key> diff --git a/bt5/erp5_forge/bt/revision b/bt5/erp5_forge/bt/revision index 7703a12954702241b2e8b9ee181bf20cfe3195b9..06834d4380c79b7a19421ace4adf19483fd318f3 100644 --- a/bt5/erp5_forge/bt/revision +++ b/bt5/erp5_forge/bt/revision @@ -1 +1 @@ -656 \ No newline at end of file +657 \ No newline at end of file diff --git a/product/ERP5VCS/Git.py b/product/ERP5VCS/Git.py index 55c084076ef9043513af763560e633a1cd9b6695..f540ddcd5336df16d749a181c16cd3d8def8d4f0 100644 --- a/product/ERP5VCS/Git.py +++ b/product/ERP5VCS/Git.py @@ -28,6 +28,7 @@ import os, re, subprocess from AccessControl import ClassSecurityInfo +from AccessControl.SecurityInfo import ModuleSecurityInfo from Acquisition import aq_base from DateTime import DateTime from Products.ERP5Type.Message import translateString @@ -35,12 +36,19 @@ from ZTUtils import make_query from Products.ERP5VCS.WorkingCopy import \ WorkingCopy, NotAWorkingCopyError, NotVersionedError, Dir, File, selfcached +# TODO: write a similar helper for 'nt' platform +GIT_ASKPASS = os.path.join(os.path.dirname(__file__), 'bin', 'git_askpass') + class GitError(EnvironmentError): def __init__(self, err, out, returncode): EnvironmentError.__init__(self, err) self.stdout = out self.returncode = returncode +class GitLoginError(EnvironmentError): + """Raised when an authentication is required""" +ModuleSecurityInfo(__name__).declarePublic('GitLoginError') + class Git(WorkingCopy): security = ClassSecurityInfo() @@ -48,6 +56,8 @@ class Git(WorkingCopy): reference = 'git' title = 'Git' + _login_cookie_name = 'erp5_git_login' + def _git(self, *args, **kw): kw.setdefault('cwd', self.working_copy) argv = ['git'] @@ -64,6 +74,41 @@ class Git(WorkingCopy): return out.strip() return out + @selfcached + def _getLogin(self): + target_url = self.getRemoteUrl() + try: + for url, user, password in self._getCookie(self._login_cookie_name, ()): + if target_url == url: + return user, password + except ValueError: + pass + + def setLogin(self, remote_url, user, password): + """Set login information""" + login_list = [x for x in self._getCookie(self._login_cookie_name, ()) + if x[0] != remote_url] + login_list.append((remote_url, user, password)) + self._setCookie(self._login_cookie_name, login_list) + + def remote_git(self, *args, **kw): + try: + env = kw['env'] + except KeyError: + kw['env'] = env = dict(os.environ) + env['GIT_ASKPASS'] = GIT_ASKPASS + userpwd = self._getLogin() + if userpwd: + env.update(ERP5_GIT_USERNAME=userpwd[0], ERP5_GIT_PASSWORD=userpwd[1]) + try: + return self.git(*args, **kw) + except GitError, e: + message = 'Authentication failed' + if message in str(e): + raise GitLoginError(userpwd and message or + 'Server needs authentication, no cookie found') + raise + def __init__(self, *args, **kw): WorkingCopy.__init__(self, *args, **kw) out = self._git('rev-parse', '--show-toplevel', '--show-prefix', @@ -206,7 +251,7 @@ class Git(WorkingCopy): raise NotImplementedError if not keep: self.clean() - self.git('pull', '--ff-only') + self.remote_git('pull', '--ff-only') elif 1: # elif local_changes: raise NotImplementedError # addremove @@ -219,7 +264,7 @@ class Git(WorkingCopy): # finally: # symbolic-ref HEAD B else: - self.git('pull', '--ff-only') + self.remote_git('pull', '--ff-only') return self.aq_parent.download(self.working_copy) def showOld(self, path): @@ -279,14 +324,14 @@ class Git(WorkingCopy): remote, dst = remote.split('/', 1) push_args = 'push', '--porcelain', remote, '%s:%s' % (src, dst) try: - self.git(*push_args) + self.remote_git(*push_args) except GitError, e: # first check why we could not push status = [x for x in e.stdout.splitlines() if x[:1] == '!'] if (len(status) != 1 or status[0].split()[2:] != ['[rejected]', '(non-fast-forward)']): raise - self.git('fetch', '--prune', remote) + self.remote_git('fetch', '--prune', remote) if not self.getBehindCount(): raise # try to update our working copy @@ -305,7 +350,7 @@ class Git(WorkingCopy): if merge == 'merge': reset += 1 # retry to push everything - self.git(*push_args) + self.remote_git(*push_args) except GitError, e: self.git('reset', '--soft', '@{%u}' % reset) portal_status_message = str(e) diff --git a/product/ERP5VCS/Subversion.py b/product/ERP5VCS/Subversion.py index b6bfda92ca27d01cc96ff3b9623c2663baa259d7..ce80906b8efefbeb2e8b9e2196aea4dfce2f17e5 100644 --- a/product/ERP5VCS/Subversion.py +++ b/product/ERP5VCS/Subversion.py @@ -29,9 +29,7 @@ # ############################################################################## -import errno, glob, json, os, re, shutil -from base64 import b64encode, b64decode -from DateTime import DateTime +import errno, glob, os, re, shutil from ZTUtils import make_query from Products.ERP5Type.Message import translateString from Products.ERP5.Document.BusinessTemplate import BusinessTemplateFolder @@ -55,22 +53,6 @@ class Subversion(WorkingCopy): if path and not os.path.exists(os.path.join(self.working_copy, '.svn')): raise NotAWorkingCopyError(self.working_copy) - def _getCookie(self, name, default=None): - try: - return json.loads(b64decode(self.REQUEST[name])) - except StandardError: - return default - - def _setCookie(self, name, value, days=30): - portal = self.getPortalObject() - request = portal.REQUEST - value = b64encode(json.dumps(value)) - request.set(name, value) - if days: - expires = (DateTime() + days).toZone('GMT').rfc822() - request.RESPONSE.setCookie(name, value, path=portal.absolute_url_path(), - expires=expires) - def setLogin(self, realm, user, password): """Set login information. """ diff --git a/product/ERP5VCS/WorkingCopy.py b/product/ERP5VCS/WorkingCopy.py index 12b9aef960a0e98df999db49b196578ecf333367..87889087a568b1cf07a1b2384af079a023000377 100644 --- a/product/ERP5VCS/WorkingCopy.py +++ b/product/ERP5VCS/WorkingCopy.py @@ -29,13 +29,15 @@ # ############################################################################## -import errno, os, re, shutil +import errno, json, os, re, shutil +from base64 import b64encode, b64decode from tempfile import gettempdir import transaction from AccessControl import Unauthorized from AccessControl.SecurityInfo import ModuleSecurityInfo from Acquisition import aq_base, Implicit from App.config import getConfiguration +from DateTime import DateTime from ZTUtils import make_query from Products.ERP5.Document.BusinessTemplate import BusinessTemplateFolder from Products.ERP5Type.Utils import simple_decorator @@ -141,6 +143,22 @@ class WorkingCopy(Implicit): raise Unauthorized("Unauthorized access to path %r." " It is NOT in your Zope home instance." % path) + def _getCookie(self, name, default=None): + try: + return json.loads(b64decode(self.REQUEST[name])) + except StandardError: + return default + + def _setCookie(self, name, value, days=30): + portal = self.getPortalObject() + request = portal.REQUEST + value = b64encode(json.dumps(value)) + request.set(name, value) + if days: + expires = (DateTime() + days).toZone('GMT').rfc822() + request.RESPONSE.setCookie(name, value, path=portal.absolute_url_path(), + expires=expires) + # path is the path in svn working copy # return edit_path in zodb to edit it def editPath(self, path, html=False): diff --git a/product/ERP5VCS/bin/git_askpass b/product/ERP5VCS/bin/git_askpass new file mode 100755 index 0000000000000000000000000000000000000000..65b6ea253a8a8d8e0ed63efb8c5e2e716b467f62 --- /dev/null +++ b/product/ERP5VCS/bin/git_askpass @@ -0,0 +1,7 @@ +#!/bin/sh -e + +case "$1" in + Username:\ ) echo -n "$ERP5_GIT_USERNAME" ;; + Password:\ ) echo -n "$ERP5_GIT_PASSWORD" ;; + *) false ;; +esac