Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion proto
25 changes: 23 additions & 2 deletions src/handlers/mfa_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use crate::{
proto::{
CodeMfaSetupFinishRequest, CodeMfaSetupFinishResponse, CodeMfaSetupStartRequest,
CodeMfaSetupStartResponse, DeviceInfo, MfaConfigAuthorizeRequest,
MfaConfigAuthorizeResponse, MfaConfigSendCodeRequest, MfaConfigStartRequest,
MfaConfigStartResponse, core_request, core_response,
MfaConfigAuthorizeResponse, MfaConfigEndRequest, MfaConfigSendCodeRequest,
MfaConfigStartRequest, MfaConfigStartResponse, core_request, core_response,
},
};

Expand All @@ -21,6 +21,7 @@ pub(crate) fn router() -> Router<AppState> {
.route("/authorize", post(authorize_mfa_config))
.route("/setup/start", post(start_mfa_setup))
.route("/setup/finish", post(finish_mfa_setup))
.route("/end", post(end_mfa_config))
}

#[instrument(level = "debug", skip(state, req))]
Expand Down Expand Up @@ -97,3 +98,23 @@ async fn finish_mfa_setup(
) -> Result<Json<CodeMfaSetupFinishResponse>, ApiError> {
code_mfa_setup_finish(&state, device_info, req).await
}

/// Ends the whole MFA configuration session.
#[instrument(level = "debug", skip(state, req))]
async fn end_mfa_config(
State(state): State<AppState>,
device_info: DeviceInfo,
Json(req): Json<MfaConfigEndRequest>,
) -> Result<(), ApiError> {
info!("Ending MFA configuration session");
let rx = state
.grpc_server
.send(core_request::Payload::MfaConfigEnd(req), device_info)?;
let payload = get_core_response(rx, None).await?;
if let core_response::Payload::Empty(()) = payload {
Ok(())
} else {
error!("Received invalid gRPC response type, expected Empty");
Err(ApiError::InvalidResponseType)
}
}
14 changes: 13 additions & 1 deletion src/tests/mfa_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ fn fallback_then_totp(
recovery_codes: vec!["aaaa-bbbb".into(), "cccc-dddd".into()],
})
}
core_request::Payload::MfaConfigEnd(req) => {
assert_eq!(req.session_token, SESSION_TOKEN);
core_response::Payload::Empty(())
}
_ => panic!("unexpected request to Core"),
}
}
Expand Down Expand Up @@ -119,9 +123,17 @@ async fn test_mfa_config_flow_forwards_session_token() {
assert_eq!(status, StatusCode::OK, "{body}");
assert_eq!(body["recovery_codes"], json!(["aaaa-bbbb", "cccc-dddd"]));

let (status, body) = post_json(
&app,
"/api/v1/mfa-config/end",
&json!({ "session_token": session_token }),
)
.await;
assert_eq!(status, StatusCode::OK, "{body}");

assert_eq!(
steps.load(Ordering::Relaxed),
5,
6,
"Core must see every step once"
);
}
Expand Down
Loading