Skip to content

Commit

Permalink
Support auth token based auth
Browse files Browse the repository at this point in the history
  • Loading branch information
obmarg committed Jul 24, 2021
1 parent e3f0e49 commit c83caf0
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 25 deletions.
6 changes: 4 additions & 2 deletions ingle/src/database/auth/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 6,16 @@ pub use token::Token;

#[derive(Clone)]
pub enum Credentials {
Default(Token),
ServiceAccount(Token),
AuthToken(String),
EmulatorOwner,
}

impl std::fmt::Debug for Credentials {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Credentials::Default(_) => write!(f, "Credentials::Default(_)"),
Credentials::ServiceAccount(_) => write!(f, "Credentials::ServiceAccount(_)"),
Credentials::AuthToken(_) => write!(f, "Credentials::AuthToken(_)"),
Credentials::EmulatorOwner => write!(f, "Credentials::EmulatorOwner"),
}
}
Expand Down
17 changes: 12 additions & 5 deletions ingle/src/database/auth/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 2,7 @@
use std::sync::Arc;
use std::task::{Context, Poll};
use tonic::codegen::http::{HeaderValue, Request};
use tonic::codegen::http::{header::AUTHORIZATION, HeaderValue, Request};
use tonic::metadata::MetadataValue;
use tower_service::Service;

Expand Down Expand Up @@ -37,15 37,22 @@ where
#[inline]
fn call(&mut self, mut request: Request<Body>) -> Self::Future {
match &self.credentials {
Some(Credentials::Default(token)) => {
Some(Credentials::ServiceAccount(token)) => {
let jwt = token.jwt();
request.headers_mut().insert(
"authorization",
HeaderValue::from_str(&format!("Bearer {}", token.jwt())).unwrap(),
AUTHORIZATION,
HeaderValue::from_str(&format!("Bearer {}", jwt)).unwrap(),
);
}
Some(Credentials::AuthToken(token)) => {
request.headers_mut().insert(
AUTHORIZATION,
HeaderValue::from_str(&format!("Bearer {}", token)).unwrap(),
);
}
Some(Credentials::EmulatorOwner) => {
request.headers_mut().insert(
"authorization",
AUTHORIZATION,
HeaderValue::from_str("Bearer owner").unwrap(),
);
}
Expand Down
16 changes: 4 additions & 12 deletions ingle/src/database/auth/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 51,6 @@ impl Token {
) -> Result<Self, frank_jwt::Error> {
Token::new(audience, credentials_from_file(path)?)
}

pub fn from_default_credentials(audience: impl ToString) -> Result<Self, frank_jwt::Error> {
Token::from_file(
std::env::var("GOOGLE_APPLICATION_CREDENTIALS")
.expect("GOOGLE_APPLICATION_CREDENTIALS not defined"),
audience,
)
}
}

static JWT_VALID_TIME: Duration = Duration::from_secs(10 * 60);
Expand Down Expand Up @@ -92,11 84,11 @@ impl TokenInner {
.as_secs();

let claims = json!({
"sub": email.clone(),
"iss": email.clone(),
"aud": audience.to_owned(),
"sub": &email,
"iss": &email,
"aud": &audience,
"iat": now_timestamp,
"exp": expires_at_timestamp,
"exp": expires_at_timestamp
});

let header = json!({});
Expand Down
19 changes: 15 additions & 4 deletions ingle/src/database/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 2,7 @@ use std::time::Duration;

use tonic::{
metadata::MetadataValue,
transport::{self, Endpoint},
transport::{self, ClientTlsConfig, Endpoint},
Request,
};

Expand All @@ -28,7 28,9 @@ pub struct DatabaseBuilder {
impl DatabaseBuilder {
pub fn new(project_id: impl Into<String>) -> DatabaseBuilder {
DatabaseBuilder {
endpoint: Endpoint::from_static(FIRESTORE_ENDPOINT),
endpoint: Endpoint::from_static(FIRESTORE_ENDPOINT)
.tls_config(ClientTlsConfig::default())
.expect("Couldn't configure TLS"),
credentials: None,
project_id: project_id.into(),
database_id: DEFAULT_DATABASE.to_string(),
Expand All @@ -38,7 40,9 @@ impl DatabaseBuilder {
pub fn https_endpoint(self, url: &str) -> Self {
DatabaseBuilder {
endpoint: Endpoint::from_shared(format!("https://{}", url))
.expect("Invalid firestore URL"),
.expect("Invalid firestore URL")
.tls_config(ClientTlsConfig::default())
.expect("Couldn't initialise TLS"),
..self
}
}
Expand Down Expand Up @@ -85,7 89,7 @@ impl DatabaseBuilder {
};

Ok(DatabaseBuilder {
credentials: Some(Credentials::Default(Token::from_file(
credentials: Some(Credentials::ServiceAccount(Token::from_file(
filename,
FIRESTORE_TOKEN_AUDIENCE,
)?)),
Expand All @@ -100,6 104,13 @@ impl DatabaseBuilder {
}
}

pub fn auth_token(self, token: impl Into<String>) -> Self {
DatabaseBuilder {
credentials: Some(Credentials::AuthToken(token.into())),
..self
}
}

#[allow(clippy::redundant_closure)]
pub async fn connect(self) -> Result<Database, ConnectError> {
// TODO: Probably want retries at some point?
Expand Down
3 changes: 1 addition & 2 deletions ingle/tests/integration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 6,7 @@ use ingle::{
#[tokio::test]
async fn test_adding_document() {
let database = DatabaseBuilder::new("nandos-api-platform")
.default_credentials()
.unwrap()
.auth_token(std::env::var("GOOGLE_TOKEN").unwrap())
.connect()
.await
.unwrap();
Expand Down

0 comments on commit c83caf0

Please sign in to comment.