Fixed query parameters and dynamic Client ID
This commit is contained in:
parent
d6d73d74fe
commit
bf92aea1bb
1 changed files with 12 additions and 23 deletions
35
src/main.rs
35
src/main.rs
|
@ -1,4 +1,4 @@
|
|||
use std::{convert::Infallible, env, error::Error, net::SocketAddr, str::FromStr};
|
||||
use std::{collections::HashMap, convert::Infallible, env, error::Error, net::SocketAddr, str::FromStr};
|
||||
use redis::Commands;
|
||||
use base64::prelude::*;
|
||||
use hmac::{digest::generic_array::functional::FunctionalSequence, Hmac, Mac};
|
||||
|
@ -31,18 +31,12 @@ struct KeycloakToken {
|
|||
#[serde(rename_all = "camelCase")]
|
||||
pub struct DecodedJWT {
|
||||
#[serde(rename = "resource_access")]
|
||||
pub resource_access: Option<ResourceAccess>,
|
||||
pub resource_access: HashMap<String, Roles>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct ResourceAccess {
|
||||
pub couchdb: Option<Couchdb>,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct Couchdb {
|
||||
pub struct Roles {
|
||||
pub roles: Vec<String>,
|
||||
}
|
||||
|
||||
|
@ -80,7 +74,7 @@ impl KeycloakToken {
|
|||
}
|
||||
|
||||
fn decode_token(&self) -> Result<DecodedJWT, Box<dyn Error>> {
|
||||
let data = self.access_token.split(".").skip(1).next();
|
||||
let data = self.access_token.split('.').nth(1);
|
||||
if data.is_none() {
|
||||
return Err("Invalid JWT".into());
|
||||
}
|
||||
|
@ -92,13 +86,10 @@ impl KeycloakToken {
|
|||
impl DecodedJWT {
|
||||
/// Creates the user struct from the JWT Token
|
||||
fn get_user(self, name: String) -> User {
|
||||
let roles = match self.resource_access {
|
||||
let roles = match self.resource_access.get(&env::var("KEYCLOAK_CLIENT_ID").unwrap()) {
|
||||
None => vec![],
|
||||
Some(ra) => {
|
||||
match ra.couchdb {
|
||||
None => vec![],
|
||||
Some(cdb) => cdb.roles
|
||||
}
|
||||
Some(roles) => {
|
||||
roles.roles.clone()
|
||||
}
|
||||
};
|
||||
User {
|
||||
|
@ -191,9 +182,9 @@ async fn authenticate_keycloak(username: String, password: String) -> Result<Use
|
|||
/// Retrieves the username and password from a Basic Auth
|
||||
fn extract_creds_from_request(req: &Request<Body>) -> Option<(String, String)> {
|
||||
let auth_value = req.headers().get("authorization")?;
|
||||
let b64_auth = auth_value.to_str().unwrap_or("").split(" ").skip(1).next()?;
|
||||
let b64_auth = auth_value.to_str().unwrap_or("").split(' ').nth(1)?;
|
||||
let decoded_auth = String::from_utf8(BASE64_STANDARD.decode(b64_auth.as_bytes()).unwrap_or(vec![])).unwrap();
|
||||
if let [username, password] = &decoded_auth.split(":").map(String::from).collect::<Vec<String>>()[..] {
|
||||
if let [username, password] = &decoded_auth.split(':').map(String::from).collect::<Vec<String>>()[..] {
|
||||
Some((username.to_string(), password.to_string()))
|
||||
} else {
|
||||
None
|
||||
|
@ -215,14 +206,13 @@ fn error_response((status_code, msg) : (u16, String)) -> Response<Body> {
|
|||
.unwrap()
|
||||
}
|
||||
|
||||
async fn handle(old_req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
|
||||
async fn handle(mut req: Request<Body>) -> Result<Response<Body>, hyper::Error> {
|
||||
let client = Client::new();
|
||||
|
||||
// Build proxied Request
|
||||
let mut req = Request::from(old_req);
|
||||
let path = req.uri().path();
|
||||
let path = req.uri().path_and_query();
|
||||
*req.uri_mut() =
|
||||
Uri::from_str(format!("http://{}:{}{}", env::var("COUCHDB_HOST").unwrap(), env::var("COUCHDB_PORT").unwrap(), path.to_string()).as_str()).unwrap();
|
||||
Uri::from_str(format!("http://{}:{}{}", env::var("COUCHDB_HOST").unwrap(), env::var("COUCHDB_PORT").unwrap(), path.unwrap()).as_str()).unwrap();
|
||||
|
||||
if req.method() == Method::OPTIONS {
|
||||
return client.request(req).await
|
||||
|
@ -257,7 +247,6 @@ async fn handle(old_req: Request<Body>) -> Result<Response<Body>, hyper::Error>
|
|||
Err(x) => Err(x),
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let make_service = make_service_fn(|_| async { Ok::<_, Infallible>(service_fn(handle)) });
|
||||
|
|
Loading…
Reference in a new issue