mirror of
https://github.com/n08i40k/schedule-parser-rusted.git
synced 2025-12-06 09:47:50 +03:00
Compare commits
5 Commits
d1ef5c032e
...
dependabot
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7b2f9cb684 | ||
|
2442641479
|
|||
|
ac16c96e5e
|
|||
|
622464e4c3
|
|||
|
39c60ef939
|
3
.github/workflows/build.yml
vendored
3
.github/workflows/build.yml
vendored
@@ -140,3 +140,6 @@ jobs:
|
||||
cache-to: type=gha,mode=max
|
||||
build-args: |
|
||||
"BINARY_NAME=${{ env.BINARY_NAME }}"
|
||||
|
||||
- name: Deploy
|
||||
run: curl ${{ secrets.DEPLOY_URL }}
|
||||
|
||||
83
Cargo.lock
generated
83
Cargo.lock
generated
@@ -534,11 +534,10 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "axum"
|
||||
version = "0.7.9"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edca88bc138befd0323b20752846e6587272d3b03b0343c8ea28a6f819e6e71f"
|
||||
checksum = "8a18ed336352031311f4e0b4dd2ff392d4fbb370777c9d18d7fc9d7359f73871"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"axum-core",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
@@ -551,29 +550,26 @@ dependencies = [
|
||||
"mime",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustversion",
|
||||
"serde",
|
||||
"serde_core",
|
||||
"sync_wrapper",
|
||||
"tower 0.5.2",
|
||||
"tower",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "axum-core"
|
||||
version = "0.4.5"
|
||||
version = "0.5.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09f2bd6146b97ae3359fa0cc6d6b376d9539582c7b4220f041a33ec24c226199"
|
||||
checksum = "59446ce19cd142f8833f856eb31f3eb097812d1479ab224f54d72428ca21ea22"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"futures-core",
|
||||
"http 1.3.1",
|
||||
"http-body",
|
||||
"http-body-util",
|
||||
"mime",
|
||||
"pin-project-lite",
|
||||
"rustversion",
|
||||
"sync_wrapper",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
@@ -969,22 +965,23 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "console-api"
|
||||
version = "0.8.1"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8030735ecb0d128428b64cd379809817e620a40e5001c54465b99ec5feec2857"
|
||||
checksum = "e8599749b6667e2f0c910c1d0dff6901163ff698a52d5a39720f61b5be4b20d3"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"prost",
|
||||
"prost-types",
|
||||
"tonic",
|
||||
"tonic-prost",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "console-subscriber"
|
||||
version = "0.4.1"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6539aa9c6a4cd31f4b1c040f860a1eac9aa80e7df6b05d506a6e7179936d6a01"
|
||||
checksum = "fb4915b7d8dd960457a1b6c380114c2944f728e7c65294ab247ae6b6f1f37592"
|
||||
dependencies = [
|
||||
"console-api",
|
||||
"crossbeam-channel",
|
||||
@@ -2523,9 +2520,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "matchit"
|
||||
version = "0.7.3"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
|
||||
checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
|
||||
|
||||
[[package]]
|
||||
name = "md-5"
|
||||
@@ -3061,9 +3058,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "prost"
|
||||
version = "0.13.5"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2796faa41db3ec313a31f7624d9286acf277b52de526150b7e69f3debf891ee5"
|
||||
checksum = "7231bd9b3d3d33c86b58adbac74b5ec0ad9f496b19d22801d773636feaa95f3d"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"prost-derive",
|
||||
@@ -3071,9 +3068,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "prost-derive"
|
||||
version = "0.13.5"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a56d757972c98b346a9b766e3f02746cde6dd1cd1d1d563472929fdd74bec4d"
|
||||
checksum = "9120690fafc389a67ba3803df527d0ec9cbbc9cc45e4cc20b332996dfb672425"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools",
|
||||
@@ -3084,9 +3081,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "prost-types"
|
||||
version = "0.13.5"
|
||||
version = "0.14.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52c2c1bf36ddb1a1c396b3601a3cec27c2462e45f07c386894ec3ccf5332bd16"
|
||||
checksum = "b9b4db3d6da204ed77bb26ba83b6122a73aeb2e87e25fbf7ad2e84c4ccbf8f72"
|
||||
dependencies = [
|
||||
"prost",
|
||||
]
|
||||
@@ -3389,7 +3386,7 @@ dependencies = [
|
||||
"sync_wrapper",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tower 0.5.2",
|
||||
"tower",
|
||||
"tower-http",
|
||||
"tower-service",
|
||||
"url",
|
||||
@@ -4802,11 +4799,10 @@ checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2"
|
||||
|
||||
[[package]]
|
||||
name = "tonic"
|
||||
version = "0.12.3"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877c5b330756d856ffcc4553ab34a5684481ade925ecc54bcd1bf02b1d0d4d52"
|
||||
checksum = "eb7613188ce9f7df5bfe185db26c5814347d110db17920415cf2fbcad85e7203"
|
||||
dependencies = [
|
||||
"async-stream",
|
||||
"async-trait",
|
||||
"axum",
|
||||
"base64 0.22.1",
|
||||
@@ -4820,34 +4816,25 @@ dependencies = [
|
||||
"hyper-util",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"prost",
|
||||
"socket2 0.5.10",
|
||||
"socket2 0.6.1",
|
||||
"sync_wrapper",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
"tower 0.4.13",
|
||||
"tower",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower"
|
||||
version = "0.4.13"
|
||||
name = "tonic-prost"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
|
||||
checksum = "66bd50ad6ce1252d87ef024b3d64fe4c3cf54a86fb9ef4c631fdd0ded7aeaa67"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"indexmap 1.9.3",
|
||||
"pin-project",
|
||||
"pin-project-lite",
|
||||
"rand 0.8.5",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
"bytes",
|
||||
"prost",
|
||||
"tonic",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4858,11 +4845,15 @@ checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"indexmap 2.12.0",
|
||||
"pin-project-lite",
|
||||
"slab",
|
||||
"sync_wrapper",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4878,7 +4869,7 @@ dependencies = [
|
||||
"http-body",
|
||||
"iri-string",
|
||||
"pin-project-lite",
|
||||
"tower 0.5.2",
|
||||
"tower",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
@@ -103,6 +103,9 @@ pub enum LessonType {
|
||||
|
||||
/// Практическое занятие.
|
||||
Practice,
|
||||
|
||||
/// Дифференцированный зачёт.
|
||||
DifferentiatedExam,
|
||||
}
|
||||
|
||||
#[derive(Clone, Hash, Debug, Serialize, Deserialize, ToSchema)]
|
||||
|
||||
@@ -187,6 +187,7 @@ fn guess_lesson_type(text: &str) -> Option<LessonType> {
|
||||
("курсовой проект", LessonType::CourseProject),
|
||||
("защита курсового проекта", LessonType::CourseProjectDefense),
|
||||
("практическое занятие", LessonType::Practice),
|
||||
("дифференцированный зачет", LessonType::DifferentiatedExam),
|
||||
])
|
||||
});
|
||||
|
||||
|
||||
17
src/main.rs
17
src/main.rs
@@ -50,7 +50,22 @@ pub fn get_api_scope<
|
||||
.service(routes::auth::sign_up_vk);
|
||||
|
||||
let users_scope = utoipa_actix_web::scope("/users")
|
||||
.wrap(JWTAuthorizationBuilder::new().build())
|
||||
.wrap(
|
||||
JWTAuthorizationBuilder::new()
|
||||
.add_paths(
|
||||
["/by/id/{id}", "/by/telegram-id/{id}"],
|
||||
Some(ServiceConfig {
|
||||
allow_service: true,
|
||||
user_roles: Some(&[UserRole::Admin]),
|
||||
}),
|
||||
)
|
||||
.build(),
|
||||
)
|
||||
.service(
|
||||
utoipa_actix_web::scope("/by")
|
||||
.service(routes::users::by::by_id)
|
||||
.service(routes::users::by::by_telegram_id),
|
||||
)
|
||||
.service(routes::users::change_group)
|
||||
.service(routes::users::change_username)
|
||||
.service(routes::users::me);
|
||||
|
||||
@@ -5,13 +5,13 @@ use actix_web::body::{BoxBody, EitherBody};
|
||||
use actix_web::dev::{forward_ready, Service, ServiceRequest, ServiceResponse, Transform};
|
||||
use actix_web::{web, Error, HttpRequest, ResponseError};
|
||||
use database::entity::sea_orm_active_enums::UserRole;
|
||||
use database::entity::UserType;
|
||||
use database::query::Query;
|
||||
use futures_util::future::LocalBoxFuture;
|
||||
use std::future::{ready, Ready};
|
||||
use std::ops::Deref;
|
||||
use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
use database::entity::UserType;
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub struct ServiceConfig {
|
||||
@@ -42,7 +42,11 @@ impl JWTAuthorizationBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_paths(mut self, paths: impl AsRef<[&'static str]>, config: Option<ServiceConfig>) -> Self {
|
||||
pub fn add_paths(
|
||||
mut self,
|
||||
paths: impl AsRef<[&'static str]>,
|
||||
config: Option<ServiceConfig>,
|
||||
) -> Self {
|
||||
self.path_configs.push((Arc::from(paths.as_ref()), config));
|
||||
self
|
||||
}
|
||||
@@ -176,11 +180,20 @@ where
|
||||
fn call(&self, req: ServiceRequest) -> Self::Future {
|
||||
let service = Rc::clone(&self.service);
|
||||
|
||||
let Some(config) = Self::find_config(
|
||||
req.match_info().unprocessed(),
|
||||
&self.path_configs,
|
||||
&self.default_config,
|
||||
) else {
|
||||
let match_info = req.match_info();
|
||||
let path = if let Some(pattern) = req.match_pattern() {
|
||||
let scope_start_idx = match_info
|
||||
.as_str()
|
||||
.find(match_info.unprocessed())
|
||||
.unwrap_or(0);
|
||||
|
||||
pattern.as_str().split_at(scope_start_idx).1.to_owned()
|
||||
} else {
|
||||
match_info.unprocessed().to_owned()
|
||||
};
|
||||
|
||||
let Some(config) = Self::find_config(&path, &self.path_configs, &self.default_config)
|
||||
else {
|
||||
let fut = self.service.call(req);
|
||||
return Box::pin(async move { Ok(fut.await?.map_into_left_body()) });
|
||||
};
|
||||
|
||||
@@ -163,6 +163,7 @@ pub mod user {
|
||||
#[schema(examples(
|
||||
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IjY3ZGNjOWE5NTA3YjAwMDA3NzI3NDRhMiIsImlhdCI6IjE3NDMxMDgwOTkiLCJleHAiOiIxODY5MjUyMDk5In0.rMgXRb3JbT9AvLK4eiY9HMB5LxgUudkpQyoWKOypZFY"
|
||||
))]
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
pub access_token: Option<String>,
|
||||
}
|
||||
|
||||
|
||||
56
src/routes/users/by.rs
Normal file
56
src/routes/users/by.rs
Normal file
@@ -0,0 +1,56 @@
|
||||
use crate::routes::schema::user::UserResponse;
|
||||
use crate::routes::users::by::schema::{ErrorCode, ServiceResponse};
|
||||
use crate::state::AppState;
|
||||
use actix_web::{get, web};
|
||||
use database::query::Query;
|
||||
|
||||
#[utoipa::path(responses((status = OK, body = UserResponse)))]
|
||||
#[get("/id/{id}")]
|
||||
pub async fn by_id(app_state: web::Data<AppState>, path: web::Path<String>) -> ServiceResponse {
|
||||
let user_id = path.into_inner();
|
||||
|
||||
let db = app_state.get_database();
|
||||
|
||||
match Query::find_user_by_id(db, &user_id).await {
|
||||
Ok(Some(user)) => Ok(UserResponse::from(user)),
|
||||
_ => Err(ErrorCode::NotFound),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
#[utoipa::path(responses((status = OK, body = UserResponse)))]
|
||||
#[get("/telegram-id/{id}")]
|
||||
pub async fn by_telegram_id(
|
||||
app_state: web::Data<AppState>,
|
||||
path: web::Path<i64>,
|
||||
) -> ServiceResponse {
|
||||
let telegram_id = path.into_inner();
|
||||
|
||||
let db = app_state.get_database();
|
||||
|
||||
match Query::find_user_by_telegram_id(db, telegram_id).await {
|
||||
Ok(Some(user)) => Ok(UserResponse::from(user)),
|
||||
_ => Err(ErrorCode::NotFound),
|
||||
}
|
||||
.into()
|
||||
}
|
||||
|
||||
mod schema {
|
||||
use crate::routes::schema::user::UserResponse;
|
||||
use actix_macros::ErrResponse;
|
||||
use derive_more::Display;
|
||||
use serde::Serialize;
|
||||
use utoipa::ToSchema;
|
||||
|
||||
pub type ServiceResponse = crate::routes::schema::Response<UserResponse, ErrorCode>;
|
||||
|
||||
#[derive(Clone, Serialize, Display, ToSchema, ErrResponse)]
|
||||
#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
|
||||
#[schema(as = Users::By::ErrorCode)]
|
||||
pub enum ErrorCode {
|
||||
/// User not found.
|
||||
#[status_code = "actix_web::http::StatusCode::NOT_FOUND"]
|
||||
#[display("Required user not found.")]
|
||||
NotFound,
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,4 @@
|
||||
pub mod by;
|
||||
mod change_group;
|
||||
mod change_username;
|
||||
mod me;
|
||||
|
||||
Reference in New Issue
Block a user