[BE] Get session cookie from online classroom
This commit is contained in:
parent
73205c5622
commit
5992908ce6
77
backend/Cargo.lock
generated
77
backend/Cargo.lock
generated
@ -237,6 +237,17 @@ version = "0.9.5"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f"
|
checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cookie"
|
||||||
|
version = "0.16.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb"
|
||||||
|
dependencies = [
|
||||||
|
"percent-encoding",
|
||||||
|
"time 0.3.27",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cookie"
|
name = "cookie"
|
||||||
version = "0.17.0"
|
version = "0.17.0"
|
||||||
@ -248,6 +259,23 @@ dependencies = [
|
|||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cookie_store"
|
||||||
|
version = "0.16.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d606d0fba62e13cf04db20536c05cb7f13673c161cb47a47a82b9b9e7d3f1daa"
|
||||||
|
dependencies = [
|
||||||
|
"cookie 0.16.2",
|
||||||
|
"idna 0.2.3",
|
||||||
|
"log",
|
||||||
|
"publicsuffix",
|
||||||
|
"serde",
|
||||||
|
"serde_derive",
|
||||||
|
"serde_json",
|
||||||
|
"time 0.3.27",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "core-foundation"
|
name = "core-foundation"
|
||||||
version = "0.9.3"
|
version = "0.9.3"
|
||||||
@ -828,6 +856,27 @@ dependencies = [
|
|||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "idna"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
|
||||||
|
dependencies = [
|
||||||
|
"matches",
|
||||||
|
"unicode-bidi",
|
||||||
|
"unicode-normalization",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "idna"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6"
|
||||||
|
dependencies = [
|
||||||
|
"unicode-bidi",
|
||||||
|
"unicode-normalization",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
@ -984,6 +1033,12 @@ dependencies = [
|
|||||||
"regex-automata 0.1.10",
|
"regex-automata 0.1.10",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "matches"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "md-5"
|
name = "md-5"
|
||||||
version = "0.10.5"
|
version = "0.10.5"
|
||||||
@ -1366,6 +1421,22 @@ dependencies = [
|
|||||||
"yansi 1.0.0-rc.1",
|
"yansi 1.0.0-rc.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "psl-types"
|
||||||
|
version = "2.0.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "publicsuffix"
|
||||||
|
version = "2.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96a8c1bda5ae1af7f99a2962e49df150414a43d62404644d98dd5c3a93d07457"
|
||||||
|
dependencies = [
|
||||||
|
"idna 0.3.0",
|
||||||
|
"psl-types",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.33"
|
version = "1.0.33"
|
||||||
@ -1486,6 +1557,8 @@ checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
"cookie 0.16.2",
|
||||||
|
"cookie_store",
|
||||||
"encoding_rs",
|
"encoding_rs",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
@ -1615,7 +1688,7 @@ version = "0.5.0-rc.3"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "936012c99162a03a67f37f9836d5f938f662e26f2717809761a9ac46432090f4"
|
checksum = "936012c99162a03a67f37f9836d5f938f662e26f2717809761a9ac46432090f4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cookie",
|
"cookie 0.17.0",
|
||||||
"either",
|
"either",
|
||||||
"futures",
|
"futures",
|
||||||
"http",
|
"http",
|
||||||
@ -2552,7 +2625,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||||||
checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
|
checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"form_urlencoded",
|
"form_urlencoded",
|
||||||
"idna",
|
"idna 0.4.0",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -6,7 +6,7 @@ edition = "2021"
|
|||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
reqwest = { version = "0.11", features = ["json"] }
|
reqwest = { version = "0.11", features = ["json", "cookies"] }
|
||||||
rocket = { version = "=0.5.0-rc.3" , features = ["json", "msgpack", "uuid"] }
|
rocket = { version = "=0.5.0-rc.3" , features = ["json", "msgpack", "uuid"] }
|
||||||
sqlx = { version = "0.7.1", features = [ "runtime-tokio", "tls-rustls", "mysql", "macros", "chrono" ] }
|
sqlx = { version = "0.7.1", features = [ "runtime-tokio", "tls-rustls", "mysql", "macros", "chrono" ] }
|
||||||
once_cell = "1.18.0"
|
once_cell = "1.18.0"
|
||||||
|
@ -50,6 +50,10 @@ async fn rocket() -> _ {
|
|||||||
controller::register::get_by_dni,
|
controller::register::get_by_dni,
|
||||||
controller::register::delete,
|
controller::register::delete,
|
||||||
controller::custom_label::get_all,
|
controller::custom_label::get_all,
|
||||||
|
//
|
||||||
|
// Online classroom routes
|
||||||
|
//
|
||||||
|
online_classroom::connection,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,85 @@
|
|||||||
|
use once_cell::sync::OnceCell;
|
||||||
|
|
||||||
pub fn get_cookie() {
|
use reqwest::Client;
|
||||||
|
use rocket::{http::Status, serde::json::Json};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
static SESSION_COOKIE: OnceCell<String> = OnceCell::new();
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub enum ConnectionResult {
|
||||||
|
Ok(),
|
||||||
|
Error(ConnectionError),
|
||||||
|
}
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct ConnectionError {
|
||||||
|
reason: String,
|
||||||
|
}
|
||||||
|
fn new_error(reason: String) -> ConnectionResult {
|
||||||
|
ConnectionResult::Error(ConnectionError { reason })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Tries to connect to the online classroom, and get a session cookie
|
||||||
|
#[get("/classroom/connect")]
|
||||||
|
pub async fn connection() -> (Status, Json<ConnectionResult>) {
|
||||||
|
// Get session cookie
|
||||||
|
let _cookie = match get_cookie().await {
|
||||||
|
Ok(cookie) => cookie,
|
||||||
|
Err(reason) => return (Status::InternalServerError, Json(new_error(reason))),
|
||||||
|
};
|
||||||
|
|
||||||
|
(Status::Ok, Json(ConnectionResult::Ok()))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_cookie<'a>() -> Result<&'a String, String> {
|
||||||
|
match SESSION_COOKIE.get() {
|
||||||
|
Some(cookie) => Ok(cookie),
|
||||||
|
None => {
|
||||||
|
// Try to create cookie
|
||||||
|
let _ = create_cookie().await?;
|
||||||
|
|
||||||
|
// Try to get cookie again
|
||||||
|
match SESSION_COOKIE.get() {
|
||||||
|
Some(cookie) => Ok(cookie),
|
||||||
|
None => Err("Error getting session cookie".into()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Tries to connect to the online classroom, and get a session cookie.
|
||||||
|
/// Stores the session coookie in a global static variable.
|
||||||
|
pub async fn create_cookie() -> Result<(), String> {
|
||||||
|
let clasroom_url = std::env::var("CLASSROOM_URL").expect("CLASSROOM_URL env var is not set!");
|
||||||
|
let clasroom_user =
|
||||||
|
std::env::var("CLASSROOM_USER").expect("CLASSROOM_USER env var is not set!");
|
||||||
|
let clasroom_password =
|
||||||
|
std::env::var("CLASSROOM_PASSWORD").expect("CLASSROOM_PASSWORD env var is not set!");
|
||||||
|
|
||||||
|
let params = [
|
||||||
|
("login", clasroom_user),
|
||||||
|
("password", clasroom_password),
|
||||||
|
("submitAuth", "".into()),
|
||||||
|
("_qf__formLogin", "".into()),
|
||||||
|
];
|
||||||
|
let client = Client::new();
|
||||||
|
let result = client
|
||||||
|
.post(format!("{}/index.php", clasroom_url))
|
||||||
|
.form(¶ms)
|
||||||
|
.send()
|
||||||
|
.await;
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Ok(response) => {
|
||||||
|
let Some(session_cookie) = response.cookies().find(|c| c.name() == "ch_sid") else {
|
||||||
|
return Err("Response succeeded, but no session cookie was foun".into());
|
||||||
|
};
|
||||||
|
|
||||||
|
match SESSION_COOKIE.set(session_cookie.value().into()) {
|
||||||
|
Ok(_) => Ok(()),
|
||||||
|
Err(error) => Err(format!("Error setting session cookie: {:?}", error)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(error) => Err(format!("Error connecting to online classroom: {:?}", error)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
58
frontend/src/OnlineClassroom/ConnectionStatus.tsx
Normal file
58
frontend/src/OnlineClassroom/ConnectionStatus.tsx
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import { Match, Switch, createSignal, onMount } from "solid-js";
|
||||||
|
|
||||||
|
type ConnectionStatus = "connected" | "connecting" | "disconnected" | "error";
|
||||||
|
export function ClassroomConection() {
|
||||||
|
const [status, setStatus] = createSignal<ConnectionStatus>("disconnected");
|
||||||
|
|
||||||
|
const connectToRemote = () => {
|
||||||
|
setStatus("connecting");
|
||||||
|
|
||||||
|
fetch(`${import.meta.env.VITE_BACKEND_URL}/api/classroom/connect`)
|
||||||
|
.then((response) => {
|
||||||
|
if (response.ok) {
|
||||||
|
setStatus("connected");
|
||||||
|
} else {
|
||||||
|
response.json().then((json) => {
|
||||||
|
console.error(json);
|
||||||
|
setStatus("error");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.error(err);
|
||||||
|
setStatus("error");
|
||||||
|
});
|
||||||
|
|
||||||
|
// setTimeout(() => setStatus("disconnected"), 5000);
|
||||||
|
};
|
||||||
|
|
||||||
|
onMount(connectToRemote);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class="bg-c-surface-variant text-c-on-surface-variant rounded-md p-2 mt-4">
|
||||||
|
Conexión al aula virtual:
|
||||||
|
<Switch fallback={"Desconectado"}>
|
||||||
|
<Match when={status() === "connected"}>
|
||||||
|
<span class="bg-c-success text-c-on-success px-2 rounded select-none font-mono">
|
||||||
|
Conectado
|
||||||
|
</span>
|
||||||
|
</Match>
|
||||||
|
<Match when={status() === "connecting"}>
|
||||||
|
<span class="font-mono" style={{color: "orange"}}>
|
||||||
|
Conectando...
|
||||||
|
</span>
|
||||||
|
</Match>
|
||||||
|
<Match when={status() === "error"}>
|
||||||
|
<span class="bg-c-error text-c-on-error px-2 rounded font-mono">
|
||||||
|
Error
|
||||||
|
</span>
|
||||||
|
</Match>
|
||||||
|
<Match when={status() === "disconnected"}>
|
||||||
|
<span class="bg-c-error-container text-c-on-error-container px-2 rounded font-mono">
|
||||||
|
Desconectado
|
||||||
|
</span>
|
||||||
|
</Match>
|
||||||
|
</Switch>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -1,6 +1,7 @@
|
|||||||
import { Show, createSignal } from "solid-js";
|
import { Show, createSignal } from "solid-js";
|
||||||
import { Search } from "../certs/Search";
|
import { Search } from "../certs/Search";
|
||||||
import { Person } from "../types/Person";
|
import { Person } from "../types/Person";
|
||||||
|
import { ClassroomConection } from "./ConnectionStatus";
|
||||||
|
|
||||||
export function OnlineClassroom() {
|
export function OnlineClassroom() {
|
||||||
const [person, setPerson] = createSignal<Person | null>(null);
|
const [person, setPerson] = createSignal<Person | null>(null);
|
||||||
@ -18,13 +19,7 @@ export function OnlineClassroom() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function ClassroomConection() {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
Connection status
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function ClassroomUsers(props: {person: Person}) {
|
function ClassroomUsers(props: {person: Person}) {
|
||||||
return (
|
return (
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
--c-green-outline: #8d9387;
|
--c-green-outline: #8d9387;
|
||||||
--c-green-surface-variant: #43483f;
|
--c-green-surface-variant: #43483f;
|
||||||
--c-green-on-surface-variant: #c3c8bc;
|
--c-green-on-surface-variant: #c3c8bc;
|
||||||
|
|
||||||
|
--c-green-success: #adc6ff;
|
||||||
|
--c-green-on-success: #002e69;
|
||||||
}
|
}
|
||||||
@media (prefers-color-scheme: light) {
|
@media (prefers-color-scheme: light) {
|
||||||
:root {
|
:root {
|
||||||
|
Loading…
Reference in New Issue
Block a user