summaryrefslogtreecommitdiffstats
path: root/crates/auth-service/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'crates/auth-service/src/server')
-rw-r--r--crates/auth-service/src/server/keys.rs38
-rw-r--r--crates/auth-service/src/server/routes/authorised.rs12
2 files changed, 46 insertions, 4 deletions
diff --git a/crates/auth-service/src/server/keys.rs b/crates/auth-service/src/server/keys.rs
new file mode 100644
index 0000000..5c9ee43
--- /dev/null
+++ b/crates/auth-service/src/server/keys.rs
@@ -0,0 +1,38 @@
+use rsa::{
+ pkcs8::{EncodePrivateKey, EncodePublicKey, LineEnding},
+ RsaPrivateKey,
+ RsaPublicKey,
+};
+
+use crate::error::AppError;
+
+/// A private/public key pair used for HTTP signatures
+#[derive(Debug, Clone)]
+pub struct Keypair {
+ /// Private key in PEM format
+ pub private_key: String,
+ /// Public key in PEM format
+ pub public_key: String,
+}
+
+impl Keypair {
+ /// Helper method to turn this into an openssl private key
+ #[cfg(test)]
+ pub(crate) fn private_key(&self) -> Result<RsaPrivateKey, anyhow::Error> {
+ use rsa::pkcs8::DecodePrivateKey;
+
+ Ok(RsaPrivateKey::from_pkcs8_pem(&self.private_key)?)
+ }
+}
+
+pub fn generate_actor_keypair() -> Result<Keypair, AppError> {
+ let mut rng = rand::thread_rng();
+ let rsa = RsaPrivateKey::new(&mut rng, 2048)?;
+ let pkey = RsaPublicKey::from(&rsa);
+ let public_key = pkey.to_public_key_pem(LineEnding::default())?;
+ let private_key = rsa.to_pkcs8_pem(LineEnding::default())?.to_string();
+ Ok(Keypair {
+ private_key,
+ public_key,
+ })
+}
diff --git a/crates/auth-service/src/server/routes/authorised.rs b/crates/auth-service/src/server/routes/authorised.rs
index 2538cdc..b4c2e00 100644
--- a/crates/auth-service/src/server/routes/authorised.rs
+++ b/crates/auth-service/src/server/routes/authorised.rs
@@ -23,7 +23,7 @@ use crate::{
auth::Claims,
error::AppError,
server::{
- OAUTH_CSRF_COOKIE, csrf_token_validation::csrf_token_validation_workflow, routes::Provider,
+ csrf_token_validation::csrf_token_validation_workflow, keys::generate_actor_keypair, routes::Provider, OAUTH_CSRF_COOKIE
},
state::AppHandle,
};
@@ -49,6 +49,7 @@ struct User {
struct DbUser {
id: Uuid,
email: String,
+ private_key: String,
created_at: OffsetDateTime,
updated_at: OffsetDateTime,
}
@@ -92,8 +93,6 @@ pub async fn login_authorised(
.await
.context("failed to deserialise response as JSON")?;
- dbg!(&user_data);
-
let user_data: User = serde_json::from_value(user_data)?;
if !user_data.verified {
@@ -124,19 +123,22 @@ pub async fn login_authorised(
.fetch_optional(&mut *transaction)
.await?;
+ let keys = generate_actor_keypair()?;
+
let user = if let Some(user) = user {
user
} else {
let uuid = uuid::Uuid::now_v7();
let user = sqlx::query_as!(
DbUser,
- "insert into auth_user (id, email) values ($1, $2)
+ "insert into auth_user (id, email, private_key) values ($1, $2, $3)
on conflict (email) do update
set email = excluded.email
returning *;
",
uuid,
user_data.email,
+ keys.private_key,
)
.fetch_one(&mut *transaction)
.await?;
@@ -180,6 +182,7 @@ pub async fn login_authorised(
),
)?;
+
let user_request = CreateUserRequest {
email: user_data.email.to_owned(),
avatar: user_data.avatar.as_ref().map(|value| {
@@ -188,6 +191,7 @@ pub async fn login_authorised(
user_data.id
)
}),
+ public_key: keys.public_key,
};
store