libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

commit e5c3c0d1d2561d43829200321f4fd326174987ce
parent 23acdbd445d2a9a8f22eecc2459cc4e962d4a4f1
Author: Antoine A <>
Date:   Fri,  4 Sep 2026 13:08:51 +0200

bank: fix token API

Diffstat:
MCargo.lock | 48++++++++++++++++++++++++------------------------
Mlibeufin-bank/src/api.rs | 46++++++++++++++++++++++++++++++++--------------
Mlibeufin-bank/src/api/account.rs | 24+++++++++++++-----------
Mlibeufin-bank/src/api/cashout.rs | 2+-
Mlibeufin-bank/src/api/prepared.rs | 2+-
Mlibeufin-bank/src/api/tan.rs | 4+++-
Mlibeufin-bank/src/api/token.rs | 117+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------
Mlibeufin-bank/src/api/tx.rs | 2+-
Mlibeufin-bank/src/auth.rs | 4++--
Mlibeufin-bank/src/bench.rs | 2+-
Mlibeufin-bank/src/db/token.rs | 14+++++++-------
Mlibeufin-bank/src/lib.rs | 2+-
Mlibeufin-bank/src/pw.rs | 2+-
Mlibeufin-nexus/src/api.rs | 2+-
Mlibeufin-nexus/src/bench.rs | 2+-
15 files changed, 195 insertions(+), 78 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -170,9 +170,9 @@ checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "aws-lc-rs" -version = "1.18.0" +version = "1.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce2b2dcc879c3bae0d371e77c99f2238400ef24ec001394befa67b6e543add9e" +checksum = "b281d307588d634de920874890732659e2e7672f72b5e10e81badc1a8a83621e" dependencies = [ "aws-lc-sys", "untrusted 0.7.1", @@ -181,9 +181,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.44.0" +version = "0.45.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f09fae7be8bb3174e05c6afdb34199e6dc0c7c04ba9fa237b1967adfbde27483" +checksum = "9bff6c3b54fad79a2e60b8102caf565819711497c1f5f092f49508e2f5c31b27" dependencies = [ "cc", "cmake", @@ -390,9 +390,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.4.4" +version = "1.4.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad534f4357a5264cce5019c989cf66a4f0dc4e0d1b1d15f8aacec0ff7360273" +checksum = "005ec2760ca554fae18df7a11195552ec576cd665632a881bc011d5bb2fd4d80" dependencies = [ "find-msvc-tools", "jobserver", @@ -1005,9 +1005,9 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.11" +version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d45db016d36b838f563236e9193d0ee6ce38f3f68b6c94e914b4929c96bbb890" +checksum = "3e0f1c7c3a72c66fd80abe965175f7523475c0489a87d3ff9d6e8c87d87a9d2d" [[package]] name = "flate2" @@ -1349,7 +1349,7 @@ dependencies = [ [[package]] name = "http-client" version = "1.5.0" -source = "git+git://git.taler.net/taler-rust.git/#48c40c365ac671cbbe1ac2fb359e1a5cf7e165a3" +source = "git+git://git.taler.net/taler-rust.git/#14f571a7e85caf215a7e9995914026f064f488fe" dependencies = [ "compact_str", "futures-util", @@ -1917,9 +1917,9 @@ dependencies = [ [[package]] name = "libredox" -version = "0.1.21" +version = "0.1.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7955dfc218a8afb29dfeffd540e3a6e96baeb94fe7138228dd7cc6937fbbf96" +checksum = "8d8f1ea3f21fd3405dcaf6c9b5c1630af9afc422d9073ea39c5f6d6c772e08ed" dependencies = [ "bitflags 2.13.1", "libc", @@ -2042,9 +2042,9 @@ checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" [[package]] name = "mio" -version = "1.2.2" +version = "1.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427" +checksum = "4b18443e9c262bfe8fa82f51666e2642c53393f7e5c27b3e1aeab922cff5b9d8" dependencies = [ "libc", "log", @@ -3090,9 +3090,9 @@ checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" [[package]] name = "smallvec" -version = "1.15.2" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ed6a63f02c8539c91a8685a86f4099661ba3da017932f6ebbea6de3f0fa7c90" +checksum = "b9be42f50aa861c555654aa3a37f52f4b1074bacf4e48fe0ef7fa584e80f1f0f" dependencies = [ "serde", ] @@ -3451,7 +3451,7 @@ dependencies = [ [[package]] name = "taler-api" version = "1.5.0" -source = "git+git://git.taler.net/taler-rust.git/#48c40c365ac671cbbe1ac2fb359e1a5cf7e165a3" +source = "git+git://git.taler.net/taler-rust.git/#14f571a7e85caf215a7e9995914026f064f488fe" dependencies = [ "aws-lc-rs", "axum", @@ -3479,12 +3479,12 @@ dependencies = [ [[package]] name = "taler-build" version = "1.5.0" -source = "git+git://git.taler.net/taler-rust.git/#48c40c365ac671cbbe1ac2fb359e1a5cf7e165a3" +source = "git+git://git.taler.net/taler-rust.git/#14f571a7e85caf215a7e9995914026f064f488fe" [[package]] name = "taler-common" version = "1.5.0" -source = "git+git://git.taler.net/taler-rust.git/#48c40c365ac671cbbe1ac2fb359e1a5cf7e165a3" +source = "git+git://git.taler.net/taler-rust.git/#14f571a7e85caf215a7e9995914026f064f488fe" dependencies = [ "anyhow", "aws-lc-rs", @@ -3514,7 +3514,7 @@ dependencies = [ [[package]] name = "taler-macros" version = "1.5.0" -source = "git+git://git.taler.net/taler-rust.git/#48c40c365ac671cbbe1ac2fb359e1a5cf7e165a3" +source = "git+git://git.taler.net/taler-rust.git/#14f571a7e85caf215a7e9995914026f064f488fe" dependencies = [ "proc-macro2", "quote", @@ -3524,7 +3524,7 @@ dependencies = [ [[package]] name = "taler-test-utils" version = "1.5.0" -source = "git+git://git.taler.net/taler-rust.git/#48c40c365ac671cbbe1ac2fb359e1a5cf7e165a3" +source = "git+git://git.taler.net/taler-rust.git/#14f571a7e85caf215a7e9995914026f064f488fe" dependencies = [ "aws-lc-rs", "axum", @@ -3661,9 +3661,9 @@ dependencies = [ [[package]] name = "tinyvec" -version = "1.12.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb4ebadaa0af04fab11ae01eb5f9fdb5f9c5b875506e210e71c07873528baa7f" +checksum = "4cf0ded5c4e56918d8f8a339e1bb67d038d3bc6d144ac407904015ba2e4cde9b" dependencies = [ "tinyvec_macros", ] @@ -3703,9 +3703,9 @@ dependencies = [ [[package]] name = "tokio-rustls" -version = "0.26.4" +version = "0.26.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +checksum = "b0c85f2c3ef0b1cd58b36682f4b17aaa995f0e5db534d85692b4903abce21f67" dependencies = [ "rustls", "tokio", diff --git a/libeufin-bank/src/api.rs b/libeufin-bank/src/api.rs @@ -354,7 +354,7 @@ pub mod test { async { let res = pw_auth( self.server.post(format!("/accounts/{username}/token")), - Some("admin"), + Some(&username), ) .json(json!({ "scope": "readwrite", @@ -363,6 +363,8 @@ pub mod test { } })) .await + .maybe_challenge(&self) + .await .assert_ok_json::<serde_json::Value>(); let token = res["access_token"].as_str().unwrap(); (username, format!("Bearer {token}")) @@ -477,7 +479,12 @@ pub mod test { .await .assert_error(ErrorCode::GENERIC_FORBIDDEN); } - Auth::UserOrAdmin | Auth::Token | Auth::Optional => {} + Auth::UserOrAdmin | Auth::Optional => {} + Auth::Token => { + self.requesta(method.clone(), path, Some("admin")) + .await + .assert_error(ErrorCode::GENERIC_TOKEN_PERMISSION_INSUFFICIENT); + } Auth::UserOnly => { self.requesta(method.clone(), path, Some("admin")) .await @@ -885,21 +892,21 @@ pub mod test { pub trait MfaRequest { fn assert_challenge_check( &self, - ctx: &BankTestCtx, + ctx: &BankClient, check: impl AsyncFnOnce(&ChallengeResponse), ) -> impl std::future::Future<Output = Self>; - fn assert_challenge(&self, ctx: &BankTestCtx) -> impl std::future::Future<Output = Self> { + fn assert_challenge(&self, ctx: &BankClient) -> impl std::future::Future<Output = Self> { self.assert_challenge_check(ctx, async |_| {}) } - fn maybe_challenge(self, ctx: &BankTestCtx) -> impl std::future::Future<Output = Self>; + fn maybe_challenge(self, ctx: &BankClient) -> impl std::future::Future<Output = Self>; } impl MfaRequest for TestResponse { async fn assert_challenge_check( &self, - ctx: &BankTestCtx, + ctx: &BankClient, check: impl AsyncFnOnce(&ChallengeResponse), ) -> TestResponse { let res: ChallengeResponse = self.assert_accepted_json(); @@ -912,7 +919,7 @@ pub mod test { }; for challenge in challenges { - ctx.posta(format!( + ctx.post(format!( "/accounts/{username}/challenge/{}", challenge.challenge_id )) @@ -922,8 +929,13 @@ pub mod test { check(&res).await; for challenge in challenges { - let code = tan_code(&challenge.tan_info).unwrap(); - ctx.posta(format!( + let info = if challenge.tan_info == "REDACTED" { + "+456" + } else { + &challenge.tan_info + }; + let code = tan_code(info).unwrap(); + ctx.post(format!( "/accounts/{username}/challenge/{}/confirm", challenge.challenge_id )) @@ -937,13 +949,19 @@ pub mod test { .into_iter() .map(|it| it.challenge_id) .join_compact(", "); - ctx.requesta(self.method.clone(), self.uri.path(), Some(username)) - .header(TALER_CHALLENGE_IDS, ids.to_string()) - .raw_json(self.req_body.clone()) - .await + let req = ctx + .request(self.method.clone(), self.uri.path()) + .header(TALER_CHALLENGE_IDS, ids.to_string()); + if let Some(auth) = self.req_headers.get(AUTHORIZATION) { + req.header(AUTHORIZATION, auth) + } else { + req + } + .raw_json(self.req_body.clone()) + .await } - async fn maybe_challenge(self, ctx: &BankTestCtx) -> Self { + async fn maybe_challenge(self, ctx: &BankClient) -> Self { if self.status == StatusCode::ACCEPTED { self.assert_challenge(ctx).await } else { diff --git a/libeufin-bank/src/api/account.rs b/libeufin-bank/src/api/account.rs @@ -561,7 +561,9 @@ pub fn account_api() -> Router<Arc<BankState>> { mfa.response_validation(&auth, &state.db, &tans).await } } - PatchResult::UnknownAccount => todo!(), + PatchResult::UnknownAccount => { + Err(failure_code(ErrorCode::BANK_UNKNOWN_ACCOUNT)) + } PatchResult::NonAdminName => { Err(failure_code(ErrorCode::BANK_NON_ADMIN_PATCH_LEGAL_NAME)) } @@ -801,10 +803,10 @@ pub async fn create_account( } /** - * This function creates the admin account ONLY IF it was - * NOT found in the database. It sets it to a random password that - * is only meant to be overridden by a dedicated CLI tool - */ +* This function creates the admin account ONLY IF it was +* NOT found in the database. It sets it to a random password that +* is only meant to be overridden by a dedicated CLI tool +*/ pub async fn create_admin_account( db: &PgPool, cfg: &BankCfg, @@ -1165,11 +1167,11 @@ pub mod test { .assert_error(ErrorCode::BANK_PASSWORD_TOO_SHORT); // Long password ctx.post("/accounts") - .json(json!(req +{ - "password": "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong-password" - })) - .await - .assert_error(ErrorCode::BANK_PASSWORD_TOO_LONG); + .json(json!(req +{ + "password": "loooooooooooooooooooooooooooooooooooooooooooooooooooooooooooong-password" + })) + .await + .assert_error(ErrorCode::BANK_PASSWORD_TOO_LONG); // Check currency ctx.post_admin("/accounts") .json(json!(req + { "debit_threshold": "EUR:100" })) @@ -1392,7 +1394,7 @@ pub mod test { #[tokio::test] async fn delete() { let mut ctx = bank_setup().await; - ctx.auth_routine(Method::DELETE, "/accounts/merchant", Auth::Token) + ctx.auth_routine(Method::DELETE, "/accounts/merchant", Auth::UserOrAdmin) .await; // Reserved accounts diff --git a/libeufin-bank/src/api/cashout.rs b/libeufin-bank/src/api/cashout.rs @@ -36,7 +36,7 @@ use taler_api::{ use taler_common::{ api::{ShortHashCode, params::PageParams}, error_code::ErrorCode, - types::{amount::Amount, timestamp::TalerTimestamp}, + types::{amount::Amount, time::TalerTimestamp}, }; use crate::{ diff --git a/libeufin-bank/src/api/prepared.rs b/libeufin-bank/src/api/prepared.rs @@ -38,7 +38,7 @@ use taler_common::{ TransferSubject, Unregistration, }, error_code::ErrorCode, - types::timestamp::TalerTimestamp, + types::time::TalerTimestamp, }; use crate::{ diff --git a/libeufin-bank/src/api/tan.rs b/libeufin-bank/src/api/tan.rs @@ -33,8 +33,9 @@ use taler_api::{ error::{failure, failure_code}, extract::{Path, Req}, }; -use taler_common::{error_code::ErrorCode, types::timestamp::TalerTimestamp}; +use taler_common::{error_code::ErrorCode, types::time::TalerTimestamp}; use tokio::{io::AsyncWriteExt as _, process::Command}; +use tracing::trace; use uuid::Uuid; use crate::{ @@ -88,6 +89,7 @@ pub fn tan_api() -> Router<Arc<BankState>> { } => { let (script, env) = &state.cfg.tan_channels[&channel]; let msg = format!("T-{code} is your {} verification code", state.cfg.name); + trace!(target: "tan", "send {code} with {script}"); let res = async { let mut child = Command::new(script) .arg(&info) diff --git a/libeufin-bank/src/api/token.rs b/libeufin-bank/src/api/token.rs @@ -36,13 +36,13 @@ use taler_common::{ error_code::ErrorCode::{self}, types::{ base32::Base32, - timestamp::{RelativeTime, TalerTimestamp}, + time::{RelativeTime, TalerTimestamp}, }, }; use crate::{ api::BankState, - auth::{TOKEN_PREFIX, TokenScope, UserAuth, UserRAuth, UserRWAuth}, + auth::{TOKEN_PREFIX, TokenScope, UserAuth, UserORWAuth, UserRAuth}, db::{ self, token::{TokenCreationResult, access, create, refresh}, @@ -177,7 +177,7 @@ pub fn token_api() -> Router<Arc<BankState>> { .route( "/accounts/{username}/tokens/{id}", delete( - async |UserAuth { username, .. }: UserRWAuth, + async |UserAuth { username, .. }: UserORWAuth, Path((_, id)): Path<((), u64)>, State(state): State<Arc<BankState>>| { if db::token::delete_by_id(&state.db, &username, id).await? { @@ -221,12 +221,13 @@ pub mod test { use taler_common::{ api::ErrorDetail, error_code::ErrorCode, - types::{base32::Base32, timestamp::TalerTimestamp}, + types::{base32::Base32, time::TalerTimestamp}, }; use taler_test_utils::{json, server::TestServer}; use crate::{ api::{ + account::AccountData, tan::ChallengeResponse, test::{Auth, MfaRequest, bank_setup, tan_code}, token::{TOKEN_DEFAULT_DURATION, TokenInfos, TokenSuccessResponse}, @@ -245,7 +246,7 @@ pub mod test { ctx.auth_routine( Method::DELETE, "/accounts/merchant/tokens/1", - Auth::UserOrAdmin, + Auth::UserOnly, ) .await; @@ -486,6 +487,43 @@ pub mod test { .unwrap() ); + // Kotlin compatibility + { + let TokenSuccessResponse { + access_token, + token_id, + .. + } = ctx + .postpw("/accounts/customer/token") + .json(json!({ + "scope": "readonly", + "refreshable" : true + })) + .await + .assert_ok_json(); + // Patch ID to use old sentinel value + sqlx::query( + "UPDATE bearer_tokens SET expiration_time=9223372036854775807 WHERE bearer_token_id=$1", + ) + .bind(token_id as i64) + .execute(&ctx.state.db) + .await + .unwrap(); + // Check token works + ctx.get("/accounts/customer/tokens") + .header(AUTHORIZATION, format!("Bearer {access_token}")) + .await + .assert_ok(); + // And can be refreshed + ctx.post("/accounts/customer/token") + .header(AUTHORIZATION, format!("Bearer {access_token}")) + .json(json!({ + "scope": "readonly" + })) + .await + .assert_ok(); + } + // 2FA { // Setup a known phone 2FA @@ -578,7 +616,44 @@ pub mod test { lock_account().await; // Check token still works - // TODO + assert!( + ctx.geta("/accounts/merchant") + .await + .assert_ok_json::<AccountData>() + .is_locked + ); + + // Check admin can unlock + ctx.patch_admin("/accounts/merchant/auth") + .json(json!({ + "new_password": "merchant-password" + })) + .await + .assert_no_content(); + assert!( + !ctx.geta("/accounts/merchant") + .await + .assert_ok_json::<AccountData>() + .is_locked + ); + lock_account().await; + + // Check token can unlock + ctx.patcha("/accounts/merchant/auth") + .json(json!({ + "old_password": "merchant-password", + "new_password": "merchant-password" + })) + .await + .assert_challenge(&ctx) + .await + .assert_no_content(); + assert!( + !ctx.geta("/accounts/merchant") + .await + .assert_ok_json::<AccountData>() + .is_locked + ); } } @@ -590,9 +665,11 @@ pub mod test { // Check OK for account in ["merchant", "customer"] { - ctx.geta(format!("/accounts/{account}/tokens")) + let res = ctx + .geta(format!("/accounts/{account}/tokens")) .await - .assert_no_content(); + .assert_ok_json::<TokenInfos>(); + assert_eq!(res.tokens.len(), 1); } for scope in ["readonly", "readwrite"] { ctx.postpw("/accounts/merchant/token") @@ -600,20 +677,38 @@ pub mod test { .await .assert_ok(); } - ctx.postpw("/accounts/customer/token") + ctx.postpw("/accounts/merchant/token") + .json(json!({ + "scope": "revenue", + "duration": { + "d_us": "forever" + } + })) + .await + .assert_ok(); + ctx.postpw("/accounts/merchant/token") .json(json!({ "scope": "revenue", + "duration": { + "d_us": 0 + } + })) + .await + .assert_ok(); + ctx.postpw("/accounts/customer/token") + .json(json!({ + "scope": "readonly", "description": "description" })) .await .assert_ok(); let res: TokenInfos = ctx.geta("/accounts/merchant/tokens").await.assert_ok_json(); - assert_eq!(res.tokens.len(), 2); + assert_eq!(res.tokens.len(), 4); for token in res.tokens { assert_eq!(token.description, None); } let res: TokenInfos = ctx.geta("/accounts/customer/tokens").await.assert_ok_json(); - assert_eq!(res.tokens.len(), 1); + assert_eq!(res.tokens.len(), 2); assert_eq!(res.tokens[0].description.as_deref(), Some("description")); } } diff --git a/libeufin-bank/src/api/tx.rs b/libeufin-bank/src/api/tx.rs @@ -36,7 +36,7 @@ use taler_api::{ use taler_common::{ api::{ShortHashCode, params::HistoryParams}, error_code::ErrorCode, - types::{amount::Amount, payto::ParsedPayto, timestamp::TalerTimestamp}, + types::{amount::Amount, payto::ParsedPayto, time::TalerTimestamp}, }; use crate::{ diff --git a/libeufin-bank/src/auth.rs b/libeufin-bank/src/auth.rs @@ -37,7 +37,7 @@ use taler_api::error::{ use taler_common::{ encoding::{base32, base64}, error_code::ErrorCode, - types::timestamp::TalerTimestamp, + types::time::TalerTimestamp, }; use taler_macros::EnumMeta; use tracing::warn; @@ -353,7 +353,7 @@ pub struct UserTokenScope; impl UserAuthScope for UserTokenScope { const SCOPE: TokenLogicalScope = TokenLogicalScope::refreshable; - const KIND: AuthKind = AuthKind::UserOrAdmin; + const KIND: AuthKind = AuthKind::UserOnly; const ALLOW_BASIC_AUTH: bool = true; } diff --git a/libeufin-bank/src/bench.rs b/libeufin-bank/src/bench.rs @@ -34,7 +34,7 @@ use taler_common::{ error_code::ErrorCode, types::{ amount::{Amount, Currency}, - timestamp::TalerTimestamp, + time::TalerTimestamp, }, }; use taler_test_utils::{json, server::TestServer}; diff --git a/libeufin-bank/src/db/token.rs b/libeufin-bank/src/db/token.rs @@ -26,7 +26,7 @@ use taler_api::{ db::{BindHelper, TypeHelper}, serialized, }; -use taler_common::{api::params::Page, types::timestamp::TalerTimestamp}; +use taler_common::{api::params::Page, types::time::TalerTimestamp}; use crate::{ api::token::TokenInfo, @@ -163,7 +163,7 @@ pub async fn access( scope: r.try_get("scope")?, is_refreshable: r.try_get("is_refreshable")?, creation: r.try_get_timestamp("creation_time")?, - expiration: r.try_get_taler_timestamp("expiration_time")?, + expiration: r.try_get("expiration_time")?, }) }) .fetch_optional(db) @@ -209,7 +209,7 @@ pub async fn access_info( scope: r.try_get("scope")?, is_refreshable: r.try_get("is_refreshable")?, creation: r.try_get_timestamp("creation_time")?, - expiration: r.try_get_taler_timestamp("expiration_time")?, + expiration: r.try_get("expiration_time")?, }, BankInfo { username: r.try_get("username")?, @@ -281,7 +281,7 @@ pub async fn page( bearer_token_id FROM bearer_tokens WHERE - expiration_time > $1 AND + (expiration_time > $1 OR expiration_time IS NULL) AND bank_customer=(SELECT customer_id FROM customers WHERE deleted_at IS NULL AND username = $2) AND ", @@ -290,12 +290,12 @@ pub async fn page( }, |r: PgRow| { Ok(TokenInfo { - creation_time: r.try_get_timestamp("creation_time")?.into(), - expiration: r.try_get_timestamp("expiration_time")?.into(), + creation_time: r.try_get("creation_time")?, + expiration: r.try_get("expiration_time")?, scope: r.try_get("scope")?, refreshable: r.try_get("is_refreshable")?, description: r.try_get("description")?, - last_access: r.try_get_timestamp("last_access")?.into(), + last_access: r.try_get("last_access")?, row_id: r.try_get_u64("bearer_token_id")?, token_id: r.try_get_u64("bearer_token_id")?, }) diff --git a/libeufin-bank/src/lib.rs b/libeufin-bank/src/lib.rs @@ -38,7 +38,7 @@ use taler_common::{ amount::Amount, base32::Base32, payto::IbanPayto, - timestamp::{RelativeTime, TalerTimestamp}, + time::{RelativeTime, TalerTimestamp}, }, }; use taler_macros::EnumMeta; diff --git a/libeufin-bank/src/pw.rs b/libeufin-bank/src/pw.rs @@ -206,7 +206,7 @@ fn pwh() { // Check compatibility with kotlin hashes let hash = "bcrypt$4$PfNp4JBeMU/t5mS5zaUY3A==$0Tjw0KzNA3ca3y9BVkh/e3TJDlHsdkEA"; assert_eq!( - crypto.checkpw("password", &hash).unwrap(), + crypto.checkpw("password", hash).unwrap(), PwCheck { matches: true, outdated: false diff --git a/libeufin-nexus/src/api.rs b/libeufin-nexus/src/api.rs @@ -52,7 +52,7 @@ use taler_common::{ amount::{Amount, Currency}, iban::IBAN, payto::{FullIbanPayto, IbanPayto, PaytoURI}, - timestamp::TalerTimestamp, + time::TalerTimestamp, }, }; use tokio::sync::watch::Sender; diff --git a/libeufin-nexus/src/bench.rs b/libeufin-nexus/src/bench.rs @@ -34,7 +34,7 @@ use taler_common::{ error_code::ErrorCode, types::{ amount::{Amount, Currency}, - timestamp::TalerTimestamp, + time::TalerTimestamp, }, }; use taler_test_utils::server::TestServer as _;