mirror of
https://github.com/servo/servo.git
synced 2025-08-03 04:30:10 +01:00
Add the requesting URL to the 401 prompt. Only show the 401 prompt when the WWW-Authenticate header is present.
This commit is contained in:
parent
224bcd7057
commit
cb63ad6c87
2 changed files with 52 additions and 14 deletions
|
@ -768,18 +768,18 @@ pub fn obtain_response<A>(request_factory: &HttpRequestFactory<R=A>,
|
|||
}
|
||||
|
||||
pub trait UIProvider {
|
||||
fn input_username_and_password(&self) -> (Option<String>, Option<String>);
|
||||
fn input_username_and_password(&self, prompt: &str) -> (Option<String>, Option<String>);
|
||||
}
|
||||
|
||||
impl UIProvider for TFDProvider {
|
||||
#[cfg(any(target_os = "macos", target_os = "linux"))]
|
||||
fn input_username_and_password(&self) -> (Option<String>, Option<String>) {
|
||||
(tinyfiledialogs::input_box("Enter username", "Username:", ""),
|
||||
tinyfiledialogs::input_box("Enter password", "Password:", ""))
|
||||
fn input_username_and_password(&self, prompt: &str) -> (Option<String>, Option<String>) {
|
||||
(tinyfiledialogs::input_box(prompt, "Username:", ""),
|
||||
tinyfiledialogs::input_box(prompt, "Password:", ""))
|
||||
}
|
||||
|
||||
#[cfg(not(any(target_os = "macos", target_os = "linux")))]
|
||||
fn input_username_and_password(&self) -> (Option<String>, Option<String>) {
|
||||
fn input_username_and_password(&self, _prompt: &str) -> (Option<String>, Option<String>) {
|
||||
(None, None)
|
||||
}
|
||||
}
|
||||
|
@ -870,8 +870,10 @@ pub fn load<A, B>(load_data: &LoadData,
|
|||
process_response_headers(&response, &doc_url, &http_state.cookie_jar, &http_state.hsts_list, &load_data);
|
||||
|
||||
//if response status is unauthorized then prompt user for username and password
|
||||
if response.status() == StatusCode::Unauthorized {
|
||||
let (username_option, password_option) = ui_provider.input_username_and_password();
|
||||
if response.status() == StatusCode::Unauthorized &&
|
||||
response.headers().get_raw("WWW-Authenticate").is_some() {
|
||||
let (username_option, password_option) =
|
||||
ui_provider.input_username_and_password(doc_url.as_str());
|
||||
|
||||
match username_option {
|
||||
Some(name) => {
|
||||
|
|
|
@ -109,15 +109,15 @@ impl TestProvider {
|
|||
}
|
||||
}
|
||||
impl UIProvider for TestProvider {
|
||||
fn input_username_and_password(&self) -> (Option<String>, Option<String>) {
|
||||
fn input_username_and_password(&self, _prompt: &str) -> (Option<String>, Option<String>) {
|
||||
(Some(self.username.to_owned()),
|
||||
Some(self.password.to_owned()))
|
||||
}
|
||||
}
|
||||
|
||||
fn basic_auth() -> MockResponse {
|
||||
fn basic_auth(headers: Headers) -> MockResponse {
|
||||
MockResponse::new(
|
||||
Headers::new(),
|
||||
headers,
|
||||
StatusCode::Unauthorized,
|
||||
RawStatus(401, Cow::Borrowed("Unauthorized")),
|
||||
b"".to_vec()
|
||||
|
@ -140,7 +140,7 @@ enum ResponseType {
|
|||
RedirectWithHeaders(String, Headers),
|
||||
Text(Vec<u8>),
|
||||
WithHeaders(Vec<u8>, Headers),
|
||||
NeedsAuth,
|
||||
NeedsAuth(Headers),
|
||||
}
|
||||
|
||||
struct MockRequest {
|
||||
|
@ -167,8 +167,8 @@ fn response_for_request_type(t: ResponseType) -> Result<MockResponse, LoadError>
|
|||
ResponseType::WithHeaders(b, h) => {
|
||||
Ok(respond_with_headers(b, h))
|
||||
},
|
||||
ResponseType::NeedsAuth => {
|
||||
Ok(basic_auth())
|
||||
ResponseType::NeedsAuth(h) => {
|
||||
Ok(basic_auth(h))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -208,7 +208,9 @@ impl HttpRequestFactory for AssertAuthHeaderRequestFactory {
|
|||
assert_headers_included(&self.expected_headers, &headers);
|
||||
MockRequest::new(ResponseType::Text(self.body.clone()))
|
||||
} else {
|
||||
MockRequest::new(ResponseType::NeedsAuth)
|
||||
let mut headers = Headers::new();
|
||||
headers.set_raw("WWW-Authenticate", vec![b"Basic realm=\"Test realm\"".to_vec()]);
|
||||
MockRequest::new(ResponseType::NeedsAuth(headers))
|
||||
};
|
||||
|
||||
Ok(request)
|
||||
|
@ -1442,6 +1444,40 @@ fn test_auth_ui_sets_header_on_401() {
|
|||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_auth_ui_needs_www_auth() {
|
||||
let url = Url::parse("http://mozilla.com").unwrap();
|
||||
let http_state = HttpState::new();
|
||||
struct AuthProvider;
|
||||
impl UIProvider for AuthProvider {
|
||||
fn input_username_and_password(&self, _prompt: &str) -> (Option<String>, Option<String>) {
|
||||
panic!("shouldn't be invoked")
|
||||
}
|
||||
}
|
||||
|
||||
struct Factory;
|
||||
|
||||
impl HttpRequestFactory for Factory {
|
||||
type R = MockRequest;
|
||||
|
||||
fn create(&self, _: Url, _: Method, _: Headers) -> Result<MockRequest, LoadError> {
|
||||
Ok(MockRequest::new(ResponseType::NeedsAuth(Headers::new())))
|
||||
}
|
||||
}
|
||||
|
||||
let load_data = LoadData::new(LoadContext::Browsing, url, None, None, None);
|
||||
|
||||
let response = load(&load_data, &AuthProvider, &http_state,
|
||||
None, &Factory, DEFAULT_USER_AGENT.to_owned(),
|
||||
&CancellationListener::new(None));
|
||||
match response {
|
||||
Err(e) => panic!("response contained error {:?}", e),
|
||||
Ok(response) => {
|
||||
assert_eq!(response.metadata.status, Some(RawStatus(401, Cow::Borrowed("Unauthorized"))));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_referer_header_matches(request_url: &str,
|
||||
referrer_url: &str,
|
||||
referrer_policy: Option<ReferrerPolicy>,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue