(
mut req: Request,
next: Next,
tls_enabled: bool,
authenticator_kind: listeners::AuthenticatorKind,
frontegg: Option<mz_frontegg_auth::Authenticator>,
oidc_rx: Delayed<mz_auth
| 1128 | } |
| 1129 | |
| 1130 | async fn http_auth( |
| 1131 | mut req: Request, |
| 1132 | next: Next, |
| 1133 | tls_enabled: bool, |
| 1134 | authenticator_kind: listeners::AuthenticatorKind, |
| 1135 | frontegg: Option<mz_frontegg_auth::Authenticator>, |
| 1136 | oidc_rx: Delayed<mz_authenticator::GenericOidcAuthenticator>, |
| 1137 | adapter_client_rx: Delayed<Client>, |
| 1138 | allowed_roles: AllowedRoles, |
| 1139 | ) -> Result<impl IntoResponse, AuthError> { |
| 1140 | let creds = if let Some(basic) = req.headers().typed_get::<Authorization<Basic>>() { |
| 1141 | Some(Credentials::Password { |
| 1142 | username: basic.username().to_owned(), |
| 1143 | password: Password(basic.password().to_owned()), |
| 1144 | }) |
| 1145 | } else if let Some(bearer) = req.headers().typed_get::<Authorization<Bearer>>() { |
| 1146 | Some(Credentials::Token { |
| 1147 | token: bearer.token().to_owned(), |
| 1148 | }) |
| 1149 | } else { |
| 1150 | None |
| 1151 | }; |
| 1152 | |
| 1153 | // Reuses an authenticated session if one already exists. |
| 1154 | // If credentials are provided, we perform a new authentication, |
| 1155 | // separate from the existing session. |
| 1156 | if creds.is_none() |
| 1157 | && let Some((session, session_data)) = |
| 1158 | maybe_get_authenticated_session(req.extensions().get::<TowerSession>()).await |
| 1159 | { |
| 1160 | let user = ensure_session_unexpired(session, session_data).await?; |
| 1161 | // Defense-in-depth: re-check the listener's `allowed_roles` policy on |
| 1162 | // every session-authenticated request. The same check runs at |
| 1163 | // `/api/login`, but enforcing it here too prevents a session minted |
| 1164 | // under a more permissive configuration (or a future bug in the login |
| 1165 | // path) from bypassing role restrictions. |
| 1166 | check_role_allowed(&user.name, allowed_roles)?; |
| 1167 | // Need this to set the user of the Adapter client. |
| 1168 | req.extensions_mut().insert(user); |
| 1169 | return Ok(next.run(req).await); |
| 1170 | } |
| 1171 | |
| 1172 | // First, extract the username from the certificate, validating that the |
| 1173 | // connection matches the TLS configuration along the way. |
| 1174 | // Fall back to existing authentication methods. |
| 1175 | let conn_protocol = req.extensions().get::<ConnProtocol>().unwrap(); |
| 1176 | match (tls_enabled, &conn_protocol) { |
| 1177 | (false, ConnProtocol::Http) => {} |
| 1178 | (false, ConnProtocol::Https { .. }) => unreachable!(), |
| 1179 | (true, ConnProtocol::Http) => { |
| 1180 | let mut parts = req.uri().clone().into_parts(); |
| 1181 | parts.scheme = Some(Scheme::HTTPS); |
| 1182 | return Ok(Redirect::permanent( |
| 1183 | &Uri::from_parts(parts) |
| 1184 | .expect("it was already a URI, just changed the scheme") |
| 1185 | .to_string(), |
| 1186 | ) |
| 1187 | .into_response()); |
no test coverage detected