Skip to content

Commit 0aea023

Browse files
committed
fix: add determine functions for working out credential status
1 parent be0dd56 commit 0aea023

File tree

1 file changed

+89
-23
lines changed

1 file changed

+89
-23
lines changed

src/web3id.rs

Lines changed: 89 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ use crate::{
66
cis4::{Cis4Contract, Cis4QueryError},
77
v2::{self, BlockIdentifier, IntoBlockIdentifier},
88
};
9+
use chrono::{Utc, DateTime};
910
pub use concordium_base::web3id::*;
1011
use concordium_base::{
1112
base::CredentialRegistrationID, cis4_types::CredentialStatus, contracts_common::AccountAddress, id::{constants::{ArCurve, IpPairing}, types::{ArInfos, IpIdentity}}, web3id
@@ -119,13 +120,9 @@ pub async fn verify_credential_metadata(
119120
"Credential creation date is not valid.".into(),
120121
)
121122
})?;
122-
let status = if valid_from > now {
123-
CredentialStatus::NotActivated
124-
} else if valid_until < now {
125-
CredentialStatus::Expired
126-
} else {
127-
CredentialStatus::Active
128-
};
123+
124+
let status = determine_credential_status_valid_from_valid_to(now, valid_from, valid_until);
125+
129126
let inputs = CredentialsInputs::Account {
130127
commitments: commitments.cmm_attributes.clone(),
131128
};
@@ -145,7 +142,6 @@ pub async fn verify_credential_metadata(
145142
Ok(CredentialWithMetadata { status, inputs })
146143
}
147144

148-
// TODO - Identity handling for credential
149145
CredentialMetadata::Identity { issuer, validity } => {
150146

151147
// get all the identity providers at current block
@@ -180,28 +176,40 @@ pub async fn verify_credential_metadata(
180176
// build inputs
181177
let inputs = CredentialsInputs::Identity { ip_info: matching_idp.clone(), ars_infos: ArInfos { anonymity_revokers: anonymity_revoker_infos } };
182178

183-
// TODO - change me, probably need to do something similar to how we handle the account - where we check the validity created at and valid to
184-
// validity.created_at
185-
// validity.valid_to
179+
// Credential Status handling
186180
let now = client.get_block_info(bi).await?.response.block_slot_time;
187181

188-
// TODO temporary dummy status for now
189-
let status = CredentialStatus::Active;
190-
/*
191-
let status = if &validity.valid_to.year < YearMonth::now() {
192-
CredentialStatus::Expired
193-
} else if &validity.valid_to >= YearMonth::now() {
194-
CredentialStatus::Active
195-
} else {
196-
CredentialStatus::NotActivated
197-
};
198-
*/
182+
let valid_to = validity.valid_to.upper()
183+
.ok_or(CredentialLookupError::InvalidResponse("Error while getting annonymity revokers.".into()))?;
184+
185+
let credential_status = determine_credential_status_valid_to(now, valid_to);
199186

200-
Ok(CredentialWithMetadata { inputs: inputs, status: status})
187+
Ok(CredentialWithMetadata { inputs: inputs, status: credential_status})
201188
}
202189
}
203190
}
204191

192+
193+
/// determine the credential status where both the valid from and valid to is provided
194+
fn determine_credential_status_valid_from_valid_to(time_to_compare_to: DateTime<Utc>, valid_from: DateTime<Utc>, valid_to: DateTime<Utc>) -> CredentialStatus {
195+
if valid_from > time_to_compare_to {
196+
CredentialStatus::NotActivated
197+
}
198+
else {
199+
determine_credential_status_valid_to(time_to_compare_to, valid_to)
200+
}
201+
}
202+
203+
/// determine the credential status where you only have a `valid to` field and no valid from (such as identity)
204+
fn determine_credential_status_valid_to(time_to_compare_to: DateTime<Utc>, valid_to: DateTime<Utc>) -> CredentialStatus {
205+
if valid_to < time_to_compare_to {
206+
CredentialStatus::Expired
207+
}
208+
else {
209+
CredentialStatus::Active
210+
}
211+
}
212+
205213
/// Retrieve the public data of credentials validating any metadata that is
206214
/// part of the credentials.
207215
///
@@ -226,3 +234,61 @@ pub async fn get_public_data(
226234
.collect::<futures::stream::FuturesOrdered<_>>();
227235
stream.try_collect().await
228236
}
237+
238+
#[cfg(test)]
239+
mod tests {
240+
use super::*;
241+
242+
/// valid from is before now, valid to is in the future, therefore credential status should be `active`
243+
#[test]
244+
fn test_determine_credential_status_as_active_for_account() {
245+
let now = Utc::now();
246+
let valid_from = now.checked_sub_days(20);
247+
let valid_to = now.checked_add_days(30);
248+
249+
let status = determine_credential_status_valid_from_valid_to(now, valid_from, valid_to);
250+
assert_eq!(CredentialStatus::Active, status);
251+
}
252+
253+
/// valid from is after now, valid to is in the future, therefore credential status should be `not activated`
254+
#[test]
255+
fn test_determine_credential_status_as_not_activated_valid_from_after_today() {
256+
let now = Utc::now();
257+
let valid_from = now.checked_add_days(2);
258+
let valid_to = now.checked_add_days(30);
259+
260+
let status = determine_credential_status_valid_from_valid_to(now, valid_from, valid_to);
261+
assert_eq!(CredentialStatus::NotActivated, status);
262+
}
263+
264+
/// valid from is before now, valid to is in the past, therefore credential status should be `expired`
265+
#[test]
266+
fn test_determine_credential_status_as_not_activated_valid_from_after_today() {
267+
let now = Utc::now();
268+
let valid_from = now.checked_sub_days(100);
269+
let valid_to = now.checked_sub_days(30);
270+
271+
let status = determine_credential_status_valid_from_valid_to(now, valid_from, valid_to);
272+
assert_eq!(CredentialStatus::Expired, status);
273+
}
274+
275+
// identity credential status check, returns as active for valid to date in the future
276+
#[test]
277+
fn test_determine_credential_status_as_active_for_account() {
278+
let now = Utc::now();
279+
let valid_to = now.checked_add_days(30);
280+
281+
let status = determine_credential_status_valid_to(now, valid_to);
282+
assert_eq!(CredentialStatus::Active, status);
283+
}
284+
285+
// identity credential status check, returns as expired for valid to date in the past
286+
#[test]
287+
fn test_determine_credential_status_as_expired_for_account() {
288+
let now = Utc::now();
289+
let valid_to = now.checked_sub_days(1);
290+
291+
let status = determine_credential_status_valid_to(now, valid_to);
292+
assert_eq!(CredentialStatus::Expired, status);
293+
}
294+
}

0 commit comments

Comments
 (0)