[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"
|
||||
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]]
|
||||
name = "cookie"
|
||||
version = "0.17.0"
|
||||
@ -248,6 +259,23 @@ dependencies = [
|
||||
"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]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.3"
|
||||
@ -828,6 +856,27 @@ dependencies = [
|
||||
"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]]
|
||||
name = "idna"
|
||||
version = "0.4.0"
|
||||
@ -984,6 +1033,12 @@ dependencies = [
|
||||
"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]]
|
||||
name = "md-5"
|
||||
version = "0.10.5"
|
||||
@ -1366,6 +1421,22 @@ dependencies = [
|
||||
"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]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
@ -1486,6 +1557,8 @@ checksum = "3e9ad3fe7488d7e34558a2033d45a0c90b72d97b4f80705666fea71472e2e6a1"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bytes",
|
||||
"cookie 0.16.2",
|
||||
"cookie_store",
|
||||
"encoding_rs",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
@ -1615,7 +1688,7 @@ version = "0.5.0-rc.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "936012c99162a03a67f37f9836d5f938f662e26f2717809761a9ac46432090f4"
|
||||
dependencies = [
|
||||
"cookie",
|
||||
"cookie 0.17.0",
|
||||
"either",
|
||||
"futures",
|
||||
"http",
|
||||
@ -2552,7 +2625,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
|
||||
dependencies = [
|
||||
"form_urlencoded",
|
||||
"idna",
|
||||
"idna 0.4.0",
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
|
@ -6,7 +6,7 @@ edition = "2021"
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[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"] }
|
||||
sqlx = { version = "0.7.1", features = [ "runtime-tokio", "tls-rustls", "mysql", "macros", "chrono" ] }
|
||||
once_cell = "1.18.0"
|
||||
|
@ -50,6 +50,10 @@ async fn rocket() -> _ {
|
||||
controller::register::get_by_dni,
|
||||
controller::register::delete,
|
||||
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 { Search } from "../certs/Search";
|
||||
import { Person } from "../types/Person";
|
||||
import { ClassroomConection } from "./ConnectionStatus";
|
||||
|
||||
export function OnlineClassroom() {
|
||||
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}) {
|
||||
return (
|
||||
|
@ -17,6 +17,9 @@
|
||||
--c-green-outline: #8d9387;
|
||||
--c-green-surface-variant: #43483f;
|
||||
--c-green-on-surface-variant: #c3c8bc;
|
||||
|
||||
--c-green-success: #adc6ff;
|
||||
--c-green-on-success: #002e69;
|
||||
}
|
||||
@media (prefers-color-scheme: light) {
|
||||
:root {
|
||||
|
Loading…
Reference in New Issue
Block a user