Skip to content

Commit

Permalink
fix(authn): only create a user if the identifier doesn't already exist (
Browse files Browse the repository at this point in the history
  • Loading branch information
its-danny authored Sep 20, 2024
1 parent 2bb4641 commit 521e9d1
Show file tree
Hide file tree
Showing 14 changed files with 122 additions and 27 deletions.
49 changes: 28 additions & 21 deletions authn/src/handlers/hook.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,36 +49,43 @@ async fn handle_registration(

let auth_session = serde_json::from_str::<AuthSessionData>(&auth_session)?;

// Create the user and associated DID.
// -----------------------------------
// Create the user and associated DID if they don't already exist.
// ---------------------------------------------------------------

state
.repos
.users
.create(
&CreateUser::builder()
.id(auth_session.user_id)
.service_id(auth_session.service_id)
.build(),
)
.await?;

state
let existing = state
.repos
.identifiers
.create(
&CreateIdentifier::builder()
.value(body.data.identifier.clone())
.user_id(auth_session.user_id)
.build(),
)
.get_by_value(&body.data.identifier)
.await?;

if existing.is_none() {
state
.repos
.users
.create(
&CreateUser::builder()
.id(auth_session.user_id)
.service_id(auth_session.service_id)
.build(),
)
.await?;

state
.repos
.identifiers
.create(
&CreateIdentifier::builder()
.value(body.data.identifier.clone())
.user_id(auth_session.user_id)
.build(),
)
.await?;
}

// Complete the registration process.
// ----------------------------------

// Send an event to the user's browser to let it know authentication is complete.
//
// This event will be picked up by an event listener in the browser listening to the `wait` handler.
state
.redis_pub_client
Expand Down
25 changes: 25 additions & 0 deletions db/.sqlx/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use serde::{Deserialize, Serialize};
use uuid::Uuid;

pub mod app;
mod crypto;
mod handlers;
mod state;
mod webhooks;

const COOKIE_KEY: &str = "id";
const REDIS_AUTH_KEY: &str = "auth";
const REDIS_AUTH_HOOK_KEY: &str = "auth-hook";
const REDIS_RESPONSE_RECEIVED_KEY: &str = "response-received";

#[derive(Serialize, Deserialize)]
pub(crate) struct AuthSessionData {
pub(crate) service_id: Uuid,
pub(crate) user_id: Uuid,
}

#[derive(Serialize, Deserialize)]
pub(crate) struct AuthHookSessionData {
pub(crate) hook_id: Uuid,
pub(crate) user_session_id: Uuid,
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 2 additions & 4 deletions db/migrations/20240908190542_create_identifiers.up.sql
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
-- Add up migration script here
create table identifiers (
id uuid primary key default uuid_generate_v4(),
value text not null,
value text unique not null,
user_id uuid not null references users(id) on delete cascade,

created_at timestamptz not null default now(),
updated_at timestamptz not null default now(),

unique (user_id, value)
updated_at timestamptz not null default now()
);

create or replace trigger set_updated_at before update on identifiers
Expand Down
4 changes: 2 additions & 2 deletions db/schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -190,11 +190,11 @@ ALTER TABLE ONLY public.identifiers


--
-- Name: identifiers identifiers_user_id_value_key; Type: CONSTRAINT; Schema: public; Owner: casper
-- Name: identifiers identifiers_value_key; Type: CONSTRAINT; Schema: public; Owner: casper
--

ALTER TABLE ONLY public.identifiers
ADD CONSTRAINT identifiers_user_id_value_key UNIQUE (user_id, value);
ADD CONSTRAINT identifiers_value_key UNIQUE (value);


--
Expand Down
1 change: 1 addition & 0 deletions db/sql/identifiers/get_by_value.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
select * from identifiers where value = $1;
9 changes: 9 additions & 0 deletions db/src/repos/identifiers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::models::identifier::{CreateIdentifier, Identifier};
#[mockall::automock]
pub trait IdentifierRepo: Send + Sync {
async fn create(&self, data: &CreateIdentifier) -> Result<Identifier>;
async fn get_by_value(&self, value: &str) -> Result<Option<Identifier>>;
}

pub struct PgIdentifierRepo {
Expand All @@ -34,4 +35,12 @@ impl IdentifierRepo for PgIdentifierRepo {

Ok(identifier)
}

async fn get_by_value(&self, value: &str) -> Result<Option<Identifier>> {
let identifier = query_file_as!(Identifier, "sql/identifiers/get_by_value.sql", value)
.fetch_optional(&self.pool)
.await?;

Ok(identifier)
}
}

0 comments on commit 521e9d1

Please sign in to comment.