Browse Source

User is now prompted for discovery credentials when adding or refreshing a web reference if the server returns a Http status of 401 (Unauthorised). Tested with basic and NT authentication.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@1005 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Matt Ward 20 years ago
parent
commit
e29ae4dd10
  1. 4
      AddIns/ICSharpCode.SharpDevelop.addin
  2. BIN
      data/resources/StringResources.cz.resources
  3. BIN
      data/resources/StringResources.es.resources
  4. BIN
      data/resources/StringResources.it.resources
  5. BIN
      data/resources/StringResources.kr.resources
  6. BIN
      data/resources/StringResources.no.resources
  7. BIN
      data/resources/StringResources.pt-br.resources
  8. BIN
      data/resources/StringResources.ro.resources
  9. BIN
      data/resources/StringResources.se.resources
  10. BIN
      data/resources/StringResources.tr.resources
  11. 5
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  12. 61
      src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/AddWebReferenceDialog.cs
  13. 46
      src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/AsyncDiscoveryState.cs
  14. 43
      src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/DiscoveryNetworkCredential.cs
  15. 72
      src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/HttpAuthenticationHeader.cs
  16. 219
      src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/UserCredentialsDialog.cs
  17. 9
      src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/WebReference.cs
  18. 50
      src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/WebServiceDiscoveryClientProtocol.cs
  19. 75
      src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/Commands/ReferenceFolderNodeCommands.cs
  20. 1
      src/Main/Base/Test/ICSharpCode.SharpDevelop.Tests.csproj
  21. 81
      src/Main/Base/Test/WebReferences/HttpAuthenticationHeaderTests.cs
  22. BIN
      src/Main/StartUp/Project/Resources/StringResources.resources

4
AddIns/ICSharpCode.SharpDevelop.addin

@ -1243,6 +1243,10 @@
<MenuItem id = "AddReference" <MenuItem id = "AddReference"
label = "${res:ProjectComponent.ContextMenu.AddReference}" label = "${res:ProjectComponent.ContextMenu.AddReference}"
class = "ICSharpCode.SharpDevelop.Project.Commands.AddReferenceToProject"/> class = "ICSharpCode.SharpDevelop.Project.Commands.AddReferenceToProject"/>
<MenuItem id = "AddWebReference"
label = "${res:ProjectComponent.ContextMenu.AddWebReference}"
class = "ICSharpCode.SharpDevelop.Project.Commands.AddWebReferenceToProject"/>
<MenuItem id = "AddSeparator" type = "Separator"/>
<Include id = "ProjectActions" path="/SharpDevelop/Pads/ProjectBrowser/ContextMenu/ProjectActions"/> <Include id = "ProjectActions" path="/SharpDevelop/Pads/ProjectBrowser/ContextMenu/ProjectActions"/>
<MenuItem id = "Separator2" type = "Separator" /> <MenuItem id = "Separator2" type = "Separator" />
<MenuItem id = "Options" <MenuItem id = "Options"

BIN
data/resources/StringResources.cz.resources

Binary file not shown.

BIN
data/resources/StringResources.es.resources

Binary file not shown.

BIN
data/resources/StringResources.it.resources

Binary file not shown.

BIN
data/resources/StringResources.kr.resources

Binary file not shown.

BIN
data/resources/StringResources.no.resources

Binary file not shown.

BIN
data/resources/StringResources.pt-br.resources

Binary file not shown.

BIN
data/resources/StringResources.ro.resources

Binary file not shown.

BIN
data/resources/StringResources.se.resources

Binary file not shown.

BIN
data/resources/StringResources.tr.resources

Binary file not shown.

5
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -745,6 +745,11 @@
<Compile Include="Src\Project\Converter\LanguageConverter.cs" /> <Compile Include="Src\Project\Converter\LanguageConverter.cs" />
<Compile Include="Src\Gui\Dialogs\TemplateCategoryComparer.cs" /> <Compile Include="Src\Gui\Dialogs\TemplateCategoryComparer.cs" />
<Compile Include="Src\Internal\Templates\TemplateCategorySortOrderFile.cs" /> <Compile Include="Src\Internal\Templates\TemplateCategorySortOrderFile.cs" />
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\HttpAuthenticationHeader.cs" />
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\UserCredentialsDialog.cs" />
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\WebServiceDiscoveryClientProtocol.cs" />
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\AsyncDiscoveryState.cs" />
<Compile Include="Src\Gui\Dialogs\ReferenceDialog\DiscoveryNetworkCredential.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\..\Libraries\DockPanel_Src\WinFormsUI\WinFormsUI.csproj"> <ProjectReference Include="..\..\..\Libraries\DockPanel_Src\WinFormsUI\WinFormsUI.csproj">

61
src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/AddWebReferenceDialog.cs

@ -22,7 +22,8 @@ namespace ICSharpCode.SharpDevelop.Gui
{ {
public class AddWebReferenceDialog : System.Windows.Forms.Form public class AddWebReferenceDialog : System.Windows.Forms.Form
{ {
DiscoveryClientProtocol discoveryClientProtocol; WebServiceDiscoveryClientProtocol discoveryClientProtocol;
CredentialCache credentialCache = new CredentialCache();
int initialFormWidth; int initialFormWidth;
int initialUrlComboBoxWidth; int initialUrlComboBoxWidth;
string namespacePrefix = String.Empty; string namespacePrefix = String.Empty;
@ -32,6 +33,7 @@ namespace ICSharpCode.SharpDevelop.Gui
delegate DiscoveryDocument DiscoverAnyAsync(string url); delegate DiscoveryDocument DiscoverAnyAsync(string url);
delegate void DiscoveredWebServicesHandler(DiscoveryClientProtocol protocol); delegate void DiscoveredWebServicesHandler(DiscoveryClientProtocol protocol);
delegate void AuthenticationHandler(Uri uri, string authenticationType);
public AddWebReferenceDialog(IProject project) public AddWebReferenceDialog(IProject project)
{ {
@ -431,7 +433,6 @@ namespace ICSharpCode.SharpDevelop.Gui
Cursor = Cursors.WaitCursor; Cursor = Cursors.WaitCursor;
stopButton.Enabled = true; stopButton.Enabled = true;
webServicesView.Clear(); webServicesView.Clear();
StartDiscovery(e.Url);
} }
void WebBrowserNavigated(object sender, WebBrowserNavigatedEventArgs e) void WebBrowserNavigated(object sender, WebBrowserNavigatedEventArgs e)
@ -439,6 +440,7 @@ namespace ICSharpCode.SharpDevelop.Gui
Cursor = Cursors.Default; Cursor = Cursors.Default;
stopButton.Enabled = false; stopButton.Enabled = false;
urlComboBox.Text = webBrowser.Url.ToString(); urlComboBox.Text = webBrowser.Url.ToString();
StartDiscovery(e.Url);
} }
void WebBrowserCanGoForwardChanged(object sender, EventArgs e) void WebBrowserCanGoForwardChanged(object sender, EventArgs e)
@ -524,6 +526,11 @@ namespace ICSharpCode.SharpDevelop.Gui
/// Starts the search for web services at the specified url. /// Starts the search for web services at the specified url.
/// </summary> /// </summary>
void StartDiscovery(Uri uri) void StartDiscovery(Uri uri)
{
StartDiscovery(uri, new DiscoveryNetworkCredential(CredentialCache.DefaultNetworkCredentials, DiscoveryNetworkCredential.DefaultAuthenticationType));
}
void StartDiscovery(Uri uri, DiscoveryNetworkCredential credential)
{ {
// Abort previous discovery. // Abort previous discovery.
StopDiscovery(); StopDiscovery();
@ -532,8 +539,8 @@ namespace ICSharpCode.SharpDevelop.Gui
discoveryUri = uri; discoveryUri = uri;
DiscoverAnyAsync asyncDelegate = new DiscoverAnyAsync(discoveryClientProtocol.DiscoverAny); DiscoverAnyAsync asyncDelegate = new DiscoverAnyAsync(discoveryClientProtocol.DiscoverAny);
AsyncCallback callback = new AsyncCallback(DiscoveryCompleted); AsyncCallback callback = new AsyncCallback(DiscoveryCompleted);
discoveryClientProtocol.Credentials = CredentialCache.DefaultCredentials; discoveryClientProtocol.Credentials = credential;
IAsyncResult result = asyncDelegate.BeginInvoke(uri.AbsoluteUri, callback, discoveryClientProtocol); IAsyncResult result = asyncDelegate.BeginInvoke(uri.AbsoluteUri, callback, new AsyncDiscoveryState(discoveryClientProtocol, uri, credential));
} }
/// <summary> /// <summary>
@ -542,7 +549,8 @@ namespace ICSharpCode.SharpDevelop.Gui
/// </summary> /// </summary>
void DiscoveryCompleted(IAsyncResult result) void DiscoveryCompleted(IAsyncResult result)
{ {
DiscoveryClientProtocol protocol = (DiscoveryClientProtocol)result.AsyncState; AsyncDiscoveryState state = (AsyncDiscoveryState)result.AsyncState;
WebServiceDiscoveryClientProtocol protocol = state.Protocol;
// Check that we are still waiting for this particular callback. // Check that we are still waiting for this particular callback.
bool wanted = false; bool wanted = false;
@ -555,10 +563,19 @@ namespace ICSharpCode.SharpDevelop.Gui
try { try {
DiscoverAnyAsync asyncDelegate = (DiscoverAnyAsync)((AsyncResult)result).AsyncDelegate; DiscoverAnyAsync asyncDelegate = (DiscoverAnyAsync)((AsyncResult)result).AsyncDelegate;
DiscoveryDocument doc = asyncDelegate.EndInvoke(result); DiscoveryDocument doc = asyncDelegate.EndInvoke(result);
if (!state.Credential.IsDefaultAuthenticationType) {
AddCredential(state.Uri, state.Credential);
}
Invoke(handler, new object[] {protocol}); Invoke(handler, new object[] {protocol});
} catch (Exception ex) { } catch (Exception ex) {
LoggingService.Error("DiscoveryCompleted", ex); if (protocol.IsAuthenticationRequired) {
Invoke(handler, new object[] {null}); HttpAuthenticationHeader authHeader = protocol.GetAuthenticationHeader();
AuthenticationHandler authHandler = new AuthenticationHandler(AuthenticateUser);
Invoke(authHandler, new object[] {state.Uri, authHeader.AuthenticationType});
} else {
LoggingService.Error("DiscoveryCompleted", ex);
Invoke(handler, new object[] {null});
}
} }
} }
} }
@ -575,7 +592,7 @@ namespace ICSharpCode.SharpDevelop.Gui
} catch (NotImplementedException) {}; } catch (NotImplementedException) {};
discoveryClientProtocol.Dispose(); discoveryClientProtocol.Dispose();
} }
discoveryClientProtocol = new DiscoveryClientProtocol(); discoveryClientProtocol = new WebServiceDiscoveryClientProtocol();
} }
} }
@ -649,7 +666,10 @@ namespace ICSharpCode.SharpDevelop.Gui
MessageService.ShowError(StringParser.Parse("${res:ICSharpCode.SharpDevelop.Gui.Dialogs.AddWebReferenceDialog.InvalidNamespaceError}")); MessageService.ShowError(StringParser.Parse("${res:ICSharpCode.SharpDevelop.Gui.Dialogs.AddWebReferenceDialog.InvalidNamespaceError}"));
return; return;
} }
webReference.Name = referenceNameTextBox.Text;
webReference.ProxyNamespace = namespaceTextBox.Text;
DialogResult = DialogResult.OK; DialogResult = DialogResult.OK;
Close(); Close();
} catch (Exception ex) { } catch (Exception ex) {
@ -695,5 +715,28 @@ namespace ICSharpCode.SharpDevelop.Gui
webServicesTabPage.Text = StringParser.Parse("${res:ICSharpCode.SharpDevelop.Gui.Dialogs.AddWebReferenceDialog.WebServicesTabPageTitle}"); webServicesTabPage.Text = StringParser.Parse("${res:ICSharpCode.SharpDevelop.Gui.Dialogs.AddWebReferenceDialog.WebServicesTabPageTitle}");
webServicesTabPage.ToolTipText = webServicesTabPage.Text; webServicesTabPage.ToolTipText = webServicesTabPage.Text;
} }
void AuthenticateUser(Uri uri, string authenticationType)
{
DiscoveryNetworkCredential credential = (DiscoveryNetworkCredential)credentialCache.GetCredential(uri, authenticationType);
if (credential != null) {
StartDiscovery(uri, credential);
} else {
using (UserCredentialsDialog credentialsForm = new UserCredentialsDialog(uri.ToString(), authenticationType)) {
if (DialogResult.OK == credentialsForm.ShowDialog()) {
StartDiscovery(uri, credentialsForm.Credential);
}
}
}
}
void AddCredential(Uri uri, DiscoveryNetworkCredential credential)
{
NetworkCredential matchedCredential = credentialCache.GetCredential(uri, credential.AuthenticationType);
if (matchedCredential != null) {
credentialCache.Remove(uri, credential.AuthenticationType);
}
credentialCache.Add(uri, credential.AuthenticationType, credential);
}
} }
} }

46
src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/AsyncDiscoveryState.cs

@ -0,0 +1,46 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
namespace ICSharpCode.SharpDevelop.Gui
{
/// <summary>
/// Holds information needed when an async web discovery call has completed.
/// </summary>
public class AsyncDiscoveryState
{
WebServiceDiscoveryClientProtocol protocol;
Uri uri;
DiscoveryNetworkCredential credential;
public WebServiceDiscoveryClientProtocol Protocol {
get {
return protocol;
}
}
public Uri Uri {
get {
return uri;
}
}
public DiscoveryNetworkCredential Credential {
get {
return credential;
}
}
public AsyncDiscoveryState(WebServiceDiscoveryClientProtocol protocol, Uri uri, DiscoveryNetworkCredential credential)
{
this.protocol = protocol;
this.uri = uri;
this.credential = credential;
}
}
}

43
src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/DiscoveryNetworkCredential.cs

@ -0,0 +1,43 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Net;
namespace ICSharpCode.SharpDevelop.Gui
{
/// <summary>
/// Adds an authentication type to the standard NetworkCredential class.
/// </summary>
public class DiscoveryNetworkCredential : NetworkCredential
{
public const string DefaultAuthenticationType = "Default";
string authenticationType = String.Empty;
public DiscoveryNetworkCredential(string userName, string password, string domain, string authenticationType) : base(userName, password, domain)
{
this.authenticationType = authenticationType;
}
public DiscoveryNetworkCredential(NetworkCredential credential, string authenticationType) : this(credential.UserName, credential.Password, credential.Domain, authenticationType)
{
}
public string AuthenticationType {
get {
return authenticationType;
}
}
public bool IsDefaultAuthenticationType {
get {
return String.Compare(authenticationType, DefaultAuthenticationType, true) == 0;
}
}
}
}

72
src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/HttpAuthenticationHeader.cs

@ -0,0 +1,72 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Net;
using System.Text;
namespace ICSharpCode.SharpDevelop.Gui
{
/// <summary>
/// Represents the WWW-Authenticate HTTP response header.
/// </summary>
public class HttpAuthenticationHeader
{
string[] authenticationSchemes;
public HttpAuthenticationHeader(WebHeaderCollection headers)
{
authenticationSchemes = headers.GetValues("WWW-Authenticate");
}
public override string ToString()
{
if (HasAuthenticationSchemes) {
StringBuilder schemes = new StringBuilder();
foreach (string scheme in authenticationSchemes) {
schemes.Append("WWW-Authenticate: ");
schemes.Append(scheme);
schemes.Append("\r\n");
}
return schemes.ToString();
}
return String.Empty;
}
/// <summary>
/// Gets a comma separated list of authentication types.
/// </summary>
public string AuthenticationType {
get {
if (HasAuthenticationSchemes) {
int schemesAdded = 0;
StringBuilder authenticationType = new StringBuilder();
for (int i = 0; i < authenticationSchemes.Length; ++i) {
string scheme = authenticationSchemes[i];
int index = scheme.IndexOf(' ');
if (index > 0) {
scheme = scheme.Substring(0, index);
}
if (schemesAdded > 0) {
authenticationType.Append(",");
}
authenticationType.Append(scheme);
schemesAdded++;
}
return authenticationType.ToString();
}
return String.Empty;
}
}
bool HasAuthenticationSchemes {
get {
return authenticationSchemes != null && authenticationSchemes.Length > 0;
}
}
}
}

219
src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/UserCredentialsDialog.cs

@ -0,0 +1,219 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using ICSharpCode.Core;
using System;
using System.Drawing;
using System.Net;
using System.Windows.Forms;
namespace ICSharpCode.SharpDevelop.Gui
{
public class UserCredentialsDialog : System.Windows.Forms.Form
{
string authenticationType = String.Empty;
public UserCredentialsDialog(string url, string authenticationType)
{
InitializeComponent();
this.url.Text = url;
this.authenticationType = authenticationType;
AddStringResources();
}
public DiscoveryNetworkCredential Credential {
get {
return new DiscoveryNetworkCredential(userTextBox.Text, passwordTextBox.Text, domainTextBox.Text, authenticationType);
}
}
#region Windows Forms Designer generated code
/// <summary>
/// This method is required for Windows Forms designer support.
/// Do not change the method contents inside the source code editor. The Forms designer might
/// not be able to load this method if it was changed manually.
/// </summary>
private void InitializeComponent()
{
this.urlLabel = new System.Windows.Forms.Label();
this.userNameLabel = new System.Windows.Forms.Label();
this.passwordLabel = new System.Windows.Forms.Label();
this.domainLabel = new System.Windows.Forms.Label();
this.userTextBox = new System.Windows.Forms.TextBox();
this.passwordTextBox = new System.Windows.Forms.TextBox();
this.domainTextBox = new System.Windows.Forms.TextBox();
this.url = new System.Windows.Forms.Label();
this.okButton = new System.Windows.Forms.Button();
this.cancelButton = new System.Windows.Forms.Button();
this.infoLabel = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// urlLabel
//
this.urlLabel.Location = new System.Drawing.Point(10, 59);
this.urlLabel.Name = "urlLabel";
this.urlLabel.Size = new System.Drawing.Size(91, 23);
this.urlLabel.TabIndex = 0;
this.urlLabel.Text = "Url:";
this.urlLabel.UseCompatibleTextRendering = true;
//
// userNameLabel
//
this.userNameLabel.Location = new System.Drawing.Point(10, 88);
this.userNameLabel.Name = "userNameLabel";
this.userNameLabel.Size = new System.Drawing.Size(91, 23);
this.userNameLabel.TabIndex = 1;
this.userNameLabel.Text = "&User name:";
this.userNameLabel.UseCompatibleTextRendering = true;
//
// passwordLabel
//
this.passwordLabel.Location = new System.Drawing.Point(10, 115);
this.passwordLabel.Name = "passwordLabel";
this.passwordLabel.Size = new System.Drawing.Size(91, 23);
this.passwordLabel.TabIndex = 3;
this.passwordLabel.Text = "&Password:";
this.passwordLabel.UseCompatibleTextRendering = true;
//
// domainLabel
//
this.domainLabel.Location = new System.Drawing.Point(10, 142);
this.domainLabel.Name = "domainLabel";
this.domainLabel.Size = new System.Drawing.Size(91, 23);
this.domainLabel.TabIndex = 5;
this.domainLabel.Text = "&Domain:";
this.domainLabel.UseCompatibleTextRendering = true;
//
// userTextBox
//
this.userTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.userTextBox.Location = new System.Drawing.Point(93, 85);
this.userTextBox.Name = "userTextBox";
this.userTextBox.Size = new System.Drawing.Size(187, 21);
this.userTextBox.TabIndex = 2;
//
// passwordTextBox
//
this.passwordTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.passwordTextBox.Location = new System.Drawing.Point(93, 112);
this.passwordTextBox.Name = "passwordTextBox";
this.passwordTextBox.PasswordChar = '*';
this.passwordTextBox.Size = new System.Drawing.Size(187, 21);
this.passwordTextBox.TabIndex = 4;
//
// domainTextBox
//
this.domainTextBox.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.domainTextBox.Location = new System.Drawing.Point(93, 139);
this.domainTextBox.Name = "domainTextBox";
this.domainTextBox.Size = new System.Drawing.Size(187, 21);
this.domainTextBox.TabIndex = 6;
//
// url
//
this.url.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.url.BorderStyle = System.Windows.Forms.BorderStyle.Fixed3D;
this.url.Location = new System.Drawing.Point(93, 57);
this.url.Name = "url";
this.url.Size = new System.Drawing.Size(187, 21);
this.url.TabIndex = 9;
this.url.UseCompatibleTextRendering = true;
//
// okButton
//
this.okButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
this.okButton.Location = new System.Drawing.Point(146, 166);
this.okButton.Name = "okButton";
this.okButton.Size = new System.Drawing.Size(64, 26);
this.okButton.TabIndex = 7;
this.okButton.Text = "OK";
this.okButton.UseCompatibleTextRendering = true;
this.okButton.UseVisualStyleBackColor = true;
//
// cancelButton
//
this.cancelButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.cancelButton.Location = new System.Drawing.Point(216, 166);
this.cancelButton.Name = "cancelButton";
this.cancelButton.Size = new System.Drawing.Size(64, 26);
this.cancelButton.TabIndex = 8;
this.cancelButton.Text = "Cancel";
this.cancelButton.UseCompatibleTextRendering = true;
this.cancelButton.UseVisualStyleBackColor = true;
//
// infoLabel
//
this.infoLabel.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.infoLabel.Location = new System.Drawing.Point(12, 9);
this.infoLabel.Name = "infoLabel";
this.infoLabel.Size = new System.Drawing.Size(267, 48);
this.infoLabel.TabIndex = 10;
this.infoLabel.Text = "Please supply the credentials to access the specified url.";
this.infoLabel.UseCompatibleTextRendering = true;
//
// UserCredentialsDialog
//
this.AcceptButton = this.okButton;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.cancelButton;
this.ClientSize = new System.Drawing.Size(292, 202);
this.Controls.Add(this.infoLabel);
this.Controls.Add(this.cancelButton);
this.Controls.Add(this.okButton);
this.Controls.Add(this.url);
this.Controls.Add(this.domainTextBox);
this.Controls.Add(this.passwordTextBox);
this.Controls.Add(this.userTextBox);
this.Controls.Add(this.domainLabel);
this.Controls.Add(this.passwordLabel);
this.Controls.Add(this.userNameLabel);
this.Controls.Add(this.urlLabel);
this.MaximizeBox = false;
this.MinimizeBox = false;
this.MinimumSize = new System.Drawing.Size(300, 236);
this.Name = "UserCredentialsDialog";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "Discovery Credential";
this.ResumeLayout(false);
this.PerformLayout();
}
private System.Windows.Forms.Label infoLabel;
private System.Windows.Forms.TextBox passwordTextBox;
private System.Windows.Forms.Label userNameLabel;
private System.Windows.Forms.Button cancelButton;
private System.Windows.Forms.Button okButton;
private System.Windows.Forms.Label url;
private System.Windows.Forms.TextBox domainTextBox;
private System.Windows.Forms.TextBox userTextBox;
private System.Windows.Forms.Label domainLabel;
private System.Windows.Forms.Label passwordLabel;
private System.Windows.Forms.Label urlLabel;
#endregion
void AddStringResources()
{
Text = StringParser.Parse("${res:ICSharpCode.SharpDevelop.Gui.Dialogs.UserCredentialsDialog.DialogTitle}");
infoLabel.Text = StringParser.Parse("${res:ICSharpCode.SharpDevelop.Gui.Dialogs.UserCredentialsDialog.InformationLabel}");
urlLabel.Text = StringParser.Parse("${res:ICSharpCode.SharpDevelop.Gui.Dialogs.UserCredentialsDialog.UrlLabel}");
userNameLabel.Text = StringParser.Parse("${res:ICSharpCode.SharpDevelop.Gui.Dialogs.UserCredentialsDialog.UserNameLabel}");
passwordLabel.Text = StringParser.Parse("${res:ICSharpCode.SharpDevelop.Gui.Dialogs.UserCredentialsDialog.PasswordLabel}");
domainLabel.Text = StringParser.Parse("${res:ICSharpCode.SharpDevelop.Gui.Dialogs.UserCredentialsDialog.DomainLabel}");
cancelButton.Text = StringParser.Parse("${res:Global.CancelButtonText}");
okButton.Text = StringParser.Parse("${res:Global.OKButtonText}");
}
}
}

9
src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/WebReference.cs

@ -172,6 +172,15 @@ namespace ICSharpCode.SharpDevelop.Gui
} }
} }
public string ProxyNamespace {
get {
return proxyNamespace;
}
set {
proxyNamespace = value;
}
}
public List<ProjectItem> Items { public List<ProjectItem> Items {
get { get {
if (items == null) { if (items == null) {

50
src/Main/Base/Project/Src/Gui/Dialogs/ReferenceDialog/WebServiceDiscoveryClientProtocol.cs

@ -0,0 +1,50 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using System;
using System.Net;
using System.Web.Services.Discovery;
namespace ICSharpCode.SharpDevelop.Gui
{
/// <summary>
/// Custom DiscoveryClientProtocol that determines whether user authentication
/// is required.
/// </summary>
public class WebServiceDiscoveryClientProtocol : DiscoveryClientProtocol
{
HttpWebResponse lastResponseReceived;
public WebServiceDiscoveryClientProtocol()
{
}
public HttpAuthenticationHeader GetAuthenticationHeader()
{
if (lastResponseReceived != null) {
return new HttpAuthenticationHeader(lastResponseReceived.Headers);
}
return null;
}
public bool IsAuthenticationRequired {
get {
if (lastResponseReceived != null) {
return lastResponseReceived.StatusCode == HttpStatusCode.Unauthorized;
}
return false;
}
}
protected override WebResponse GetWebResponse(WebRequest request)
{
lastResponseReceived = null;
lastResponseReceived = base.GetWebResponse(request) as HttpWebResponse;
return lastResponseReceived;
}
}
}

75
src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/Commands/ReferenceFolderNodeCommands.cs

@ -53,37 +53,64 @@ namespace ICSharpCode.SharpDevelop.Project.Commands
WebReferenceUrl url = (WebReferenceUrl)node.ProjectItem; WebReferenceUrl url = (WebReferenceUrl)node.ProjectItem;
try { try {
// Discover web services at url. // Discover web services at url.
DiscoveryClientProtocol protocol = new DiscoveryClientProtocol(); DiscoveryClientProtocol protocol = DiscoverWebServices(url.UpdateFromURL);
protocol.DiscoverAny(url.UpdateFromURL); if (protocol != null) {
protocol.ResolveOneLevel(); // Save web services.
WebReference webReference = new WebReference(url.Project, url.UpdateFromURL, node.Text, url.Project.RootNamespace, protocol);
// Save web services. webReference.Save();
WebReference webReference = new WebReference(url.Project, url.UpdateFromURL, node.Text, url.Project.RootNamespace, protocol);
webReference.Save(); // Update project.
WebReferenceChanges changes = webReference.GetChanges(url.Project);
// Update project. if (changes.Changed) {
WebReferenceChanges changes = webReference.GetChanges(url.Project); foreach (ProjectItem itemRemoved in changes.ItemsRemoved) {
if (changes.Changed) { ProjectService.RemoveProjectItem(url.Project, itemRemoved);
foreach (ProjectItem itemRemoved in changes.ItemsRemoved) { FileService.RemoveFile(itemRemoved.FileName, false);
ProjectService.RemoveProjectItem(url.Project, itemRemoved); }
FileService.RemoveFile(itemRemoved.FileName, false); foreach (ProjectItem newItem in changes.NewItems) {
} ProjectService.AddProjectItem(url.Project, newItem);
foreach (ProjectItem newItem in changes.NewItems) { FileNode fileNode = new FileNode(newItem.FileName, FileNodeStatus.InProject);
ProjectService.AddProjectItem(url.Project, newItem); fileNode.AddTo(node);
FileNode fileNode = new FileNode(newItem.FileName, FileNodeStatus.InProject); }
fileNode.AddTo(node); ProjectBrowserPad.Instance.ProjectBrowserControl.TreeView.Sort();
url.Project.Save();
} }
ProjectBrowserPad.Instance.ProjectBrowserControl.TreeView.Sort();
url.Project.Save(); // Update code completion.
ParserService.ParseFile(webReference.WebProxyFileName);
} }
// Update code completion.
ParserService.ParseFile(webReference.WebProxyFileName);
} catch (WebException ex) { } catch (WebException ex) {
MessageService.ShowError(ex, String.Format(StringParser.Parse("${res:ICSharpCode.SharpDevelop.Commands.ProjectBrowser.RefreshWebReference.ReadServiceDescriptionError}"), url.UpdateFromURL)); MessageService.ShowError(ex, String.Format(StringParser.Parse("${res:ICSharpCode.SharpDevelop.Commands.ProjectBrowser.RefreshWebReference.ReadServiceDescriptionError}"), url.UpdateFromURL));
} }
} }
} }
DiscoveryClientProtocol DiscoverWebServices(string url)
{
WebServiceDiscoveryClientProtocol protocol = new WebServiceDiscoveryClientProtocol();
NetworkCredential credential = CredentialCache.DefaultNetworkCredentials;
bool retry = true;
while (retry) {
try {
protocol.Credentials = credential;
protocol.DiscoverAny(url);
protocol.ResolveOneLevel();
return protocol;
} catch (WebException ex) {
if (protocol.IsAuthenticationRequired) {
using (UserCredentialsDialog dialog = new UserCredentialsDialog(url, protocol.GetAuthenticationHeader().AuthenticationType)) {
if (dialog.ShowDialog() == DialogResult.OK) {
credential = dialog.Credential;
} else {
retry = false;
}
}
} else {
throw ex;
}
}
}
return null;
}
} }
public class AddWebReferenceToProject : AbstractMenuCommand public class AddWebReferenceToProject : AbstractMenuCommand

1
src/Main/Base/Test/ICSharpCode.SharpDevelop.Tests.csproj

@ -66,6 +66,7 @@
<Compile Include="Templates\ProjectTemplateCategoryComparerTests.cs" /> <Compile Include="Templates\ProjectTemplateCategoryComparerTests.cs" />
<Compile Include="Templates\CategorySortOrderTests.cs" /> <Compile Include="Templates\CategorySortOrderTests.cs" />
<Compile Include="Templates\FileTemplateCategoryComparerTests.cs" /> <Compile Include="Templates\FileTemplateCategoryComparerTests.cs" />
<Compile Include="WebReferences\HttpAuthenticationHeaderTests.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Project\ICSharpCode.SharpDevelop.csproj"> <ProjectReference Include="..\Project\ICSharpCode.SharpDevelop.csproj">

81
src/Main/Base/Test/WebReferences/HttpAuthenticationHeaderTests.cs

@ -0,0 +1,81 @@
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Matthew Ward" email="mrward@users.sourceforge.net"/>
// <version>$Revision$</version>
// </file>
using ICSharpCode.SharpDevelop.Gui;
using NUnit.Framework;
using System;
using System.Net;
namespace ICSharpCode.SharpDevelop.Tests.WebReferences
{
[TestFixture]
public class HttpAuthenticationHeaderTests
{
[Test]
public void IsBasicAuthentication()
{
WebHeaderCollection headers = new WebHeaderCollection();
headers.Add(HttpResponseHeader.WwwAuthenticate, "Basic realm='localhost'");
HttpAuthenticationHeader authenticationHeader = new HttpAuthenticationHeader(headers);
Assert.AreEqual("Basic", authenticationHeader.AuthenticationType);
}
[Test]
public void NoHeadersAdded()
{
WebHeaderCollection headers = new WebHeaderCollection();
HttpAuthenticationHeader authenticationHeader = new HttpAuthenticationHeader(headers);
Assert.AreEqual(String.Empty, authenticationHeader.AuthenticationType);
}
[Test]
public void NonStandardAuthenticationHeaderAdded()
{
WebHeaderCollection headers = new WebHeaderCollection();
headers.Add(HttpResponseHeader.WwwAuthenticate, "Foo");
HttpAuthenticationHeader authenticationHeader = new HttpAuthenticationHeader(headers);
Assert.AreEqual("Foo", authenticationHeader.AuthenticationType);
}
[Test]
public void IsWindowsAuthentication()
{
WebHeaderCollection headers = new WebHeaderCollection();
headers.Add(HttpResponseHeader.WwwAuthenticate, "Negotiate");
headers.Add(HttpResponseHeader.WwwAuthenticate, "NTLM");
HttpAuthenticationHeader authenticationHeader = new HttpAuthenticationHeader(headers);
Assert.AreEqual("Negotiate,NTLM", authenticationHeader.AuthenticationType);
}
[Test]
public void ManyAuthenticationSchemesAdded()
{
WebHeaderCollection headers = new WebHeaderCollection();
headers.Add(HttpResponseHeader.WwwAuthenticate, "Negotiate");
headers.Add(HttpResponseHeader.WwwAuthenticate, "NTLM");
headers.Add(HttpResponseHeader.WwwAuthenticate, "Basic realm='test'");
HttpAuthenticationHeader authenticationHeader = new HttpAuthenticationHeader(headers);
Assert.AreEqual("Negotiate,NTLM,Basic", authenticationHeader.AuthenticationType);
}
[Test]
public void DigestAuthenticationSchemeAdded()
{
WebHeaderCollection headers = new WebHeaderCollection();
headers.Add(HttpResponseHeader.WwwAuthenticate, "Digest realm='test'");
headers.Add(HttpResponseHeader.WwwAuthenticate, "NTLM");
HttpAuthenticationHeader authenticationHeader = new HttpAuthenticationHeader(headers);
Assert.AreEqual("Digest,NTLM", authenticationHeader.AuthenticationType);
}
}
}

BIN
src/Main/StartUp/Project/Resources/StringResources.resources

Binary file not shown.
Loading…
Cancel
Save