feat: update to actix-web 2.0 and implement restful api
This commit is contained in:
parent
941388aceb
commit
6e91d2ce55
2236
Cargo.lock
generated
2236
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
50
Cargo.toml
50
Cargo.toml
@ -7,38 +7,40 @@ license = "MIT"
|
|||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
dotenv = "0.14.1"
|
dotenv = "0.15.0"
|
||||||
lazy_static = "1.3.0"
|
openssl = "0.10.27"
|
||||||
openssl = "0.10.23"
|
|
||||||
|
|
||||||
# serde
|
# serde
|
||||||
serde = "1.0.92"
|
serde = "1.0.104"
|
||||||
serde_derive = "1.0.92"
|
serde_derive = "1.0.104"
|
||||||
|
|
||||||
r2d2 = "0.8.5"
|
r2d2 = "0.8.8"
|
||||||
diesel = { version = "1.4.2", features = ["postgres", "r2d2", "chrono"] }
|
diesel = { version = "1.4.3", features = ["postgres", "r2d2", "chrono"] }
|
||||||
diesel_derives = "1.4.0"
|
diesel_derives = "1.4.1"
|
||||||
diesel_migrations = "1.4.0"
|
diesel_migrations = "1.4.0"
|
||||||
|
|
||||||
tera = "0.11.20"
|
tera = "1.0.2"
|
||||||
pulldown-cmark = { version = "0.5.2", default-features = false }
|
pulldown-cmark = { version = "0.6.1", default-features = false }
|
||||||
|
|
||||||
chrono = { version = "0.4.6", features = ["serde"] }
|
chrono = { version = "0.4.10", features = ["serde"] }
|
||||||
rust-crypto = "0.2.36"
|
rust-crypto = "0.2.36"
|
||||||
|
|
||||||
http = "0.1.17"
|
http = "0.2.0"
|
||||||
actix-web= "1.0.2"
|
actix-web= "2.0.0"
|
||||||
actix-files = "0.1.2"
|
actix-files = "0.2.1"
|
||||||
futures = "0.1.27"
|
futures = "0.3.1"
|
||||||
|
|
||||||
# log
|
# log
|
||||||
log = "0.4.6"
|
log = "0.4.8"
|
||||||
pretty_env_logger = "0.3.0"
|
pretty_env_logger = "0.4.0"
|
||||||
|
|
||||||
time = "0.1.42"
|
time = "0.1"
|
||||||
rand = "0.6.5"
|
rand = "0.7.3"
|
||||||
rss = "1.8.0"
|
rss = "1.9.0"
|
||||||
actix = "0.8.3"
|
actix = "0.9.0"
|
||||||
jsonwebtoken = "6.0.1"
|
jsonwebtoken = "7.0.1"
|
||||||
actix-cors = "0.1.0"
|
actix-cors = "0.2.0"
|
||||||
actix-identity = "0.1.0"
|
|
||||||
|
actix-rt = "1.0.0"
|
||||||
|
once_cell = "1.3.1"
|
||||||
|
derive_more = "0.99.2"
|
||||||
|
41
src/error.rs
Normal file
41
src/error.rs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
use actix_web::error::ResponseError;
|
||||||
|
use derive_more::Display;
|
||||||
|
use actix_web::body::Body;
|
||||||
|
use http::{StatusCode};
|
||||||
|
use actix_web::HttpResponse;
|
||||||
|
use serde::Serialize;
|
||||||
|
use std::fmt::Debug;
|
||||||
|
|
||||||
|
#[derive(Debug, Display)]
|
||||||
|
pub enum RubbleError<T> {
|
||||||
|
Unauthorized(T),
|
||||||
|
BadRequest(T),
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize)]
|
||||||
|
struct ErrorMsg<T> {
|
||||||
|
message: T
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
impl<T> ResponseError for RubbleError<T> where T: Debug + std::fmt::Display + Serialize {
|
||||||
|
fn status_code(&self) -> StatusCode {
|
||||||
|
match self {
|
||||||
|
RubbleError::Unauthorized(_) => StatusCode::UNAUTHORIZED,
|
||||||
|
RubbleError::BadRequest(_) => StatusCode::BAD_REQUEST
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn error_response(&self) -> HttpResponse {
|
||||||
|
match self {
|
||||||
|
RubbleError::Unauthorized(message) => {
|
||||||
|
HttpResponse::Unauthorized().json(&ErrorMsg{message})
|
||||||
|
},
|
||||||
|
RubbleError::BadRequest(message) => {
|
||||||
|
HttpResponse::BadRequest().json(&ErrorMsg{message})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
57
src/main.rs
57
src/main.rs
@ -1,26 +1,23 @@
|
|||||||
extern crate openssl;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate diesel;
|
extern crate diesel;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate diesel_derives;
|
extern crate diesel_derives;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate diesel_migrations;
|
extern crate diesel_migrations;
|
||||||
|
extern crate openssl;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use actix_identity::{CookieIdentityPolicy, IdentityService};
|
|
||||||
use actix_web::{
|
|
||||||
middleware::{Logger, NormalizePath},
|
|
||||||
web::{FormConfig, JsonConfig},
|
|
||||||
App, HttpServer,
|
|
||||||
};
|
|
||||||
|
|
||||||
use actix_cors::Cors;
|
use actix_cors::Cors;
|
||||||
use tera::compile_templates;
|
use actix_web::{
|
||||||
use time::Duration;
|
App,
|
||||||
|
HttpServer,
|
||||||
|
middleware::{Logger, NormalizePath}, web::{FormConfig, JsonConfig},
|
||||||
|
};
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
|
use tera::Tera;
|
||||||
|
|
||||||
use dotenv::dotenv;
|
use dotenv::dotenv;
|
||||||
use lazy_static::lazy_static;
|
|
||||||
|
|
||||||
use crate::{data::RubbleData, pg_pool::database_pool_establish};
|
use crate::{data::RubbleData, pg_pool::database_pool_establish};
|
||||||
|
|
||||||
@ -30,47 +27,47 @@ mod pg_pool;
|
|||||||
mod routers;
|
mod routers;
|
||||||
mod schema;
|
mod schema;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
mod error;
|
||||||
|
|
||||||
embed_migrations!();
|
embed_migrations!();
|
||||||
|
|
||||||
lazy_static! {
|
const TOKEN_KEY: Lazy<Vec<u8>> = Lazy::new(|| {
|
||||||
static ref RANDOM_TOKEN_KEY: Vec<u8> = (0..32).map(|_| rand::random::<u8>()).collect();
|
std::env::var("TOKEN_KEY")
|
||||||
}
|
.map(|token| Vec::from(token.as_bytes()))
|
||||||
|
.unwrap_or_else(|_| (0..32).into_iter().map(|_| rand::random::<u8>()).collect())
|
||||||
|
});
|
||||||
|
|
||||||
fn main() {
|
#[actix_rt::main]
|
||||||
|
async fn main() {
|
||||||
dotenv().ok();
|
dotenv().ok();
|
||||||
let sys = actix::System::new("rubble");
|
|
||||||
pretty_env_logger::init();
|
pretty_env_logger::init();
|
||||||
|
|
||||||
let database_url = std::env::var("DATABASE_URL").expect("database_url must be set");
|
let database_url = std::env::var("DATABASE_URL").expect("database_url must be set");
|
||||||
|
|
||||||
let data = RubbleData {
|
let data = RubbleData {
|
||||||
pool: database_pool_establish(&database_url),
|
pool: database_pool_establish(&database_url),
|
||||||
tera: Arc::new(compile_templates!("templates/**/*.html")),
|
tera: Arc::new(Tera::new("templates/**/*.html").unwrap()),
|
||||||
};
|
};
|
||||||
|
|
||||||
embedded_migrations::run(&data.pool.get().expect("cannot get connection"))
|
embedded_migrations::run(&data.pool.get().expect("cannot get connection"))
|
||||||
.expect("panic on embedded database migration");
|
.expect("panic on embedded database migration");
|
||||||
|
|
||||||
|
println!("rubble is listening on 127.0.0.1:8000");
|
||||||
|
|
||||||
HttpServer::new(move || {
|
HttpServer::new(move || {
|
||||||
App::new()
|
App::new()
|
||||||
|
.app_data(data.clone())
|
||||||
.data(data.clone())
|
.data(data.clone())
|
||||||
.data(JsonConfig::default().limit(256_000))
|
.data(JsonConfig::default().limit(256_000))
|
||||||
.data(FormConfig::default().limit(256_000))
|
.data(FormConfig::default().limit(256_000))
|
||||||
.wrap(Logger::default())
|
.wrap(Logger::default())
|
||||||
.wrap(Cors::default())
|
.wrap(Cors::default())
|
||||||
.wrap(NormalizePath)
|
.wrap(NormalizePath)
|
||||||
.wrap(IdentityService::new(
|
.configure(routers::routes)
|
||||||
CookieIdentityPolicy::new(&RANDOM_TOKEN_KEY)
|
|
||||||
.name("auth-cookie")
|
|
||||||
.secure(false)
|
|
||||||
.max_age_time(Duration::days(3)),
|
|
||||||
))
|
|
||||||
.service(routers::routes())
|
|
||||||
})
|
})
|
||||||
.bind(("0.0.0.0", 8000))
|
.bind(("0.0.0.0", 8000))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.system_exit()
|
.run()
|
||||||
.start();
|
.await
|
||||||
|
.unwrap()
|
||||||
sys.run().expect("wrong on actix system run")
|
|
||||||
}
|
}
|
||||||
|
@ -1,17 +1,16 @@
|
|||||||
use crate::models::CRUD;
|
use actix_web::{dev::Payload, error, FromRequest, HttpRequest};
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
use diesel::{pg::PgConnection, result::Error};
|
|
||||||
|
|
||||||
use crate::schema::users;
|
|
||||||
use crypto::{digest::Digest, sha3::Sha3};
|
use crypto::{digest::Digest, sha3::Sha3};
|
||||||
use diesel::prelude::*;
|
use diesel::{pg::PgConnection, result::Error};
|
||||||
|
|
||||||
use diesel::{AsChangeset, Insertable, Queryable};
|
use diesel::{AsChangeset, Insertable, Queryable};
|
||||||
|
use diesel::prelude::*;
|
||||||
|
use futures::future::{err, ok, Ready};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::{data::RubbleData, utils::jwt::JWTClaims};
|
use crate::{data::RubbleData, utils::jwt::JWTClaims};
|
||||||
use actix_web::{dev::Payload, error, FromRequest, HttpRequest};
|
use crate::models::CRUD;
|
||||||
use futures::IntoFuture;
|
use crate::schema::users;
|
||||||
|
use crate::error::RubbleError;
|
||||||
|
|
||||||
#[derive(Queryable, Debug, Serialize, Insertable, AsChangeset)]
|
#[derive(Queryable, Debug, Serialize, Insertable, AsChangeset)]
|
||||||
#[table_name = "users"]
|
#[table_name = "users"]
|
||||||
@ -69,30 +68,42 @@ impl CRUD<(), User, i32> for User {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl FromRequest for User {
|
impl FromRequest for User {
|
||||||
|
type Error = RubbleError<&'static str>;
|
||||||
|
type Future = Ready<Result<Self, Self::Error>>;
|
||||||
type Config = ();
|
type Config = ();
|
||||||
type Error = actix_web::error::Error;
|
|
||||||
type Future = Result<Self, Self::Error>;
|
|
||||||
|
|
||||||
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
|
fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
|
||||||
let tokens: Vec<&str> = req
|
|
||||||
|
let data = req.app_data::<RubbleData>().expect("cannot get app data");
|
||||||
|
let user = req
|
||||||
.headers()
|
.headers()
|
||||||
.get("Authorization")
|
.get("Authorization")
|
||||||
.ok_or(error::ErrorUnauthorized("cannot find authorization header"))?
|
.ok_or(RubbleError::Unauthorized("cannot find authorization header"))
|
||||||
.to_str()
|
.and_then(|header| {
|
||||||
.map_err(|_| error::ErrorBadRequest("error on deserialize token"))?
|
header.to_str().map_err(|_| RubbleError::BadRequest("error on deserialize token"))
|
||||||
.splitn(2, ' ')
|
})
|
||||||
.collect();
|
.map(|header| header.splitn(2, ' ').collect::<Vec<&str>>())
|
||||||
|
.and_then(|tokens| {
|
||||||
|
if tokens.len() == 2 {
|
||||||
|
Ok(tokens[1])
|
||||||
|
}else {
|
||||||
|
Err(RubbleError::BadRequest("error on deserialize token"))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.and_then(|jwt| {
|
||||||
|
JWTClaims::decode(jwt.into()).map_err(|_| RubbleError::Unauthorized("invalid jwt token"))
|
||||||
|
})
|
||||||
|
.and_then(|user_id| {
|
||||||
|
User::find_by_username(&data.postgres(), &user_id)
|
||||||
|
.map_err(|_| RubbleError::Unauthorized("error on get user"))
|
||||||
|
});
|
||||||
|
|
||||||
let user_id = JWTClaims::decode(tokens[1].into())
|
|
||||||
.map_err(|_| error::ErrorUnauthorized("invalid jwt token"))?;
|
|
||||||
let data = req
|
|
||||||
.app_data::<RubbleData>()
|
|
||||||
.ok_or(error::ErrorBadGateway("error on get rubble data"))?;
|
|
||||||
|
|
||||||
let result = User::find_by_username(&data.postgres(), &user_id)
|
match user {
|
||||||
.map_err(|_| error::ErrorUnauthorized("error on get user"))?;
|
Ok(user) => ok(user),
|
||||||
|
Err(e) => err(e)
|
||||||
|
}
|
||||||
|
|
||||||
Ok(result)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
use actix_identity::Identity;
|
|
||||||
use actix_web::{
|
use actix_web::{
|
||||||
get, post,
|
get, post,
|
||||||
web::{self, Form},
|
web::{self, Form},
|
||||||
@ -33,231 +32,232 @@ pub struct NewPassword {
|
|||||||
password: String,
|
password: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("")]
|
//
|
||||||
pub fn redirect_to_admin_panel() -> impl Responder {
|
//#[get("")]
|
||||||
RubbleResponder::redirect("/admin/panel")
|
//pub fn redirect_to_admin_panel() -> impl Responder {
|
||||||
}
|
// RubbleResponder::redirect("/admin/panel")
|
||||||
|
//}
|
||||||
#[get("/login")]
|
//
|
||||||
pub fn admin_login(id: Identity, data: web::Data<RubbleData>) -> impl Responder {
|
//#[get("/login")]
|
||||||
if id.identity().is_some() {
|
//pub fn admin_login(id: Identity, data: web::Data<RubbleData>) -> impl Responder {
|
||||||
RubbleResponder::redirect("/admin/panel")
|
// if id.identity().is_some() {
|
||||||
} else {
|
// RubbleResponder::redirect("/admin/panel")
|
||||||
RubbleResponder::html(data.render("admin/login.html", &Context::new()))
|
// } else {
|
||||||
}
|
// RubbleResponder::html(data.render("admin/login.html", &Context::new()))
|
||||||
}
|
// }
|
||||||
|
//}
|
||||||
#[post("/login")]
|
//
|
||||||
pub fn admin_authentication(
|
//#[post("/login")]
|
||||||
id: Identity,
|
//pub fn admin_authentication(
|
||||||
user: Form<LoginForm>,
|
// id: Identity,
|
||||||
data: web::Data<RubbleData>,
|
// user: Form<LoginForm>,
|
||||||
) -> impl Responder {
|
// data: web::Data<RubbleData>,
|
||||||
let fetched_user = User::find_by_username(&data.postgres(), &user.username);
|
//) -> impl Responder {
|
||||||
|
// let fetched_user = User::find_by_username(&data.postgres(), &user.username);
|
||||||
match fetched_user {
|
//
|
||||||
Ok(login_user) => {
|
// match fetched_user {
|
||||||
if login_user.authenticated(&user.password) {
|
// Ok(login_user) => {
|
||||||
id.remember(login_user.username);
|
// if login_user.authenticated(&user.password) {
|
||||||
|
// id.remember(login_user.username);
|
||||||
RubbleResponder::redirect("/admin/panel")
|
//
|
||||||
} else {
|
// RubbleResponder::redirect("/admin/panel")
|
||||||
RubbleResponder::redirect("/admin/login")
|
// } else {
|
||||||
}
|
// RubbleResponder::redirect("/admin/login")
|
||||||
}
|
// }
|
||||||
Err(_) => RubbleResponder::redirect("/admin/login"),
|
// }
|
||||||
}
|
// Err(_) => RubbleResponder::redirect("/admin/login"),
|
||||||
}
|
// }
|
||||||
|
//}
|
||||||
#[get("/panel")]
|
//
|
||||||
pub fn admin_panel(id: Identity, data: web::Data<RubbleData>) -> impl Responder {
|
//#[get("/panel")]
|
||||||
if id.identity().is_none() {
|
//pub fn admin_panel(id: Identity, data: web::Data<RubbleData>) -> impl Responder {
|
||||||
return RubbleResponder::redirect("/admin/login");
|
// if id.identity().is_none() {
|
||||||
}
|
// return RubbleResponder::redirect("/admin/login");
|
||||||
|
// }
|
||||||
let articles = Article::read(&data.postgres());
|
//
|
||||||
let settings = Setting::load(&data.postgres());
|
// let articles = Article::read(&data.postgres());
|
||||||
|
// let settings = Setting::load(&data.postgres());
|
||||||
let admin = User::find_by_username(&data.postgres(), &id.identity().unwrap())
|
//
|
||||||
.expect("cannot found this user");
|
// let admin = User::find_by_username(&data.postgres(), &id.identity().unwrap())
|
||||||
|
// .expect("cannot found this user");
|
||||||
let mut context = Context::new();
|
//
|
||||||
context.insert("setting", &settings);
|
// let mut context = Context::new();
|
||||||
context.insert("articles", &articles);
|
// context.insert("setting", &settings);
|
||||||
context.insert("admin", &admin);
|
// context.insert("articles", &articles);
|
||||||
|
// context.insert("admin", &admin);
|
||||||
RubbleResponder::html(data.render("admin/panel.html", &context))
|
//
|
||||||
}
|
// RubbleResponder::html(data.render("admin/panel.html", &context))
|
||||||
|
//}
|
||||||
#[get("/{path}")]
|
//
|
||||||
pub fn admin_show_page(
|
//#[get("/{path}")]
|
||||||
id: Identity,
|
//pub fn admin_show_page(
|
||||||
path: web::Path<String>,
|
// id: Identity,
|
||||||
data: web::Data<RubbleData>,
|
// path: web::Path<String>,
|
||||||
) -> impl Responder {
|
// data: web::Data<RubbleData>,
|
||||||
if id.identity().is_none() {
|
//) -> impl Responder {
|
||||||
return RubbleResponder::redirect("/admin/login");
|
// if id.identity().is_none() {
|
||||||
}
|
// return RubbleResponder::redirect("/admin/login");
|
||||||
|
// }
|
||||||
let settings = Setting::load(&data.postgres());
|
//
|
||||||
|
// let settings = Setting::load(&data.postgres());
|
||||||
let admin = User::find_by_username(&data.postgres(), &id.identity().unwrap())
|
//
|
||||||
.expect("cannot found this user");
|
// let admin = User::find_by_username(&data.postgres(), &id.identity().unwrap())
|
||||||
|
// .expect("cannot found this user");
|
||||||
let mut context = Context::new();
|
//
|
||||||
context.insert("setting", &settings);
|
// let mut context = Context::new();
|
||||||
context.insert("admin", &admin);
|
// context.insert("setting", &settings);
|
||||||
RubbleResponder::html(data.render(&format!("admin/{}.html", path), &context))
|
// context.insert("admin", &admin);
|
||||||
}
|
// RubbleResponder::html(data.render(&format!("admin/{}.html", path), &context))
|
||||||
|
//}
|
||||||
#[get("/article/new")]
|
//
|
||||||
pub fn article_creation(id: Identity, data: web::Data<RubbleData>) -> impl Responder {
|
//#[get("/article/new")]
|
||||||
if id.identity().is_none() {
|
//pub fn article_creation(id: Identity, data: web::Data<RubbleData>) -> impl Responder {
|
||||||
return RubbleResponder::redirect("/admin/login");
|
// if id.identity().is_none() {
|
||||||
}
|
// return RubbleResponder::redirect("/admin/login");
|
||||||
let settings = Setting::load(&data.postgres());
|
// }
|
||||||
let admin = User::find_by_username(&data.postgres(), &id.identity().unwrap())
|
// let settings = Setting::load(&data.postgres());
|
||||||
.expect("cannot found this user");
|
// let admin = User::find_by_username(&data.postgres(), &id.identity().unwrap())
|
||||||
|
// .expect("cannot found this user");
|
||||||
let mut context = Context::new();
|
//
|
||||||
|
// let mut context = Context::new();
|
||||||
let article = NewArticle {
|
//
|
||||||
title: String::new(),
|
// let article = NewArticle {
|
||||||
body: String::new(),
|
// title: String::new(),
|
||||||
published: true,
|
// body: String::new(),
|
||||||
user_id: admin.id,
|
// published: true,
|
||||||
publish_at: Some(NaiveDateTime::from_timestamp(Utc::now().timestamp(), 0)),
|
// user_id: admin.id,
|
||||||
url: None,
|
// publish_at: Some(NaiveDateTime::from_timestamp(Utc::now().timestamp(), 0)),
|
||||||
keywords: vec![],
|
// url: None,
|
||||||
};
|
// keywords: vec![],
|
||||||
|
// };
|
||||||
context.insert("article", &article);
|
//
|
||||||
context.insert("setting", &settings);
|
// context.insert("article", &article);
|
||||||
context.insert("admin", &admin);
|
// context.insert("setting", &settings);
|
||||||
|
// context.insert("admin", &admin);
|
||||||
RubbleResponder::html(data.render("admin/article_add.html", &context))
|
//
|
||||||
}
|
// RubbleResponder::html(data.render("admin/article_add.html", &context))
|
||||||
|
//}
|
||||||
#[get("/article/{article_id}")]
|
//
|
||||||
pub fn article_edit(
|
//#[get("/article/{article_id}")]
|
||||||
id: Identity,
|
//pub fn article_edit(
|
||||||
article_id: web::Path<i32>,
|
// id: Identity,
|
||||||
data: web::Data<RubbleData>,
|
// article_id: web::Path<i32>,
|
||||||
) -> impl Responder {
|
// data: web::Data<RubbleData>,
|
||||||
if id.identity().is_none() {
|
//) -> impl Responder {
|
||||||
return RubbleResponder::redirect("/admin/login");
|
// if id.identity().is_none() {
|
||||||
}
|
// return RubbleResponder::redirect("/admin/login");
|
||||||
let settings = Setting::load(&data.postgres());
|
// }
|
||||||
let admin = User::find_by_username(&data.postgres(), &id.identity().unwrap())
|
// let settings = Setting::load(&data.postgres());
|
||||||
.expect("cannot found this user");
|
// let admin = User::find_by_username(&data.postgres(), &id.identity().unwrap())
|
||||||
|
// .expect("cannot found this user");
|
||||||
let result = Article::get_by_pk(&data.postgres(), article_id.into_inner());
|
//
|
||||||
|
// let result = Article::get_by_pk(&data.postgres(), article_id.into_inner());
|
||||||
match result {
|
//
|
||||||
Ok(article) => {
|
// match result {
|
||||||
let mut context = Context::new();
|
// Ok(article) => {
|
||||||
context.insert("article", &article);
|
// let mut context = Context::new();
|
||||||
context.insert("setting", &settings);
|
// context.insert("article", &article);
|
||||||
context.insert("admin", &admin);
|
// context.insert("setting", &settings);
|
||||||
RubbleResponder::html(data.render("admin/article_add.html", &context))
|
// context.insert("admin", &admin);
|
||||||
}
|
// RubbleResponder::html(data.render("admin/article_add.html", &context))
|
||||||
Err(_) => RubbleResponder::redirect("/admin/panel"),
|
// }
|
||||||
}
|
// Err(_) => RubbleResponder::redirect("/admin/panel"),
|
||||||
}
|
// }
|
||||||
|
//}
|
||||||
#[post("/article")]
|
//
|
||||||
pub fn article_save(
|
//#[post("/article")]
|
||||||
id: Identity,
|
//pub fn article_save(
|
||||||
article: Form<crate::models::article::form::NewArticleFrom>,
|
// id: Identity,
|
||||||
data: web::Data<RubbleData>,
|
// article: Form<crate::models::article::form::NewArticleFrom>,
|
||||||
) -> impl Responder {
|
// data: web::Data<RubbleData>,
|
||||||
if id.identity().is_none() {
|
//) -> impl Responder {
|
||||||
return RubbleResponder::redirect("/admin/login");
|
// if id.identity().is_none() {
|
||||||
}
|
// return RubbleResponder::redirect("/admin/login");
|
||||||
|
// }
|
||||||
let article_title = article.title.clone();
|
//
|
||||||
|
// let article_title = article.title.clone();
|
||||||
let admin = User::find_by_username(&data.postgres(), &id.identity().unwrap())
|
//
|
||||||
.expect("cannot found this user");
|
// let admin = User::find_by_username(&data.postgres(), &id.identity().unwrap())
|
||||||
Article::create(&data.postgres(), &article.into_inner().into());
|
// .expect("cannot found this user");
|
||||||
|
// Article::create(&data.postgres(), &article.into_inner().into());
|
||||||
RubbleResponder::redirect("/admin/panel")
|
//
|
||||||
}
|
// RubbleResponder::redirect("/admin/panel")
|
||||||
|
//}
|
||||||
#[post("/article/{aid}")]
|
//
|
||||||
pub fn article_update(
|
//#[post("/article/{aid}")]
|
||||||
id: Identity,
|
//pub fn article_update(
|
||||||
aid: web::Path<i32>,
|
// id: Identity,
|
||||||
article: Form<crate::models::article::form::NewArticleFrom>,
|
// aid: web::Path<i32>,
|
||||||
data: web::Data<RubbleData>,
|
// article: Form<crate::models::article::form::NewArticleFrom>,
|
||||||
) -> impl Responder {
|
// data: web::Data<RubbleData>,
|
||||||
if id.identity().is_none() {
|
//) -> impl Responder {
|
||||||
return RubbleResponder::redirect("/admin/login");
|
// if id.identity().is_none() {
|
||||||
}
|
// return RubbleResponder::redirect("/admin/login");
|
||||||
|
// }
|
||||||
let admin = User::find_by_username(&data.postgres(), &id.identity().unwrap())
|
//
|
||||||
.expect("cannot found this user");
|
// let admin = User::find_by_username(&data.postgres(), &id.identity().unwrap())
|
||||||
Article::update(&data.postgres(), *aid, &article.into_inner().into());
|
// .expect("cannot found this user");
|
||||||
|
// Article::update(&data.postgres(), *aid, &article.into_inner().into());
|
||||||
RubbleResponder::redirect("/admin/panel")
|
//
|
||||||
}
|
// RubbleResponder::redirect("/admin/panel")
|
||||||
|
//}
|
||||||
#[post("/article/delete/{article_id}")]
|
//
|
||||||
pub fn article_deletion(
|
//#[post("/article/delete/{article_id}")]
|
||||||
id: Identity,
|
//pub fn article_deletion(
|
||||||
article_id: web::Path<i32>,
|
// id: Identity,
|
||||||
data: web::Data<RubbleData>,
|
// article_id: web::Path<i32>,
|
||||||
) -> impl Responder {
|
// data: web::Data<RubbleData>,
|
||||||
if id.identity().is_none() {
|
//) -> impl Responder {
|
||||||
return RubbleResponder::redirect("/admin/login");
|
// if id.identity().is_none() {
|
||||||
}
|
// return RubbleResponder::redirect("/admin/login");
|
||||||
|
// }
|
||||||
let admin = User::find_by_username(&data.postgres(), &id.identity().unwrap())
|
//
|
||||||
.expect("cannot found this user");
|
// let admin = User::find_by_username(&data.postgres(), &id.identity().unwrap())
|
||||||
|
// .expect("cannot found this user");
|
||||||
let i = article_id.into_inner();
|
//
|
||||||
Article::delete(&data.postgres(), i);
|
// let i = article_id.into_inner();
|
||||||
|
// Article::delete(&data.postgres(), i);
|
||||||
RubbleResponder::redirect("/admin/panel")
|
//
|
||||||
}
|
// RubbleResponder::redirect("/admin/panel")
|
||||||
|
//}
|
||||||
#[post("/password")]
|
//
|
||||||
pub fn change_password(
|
//#[post("/password")]
|
||||||
id: Identity,
|
//pub fn change_password(
|
||||||
password: web::Form<NewPassword>,
|
// id: Identity,
|
||||||
data: web::Data<RubbleData>,
|
// password: web::Form<NewPassword>,
|
||||||
) -> impl Responder {
|
// data: web::Data<RubbleData>,
|
||||||
if id.identity().is_none() {
|
//) -> impl Responder {
|
||||||
return RubbleResponder::redirect("/admin/login");
|
// if id.identity().is_none() {
|
||||||
}
|
// return RubbleResponder::redirect("/admin/login");
|
||||||
|
// }
|
||||||
let mut admin = User::find_by_username(&data.postgres(), &id.identity().unwrap())
|
//
|
||||||
.expect("cannot found this user");
|
// let mut admin = User::find_by_username(&data.postgres(), &id.identity().unwrap())
|
||||||
admin.password = User::password_generate(&password.password).to_string();
|
// .expect("cannot found this user");
|
||||||
User::update(&data.postgres(), admin.id, &admin);
|
// admin.password = User::password_generate(&password.password).to_string();
|
||||||
id.forget();
|
// User::update(&data.postgres(), admin.id, &admin);
|
||||||
RubbleResponder::redirect("/admin/panel")
|
// id.forget();
|
||||||
}
|
// RubbleResponder::redirect("/admin/panel")
|
||||||
|
//}
|
||||||
#[post("/setting")]
|
//
|
||||||
pub fn change_setting(
|
//#[post("/setting")]
|
||||||
id: Identity,
|
//pub fn change_setting(
|
||||||
setting: web::Form<Setting>,
|
// id: Identity,
|
||||||
data: web::Data<RubbleData>,
|
// setting: web::Form<Setting>,
|
||||||
) -> impl Responder {
|
// data: web::Data<RubbleData>,
|
||||||
if id.identity().is_none() {
|
//) -> impl Responder {
|
||||||
return RubbleResponder::redirect("/admin/login");
|
// if id.identity().is_none() {
|
||||||
}
|
// return RubbleResponder::redirect("/admin/login");
|
||||||
|
// }
|
||||||
let mut admin = User::find_by_username(&data.postgres(), &id.identity().unwrap())
|
//
|
||||||
.expect("cannot found this user");
|
// let mut admin = User::find_by_username(&data.postgres(), &id.identity().unwrap())
|
||||||
|
// .expect("cannot found this user");
|
||||||
let update_setting = UpdateSetting {
|
//
|
||||||
value: setting.value.clone(),
|
// let update_setting = UpdateSetting {
|
||||||
};
|
// value: setting.value.clone(),
|
||||||
Setting::update(&data.postgres(), setting.name.clone(), &update_setting);
|
// };
|
||||||
RubbleResponder::redirect("/admin/site-setting")
|
// Setting::update(&data.postgres(), setting.name.clone(), &update_setting);
|
||||||
}
|
// RubbleResponder::redirect("/admin/site-setting")
|
||||||
|
//}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod test {
|
mod test {
|
||||||
|
@ -4,36 +4,37 @@ use crate::{
|
|||||||
routers::RubbleResponder,
|
routers::RubbleResponder,
|
||||||
};
|
};
|
||||||
use actix_web::{delete, get, post, put, web, Responder};
|
use actix_web::{delete, get, post, put, web, Responder};
|
||||||
|
use crate::error::RubbleError;
|
||||||
|
|
||||||
#[get("")]
|
#[get("/articles")]
|
||||||
pub fn get_all_article(user: User, data: web::Data<RubbleData>) -> impl Responder {
|
pub async fn get_all_article(user: User, data: web::Data<RubbleData>) -> impl Responder {
|
||||||
RubbleResponder::json(Article::read(&data.postgres()))
|
RubbleResponder::json(Article::read(&data.postgres()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/{id}")]
|
#[get("/articles/{id}")]
|
||||||
pub fn get_all_article_by_id(
|
pub async fn get_article_by_id(
|
||||||
user: User,
|
user: User,
|
||||||
id: web::Path<i32>,
|
id: web::Path<i32>,
|
||||||
data: web::Data<RubbleData>,
|
data: web::Data<RubbleData>,
|
||||||
) -> impl Responder {
|
) -> impl Responder {
|
||||||
Article::get_by_pk(&data.postgres(), *id)
|
Article::get_by_pk(&data.postgres(), *id)
|
||||||
.map(|data| RubbleResponder::json(data))
|
.map(RubbleResponder::json)
|
||||||
.map_err(|_| RubbleResponder::not_found())
|
.map_err(|_| RubbleResponder::not_found())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("")]
|
#[post("/articles")]
|
||||||
pub fn crate_article(
|
pub async fn crate_article(
|
||||||
user: User,
|
user: User,
|
||||||
article: web::Json<crate::models::article::NewArticle>,
|
article: web::Json<crate::models::article::NewArticle>,
|
||||||
data: web::Data<RubbleData>,
|
data: web::Data<RubbleData>,
|
||||||
) -> impl Responder {
|
) -> impl Responder {
|
||||||
Article::create(&data.postgres(), &article)
|
Article::create(&data.postgres(), &article)
|
||||||
.map(RubbleResponder::json)
|
.map(RubbleResponder::json)
|
||||||
.map_err(|_| RubbleResponder::bad_request("something wrong when creating article"))
|
.map_err(|_| RubbleError::BadRequest("something wrong when creating article"))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[put("/{id}")]
|
#[put("/articles/{id}")]
|
||||||
pub fn update_article_by_id(
|
pub async fn update_article_by_id(
|
||||||
user: User,
|
user: User,
|
||||||
id: web::Path<i32>,
|
id: web::Path<i32>,
|
||||||
article: web::Json<crate::models::article::NewArticle>,
|
article: web::Json<crate::models::article::NewArticle>,
|
||||||
@ -41,16 +42,16 @@ pub fn update_article_by_id(
|
|||||||
) -> impl Responder {
|
) -> impl Responder {
|
||||||
Article::update(&data.postgres(), *id, &article)
|
Article::update(&data.postgres(), *id, &article)
|
||||||
.map(|data| RubbleResponder::json(data))
|
.map(|data| RubbleResponder::json(data))
|
||||||
.map_err(|_| RubbleResponder::bad_request("something wrong when updating article"))
|
.map_err(|_| RubbleError::BadRequest("something wrong when updating article"))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[delete("/{id}")]
|
#[delete("/articles/{id}")]
|
||||||
pub fn delete_article_by_id(
|
pub async fn delete_article_by_id(
|
||||||
user: User,
|
user: User,
|
||||||
id: web::Path<i32>,
|
id: web::Path<i32>,
|
||||||
data: web::Data<RubbleData>,
|
data: web::Data<RubbleData>,
|
||||||
) -> impl Responder {
|
) -> impl Responder {
|
||||||
Article::delete(&data.postgres(), *id)
|
Article::delete(&data.postgres(), *id)
|
||||||
.map(|_| RubbleResponder::json("Ok"))
|
.map(|_| RubbleResponder::json("Ok"))
|
||||||
.map_err(|_| RubbleResponder::bad_request("something wrong when deleting article"))
|
.map_err(|_| RubbleError::BadRequest("something wrong when deleting article"))
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,21 @@
|
|||||||
|
use actix_web::web;
|
||||||
|
|
||||||
pub mod article;
|
pub mod article;
|
||||||
pub mod setting;
|
pub mod setting;
|
||||||
pub mod user;
|
pub mod user;
|
||||||
|
|
||||||
|
|
||||||
|
pub fn routes(cfg: &mut web::ServiceConfig) {
|
||||||
|
cfg
|
||||||
|
.service(user::admin_authentication)
|
||||||
|
|
||||||
|
.service(article::get_all_article)
|
||||||
|
.service(article::crate_article)
|
||||||
|
.service(article::get_article_by_id)
|
||||||
|
.service(article::update_article_by_id)
|
||||||
|
.service(article::delete_article_by_id)
|
||||||
|
|
||||||
|
.service(setting::get_settings)
|
||||||
|
.service(setting::update_setting_by_key)
|
||||||
|
;
|
||||||
|
}
|
@ -8,14 +8,15 @@ use crate::{
|
|||||||
routers::RubbleResponder,
|
routers::RubbleResponder,
|
||||||
};
|
};
|
||||||
use actix_web::{delete, get, post, put, web, Responder};
|
use actix_web::{delete, get, post, put, web, Responder};
|
||||||
|
use crate::error::RubbleError;
|
||||||
|
|
||||||
#[get("")]
|
#[get("/settings")]
|
||||||
pub fn get_settings(user: User, data: web::Data<RubbleData>) -> impl Responder {
|
pub async fn get_settings(user: User, data: web::Data<RubbleData>) -> impl Responder {
|
||||||
RubbleResponder::json(Setting::load(&data.postgres()))
|
RubbleResponder::json(Setting::load(&data.postgres()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[put("/{key}")]
|
#[put("settings/{key}")]
|
||||||
pub fn update_setting_by_key(
|
pub async fn update_setting_by_key(
|
||||||
user: User,
|
user: User,
|
||||||
key: web::Path<String>,
|
key: web::Path<String>,
|
||||||
value: web::Json<UpdateSetting>,
|
value: web::Json<UpdateSetting>,
|
||||||
@ -24,5 +25,5 @@ pub fn update_setting_by_key(
|
|||||||
let string = (*key).clone();
|
let string = (*key).clone();
|
||||||
Setting::update(&data.postgres(), string, &value)
|
Setting::update(&data.postgres(), string, &value)
|
||||||
.map(RubbleResponder::json)
|
.map(RubbleResponder::json)
|
||||||
.map_err(|_| RubbleResponder::bad_request("error on updating setting"))
|
.map_err(|_| RubbleError::BadRequest("error on updating setting"))
|
||||||
}
|
}
|
||||||
|
@ -10,9 +10,10 @@ use crate::{
|
|||||||
utils::jwt::JWTClaims,
|
utils::jwt::JWTClaims,
|
||||||
};
|
};
|
||||||
use actix_web::{delete, get, post, put, web, Responder};
|
use actix_web::{delete, get, post, put, web, Responder};
|
||||||
|
use crate::error::RubbleError;
|
||||||
|
|
||||||
#[post("/token")]
|
#[post("/user/token")]
|
||||||
pub fn admin_authentication(
|
pub async fn admin_authentication(
|
||||||
user: web::Json<LoginForm>,
|
user: web::Json<LoginForm>,
|
||||||
data: web::Data<RubbleData>,
|
data: web::Data<RubbleData>,
|
||||||
) -> impl Responder {
|
) -> impl Responder {
|
||||||
@ -23,36 +24,36 @@ pub fn admin_authentication(
|
|||||||
if login_user.authenticated(&user.password) {
|
if login_user.authenticated(&user.password) {
|
||||||
let string = JWTClaims::encode(&login_user);
|
let string = JWTClaims::encode(&login_user);
|
||||||
|
|
||||||
RubbleResponder::json(Token { token: string })
|
Ok(RubbleResponder::json(Token { token: string }))
|
||||||
} else {
|
} else {
|
||||||
RubbleResponder::unauthorized("invalid password")
|
Err(RubbleError::Unauthorized("invalid password"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(_) => RubbleResponder::unauthorized("invalid username"),
|
Err(_) => Err(RubbleError::Unauthorized("invalid username")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
//
|
||||||
#[get("")]
|
//#[get("")]
|
||||||
pub fn get_all_users() -> impl Responder {
|
//pub fn get_all_users() -> impl Responder {
|
||||||
unreachable!()
|
// unreachable!()
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
#[post("")]
|
//#[post("")]
|
||||||
pub fn crate_user() -> impl Responder {
|
//pub fn crate_user() -> impl Responder {
|
||||||
unreachable!()
|
// unreachable!()
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
#[put("/{id}")]
|
//#[put("/{id}")]
|
||||||
pub fn update_user_by_id() -> impl Responder {
|
//pub fn update_user_by_id() -> impl Responder {
|
||||||
unreachable!()
|
// unreachable!()
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
#[delete("/{id}")]
|
//#[delete("/{id}")]
|
||||||
pub fn delete_user_by_id() -> impl Responder {
|
//pub fn delete_user_by_id() -> impl Responder {
|
||||||
unreachable!()
|
// unreachable!()
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
#[put("/{id}/password")]
|
//#[put("/{id}/password")]
|
||||||
pub fn update_user_password() -> impl Responder {
|
//pub fn update_user_password() -> impl Responder {
|
||||||
unreachable!()
|
// unreachable!()
|
||||||
}
|
//}
|
||||||
|
@ -12,8 +12,8 @@ use actix_web::{get, web, Either, HttpResponse, Responder};
|
|||||||
use std::{result::Result, sync::Arc};
|
use std::{result::Result, sync::Arc};
|
||||||
use tera::{Context, Tera};
|
use tera::{Context, Tera};
|
||||||
|
|
||||||
#[get("")]
|
#[get("/")]
|
||||||
pub fn homepage(data: web::Data<RubbleData>) -> impl Responder {
|
pub async fn homepage(data: web::Data<RubbleData>) -> impl Responder {
|
||||||
let vec: Vec<Article> = Article::read(&data.postgres());
|
let vec: Vec<Article> = Article::read(&data.postgres());
|
||||||
let article_view: Vec<_> = vec
|
let article_view: Vec<_> = vec
|
||||||
.iter()
|
.iter()
|
||||||
@ -31,7 +31,7 @@ pub fn homepage(data: web::Data<RubbleData>) -> impl Responder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[get("archives/{archives_id}")]
|
#[get("archives/{archives_id}")]
|
||||||
pub fn single_article(archives_id: web::Path<i32>, data: web::Data<RubbleData>) -> impl Responder {
|
pub async fn single_article(archives_id: web::Path<i32>, data: web::Data<RubbleData>) -> impl Responder {
|
||||||
let article = Article::get_by_pk(&data.postgres(), archives_id.into_inner());
|
let article = Article::get_by_pk(&data.postgres(), archives_id.into_inner());
|
||||||
|
|
||||||
if let Err(e) = article {
|
if let Err(e) = article {
|
||||||
@ -58,7 +58,7 @@ pub fn single_article(archives_id: web::Path<i32>, data: web::Data<RubbleData>)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[get("{url}")]
|
#[get("{url}")]
|
||||||
pub fn get_article_by_url(url: web::Path<String>, data: web::Data<RubbleData>) -> impl Responder {
|
pub async fn get_article_by_url(url: web::Path<String>, data: web::Data<RubbleData>) -> impl Responder {
|
||||||
let article = Article::find_by_url(&data.postgres(), &url.into_inner());
|
let article = Article::find_by_url(&data.postgres(), &url.into_inner());
|
||||||
|
|
||||||
if let Err(e) = article {
|
if let Err(e) = article {
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
use actix_web::{HttpRequest, HttpResponse, Responder};
|
use actix_web::{error::Error, HttpRequest, HttpResponse, Responder, Scope, web};
|
||||||
|
use futures::future::{err, ok};
|
||||||
use actix_web::{error::Error, web, Scope};
|
|
||||||
use futures::future::{err, ok, FutureResult};
|
|
||||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
|
|
||||||
pub mod admin;
|
pub mod admin;
|
||||||
@ -57,53 +55,11 @@ impl RubbleResponder {
|
|||||||
HttpResponse::NotFound().finish()
|
HttpResponse::NotFound().finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unauthorized(reason: impl Serialize) -> HttpResponse {
|
|
||||||
HttpResponse::Unauthorized().json(&ErrorResponse { message: reason })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn bad_gateway(reason: impl Serialize) -> HttpResponse {
|
|
||||||
HttpResponse::BadGateway().json(&ErrorResponse { message: reason })
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn bad_request(reason: impl Serialize) -> HttpResponse {
|
|
||||||
HttpResponse::BadRequest().json(&ErrorResponse { message: reason })
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn routes() -> Scope {
|
pub fn routes(cfg: &mut web::ServiceConfig) {
|
||||||
web::scope("/")
|
cfg
|
||||||
.service(
|
.service(web::scope("/api").configure(api::routes))
|
||||||
web::scope("/api")
|
|
||||||
.service(web::scope("/users").service(api::user::admin_authentication))
|
|
||||||
.service(
|
|
||||||
web::scope("/articles")
|
|
||||||
.service(api::article::get_all_article)
|
|
||||||
.service(api::article::get_all_article_by_id)
|
|
||||||
.service(api::article::crate_article)
|
|
||||||
.service(api::article::update_article_by_id)
|
|
||||||
.service(api::article::delete_article_by_id),
|
|
||||||
)
|
|
||||||
.service(
|
|
||||||
web::scope("/settings")
|
|
||||||
.service(api::setting::get_settings)
|
|
||||||
.service(api::setting::update_setting_by_key),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
.service(
|
|
||||||
web::scope("/admin")
|
|
||||||
.service(admin::redirect_to_admin_panel)
|
|
||||||
.service(admin::admin_login)
|
|
||||||
.service(admin::admin_authentication)
|
|
||||||
.service(admin::admin_panel)
|
|
||||||
.service(admin::article_creation)
|
|
||||||
.service(admin::article_deletion)
|
|
||||||
.service(admin::article_edit)
|
|
||||||
.service(admin::article_save)
|
|
||||||
.service(admin::article_update)
|
|
||||||
.service(admin::change_password)
|
|
||||||
.service(admin::change_setting)
|
|
||||||
.service(admin::admin_show_page),
|
|
||||||
)
|
|
||||||
.service(article::homepage)
|
.service(article::homepage)
|
||||||
.service(article::single_article)
|
.service(article::single_article)
|
||||||
.service(actix_files::Files::new(
|
.service(actix_files::Files::new(
|
||||||
@ -111,5 +67,5 @@ pub fn routes() -> Scope {
|
|||||||
"./templates/resources/",
|
"./templates/resources/",
|
||||||
))
|
))
|
||||||
.service(rss::rss_)
|
.service(rss::rss_)
|
||||||
.service(article::get_article_by_url)
|
.service(article::get_article_by_url);
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ use rss::{Channel, ChannelBuilder, Item, ItemBuilder};
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
#[get("/rss")]
|
#[get("/rss")]
|
||||||
pub fn rss_(data: web::Data<RubbleData>) -> impl Responder {
|
pub async fn rss_(data: web::Data<RubbleData>) -> impl Responder {
|
||||||
let articles = Article::read(&data.postgres());
|
let articles = Article::read(&data.postgres());
|
||||||
let setting = Setting::load(&data.postgres());
|
let setting = Setting::load(&data.postgres());
|
||||||
|
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use crate::{models::user::User, RANDOM_TOKEN_KEY};
|
use crate::{models::user::User, TOKEN_KEY};
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
use jsonwebtoken::{decode as jwt_decode, encode as jwt_encode, Algorithm, Header, Validation};
|
use jsonwebtoken::{decode as jwt_decode, encode as jwt_encode, Algorithm, Header, Validation, DecodingKey, EncodingKey};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::ops::Add;
|
use std::ops::{Add, Deref};
|
||||||
use time::Duration;
|
use time::Duration;
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
@ -26,13 +26,13 @@ impl JWTClaims {
|
|||||||
username: user.username.clone(),
|
username: user.username.clone(),
|
||||||
};
|
};
|
||||||
|
|
||||||
jwt_encode(&Header::default(), &claims, &RANDOM_TOKEN_KEY).unwrap()
|
jwt_encode(&Header::default(), &claims, &EncodingKey::from_secret(&TOKEN_KEY)).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn decode(token: String) -> Result<String, ()> {
|
pub fn decode(token: String) -> Result<String, ()> {
|
||||||
let claims = jwt_decode::<JWTClaims>(
|
let claims = jwt_decode::<JWTClaims>(
|
||||||
token.as_str(),
|
token.as_str(),
|
||||||
&RANDOM_TOKEN_KEY,
|
&DecodingKey::from_secret(&TOKEN_KEY),
|
||||||
&Validation::new(Algorithm::HS256),
|
&Validation::new(Algorithm::HS256),
|
||||||
)
|
)
|
||||||
.map_err(|_| ())?;
|
.map_err(|_| ())?;
|
||||||
|
Loading…
Reference in New Issue
Block a user