Skip to content

Commit

Permalink
feat(fc-pallet-pass): cache authentication attempt result to avoid re…
Browse files Browse the repository at this point in the history
…peating ourselves
  • Loading branch information
pandres95 committed Oct 10, 2024
1 parent 594c901 commit a9cc757
Showing 1 changed file with 33 additions and 24 deletions.
57 changes: 33 additions & 24 deletions pallets/pass/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ pub mod pallet {
pub type Sessions<T: Config<I>, I: 'static = ()> =
StorageMap<_, Blake2_128Concat, T::AccountId, (T::AccountId, BlockNumberFor<T>)>;

#[pallet::storage]
pub type AuthenticationAttempts<T: Config<I>, I: 'static = ()> =
StorageMap<_, Blake2_128Concat, DeviceId, Result<T::AccountId, DispatchError>>;

#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config<I>, I: 'static = ()> {
Expand Down Expand Up @@ -154,19 +158,9 @@ pub mod pallet {

#[pallet::feeless_if(
|_: &OriginFor<T>, device_id: &DeviceId, credential: &CredentialOf<T, I>, _: &Option<BlockNumberFor<T>>| -> bool {
Pallet::<T, I>::account_id_for(credential.user_id())
.and_then(|account_id| {
ensure!(
Pallet::<T, I>::account_exists(&account_id),
Error::<T, I>::AccountNotFound
);
let device = Devices::<T, I>::get(&account_id, device_id)
.ok_or::<DispatchError>(Error::<T, I>::DeviceNotFound.into())?;
device
.verify_user(credential)
.ok_or(Error::<T, I>::CredentialInvalid.into())
})
.is_ok()
let authentication_attempt = Pallet::<T, I>::try_authenticate(device_id, credential);
AuthenticationAttempts::<T, I>::insert(device_id, authentication_attempt.clone());
authentication_attempt.is_ok()
}
)]
#[pallet::call_index(3)]
Expand All @@ -177,17 +171,14 @@ pub mod pallet {
duration: Option<BlockNumberFor<T>>,
) -> DispatchResult {
let who = ensure_signed(origin)?;
let account_id = Self::account_id_for(credential.user_id())?;
ensure!(
Self::account_exists(&account_id),
Error::<T, I>::AccountNotFound
);

let device = Devices::<T, I>::get(&account_id, device_id)
.ok_or(Error::<T, I>::DeviceNotFound)?;
device
.verify_user(&credential)
.ok_or(Error::<T, I>::CredentialInvalid)?;
let account_id = if let Some(authentication_attempt) =
AuthenticationAttempts::<T, I>::get(device_id)
{
AuthenticationAttempts::<T, I>::remove(device_id);
authentication_attempt
} else {
Self::try_authenticate(&device_id, &credential)
}?;

Self::do_add_session(&who, &account_id, duration);
Ok(())
Expand Down Expand Up @@ -267,6 +258,24 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
Ok(())
}

pub(crate) fn try_authenticate(
device_id: &DeviceId,
credential: &CredentialOf<T, I>,
) -> Result<T::AccountId, DispatchError> {
let account_id = Self::account_id_for(credential.user_id())?;
ensure!(
Self::account_exists(&account_id),
Error::<T, I>::AccountNotFound
);
let device =
Devices::<T, I>::get(&account_id, device_id).ok_or(Error::<T, I>::DeviceNotFound)?;
device
.verify_user(credential)
.ok_or(Error::<T, I>::CredentialInvalid)?;

Ok(account_id)
}

pub(crate) fn do_add_device(
who: &T::AccountId,
attestation: DeviceAttestationOf<T, I>,
Expand Down

0 comments on commit a9cc757

Please sign in to comment.