Updated auth to use pem keys instead of base64 keys in strings?
This commit is contained in:
@@ -1,31 +1,25 @@
|
|||||||
RUST_LOG=warn,service=info
|
RUST_LOG=warn,service=info
|
||||||
|
|
||||||
DATABASE_CONTAINER=weather-service
|
|
||||||
|
|
||||||
DATABASE_USER=weather
|
DATABASE_USER=weather
|
||||||
DATABASE_PASSWORD=
|
DATABASE_PASSWORD=
|
||||||
DATABASE_NAME=weather
|
DATABASE_NAME=weather
|
||||||
DATABASE_HOST=localhost
|
DATABASE_HOST=db
|
||||||
DATABASE_PORT=5432
|
DATABASE_PORT=5432
|
||||||
|
|
||||||
REDIS_HOST=localhost
|
REDIS_HOST=redis
|
||||||
REDIS_PORT=6379
|
REDIS_PORT=6379
|
||||||
|
|
||||||
MINIO_ROOT_USER=siren
|
MINIO_ROOT_USER=weather
|
||||||
MINIO_ROOT_PASSWORD=
|
MINIO_ROOT_PASSWORD=
|
||||||
MINIO_HOST=localhost
|
MINIO_HOST=localhost
|
||||||
MINIO_PORT=9000
|
MINIO_PORT=9000
|
||||||
MINIO_PORT_INTERNAL=9001
|
MINIO_PORT_INTERNAL=9001
|
||||||
|
|
||||||
SERVICE_HOST=localhost
|
SERVICE_HOST=service
|
||||||
SERVICE_PORT=5000
|
SERVICE_PORT=5000
|
||||||
|
|
||||||
ACCESS_TOKEN_PRIVATE_KEY=
|
KEYS_DIR_PATH=
|
||||||
ACCESS_TOKEN_PUBLIC_KEY=
|
|
||||||
ACCESS_TOKEN_MAXAGE=5
|
ACCESS_TOKEN_MAXAGE=5
|
||||||
|
|
||||||
REFRESH_TOKEN_PRIVATE_KEY=
|
|
||||||
REFRESH_TOKEN_PUBLIC_KEY=
|
|
||||||
REFRESH_TOKEN_MAXAGE=30
|
REFRESH_TOKEN_MAXAGE=30
|
||||||
|
|
||||||
GOV_API_URL=https://aviationweather.gov/cgi-bin/data
|
GOV_API_URL=https://aviationweather.gov/cgi-bin/data
|
||||||
|
|||||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -18,6 +18,8 @@ node_modules
|
|||||||
# misc
|
# misc
|
||||||
.DS_Store
|
.DS_Store
|
||||||
*.pem
|
*.pem
|
||||||
|
*.pem.pub
|
||||||
|
keys/
|
||||||
|
|
||||||
# debug
|
# debug
|
||||||
npm-debug.log*
|
npm-debug.log*
|
||||||
|
|||||||
14
Makefile
14
Makefile
@@ -20,9 +20,6 @@ up: ## Start Docker containers
|
|||||||
down: ## Stop Docker containers
|
down: ## Stop Docker containers
|
||||||
docker compose down
|
docker compose down
|
||||||
|
|
||||||
connect: ## Connect to the Weather DB
|
|
||||||
docker exec -it ${DATABASE_CONTAINER} psql -U postgres
|
|
||||||
|
|
||||||
clean: ## Cleanup Docker containers
|
clean: ## Cleanup Docker containers
|
||||||
docker compose down && \
|
docker compose down && \
|
||||||
docker image rm weather-ui || \
|
docker image rm weather-ui || \
|
||||||
@@ -30,8 +27,9 @@ clean: ## Cleanup Docker containers
|
|||||||
docker network rm weather-frontend || \
|
docker network rm weather-frontend || \
|
||||||
docker network rm weather-backend
|
docker network rm weather-backend
|
||||||
|
|
||||||
clean-db: ## Remove database
|
generate: ## Generate RSA keys
|
||||||
docker exec -i ${DATABASE_CONTAINER} sh -c 'PGPASSWORD=${DATABASE_PASSWORD} psql -U ${DATABASE_USER} -d postgres -c "DROP DATABASE IF EXISTS \"${DATABASE_NAME}\";"'
|
mkdir keys
|
||||||
docker exec -i ${DATABASE_CONTAINER} sh -c 'PGPASSWORD=${DATABASE_PASSWORD} psql -U ${DATABASE_USER} -d postgres -c "CREATE DATABASE \"${DATABASE_NAME}\";"' || true
|
openssl genrsa -out keys/access_private_key.pem 4096
|
||||||
|
openssl rsa -in keys/access_private_key.pem -pubout -outform PEM -out keys/access_public_key.pem
|
||||||
|
openssl genrsa -out keys/refresh_private_key.pem 4096
|
||||||
|
openssl rsa -in keys/refresh_private_key.pem -pubout -outform PEM -out keys/refresh_public_key.pem
|
||||||
|
|||||||
@@ -2,3 +2,10 @@
|
|||||||
|
|
||||||
## Makefile
|
## Makefile
|
||||||
`make help` to list all commands
|
`make help` to list all commands
|
||||||
|
|
||||||
|
## Setup
|
||||||
|
|
||||||
|
1. Copy `.env.TEMPLATE` to `.env`
|
||||||
|
2. Generate JWT RS256 (RSA Signature with SHA-256) Private/Public keys with `make generate`
|
||||||
|
3. Build the service and ui images with `make build`
|
||||||
|
4. Run the application with `make up`
|
||||||
@@ -31,7 +31,7 @@ services:
|
|||||||
|
|
||||||
minio:
|
minio:
|
||||||
image: minio/minio
|
image: minio/minio
|
||||||
container_name: siren-minio
|
container_name: weather-minio
|
||||||
environment:
|
environment:
|
||||||
MINIO_ROOT_USER: ${MINIO_ROOT_USER}
|
MINIO_ROOT_USER: ${MINIO_ROOT_USER}
|
||||||
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
|
MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD}
|
||||||
@@ -49,6 +49,8 @@ services:
|
|||||||
container_name: weather-service
|
container_name: weather-service
|
||||||
env_file:
|
env_file:
|
||||||
- .env
|
- .env
|
||||||
|
volumes:
|
||||||
|
- ${KEYS_DIR_PATH}:/keys
|
||||||
ports:
|
ports:
|
||||||
- "${SERVICE_PORT:-5000}:5000"
|
- "${SERVICE_PORT:-5000}:5000"
|
||||||
build:
|
build:
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ DATABASE_PORT=5432
|
|||||||
REDIS_HOST=localhost
|
REDIS_HOST=localhost
|
||||||
REDIS_PORT=6379
|
REDIS_PORT=6379
|
||||||
|
|
||||||
MINIO_ROOT_USER=siren
|
MINIO_ROOT_USER=weather
|
||||||
MINIO_ROOT_PASSWORD=7LtSkxU15ix40nu
|
MINIO_ROOT_PASSWORD=7LtSkxU15ix40nu
|
||||||
MINIO_HOST=localhost
|
MINIO_HOST=localhost
|
||||||
MINIO_PORT=9000
|
MINIO_PORT=9000
|
||||||
@@ -20,12 +20,8 @@ MINIO_PORT_INTERNAL=9001
|
|||||||
SERVICE_HOST=localhost
|
SERVICE_HOST=localhost
|
||||||
SERVICE_PORT=5000
|
SERVICE_PORT=5000
|
||||||
|
|
||||||
ACCESS_TOKEN_PRIVATE_KEY=
|
KEYS_DIR_PATH=
|
||||||
ACCESS_TOKEN_PUBLIC_KEY=
|
|
||||||
ACCESS_TOKEN_MAXAGE=5
|
ACCESS_TOKEN_MAXAGE=5
|
||||||
|
|
||||||
REFRESH_TOKEN_PRIVATE_KEY=
|
|
||||||
REFRESH_TOKEN_PUBLIC_KEY=
|
|
||||||
REFRESH_TOKEN_MAXAGE=30
|
REFRESH_TOKEN_MAXAGE=30
|
||||||
|
|
||||||
GOV_API_URL=https://aviationweather.gov/cgi-bin/data
|
GOV_API_URL=https://aviationweather.gov/cgi-bin/data
|
||||||
|
|||||||
1
service/Cargo.lock
generated
1
service/Cargo.lock
generated
@@ -1805,7 +1805,6 @@ dependencies = [
|
|||||||
"actix-web",
|
"actix-web",
|
||||||
"actix-web-httpauth",
|
"actix-web-httpauth",
|
||||||
"argon2",
|
"argon2",
|
||||||
"base64",
|
|
||||||
"chrono",
|
"chrono",
|
||||||
"diesel",
|
"diesel",
|
||||||
"diesel_migrations",
|
"diesel_migrations",
|
||||||
|
|||||||
@@ -32,5 +32,4 @@ log = "0.4.20"
|
|||||||
argon2 = "0.5.2"
|
argon2 = "0.5.2"
|
||||||
jsonwebtoken = "9.0.0"
|
jsonwebtoken = "9.0.0"
|
||||||
redis = { version = "0.23.3", features = ["tokio-comp", "connection-manager", "r2d2"] }
|
redis = { version = "0.23.3", features = ["tokio-comp", "connection-manager", "r2d2"] }
|
||||||
base64 = "0.21.4"
|
|
||||||
rustix = "0.38.19" # https://github.com/imsnif/bandwhich/issues/284
|
rustix = "0.38.19" # https://github.com/imsnif/bandwhich/issues/284
|
||||||
|
|||||||
@@ -11,14 +11,26 @@ COPY Cargo.toml ./
|
|||||||
RUN apt-get update && apt-get install -y cmake
|
RUN apt-get update && apt-get install -y cmake
|
||||||
RUN cargo build --release
|
RUN cargo build --release
|
||||||
|
|
||||||
|
# ======
|
||||||
|
# Keys
|
||||||
|
# ======
|
||||||
|
FROM debian:bookworm-slim as keys
|
||||||
|
WORKDIR /keys
|
||||||
|
|
||||||
|
RUN apt-get update && apt-get install -y openssl libpq-dev
|
||||||
|
RUN openssl genrsa -out access.pem 4096
|
||||||
|
RUN openssl rsa -in access.pem -pubout -outform PEM -out access.pem.pub
|
||||||
|
RUN openssl genrsa -out refresh.pem 4096
|
||||||
|
RUN openssl rsa -in refresh.pem -pubout -outform PEM -out refresh.pem.pub
|
||||||
|
|
||||||
# =========
|
# =========
|
||||||
# Runtime
|
# Runtime
|
||||||
# =========
|
# =========
|
||||||
FROM debian:bookworm-slim as runtime
|
FROM keys as runtime
|
||||||
WORKDIR /service
|
WORKDIR /service
|
||||||
USER root
|
USER root
|
||||||
|
|
||||||
COPY --from=builder /builder/target/release/service /usr/local/bin/service
|
COPY --from=builder /builder/target/release/service /usr/local/bin/service
|
||||||
COPY --from=packages /packages /usr/bin
|
COPY --from=keys /keys /keys
|
||||||
|
|
||||||
CMD ["service"]
|
CMD ["service"]
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ build: ## Build the Docker image
|
|||||||
utils: ## Start the utils
|
utils: ## Start the utils
|
||||||
docker compose up -d db
|
docker compose up -d db
|
||||||
docker compose up -d redis
|
docker compose up -d redis
|
||||||
|
docker compose up -d minio
|
||||||
|
|
||||||
up: ## Start the Docker containers
|
up: ## Start the Docker containers
|
||||||
docker compose up -d
|
docker compose up -d
|
||||||
@@ -36,4 +37,10 @@ clean-db: ## Remove database
|
|||||||
docker exec -i ${DATABASE_CONTAINER} sh -c 'PGPASSWORD=${DATABASE_PASSWORD} psql -U ${DATABASE_USER} -d postgres -c "DROP DATABASE IF EXISTS \"${DATABASE_NAME}\";"'
|
docker exec -i ${DATABASE_CONTAINER} sh -c 'PGPASSWORD=${DATABASE_PASSWORD} psql -U ${DATABASE_USER} -d postgres -c "DROP DATABASE IF EXISTS \"${DATABASE_NAME}\";"'
|
||||||
docker exec -i ${DATABASE_CONTAINER} sh -c 'PGPASSWORD=${DATABASE_PASSWORD} psql -U ${DATABASE_USER} -d postgres -c "CREATE DATABASE \"${DATABASE_NAME}\";"' || true
|
docker exec -i ${DATABASE_CONTAINER} sh -c 'PGPASSWORD=${DATABASE_PASSWORD} psql -U ${DATABASE_USER} -d postgres -c "CREATE DATABASE \"${DATABASE_NAME}\";"' || true
|
||||||
|
|
||||||
|
generate: ## Generate RSA keys
|
||||||
|
mkdir ../keys/
|
||||||
|
openssl genrsa -out ../keys/access_private_key.pem 4096
|
||||||
|
openssl rsa -in ../keys/access_private_key.pem -pubout -outform PEM -out ../keys/access_public_key.pem
|
||||||
|
openssl genrsa -out ../keys/refresh_private_key.pem 4096
|
||||||
|
openssl rsa -in ../keys/refresh_private_key.pem -pubout -outform PEM -out ../keys/refresh_public_key.pem
|
||||||
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
# Aviation Weather
|
|
||||||
|
|
||||||
## UI
|
|
||||||
|
|
||||||
## Service
|
|
||||||
|
|
||||||
## REST API
|
|
||||||
The REST API for the weather service is described below.
|
|
||||||
|
|
||||||
### Import Airports
|
|
||||||
---
|
|
||||||
#### Request
|
|
||||||
`GET /import`
|
|
||||||
|
|
||||||
#### Response
|
|
||||||
```
|
|
||||||
```
|
|
||||||
|
|
||||||
### Get Airports
|
|
||||||
---
|
|
||||||
#### Request
|
|
||||||
`GET /airports`
|
|
||||||
|
|
||||||
#### Response
|
|
||||||
```
|
|
||||||
```
|
|
||||||
|
|
||||||
### Get Airport
|
|
||||||
---
|
|
||||||
#### Request
|
|
||||||
`GET /airports/{icao}`
|
|
||||||
|
|
||||||
#### Response
|
|
||||||
```
|
|
||||||
```
|
|
||||||
|
|
||||||
### Create Airport
|
|
||||||
---
|
|
||||||
#### Request
|
|
||||||
`CREATE /airports`
|
|
||||||
|
|
||||||
#### Response
|
|
||||||
```
|
|
||||||
```
|
|
||||||
|
|
||||||
### Update Airport
|
|
||||||
---
|
|
||||||
#### Request
|
|
||||||
`PUT /airports/{icao}`
|
|
||||||
|
|
||||||
#### Response
|
|
||||||
```
|
|
||||||
```
|
|
||||||
|
|
||||||
### Delete Airport
|
|
||||||
---
|
|
||||||
#### Request
|
|
||||||
`DELETE /airports/{icao}`
|
|
||||||
|
|
||||||
#### Response
|
|
||||||
```
|
|
||||||
```
|
|
||||||
@@ -54,6 +54,8 @@ services:
|
|||||||
REDIS_PORT: 6379
|
REDIS_PORT: 6379
|
||||||
SERVICE_HOST: service
|
SERVICE_HOST: service
|
||||||
SERVICE_PORT: 5000
|
SERVICE_PORT: 5000
|
||||||
|
volumes:
|
||||||
|
- ${KEYS_DIR_PATH}:/keys
|
||||||
ports:
|
ports:
|
||||||
- "${SERVICE_PORT:-5000}:5000"
|
- "${SERVICE_PORT:-5000}:5000"
|
||||||
build:
|
build:
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
use argon2::{password_hash::{rand_core::OsRng, PasswordHasher, PasswordVerifier, SaltString, Error as HashError}, Argon2, PasswordHash};
|
use argon2::{password_hash::{rand_core::OsRng, PasswordHasher, PasswordVerifier, SaltString, Error as HashError}, Argon2, PasswordHash};
|
||||||
use base64::{engine::general_purpose, Engine as _};
|
|
||||||
use jsonwebtoken::{DecodingKey, EncodingKey, Header, encode, decode, Validation, Algorithm};
|
use jsonwebtoken::{DecodingKey, EncodingKey, Header, encode, decode, Validation, Algorithm};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
@@ -31,9 +30,7 @@ pub struct TokenDetails {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn verify_token(token: &str, public_key: &str) -> Result<TokenDetails, ServiceError> {
|
pub fn verify_token(token: &str, public_key: &str) -> Result<TokenDetails, ServiceError> {
|
||||||
let bytes_public_key = general_purpose::STANDARD.decode(public_key).unwrap();
|
let key = DecodingKey::from_rsa_pem(public_key.as_bytes())?;
|
||||||
let decoded_public_key = String::from_utf8(bytes_public_key).unwrap();
|
|
||||||
let key = DecodingKey::from_rsa_pem(decoded_public_key.as_bytes())?;
|
|
||||||
let validation = Validation::new(Algorithm::RS256);
|
let validation = Validation::new(Algorithm::RS256);
|
||||||
let decoded = decode::<TokenClaims>(token, &key, &validation)?;
|
let decoded = decode::<TokenClaims>(token, &key, &validation)?;
|
||||||
let email = decoded.claims.sub;
|
let email = decoded.claims.sub;
|
||||||
@@ -43,21 +40,21 @@ pub fn verify_token(token: &str, public_key: &str) -> Result<TokenDetails, Servi
|
|||||||
|
|
||||||
pub fn generate_access_token(email: &str) -> Result<TokenDetails, ServiceError> {
|
pub fn generate_access_token(email: &str) -> Result<TokenDetails, ServiceError> {
|
||||||
let access_token_max_age = env::var("ACCESS_TOKEN_MAXAGE")
|
let access_token_max_age = env::var("ACCESS_TOKEN_MAXAGE")
|
||||||
.expect("ACCESS_TOKEN_MAXAGE must be set")
|
.expect("ACCESS_TOKEN_MAXAGE must be set")
|
||||||
.parse::<i64>()
|
.parse::<i64>()
|
||||||
.expect("ACCESS_TOKEN_MAXAGE must be an integer");
|
.expect("ACCESS_TOKEN_MAXAGE must be an integer");
|
||||||
let access_private_key = env::var("ACCESS_TOKEN_PRIVATE_KEY")
|
let keys_dir = env::var("KEYS_DIR_PATH")?;
|
||||||
.expect("ACCESS_TOKEN_PRIVATE_KEY must be set");
|
let access_private_key = std::fs::read_to_string(format!("{}/access_private_key.pem", keys_dir))?;
|
||||||
generate_token(&email, access_token_max_age, &access_private_key)
|
generate_token(&email, access_token_max_age, &access_private_key)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generate_refresh_token(email: &str) -> Result<TokenDetails, ServiceError> {
|
pub fn generate_refresh_token(email: &str) -> Result<TokenDetails, ServiceError> {
|
||||||
let refresh_token_max_age = env::var("REFRESH_TOKEN_MAXAGE")
|
let refresh_token_max_age = env::var("REFRESH_TOKEN_MAXAGE")
|
||||||
.expect("REFRESH_TOKEN_MAXAGE must be set")
|
.expect("REFRESH_TOKEN_MAXAGE must be set")
|
||||||
.parse::<i64>()
|
.parse::<i64>()
|
||||||
.expect("REFRESH_TOKEN_MAXAGE must be an integer");
|
.expect("REFRESH_TOKEN_MAXAGE must be an integer");
|
||||||
let refresh_private_key = env::var("REFRESH_TOKEN_PRIVATE_KEY")
|
let keys_dir = env::var("KEYS_DIR_PATH")?;
|
||||||
.expect("REFRESH_TOKEN_PRIVATE_KEY must be set");
|
let refresh_private_key = std::fs::read_to_string(format!("{}/refresh_private_key.pem", keys_dir))?;
|
||||||
generate_token(&email, refresh_token_max_age, &refresh_private_key)
|
generate_token(&email, refresh_token_max_age, &refresh_private_key)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,9 +75,7 @@ pub fn generate_token(email: &str, ttl: i64, private_key: &str) -> Result<TokenD
|
|||||||
nbf: now.timestamp()
|
nbf: now.timestamp()
|
||||||
};
|
};
|
||||||
let header = Header::new(Algorithm::RS256);
|
let header = Header::new(Algorithm::RS256);
|
||||||
let bytes_private_key = general_purpose::STANDARD.decode(private_key).unwrap();
|
let key = EncodingKey::from_rsa_pem(private_key.as_bytes())?;
|
||||||
let decoded_private_key = String::from_utf8(bytes_private_key).unwrap();
|
|
||||||
let key = EncodingKey::from_rsa_pem(decoded_private_key.as_bytes())?;
|
|
||||||
let token = encode(&header, &claims, &key)?;
|
let token = encode(&header, &claims, &key)?;
|
||||||
token_details.token = Some(token);
|
token_details.token = Some(token);
|
||||||
Ok(token_details)
|
Ok(token_details)
|
||||||
|
|||||||
@@ -157,8 +157,8 @@ impl FromRequest for JwtAuth {
|
|||||||
})))
|
})))
|
||||||
};
|
};
|
||||||
|
|
||||||
let public_key = env::var("ACCESS_TOKEN_PUBLIC_KEY")
|
let keys_dir = env::var("KEYS_DIR_PATH").expect("KEYS_DIR_PATH must be set");
|
||||||
.expect("ACCESS_TOKEN_PUBLIC_KEY must be set");
|
let public_key = std::fs::read_to_string(format!("{}/access_public_key.pem", keys_dir)).expect("Failed to read access public key");
|
||||||
|
|
||||||
let access_token_details = match verify_token(&access_token, &public_key) {
|
let access_token_details = match verify_token(&access_token, &public_key) {
|
||||||
Ok(token_details) => token_details,
|
Ok(token_details) => token_details,
|
||||||
|
|||||||
@@ -150,8 +150,9 @@ async fn refresh(req: HttpRequest) -> HttpResponse {
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
let public_key = env::var("REFRESH_TOKEN_PUBLIC_KEY")
|
let keys_dir = env::var("KEYS_DIR_PATH").expect("KEYS_DIR_PATH must be set");
|
||||||
.expect("REFRESH_TOKEN_PUBLIC_KEY must be set");
|
let public_key = std::fs::read_to_string(format!("{}/refresh_public_key.pem", keys_dir))
|
||||||
|
.expect("Unable to read refresh public key");
|
||||||
let refresh_token_details = match verify_token(&refresh_token, &public_key) {
|
let refresh_token_details = match verify_token(&refresh_token, &public_key) {
|
||||||
Ok(token_details) => token_details,
|
Ok(token_details) => token_details,
|
||||||
Err(err) => return ResponseError::error_response(&err)
|
Err(err) => return ResponseError::error_response(&err)
|
||||||
@@ -181,8 +182,9 @@ async fn refresh(req: HttpRequest) -> HttpResponse {
|
|||||||
match req.cookie("access_token") {
|
match req.cookie("access_token") {
|
||||||
Some(cookie) => {
|
Some(cookie) => {
|
||||||
let access_token = cookie.value().to_string();
|
let access_token = cookie.value().to_string();
|
||||||
let public_key = env::var("ACCESS_TOKEN_PUBLIC_KEY")
|
let keys_dir = env::var("KEYS_DIR_PATH").expect("KEYS_DIR_PATH must be set");
|
||||||
.expect("ACCESS_TOKEN_PUBLIC_KEY must be set");
|
let public_key = std::fs::read_to_string(format!("{}/access_public_key.pem", keys_dir))
|
||||||
|
.expect("Unable to read access public key");
|
||||||
match verify_token(&access_token, &public_key) {
|
match verify_token(&access_token, &public_key) {
|
||||||
Ok(token_details) => {
|
Ok(token_details) => {
|
||||||
let _: redis::RedisResult<()> = conn.del(token_details.token_uuid.to_string()).await;
|
let _: redis::RedisResult<()> = conn.del(token_details.token_uuid.to_string()).await;
|
||||||
@@ -285,8 +287,9 @@ async fn logout(req: HttpRequest, auth: JwtAuth) -> HttpResponse {
|
|||||||
message: "Refresh token not found".to_string()
|
message: "Refresh token not found".to_string()
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
let public_key = env::var("REFRESH_TOKEN_PUBLIC_KEY")
|
let keys_dir = env::var("KEYS_DIR_PATH").expect("KEYS_DIR_PATH must be set");
|
||||||
.expect("REFRESH_TOKEN_PUBLIC_KEY must be set");
|
let public_key = std::fs::read_to_string(format!("{}/refresh_public_key.pem", keys_dir))
|
||||||
|
.expect("Unable to read refresh public key");
|
||||||
let refresh_token_details = match verify_token(&refresh_token, &public_key) {
|
let refresh_token_details = match verify_token(&refresh_token, &public_key) {
|
||||||
Ok(token_details) => token_details,
|
Ok(token_details) => token_details,
|
||||||
Err(err) => return ResponseError::error_response(&err)
|
Err(err) => return ResponseError::error_response(&err)
|
||||||
|
|||||||
@@ -38,6 +38,18 @@ impl fmt::Display for ServiceError {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl From<std::io::Error> for ServiceError {
|
||||||
|
fn from(error: std::io::Error) -> ServiceError {
|
||||||
|
ServiceError::new(500, format!("Unknown IO error: {}", error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<std::env::VarError> for ServiceError {
|
||||||
|
fn from(error: std::env::VarError) -> ServiceError {
|
||||||
|
ServiceError::new(500, format!("Unknown environment variable error: {}", error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl From<DieselError> for ServiceError {
|
impl From<DieselError> for ServiceError {
|
||||||
fn from(error: DieselError) -> ServiceError {
|
fn from(error: DieselError) -> ServiceError {
|
||||||
match error {
|
match error {
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ services:
|
|||||||
- ./public:/app/public
|
- ./public:/app/public
|
||||||
- ./styles:/app/styles
|
- ./styles:/app/styles
|
||||||
networks:
|
networks:
|
||||||
- weather-frontend
|
- frontend
|
||||||
restart: unless-stopped
|
restart: unless-stopped
|
||||||
|
|
||||||
networks:
|
networks:
|
||||||
weather-frontend:
|
frontend:
|
||||||
|
|||||||
Reference in New Issue
Block a user