Skip to content

Commit 09fdafa

Browse files
committed
upgrade
2 parents 6b17b13 + bbc4914 commit 09fdafa

File tree

8 files changed

+117
-83
lines changed

8 files changed

+117
-83
lines changed

.vscode/launch.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,24 @@
44
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
55
"version": "0.2.0",
66
"configurations": [
7+
{
8+
"type": "lldb",
9+
"request": "launch",
10+
"name": "Debug executable 'actix-web-rest-api-with-jwt'",
11+
"cargo": {
12+
"args": [
13+
"build",
14+
"--bin=actix-web-rest-api-with-jwt",
15+
"--package=actix-web-rest-api-with-jwt"
16+
],
17+
"filter": {
18+
"name": "actix-web-rest-api-with-jwt",
19+
"kind": "bin"
20+
}
21+
},
22+
"args": [],
23+
"cwd": "${workspaceFolder}"
24+
},
725
{
826
"type": "lldb",
927
"request": "launch",

Cargo.toml

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,29 +5,29 @@ authors = ["SakaDream <bahaimt@gmail.com>"]
55
edition = "2018"
66

77
[dependencies]
8-
actix-web = "1.0.8"
9-
actix-rt = "0.2.5"
10-
actix-service = "0.4.2"
8+
actix-web = "2.0.0"
9+
actix-rt = "1.0.0"
10+
actix-service = "1.0.1"
1111
log = "0.4.8"
1212
log4rs = "0.9.0"
1313
diesel_migrations = "1.4.0"
14-
serde = "1.0.102"
15-
serde_derive = "1.0.102"
16-
serde_json = "1.0.41"
14+
serde = "1.0.104"
15+
serde_derive = "1.0.104"
16+
serde_json = "1.0.44"
1717
dotenv = "0.15.0"
18-
futures = "0.1.29"
18+
futures = "0.3.1"
1919
failure = "0.1.6"
20-
derive_more = "0.15.0"
20+
derive_more = "0.99.2"
2121
jsonwebtoken = "6.0.1"
2222
bcrypt = "0.6.1"
23-
time = "0.1.42"
23+
time = "0.2.1"
2424

2525
[dependencies.diesel]
2626
version = "1.4.3"
2727
features = ["postgres", "r2d2", "chrono"]
2828

2929
[dependencies.chrono]
30-
version = "0.4.9"
30+
version = "0.4.10"
3131
features = ["serde"]
3232

3333
[dependencies.uuid]

src/api/account_controller.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,35 @@ use crate::{
77
},
88
services::account_service,
99
};
10-
use actix_web::{web, Error, HttpRequest, HttpResponse};
11-
use futures::future::{ok, Future};
10+
use actix_web::{web, HttpRequest, HttpResponse, Result};
1211

1312
// POST api/auth/signup
14-
pub fn signup(user_dto: web::Json<UserDTO>, pool: web::Data<Pool>) -> impl Future<Item = HttpResponse, Error = Error> {
13+
pub async fn signup(user_dto: web::Json<UserDTO>, pool: web::Data<Pool>) -> Result<HttpResponse> {
1514
match account_service::signup(user_dto.0, &pool) {
16-
Ok(message) => ok(HttpResponse::Ok().json(ResponseBody::new(&message, constants::EMPTY))),
17-
Err(err) => ok(err.response()),
15+
Ok(message) => Ok(HttpResponse::Ok().json(ResponseBody::new(&message, constants::EMPTY))),
16+
Err(err) => Ok(err.response()),
1817
}
1918
}
2019

2120
// POST api/auth/login
22-
pub fn login(login_dto: web::Json<LoginDTO>, pool: web::Data<Pool>) -> impl Future<Item = HttpResponse, Error = Error> {
21+
pub async fn login(login_dto: web::Json<LoginDTO>, pool: web::Data<Pool>) -> Result<HttpResponse> {
2322
match account_service::login(login_dto.0, &pool) {
24-
Ok(token_res) => ok(HttpResponse::Ok().json(ResponseBody::new(constants::MESSAGE_LOGIN_SUCCESS, token_res))),
25-
Err(err) => ok(err.response()),
23+
Ok(token_res) => Ok(HttpResponse::Ok().json(ResponseBody::new(constants::MESSAGE_LOGIN_SUCCESS, token_res))),
24+
Err(err) => Ok(err.response()),
2625
}
2726
}
2827

2928
// POST api/auth/logout
29+
<<<<<<< HEAD
3030
pub fn logout(req: HttpRequest, pool: web::Data<Pool>) -> impl Future<Item = HttpResponse, Error = Error> {
3131
debug!("{:?}",req);
32+
=======
33+
pub async fn logout(req: HttpRequest, pool: web::Data<Pool>) -> Result<HttpResponse> {
34+
>>>>>>> bbc4914b638c3950e229f029fdcb3eb0f9a8e7f6
3235
if let Some(authen_header) = req.headers().get(constants::AUTHORIZATION) {
3336
account_service::logout(authen_header, &pool);
34-
ok(HttpResponse::Ok().json(ResponseBody::new(constants::MESSAGE_LOGOUT_SUCCESS, constants::EMPTY)))
37+
Ok(HttpResponse::Ok().json(ResponseBody::new(constants::MESSAGE_LOGOUT_SUCCESS, constants::EMPTY)))
3538
} else {
36-
ok(HttpResponse::BadRequest().json(ResponseBody::new(constants::MESSAGE_TOKEN_MISSING, constants::EMPTY)))
39+
Ok(HttpResponse::BadRequest().json(ResponseBody::new(constants::MESSAGE_TOKEN_MISSING, constants::EMPTY)))
3740
}
3841
}

src/api/address_book_controller.rs

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,53 +7,52 @@ use crate::{
77
},
88
services::address_book_service,
99
};
10-
use actix_web::{web, Error, HttpResponse};
11-
use futures::future::{ok, Future};
10+
use actix_web::{web, HttpResponse, Result};
1211

1312
// GET api/address-book
14-
pub fn find_all(pool: web::Data<Pool>) -> impl Future<Item = HttpResponse, Error = Error> {
13+
pub async fn find_all(pool: web::Data<Pool>) -> Result<HttpResponse> {
1514
match address_book_service::find_all(&pool) {
16-
Ok(people) => ok(HttpResponse::Ok().json(ResponseBody::new(constants::MESSAGE_OK, people))),
17-
Err(err) => ok(err.response()),
15+
Ok(people) => Ok(HttpResponse::Ok().json(ResponseBody::new(constants::MESSAGE_OK, people))),
16+
Err(err) => Ok(err.response()),
1817
}
1918
}
2019

2120
// GET api/address-book/{id}
22-
pub fn find_by_id(id: web::Path<String>, pool: web::Data<Pool>) -> impl Future<Item = HttpResponse, Error = Error> {
21+
pub async fn find_by_id(id: web::Path<String>, pool: web::Data<Pool>) -> Result<HttpResponse> {
2322
match address_book_service::find_by_id(id.into_inner().parse::<i32>().unwrap(), &pool) {
24-
Ok(person) => ok(HttpResponse::Ok().json(ResponseBody::new(constants::MESSAGE_OK, person))),
25-
Err(err) => ok(err.response()),
23+
Ok(person) => Ok(HttpResponse::Ok().json(ResponseBody::new(constants::MESSAGE_OK, person))),
24+
Err(err) => Ok(err.response()),
2625
}
2726
}
2827

2928
// GET api/address-book/query/{query}
30-
pub fn query(query: web::Path<String>, pool: web::Data<Pool>) -> impl Future<Item = HttpResponse, Error = Error> {
29+
pub async fn query(query: web::Path<String>, pool: web::Data<Pool>) -> Result<HttpResponse> {
3130
match address_book_service::query(query.into_inner(), &pool) {
32-
Ok(people) => ok(HttpResponse::Ok().json(ResponseBody::new(constants::MESSAGE_OK, people))),
33-
Err(err) => ok(err.response()),
31+
Ok(people) => Ok(HttpResponse::Ok().json(ResponseBody::new(constants::MESSAGE_OK, people))),
32+
Err(err) => Ok(err.response()),
3433
}
3534
}
3635

3736
// POST api/address-book
38-
pub fn insert(new_person: web::Json<PersonDTO>, pool: web::Data<Pool>) -> impl Future<Item = HttpResponse, Error = Error> {
37+
pub async fn insert(new_person: web::Json<PersonDTO>, pool: web::Data<Pool>) -> Result<HttpResponse> {
3938
match address_book_service::insert(new_person.0, &pool) {
40-
Ok(()) => ok(HttpResponse::Created().json(ResponseBody::new(constants::MESSAGE_OK, constants::EMPTY))),
41-
Err(err) => ok(err.response()),
39+
Ok(()) => Ok(HttpResponse::Created().json(ResponseBody::new(constants::MESSAGE_OK, constants::EMPTY))),
40+
Err(err) => Ok(err.response()),
4241
}
4342
}
4443

4544
// PUT api/address-book/{id}
46-
pub fn update(id: web::Path<String>, updated_person: web::Json<PersonDTO>, pool: web::Data<Pool>) -> impl Future<Item = HttpResponse, Error = Error> {
45+
pub async fn update(id: web::Path<String>, updated_person: web::Json<PersonDTO>, pool: web::Data<Pool>) -> Result<HttpResponse> {
4746
match address_book_service::update(id.into_inner().parse::<i32>().unwrap(), updated_person.0, &pool) {
48-
Ok(()) => ok(HttpResponse::Ok().json(ResponseBody::new(constants::MESSAGE_OK, constants::EMPTY))),
49-
Err(err) => ok(err.response()),
47+
Ok(()) => Ok(HttpResponse::Ok().json(ResponseBody::new(constants::MESSAGE_OK, constants::EMPTY))),
48+
Err(err) => Ok(err.response()),
5049
}
5150
}
5251

5352
// DELETE api/address-book/{id}
54-
pub fn delete(id: web::Path<String>, pool: web::Data<Pool>) -> impl Future<Item = HttpResponse, Error = Error> {
53+
pub async fn delete(id: web::Path<String>, pool: web::Data<Pool>) -> Result<HttpResponse> {
5554
match address_book_service::delete(id.into_inner().parse::<i32>().unwrap(), &pool) {
56-
Ok(()) => ok(HttpResponse::Ok().json(ResponseBody::new(constants::MESSAGE_OK, constants::EMPTY))),
57-
Err(err) => ok(err.response()),
55+
Ok(()) => Ok(HttpResponse::Ok().json(ResponseBody::new(constants::MESSAGE_OK, constants::EMPTY))),
56+
Err(err) => Ok(err.response()),
5857
}
5958
}

src/config/app.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,33 +10,33 @@ pub fn config_services(cfg: &mut web::ServiceConfig) {
1010
web::scope("/auth")
1111
.service(
1212
web::resource("/signup")
13-
.route(web::post().to_async(account_controller::signup))
13+
.route(web::post().to(account_controller::signup))
1414
)
1515
.service(
1616
web::resource("/login")
17-
.route(web::post().to_async(account_controller::login))
17+
.route(web::post().to(account_controller::login))
1818
)
1919
.service(
2020
web::resource("/logout")
21-
.route(web::post().to_async(account_controller::logout))
21+
.route(web::post().to(account_controller::logout))
2222
)
2323
)
2424
.service(
2525
web::scope("/address-book")
2626
.service(
2727
web::resource("")
28-
.route(web::get().to_async(address_book_controller::find_all))
29-
.route(web::post().to_async(address_book_controller::insert))
28+
.route(web::get().to(address_book_controller::find_all))
29+
.route(web::post().to(address_book_controller::insert))
3030
)
3131
.service(
3232
web::resource("/{id}")
33-
.route(web::get().to_async(address_book_controller::find_by_id))
34-
.route(web::put().to_async(address_book_controller::update))
35-
.route(web::delete().to_async(address_book_controller::delete))
33+
.route(web::get().to(address_book_controller::find_by_id))
34+
.route(web::put().to(address_book_controller::update))
35+
.route(web::delete().to(address_book_controller::delete))
3636
)
3737
.service(
3838
web::resource("/query/{query}")
39-
.route(web::get().to_async(address_book_controller::query))
39+
.route(web::get().to(address_book_controller::query))
4040
)
4141
)
4242
);

src/main.rs

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,13 @@ mod services;
3636
mod utils;
3737

3838
use actix_web::{HttpServer, App};
39+
use actix_service::Service;
40+
use futures::FutureExt;
3941
use std::{io, env};
4042
use std::default::Default;
4143

42-
fn main() -> io::Result<()> {
44+
#[actix_rt::main]
45+
async fn main() -> io::Result<()> {
4346
dotenv::dotenv().expect("Failed to read .env file");
4447
// env::set_var("RUST_LOG", "actix_web=debug");
4548
// env_logger::init();
@@ -50,20 +53,19 @@ fn main() -> io::Result<()> {
5053
let app_url = format!("{}:{}", &app_host, &app_port);
5154
let db_url = env::var("DATABASE_URL").expect("DATABASE_URL not found.");
5255

53-
let sys = actix_rt::System::new("address-book");
5456
let pool = config::db::migrate_and_config_db(&db_url);
5557

5658
HttpServer::new(move || {
5759
App::new()
5860
.data(pool.clone())
5961
.wrap(actix_web::middleware::Logger::default())
6062
.wrap(crate::middleware::authen_middleware::Authentication)
63+
.wrap_fn(|req, srv| {
64+
srv.call(req).map(|res| res)
65+
})
6166
.configure(config::app::config_services)
6267
})
6368
.bind(&app_url)?
64-
.start();
65-
66-
info!("Server is started at {}", &app_url);
67-
68-
sys.run()
69+
.run()
70+
.await
6971
}
Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
1-
use crate::{
2-
config::db::Pool,
3-
constants,
4-
models::response::ResponseBody,
5-
utils::token_utils,
6-
};
1+
use crate::{config::db::Pool, constants, models::response::ResponseBody, utils::token_utils};
72
use actix_service::{Service, Transform};
83
use actix_web::{
9-
Error, HttpResponse,
104
dev::{ServiceRequest, ServiceResponse},
5+
Error, HttpResponse,
116
};
127
use futures::{
13-
Poll,
14-
future::{ok, Either, FutureResult},
8+
future::{ok, Ready},
9+
Future,
10+
};
11+
use std::{
12+
pin::Pin,
13+
task::{Context, Poll},
1514
};
1615
use actix_web::http::header::{HeaderName, HeaderValue};
1716

@@ -21,13 +20,14 @@ impl<S, B> Transform<S> for Authentication
2120
where
2221
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
2322
S::Future: 'static,
23+
B: 'static,
2424
{
2525
type Request = ServiceRequest;
2626
type Response = ServiceResponse<B>;
2727
type Error = Error;
2828
type InitError = ();
2929
type Transform = AuthenticationMiddleware<S>;
30-
type Future = FutureResult<Self::Transform, Self::InitError>;
30+
type Future = Ready<Result<Self::Transform, Self::InitError>>;
3131

3232
fn new_transform(&self, service: S) -> Self::Future {
3333
ok(AuthenticationMiddleware { service })
@@ -41,17 +41,20 @@ impl<S, B> Service for AuthenticationMiddleware<S>
4141
where
4242
S: Service<Request = ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
4343
S::Future: 'static,
44+
B: 'static,
4445
{
4546
type Request = ServiceRequest;
4647
type Response = ServiceResponse<B>;
4748
type Error = Error;
48-
type Future = Either<S::Future, FutureResult<Self::Response, Self::Error>>;
49+
type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>>>>;
4950

50-
fn poll_ready(&mut self) -> Poll<(), Self::Error> {
51-
self.service.poll_ready()
51+
fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
52+
self.service.poll_ready(cx)
5253
}
5354

5455
fn call(&mut self, mut req: ServiceRequest) -> Self::Future {
56+
let mut authenticate_pass: bool = false;
57+
5558
// Bypass some account routes
5659
debug!("{:?}",req.head_mut().headers());
5760
let headers = req.headers_mut();
@@ -64,7 +67,7 @@ where
6467
for ignore_route in constants::IGNORE_ROUTES.iter() {
6568
debug!("route:{}",ignore_route);
6669
if req.path().starts_with(ignore_route) {
67-
return Either::A(self.service.call(req));
70+
authenticate_pass = true;
6871
}
6972
}
7073

@@ -73,21 +76,16 @@ where
7376
if let Some(authen_header) = req.headers_mut().get(constants::AUTHORIZATION) {
7477
info!("Parsing authorization header...");
7578
if let Ok(authen_str) = authen_header.to_str() {
76-
if authen_str.starts_with("bearer") {
79+
if authen_str.starts_with("bearer") || authen_str.starts_with("Bearer") {
7780
info!("Parsing token...");
7881
let token = authen_str[6..authen_str.len()].trim();
7982
if let Ok(token_data) = token_utils::decode_token(token.to_string()) {
8083
info!("Decoding token...");
8184
if token_utils::verify_token(&token_data, &pool).is_ok() {
8285
info!("Valid token");
83-
return Either::A(self.service.call(req));
86+
authenticate_pass = true;
8487
} else {
8588
error!("Invalid token");
86-
return Either::B(ok(req.into_response(
87-
HttpResponse::Unauthorized()
88-
.json(ResponseBody::new(constants::MESSAGE_INVALID_TOKEN, constants::EMPTY))
89-
.into_body()
90-
)));
9189
}
9290
}
9391
}
@@ -96,10 +94,23 @@ where
9694
}
9795

9896
error!("{}", constants::MESSAGE_PROCESS_TOKEN_ERROR);
99-
Either::B(ok(req.into_response(
100-
HttpResponse::InternalServerError()
101-
.json(ResponseBody::new(constants::MESSAGE_PROCESS_TOKEN_ERROR, constants::EMPTY))
102-
.into_body()
103-
)))
97+
if authenticate_pass {
98+
let fut = self.service.call(req);
99+
Box::pin(async move {
100+
let res = fut.await?;
101+
Ok(res)
102+
})
103+
} else {
104+
Box::pin(async move {
105+
Ok(req.into_response(
106+
HttpResponse::Unauthorized()
107+
.json(ResponseBody::new(
108+
constants::MESSAGE_INVALID_TOKEN,
109+
constants::EMPTY,
110+
))
111+
.into_body(),
112+
))
113+
})
114+
}
104115
}
105116
}

0 commit comments

Comments
 (0)