Skip to content

Commit 97eb16c

Browse files
authored
[bidi][java] Add authentication handlers (#14334)
Related to #13993
1 parent 7a18a86 commit 97eb16c

File tree

6 files changed

+222
-3
lines changed

6 files changed

+222
-3
lines changed

java/src/org/openqa/selenium/bidi/module/Network.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,11 @@ public void onResponseCompleted(Consumer<ResponseDetails> consumer) {
169169
}
170170
}
171171

172-
public void onAuthRequired(Consumer<ResponseDetails> consumer) {
172+
public long onAuthRequired(Consumer<ResponseDetails> consumer) {
173173
if (browsingContextIds.isEmpty()) {
174-
this.bidi.addListener(authRequired, consumer);
174+
return this.bidi.addListener(authRequired, consumer);
175175
} else {
176-
this.bidi.addListener(browsingContextIds, authRequired, consumer);
176+
return this.bidi.addListener(browsingContextIds, authRequired, consumer);
177177
}
178178
}
179179

java/src/org/openqa/selenium/remote/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ java_library(
6060
"//java/src/org/openqa/selenium/bidi",
6161
"//java/src/org/openqa/selenium/bidi/log",
6262
"//java/src/org/openqa/selenium/bidi/module",
63+
"//java/src/org/openqa/selenium/bidi/network",
6364
"//java/src/org/openqa/selenium/bidi/script",
6465
"//java/src/org/openqa/selenium/concurrent",
6566
"//java/src/org/openqa/selenium/devtools",
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Licensed to the Software Freedom Conservancy (SFC) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The SFC licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.openqa.selenium.remote;
19+
20+
import org.openqa.selenium.Beta;
21+
import org.openqa.selenium.UsernameAndPassword;
22+
23+
@Beta
24+
public interface Network {
25+
26+
long addAuthenticationHandler(UsernameAndPassword usernameAndPassword);
27+
28+
void removeAuthenticationHandler(long id);
29+
30+
void clearAuthenticationHandlers();
31+
}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Licensed to the Software Freedom Conservancy (SFC) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The SFC licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.openqa.selenium.remote;
19+
20+
import java.util.HashMap;
21+
import java.util.Map;
22+
import org.openqa.selenium.Beta;
23+
import org.openqa.selenium.UsernameAndPassword;
24+
import org.openqa.selenium.WebDriver;
25+
import org.openqa.selenium.bidi.BiDi;
26+
import org.openqa.selenium.bidi.HasBiDi;
27+
import org.openqa.selenium.bidi.network.AddInterceptParameters;
28+
import org.openqa.selenium.bidi.network.InterceptPhase;
29+
30+
@Beta
31+
class RemoteNetwork implements Network {
32+
33+
private final BiDi biDi;
34+
private final org.openqa.selenium.bidi.module.Network network;
35+
36+
private final Map<Long, String> authCallbackIdMap = new HashMap<>();
37+
38+
public RemoteNetwork(WebDriver driver) {
39+
this.biDi = ((HasBiDi) driver).getBiDi();
40+
this.network = new org.openqa.selenium.bidi.module.Network(driver);
41+
}
42+
43+
@Override
44+
public long addAuthenticationHandler(UsernameAndPassword usernameAndPassword) {
45+
String intercept =
46+
network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED));
47+
48+
long id =
49+
network.onAuthRequired(
50+
responseDetails ->
51+
network.continueWithAuth(
52+
responseDetails.getRequest().getRequestId(), usernameAndPassword));
53+
54+
authCallbackIdMap.put(id, intercept);
55+
return id;
56+
}
57+
58+
@Override
59+
public void removeAuthenticationHandler(long id) {
60+
String intercept = authCallbackIdMap.get(id);
61+
62+
if (intercept != null) {
63+
network.removeIntercept(intercept);
64+
this.biDi.removeListener(id);
65+
authCallbackIdMap.remove(id);
66+
}
67+
}
68+
69+
@Override
70+
public void clearAuthenticationHandlers() {
71+
authCallbackIdMap.forEach(
72+
(callback, intercept) -> {
73+
network.removeIntercept(intercept);
74+
this.biDi.removeListener(callback);
75+
});
76+
77+
authCallbackIdMap.clear();
78+
}
79+
}

java/src/org/openqa/selenium/remote/RemoteWebDriver.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ public class RemoteWebDriver
130130

131131
private Script remoteScript;
132132

133+
private Network remoteNetwork;
134+
133135
// For cglib
134136
protected RemoteWebDriver() {
135137
this.capabilities = init(new ImmutableCapabilities());
@@ -504,6 +506,13 @@ public Script script() {
504506
return this.remoteScript;
505507
}
506508

509+
public Network network() {
510+
if (this.remoteNetwork == null) {
511+
this.remoteNetwork = new RemoteNetwork(this);
512+
}
513+
return this.remoteNetwork;
514+
}
515+
507516
protected JsonToWebElementConverter getElementConverter() {
508517
return converter;
509518
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
// Licensed to the Software Freedom Conservancy (SFC) under one
2+
// or more contributor license agreements. See the NOTICE file
3+
// distributed with this work for additional information
4+
// regarding copyright ownership. The SFC licenses this file
5+
// to you under the Apache License, Version 2.0 (the
6+
// "License"); you may not use this file except in compliance
7+
// with the License. You may obtain a copy of the License at
8+
//
9+
// http://www.apache.org/licenses/LICENSE-2.0
10+
//
11+
// Unless required by applicable law or agreed to in writing,
12+
// software distributed under the License is distributed on an
13+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
// KIND, either express or implied. See the License for the
15+
// specific language governing permissions and limitations
16+
// under the License.
17+
18+
package org.openqa.selenium;
19+
20+
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
21+
import static org.assertj.core.api.AssertionsForClassTypes.assertThat;
22+
23+
import org.junit.jupiter.api.AfterEach;
24+
import org.junit.jupiter.api.BeforeEach;
25+
import org.junit.jupiter.api.Test;
26+
import org.openqa.selenium.environment.webserver.AppServer;
27+
import org.openqa.selenium.environment.webserver.NettyAppServer;
28+
import org.openqa.selenium.remote.RemoteWebDriver;
29+
import org.openqa.selenium.testing.JupiterTestBase;
30+
import org.openqa.selenium.testing.NotYetImplemented;
31+
import org.openqa.selenium.testing.drivers.Browser;
32+
33+
class WebNetworkTest extends JupiterTestBase {
34+
35+
private String page;
36+
private AppServer server;
37+
38+
@BeforeEach
39+
public void setUp() {
40+
server = new NettyAppServer();
41+
server.start();
42+
}
43+
44+
@AfterEach
45+
public void cleanUp() {
46+
driver.quit();
47+
}
48+
49+
@Test
50+
@NotYetImplemented(Browser.CHROME)
51+
@NotYetImplemented(Browser.EDGE)
52+
void canAddAuthenticationHandler() {
53+
((RemoteWebDriver) driver)
54+
.network()
55+
.addAuthenticationHandler(new UsernameAndPassword("test", "test"));
56+
57+
page = server.whereIs("basicAuth");
58+
driver.get(page);
59+
60+
assertThat(driver.findElement(By.tagName("h1")).getText()).isEqualTo("authorized");
61+
}
62+
63+
@Test
64+
@NotYetImplemented(Browser.CHROME)
65+
@NotYetImplemented(Browser.EDGE)
66+
void canRemoveAuthenticationHandler() {
67+
long id =
68+
((RemoteWebDriver) driver)
69+
.network()
70+
.addAuthenticationHandler(new UsernameAndPassword("test", "test"));
71+
72+
((RemoteWebDriver) driver).network().removeAuthenticationHandler(id);
73+
page = server.whereIs("basicAuth");
74+
driver.get(page);
75+
76+
assertThatExceptionOfType(UnhandledAlertException.class)
77+
.isThrownBy(() -> driver.findElement(By.tagName("h1")));
78+
}
79+
80+
@Test
81+
@NotYetImplemented(Browser.CHROME)
82+
@NotYetImplemented(Browser.EDGE)
83+
void canClearAuthenticationHandlers() {
84+
((RemoteWebDriver) driver)
85+
.network()
86+
.addAuthenticationHandler(new UsernameAndPassword("test", "test"));
87+
88+
((RemoteWebDriver) driver)
89+
.network()
90+
.addAuthenticationHandler(new UsernameAndPassword("test1", "test1"));
91+
92+
((RemoteWebDriver) driver).network().clearAuthenticationHandlers();
93+
page = server.whereIs("basicAuth");
94+
driver.get(page);
95+
96+
assertThatExceptionOfType(UnhandledAlertException.class)
97+
.isThrownBy(() -> driver.findElement(By.tagName("h1")));
98+
}
99+
}

0 commit comments

Comments
 (0)