Skip to content
Merged
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.7.1.0
2.7.2.0
4 changes: 2 additions & 2 deletions src/shared/Atlassian.Bitbucket/BitbucketAuthentication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ public async Task<CredentialsPromptResult> GetCredentialsAsync(Uri targetUri, st
private async Task<CredentialsPromptResult> GetCredentialsViaUiAsync(
Uri targetUri, string userName, AuthenticationModes modes)
{
var viewModel = new CredentialsViewModel(Context.Environment)
var viewModel = new CredentialsViewModel(Context.SessionManager)
{
ShowOAuth = (modes & AuthenticationModes.OAuth) != 0,
ShowBasic = (modes & AuthenticationModes.Basic) != 0
Expand Down Expand Up @@ -259,7 +259,7 @@ public async Task<OAuth2TokenResult> CreateOAuthCredentialsAsync(InputArguments
FailureResponseHtmlFormat = BitbucketResources.AuthenticationResponseFailureHtmlFormat
};

var browser = new OAuth2SystemWebBrowser(Context.Environment, browserOptions);
var browser = new OAuth2SystemWebBrowser(Context.SessionManager, browserOptions);
var oauth2Client = _oauth2ClientRegistry.Get(input);

var authCodeResult = await oauth2Client.GetAuthorizationCodeAsync(browser, CancellationToken.None);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ protected CredentialsCommand(ICommandContext context)

private async Task<int> ExecuteAsync(Uri url, string userName, bool showOAuth, bool showBasic)
{
var viewModel = new CredentialsViewModel(Context.Environment)
var viewModel = new CredentialsViewModel(Context.SessionManager)
{
Url = url,
UserName = userName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Atlassian.Bitbucket.UI.ViewModels
{
public class CredentialsViewModel : WindowViewModel
{
private readonly IEnvironment _environment;
private readonly ISessionManager _sessionManager;

private Uri _url;
private string _userName;
Expand All @@ -22,11 +22,11 @@ public CredentialsViewModel()
// Constructor the XAML designer
}

public CredentialsViewModel(IEnvironment environment)
public CredentialsViewModel(ISessionManager sessionManager)
{
EnsureArgument.NotNull(environment, nameof(environment));
EnsureArgument.NotNull(sessionManager, nameof(sessionManager));

_environment = environment;
_sessionManager = sessionManager;

Title = "Connect to Bitbucket";
LoginCommand = new RelayCommand(AcceptBasic, CanLogin);
Expand Down Expand Up @@ -77,7 +77,7 @@ private void ForgotPassword()
? new Uri(BitbucketConstants.HelpUrls.PasswordReset)
: new Uri(_url, BitbucketConstants.HelpUrls.DataCenterPasswordReset);

BrowserUtils.OpenDefaultBrowser(_environment, passwordResetUri);
_sessionManager.OpenBrowser(passwordResetUri);
}

private void SignUp()
Expand All @@ -86,7 +86,7 @@ private void SignUp()
? new Uri(BitbucketConstants.HelpUrls.SignUp)
: new Uri(_url, BitbucketConstants.HelpUrls.DataCenterLogin);

BrowserUtils.OpenDefaultBrowser(_environment, signUpUri);
_sessionManager.OpenBrowser(signUpUri);
}

public Uri Url
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ public class OAuth2SystemWebBrowserTests
[Fact]
public void OAuth2SystemWebBrowser_UpdateRedirectUri_NonLoopback_ThrowsError()
{
var env = new TestEnvironment();
var sm = new TestSessionManager();
var options = new OAuth2WebBrowserOptions();
var browser = new OAuth2SystemWebBrowser(env, options);
var browser = new OAuth2SystemWebBrowser(sm, options);

Assert.Throws<ArgumentException>(() => browser.UpdateRedirectUri(new Uri("http://example.com")));
}
Expand All @@ -28,9 +28,9 @@ public void OAuth2SystemWebBrowser_UpdateRedirectUri_NonLoopback_ThrowsError()
[InlineData("http://127.0.0.7:1234/oauth-callback/", "http://127.0.0.7:1234/oauth-callback/")]
public void OAuth2SystemWebBrowser_UpdateRedirectUri_SpecificPort(string input, string expected)
{
var env = new TestEnvironment();
var sm = new TestSessionManager();
var options = new OAuth2WebBrowserOptions();
var browser = new OAuth2SystemWebBrowser(env, options);
var browser = new OAuth2SystemWebBrowser(sm, options);

Uri actualUri = browser.UpdateRedirectUri(new Uri(input));

Expand All @@ -48,9 +48,9 @@ public void OAuth2SystemWebBrowser_UpdateRedirectUri_SpecificPort(string input,
[InlineData("http://127.0.0.7/oauth-callback/")]
public void OAuth2SystemWebBrowser_UpdateRedirectUri_AnyPort(string input)
{
var env = new TestEnvironment();
var sm = new TestSessionManager();
var options = new OAuth2WebBrowserOptions();
var browser = new OAuth2SystemWebBrowser(env, options);
var browser = new OAuth2SystemWebBrowser(sm, options);

var inputUri = new Uri(input);
Uri actualUri = browser.UpdateRedirectUri(inputUri);
Expand Down
43 changes: 33 additions & 10 deletions src/shared/Core/Authentication/MicrosoftAuthentication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ private async Task<bool> UseDefaultAccountAsync(string userName)
}
}

var viewModel = new DefaultAccountViewModel(Context.Environment)
var viewModel = new DefaultAccountViewModel(Context.SessionManager)
{
UserName = userName
};
Expand Down Expand Up @@ -754,10 +754,33 @@ private static EmbeddedWebViewOptions GetEmbeddedWebViewOptions()
};
}

private static SystemWebViewOptions GetSystemWebViewOptions()
private SystemWebViewOptions GetSystemWebViewOptions()
{
// TODO: add nicer HTML success and error pages
return new SystemWebViewOptions();
return new SystemWebViewOptions
{
OpenBrowserAsync = OpenBrowserFunc
};

// We have special handling for Linux and WSL to open the system browser
// so we need to use our own function here. Sorry MSAL!
Task OpenBrowserFunc(Uri uri)
{
try
{
Context.SessionManager.OpenBrowser(uri);
}
catch (Exception ex)
{
Context.Trace.WriteLine("Failed to open system web browser - using MSAL fallback");
Context.Trace.WriteException(ex);

// Fallback to MSAL's default browser opening logic, preferring Edge.
return SystemWebViewOptions.OpenWithChromeEdgeBrowserAsync(uri);
}

return Task.CompletedTask;
}
}

private Task ShowDeviceCodeInTty(DeviceCodeResult dcr)
Expand Down Expand Up @@ -859,8 +882,14 @@ private void EnsureCanUseEmbeddedWebView()

private bool CanUseSystemWebView(IPublicClientApplication app, Uri redirectUri)
{
//
// MSAL requires the application redirect URI is a loopback address to use the System WebView
return Context.SessionManager.IsWebBrowserAvailable && app.IsSystemWebViewAvailable && redirectUri.IsLoopback;
//
// Note: we do NOT check the MSAL 'IsSystemWebViewAvailable' property as it only
// looks for the presence of the DISPLAY environment variable on UNIX systems.
// This is insufficient as we instead handle launching the default browser ourselves.
//
return Context.SessionManager.IsWebBrowserAvailable && redirectUri.IsLoopback;
}

private void EnsureCanUseSystemWebView(IPublicClientApplication app, Uri redirectUri)
Expand All @@ -871,12 +900,6 @@ private void EnsureCanUseSystemWebView(IPublicClientApplication app, Uri redirec
"System web view is not available without a way to start a browser.");
}

if (!app.IsSystemWebViewAvailable)
{
throw new Trace2InvalidOperationException(Context.Trace2,
"System web view is not available on this platform.");
}

if (!redirectUri.IsLoopback)
{
throw new Trace2InvalidOperationException(Context.Trace2,
Expand Down
11 changes: 5 additions & 6 deletions src/shared/Core/Authentication/OAuth/OAuth2SystemWebBrowser.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.Sockets;
using System.Threading;
Expand Down Expand Up @@ -33,15 +32,15 @@ public class OAuth2WebBrowserOptions

public class OAuth2SystemWebBrowser : IOAuth2WebBrowser
{
private readonly IEnvironment _environment;
private readonly ISessionManager _sessionManager;
private readonly OAuth2WebBrowserOptions _options;

public OAuth2SystemWebBrowser(IEnvironment environment, OAuth2WebBrowserOptions options)
public OAuth2SystemWebBrowser(ISessionManager sessionManager, OAuth2WebBrowserOptions options)
{
EnsureArgument.NotNull(environment, nameof(environment));
EnsureArgument.NotNull(sessionManager, nameof(sessionManager));
EnsureArgument.NotNull(options, nameof(options));

_environment = environment;
_sessionManager = sessionManager;
_options = options;
}

Expand Down Expand Up @@ -71,7 +70,7 @@ public async Task<Uri> GetAuthenticationCodeAsync(Uri authorizationUri, Uri redi

Task<Uri> interceptTask = InterceptRequestsAsync(redirectUri, ct);

BrowserUtils.OpenDefaultBrowser(_environment, authorizationUri);
_sessionManager.OpenBrowser(authorizationUri);

return await interceptTask;
}
Expand Down
4 changes: 2 additions & 2 deletions src/shared/Core/Authentication/OAuthAuthentication.cs
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ public async Task<OAuth2TokenResult> GetTokenByBrowserAsync(OAuth2Client client,
}

var browserOptions = new OAuth2WebBrowserOptions();
var browser = new OAuth2SystemWebBrowser(Context.Environment, browserOptions);
var browser = new OAuth2SystemWebBrowser(Context.SessionManager, browserOptions);
var authCode = await client.GetAuthorizationCodeAsync(scopes, browser, CancellationToken.None);
return await client.GetTokenByAuthorizationCodeAsync(authCode, CancellationToken.None);
}
Expand Down Expand Up @@ -241,7 +241,7 @@ public async Task<OAuth2TokenResult> GetTokenByDeviceCodeAsync(OAuth2Client clie

private Task ShowDeviceCodeViaUiAsync(OAuth2DeviceCodeResult dcr, CancellationToken ct)
{
var viewModel = new DeviceCodeViewModel(Context.Environment)
var viewModel = new DeviceCodeViewModel(Context.SessionManager)
{
UserCode = dcr.UserCode,
VerificationUrl = dcr.VerificationUri.ToString(),
Expand Down
88 changes: 0 additions & 88 deletions src/shared/Core/BrowserUtils.cs

This file was deleted.

6 changes: 3 additions & 3 deletions src/shared/Core/CommandContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ public CommandContext()
{
FileSystem = new WindowsFileSystem();
Environment = new WindowsEnvironment(FileSystem);
SessionManager = new WindowsSessionManager(Environment, FileSystem);
SessionManager = new WindowsSessionManager(Trace, Environment, FileSystem);
ProcessManager = new WindowsProcessManager(Trace2);
Terminal = new WindowsTerminal(Trace, Trace2);
string gitPath = GetGitPath(Environment, FileSystem, Trace);
Expand All @@ -120,7 +120,7 @@ public CommandContext()
{
FileSystem = new MacOSFileSystem();
Environment = new MacOSEnvironment(FileSystem);
SessionManager = new MacOSSessionManager(Environment, FileSystem);
SessionManager = new MacOSSessionManager(Trace, Environment, FileSystem);
ProcessManager = new ProcessManager(Trace2);
Terminal = new MacOSTerminal(Trace, Trace2);
string gitPath = GetGitPath(Environment, FileSystem, Trace);
Expand All @@ -137,7 +137,7 @@ public CommandContext()
{
FileSystem = new LinuxFileSystem();
Environment = new PosixEnvironment(FileSystem);
SessionManager = new LinuxSessionManager(Environment, FileSystem);
SessionManager = new LinuxSessionManager(Trace, Environment, FileSystem);
ProcessManager = new ProcessManager(Trace2);
Terminal = new LinuxTerminal(Trace, Trace2);
string gitPath = GetGitPath(Environment, FileSystem, Trace);
Expand Down
Loading
Loading