-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Extend browser user authentication provide to handle Condition Access #361
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,7 +12,6 @@ namespace testengine.user.environment.tests | |
{ | ||
public class BrowserUserManagerModuleTests | ||
{ | ||
private Mock<IBrowserContext> MockBrowserState; | ||
private Mock<ITestInfraFunctions> MockTestInfraFunctions; | ||
private Mock<ITestState> MockTestState; | ||
private Mock<ISingleTestInstanceState> MockSingleTestInstanceState; | ||
|
@@ -26,7 +25,6 @@ public class BrowserUserManagerModuleTests | |
|
||
public BrowserUserManagerModuleTests() | ||
{ | ||
MockBrowserState = new Mock<IBrowserContext>(MockBehavior.Strict); | ||
MockTestInfraFunctions = new Mock<ITestInfraFunctions>(MockBehavior.Strict); | ||
MockTestState = new Mock<ITestState>(MockBehavior.Strict); | ||
MockSingleTestInstanceState = new Mock<ISingleTestInstanceState>(MockBehavior.Strict); | ||
|
@@ -59,9 +57,24 @@ public async Task LoginWithBrowserState(bool exists, bool isDirectoryCreated, st | |
userManager.GetFiles = (path) => files.Split(','); | ||
userManager.Page = MockPage.Object; | ||
|
||
MockSingleTestInstanceState.Setup(x => x.GetLogger()).Returns(MockLogger.Object); | ||
|
||
MockTestState.Setup(x => x.GetTestSuiteDefinition()).Returns(new TestSuiteDefinition() { Persona = "User1" }); | ||
MockEnvironmentVariable.Setup(x => x.GetVariable("User1")).Returns("[email protected]"); | ||
|
||
MockBrowserContext.Setup(x => x.Pages).Returns(new List<IPage>() { MockPage.Object }); | ||
MockPage.Setup(x => x.Url).Returns("https://localhost/test"); | ||
|
||
MockLogger.Setup(x => x.Log( | ||
It.IsAny<LogLevel>(), | ||
It.IsAny<EventId>(), | ||
It.IsAny<It.IsAnyType>(), | ||
It.IsAny<Exception>(), | ||
(Func<It.IsAnyType, Exception, string>)It.IsAny<object>())); | ||
|
||
// Act | ||
await userManager.LoginAsUserAsync("*", | ||
MockBrowserState.Object, | ||
await userManager.LoginAsUserAsync("https://localhost/test", | ||
MockBrowserContext.Object, | ||
MockTestState.Object, | ||
MockSingleTestInstanceState.Object, | ||
MockEnvironmentVariable.Object, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,16 +47,15 @@ | |
{ | ||
Context = context; | ||
|
||
var logger = singleTestInstanceState.GetLogger(); | ||
|
||
if (!DirectoryExists(Location)) | ||
{ | ||
logger.LogInformation($"Creating {Location}"); | ||
CreateDirectory(Location); | ||
} | ||
|
||
if (GetFiles(Location).Count() == 0) | ||
{ | ||
ValidatePage(); | ||
await Page.PauseAsync(); | ||
} | ||
await LoginComplete(desiredUrl, testState, environmentVariable, logger); | ||
} | ||
|
||
private void ValidatePage() | ||
|
@@ -66,5 +65,71 @@ | |
Page = Context.Pages.First(); | ||
} | ||
} | ||
|
||
public async Task LoginComplete(string desiredUrl, ITestState testState, IEnvironmentVariable environmentVariable, ILogger logger) | ||
{ | ||
var complete = false; | ||
|
||
var persona = testState.GetTestSuiteDefinition().Persona; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. null checks for the definition, persona and email |
||
var personaEmail = environmentVariable.GetVariable(persona); | ||
|
||
if (string.IsNullOrEmpty(personaEmail)) | ||
{ | ||
logger.LogInformation($"Missing user persona {persona} email. Prompting user"); | ||
Console.Write("Persona Email? "); | ||
personaEmail = Console.ReadLine(); | ||
} | ||
|
||
var started = DateTime.Now; | ||
|
||
while (!complete) | ||
{ | ||
foreach (var page in Context.Pages) | ||
{ | ||
var host = new Uri(desiredUrl).Host; | ||
if (page.Url.Contains($"https://{host}")) | ||
{ | ||
logger.LogInformation($"Found destination url"); | ||
complete = true; | ||
break; | ||
} | ||
|
||
if (page.Url.Contains("common/fido")) | ||
{ | ||
logger.LogInformation($"Login required"); | ||
Console.WriteLine("Login required"); | ||
await page.PauseAsync(); | ||
} | ||
|
||
if (page.Url.Contains("oauth2/authorize")) | ||
{ | ||
if (await page.IsVisibleAsync($"[data-test-id=\"{personaEmail}\"]")) | ||
{ | ||
logger.LogInformation($"Selecting {personaEmail}"); | ||
Check warning Code scanning / CodeQL Exposure of private information Medium test
Private data returned by
access to local variable personaEmail Error loading related location Loading Private data returned by access to local variable personaEmail Error loading related location Loading Private data returned by access to local variable personaEmail Error loading related location Loading Private data returned by access to local variable personaEmail Error loading related location Loading |
||
await page.ClickAsync($"[data-test-id=\"{personaEmail}\"]"); | ||
} | ||
} | ||
|
||
if (page.Url.Contains("mcas.ms/aad_login")) | ||
{ | ||
// TODO: Handle localized values | ||
if (await page.GetByRole(AriaRole.Button, new() { Name = "Continue with current profile" }).IsVisibleAsync()) | ||
{ | ||
logger.LogInformation($"Continue with Microsoft Conditional Access"); | ||
await page.GetByRole(AriaRole.Button, new() { Name = "Continue with current profile" }).ClickAsync(); | ||
} | ||
} | ||
} | ||
|
||
if (!complete) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. would it make sense to add a pause here to wait for user to attempt login |
||
{ | ||
if (DateTime.Now.Subtract(started).TotalMinutes > 5) | ||
{ | ||
throw new Exception("Unable to complete login"); | ||
} | ||
Thread.Sleep(500); | ||
} | ||
} | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we reset the channel to input value from the user if it is specifically requested in the yaml