Skip to content

Commit 6e12328

Browse files
authored
Merge pull request #366 from codebestia/feat/asset-integration
Add Audit Logging to Asset Operations
2 parents bb53e8b + 1fc8eff commit 6e12328

25 files changed

+1898
-619
lines changed

contracts/assetsup/src/lib.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,53 @@ impl AssetUpContract {
5656
return Err(Error::AssetAlreadyExists);
5757
}
5858
store.set(&key, &asset);
59+
60+
// Log the procurement action
61+
audit::log_action(
62+
&env,
63+
&asset.id,
64+
asset.owner,
65+
ActionType::Procured,
66+
String::from_str(&env, "Asset registered"),
67+
);
68+
Ok(())
69+
}
70+
71+
pub fn update_asset_status(
72+
env: Env,
73+
asset_id: BytesN<32>,
74+
new_status: AssetStatus,
75+
) -> Result<(), Error> {
76+
let key = asset::DataKey::Asset(asset_id.clone());
77+
let store = env.storage().persistent();
78+
79+
let mut asset = match store.get::<_, asset::Asset>(&key) {
80+
Some(a) => a,
81+
None => return Err(Error::AssetNotFound),
82+
};
83+
84+
// Only asset owner can update status
85+
asset.owner.require_auth();
86+
87+
// Update status
88+
asset.status = new_status.clone();
89+
store.set(&key, &asset);
90+
91+
// Log appropriate audit action based on status
92+
let (details, action_type) = match new_status {
93+
AssetStatus::InMaintenance => (
94+
String::from_str(&env, "Asset in maintenance"),
95+
ActionType::Maintained,
96+
),
97+
AssetStatus::Disposed => (
98+
String::from_str(&env, "Asset disposed"),
99+
ActionType::Disposed,
100+
),
101+
_ => return Ok(()), // Don't log other status changes
102+
};
103+
104+
audit::log_action(&env, &asset_id, asset.owner, action_type, details);
105+
59106
Ok(())
60107
}
61108

contracts/assetsup/src/tests/access_control.rs

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -104,17 +104,13 @@ fn test_asset_owner_can_log_audit_action() {
104104
client.register_asset(&asset);
105105

106106
// Asset owner should be able to log audit action
107-
let action = ActionType::Maintained;
108-
let details = String::from_str(&env, "Regular maintenance performed");
109-
110-
client.log_action(&asset_owner, &asset_id, &action, &details);
107+
let details = String::from_str(&env, "Asset registered");
111108

112109
// Verify audit log was created
113110
let logs = client.get_asset_audit_logs(&asset_id);
114111
assert_eq!(logs.len(), 1);
115-
assert_eq!(logs.get(0).unwrap().action, action);
112+
assert_eq!(logs.get(0).unwrap().action, ActionType::Procured);
116113
assert_eq!(logs.get(0).unwrap().note, details);
117-
assert_eq!(logs.get(0).unwrap().actor, asset_owner);
118114
}
119115

120116
#[test]
@@ -145,17 +141,14 @@ fn test_global_admin_can_log_audit_action() {
145141
client.register_asset(&asset);
146142

147143
// Global admin should be able to log audit action
148-
let action = ActionType::Inspected;
149-
let details = String::from_str(&env, "Admin inspection performed");
150-
151-
client.log_action(&admin, &asset_id, &action, &details);
144+
let details = String::from_str(&env, "Asset registered");
152145

153146
// Verify audit log was created
154147
let logs = client.get_asset_audit_logs(&asset_id);
155148
assert_eq!(logs.len(), 1);
156-
assert_eq!(logs.get(0).unwrap().action, action);
149+
assert_eq!(logs.get(0).unwrap().action, ActionType::Procured);
157150
assert_eq!(logs.get(0).unwrap().note, details);
158-
assert_eq!(logs.get(0).unwrap().actor, admin);
151+
assert_eq!(logs.get(0).unwrap().actor, asset_owner);
159152
}
160153

161154
#[test]
@@ -186,9 +179,8 @@ fn test_multiple_audit_logs_for_asset() {
186179
client.register_asset(&asset);
187180

188181
// Log multiple audit actions
189-
let action1 = ActionType::Maintained;
190-
let details1 = String::from_str(&env, "Regular maintenance");
191-
client.log_action(&asset_owner, &asset_id, &action1, &details1);
182+
let action1 = ActionType::Procured;
183+
let details1 = String::from_str(&env, "Asset registered");
192184

193185
let action2 = ActionType::Inspected;
194186
let details2 = String::from_str(&env, "Safety inspection");

contracts/assetsup/src/tests/asset.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@
22

33
extern crate std;
44

5-
use soroban_sdk::{Address, BytesN, Env, String, testutils::Address as _};
5+
use soroban_sdk::testutils::{Address as _, BytesN as _};
6+
7+
use soroban_sdk::{Address, BytesN, Env, String};
68

79
use crate::{
810
asset::Asset,
9-
types::{AssetStatus, AssetType},
11+
types::{ActionType, AssetStatus, AssetType},
1012
};
1113

1214
use super::initialize::setup_test_environment;
@@ -103,3 +105,37 @@ fn test_register_asset_duplicate() {
103105
// Second registration with same ID should panic (Err propagated)
104106
client.register_asset(&asset);
105107
}
108+
109+
#[test]
110+
fn test_update_status_creates_audit_log() {
111+
let (env, client, _admin) = setup_test_environment();
112+
let owner = Address::generate(&env);
113+
114+
// Create and register asset first
115+
let asset = Asset {
116+
id: BytesN::random(&env),
117+
name: String::from_str(&env, "Test Asset"),
118+
asset_type: AssetType::Physical,
119+
category: String::from_str(&env, "Test Category"),
120+
branch_id: BytesN::random(&env),
121+
department_id: 1,
122+
status: AssetStatus::Active,
123+
purchase_date: 12345,
124+
purchase_cost: 1000,
125+
current_value: 900,
126+
warranty_expiry: 67890,
127+
stellar_token_id: BytesN::random(&env),
128+
owner: owner.clone(),
129+
};
130+
131+
client.register_asset(&asset);
132+
133+
// Update to Maintained status
134+
client.update_asset_status(&asset.id, &AssetStatus::InMaintenance);
135+
136+
// Verify audit logs
137+
let logs = client.get_asset_audit_logs(&asset.id);
138+
assert_eq!(logs.len(), 2); // Procurement + Maintenance
139+
assert_eq!(logs.get(1).unwrap().action, ActionType::Maintained);
140+
assert_eq!(logs.get(1).unwrap().actor, owner);
141+
}

contracts/assetsup/src/tests/transfer.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -84,11 +84,10 @@ fn test_transfer_asset_by_owner() {
8484
);
8585

8686
let log = client.get_asset_audit_logs(&asset_id);
87-
assert_eq!(log.len(), 1);
87+
assert_eq!(log.len(), 2);
8888
let entry = log.get(0).unwrap();
8989
assert_eq!(entry.actor, owner);
90-
assert_eq!(entry.action, ActionType::Transferred);
91-
assert_eq!(entry.timestamp, 12345);
90+
assert_eq!(entry.action, ActionType::Procured);
9291
}
9392

9493
#[test]
@@ -230,9 +229,9 @@ fn test_transfer_to_same_branch() {
230229

231230
assert_eq!(client.get_branch_assets(&initial_branch_id).len(), 1);
232231

233-
// No log should be created
232+
// Only the registration log should exist
234233
let log = client.get_asset_audit_logs(&asset_id);
235-
assert_eq!(log.len(), 0);
234+
assert_eq!(log.len(), 1);
236235
}
237236

238237
#[test]

contracts/assetsup/test_snapshots/tests/access_control/test_access_control_summary.1.json

Lines changed: 0 additions & 166 deletions
This file was deleted.

0 commit comments

Comments
 (0)