login.rs 4.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. use crate::{
  2. oidc::{token_response, AuthRequestState, AuthTokenState},
  3. router::Route,
  4. storage::PersistentWrite,
  5. DIOXUS_FRONT_URL, FERMI_AUTH_REQUEST, FERMI_AUTH_TOKEN, FERMI_CLIENT,
  6. };
  7. use dioxus::prelude::*;
  8. use dioxus_router::prelude::{Link, NavigationTarget};
  9. use fermi::*;
  10. use openidconnect::{OAuth2TokenResponse, TokenResponse};
  11. #[component]
  12. pub fn Login(cx: Scope, query_string: String) -> Element {
  13. let fermi_client = use_atom_ref(cx, &FERMI_CLIENT);
  14. let fermi_auth_token = use_atom_ref(cx, &FERMI_AUTH_TOKEN);
  15. let home_url: NavigationTarget<Route> = DIOXUS_FRONT_URL.parse().unwrap();
  16. let fermi_auth_request = use_atom_ref(cx, &FERMI_AUTH_REQUEST);
  17. let client = fermi_client.read().oidc_client.clone();
  18. let auth_token_read = fermi_auth_token.read().clone();
  19. cx.render(match (client, auth_token_read) {
  20. (Some(client_props), Some(auth_token_read)) => {
  21. match (auth_token_read.id_token, auth_token_read.refresh_token) {
  22. (Some(_id_token), Some(_refresh_token)) => {
  23. rsx! {
  24. div { "Sign in successful" }
  25. Link { to: home_url, "Go back home" }
  26. }
  27. }
  28. // If the refresh token is set but not the id_token, there was an error, we just go back home and reset their value
  29. (None, Some(_)) | (Some(_), None) => {
  30. rsx! {
  31. div { "Error while attempting to log in" }
  32. Link {
  33. to: home_url,
  34. onclick: move |_| {
  35. AuthTokenState::persistent_set(fermi_auth_token, Some(AuthTokenState::default()));
  36. AuthRequestState::persistent_set(
  37. fermi_auth_request,
  38. Some(AuthRequestState::default()),
  39. );
  40. },
  41. "Go back home"
  42. }
  43. }
  44. }
  45. (None, None) => {
  46. let mut query_pairs = form_urlencoded::parse(query_string.as_bytes());
  47. let code_pair = query_pairs.find(|(key, _value)| key == "code");
  48. match code_pair {
  49. Some((_key, code)) => {
  50. let auth_code = code.to_string();
  51. let token_response_spawn = move ||{
  52. cx.spawn({
  53. let fermi_auth_token = fermi_auth_token.to_owned();
  54. async move {
  55. let token_response_result = token_response(client_props.client, auth_code).await;
  56. match token_response_result{
  57. Ok(token_response) => {
  58. let id_token = token_response.id_token().unwrap();
  59. AuthTokenState::persistent_set(&fermi_auth_token, Some(AuthTokenState {
  60. id_token: Some(id_token.clone()),
  61. refresh_token: token_response.refresh_token().cloned()
  62. }));
  63. }
  64. Err(error) => {
  65. log::warn!{"{error}"};
  66. }
  67. }
  68. }
  69. })
  70. };
  71. token_response_spawn();
  72. rsx!{ div {} }
  73. }
  74. None => {
  75. rsx! { div { "No code provided" } }
  76. }
  77. }
  78. }
  79. }
  80. }
  81. (_, _) => {
  82. rsx! {{}}
  83. }
  84. })
  85. }