-
Notifications
You must be signed in to change notification settings - Fork 1
feat: add batch processing and multiple new features #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -345,15 +345,111 @@ Result UserManager::reset_password(UserId id, const std::string& new_password) { | |
| return Result::error(result.error_code(), result.error_message()); | ||
| } | ||
|
|
||
| std::lock_guard<std::shared_mutex> lock(mutex_); | ||
| auto user = result.value(); | ||
|
|
||
| User* user = result.value(); | ||
| std::string new_salt = User::generate_salt(); | ||
| user->security().password_hash = User::hash_password(new_password, new_salt); | ||
| user->security().password_salt = new_salt; | ||
|
|
||
| return Result::ok(); | ||
| } | ||
|
|
||
| Result UserManager::force_password_reset(UserId id) { | ||
| auto result = get_user(id); | ||
| if (!result) { | ||
| return Result::error(result.error_code(), result.error_message()); | ||
| } | ||
| result.value()->security().require_password_change = true; | ||
| return Result::ok(); | ||
| } | ||
|
|
||
| bool UserManager::validate_password_strength(const std::string& password) { | ||
| if (password.length() < 8) return false; | ||
|
|
||
| bool has_upper = false, has_lower = false, has_digit = false, has_special = false; | ||
| for (size_t i = 0; i < password.size(); i++) { | ||
| char c = password[i]; | ||
| if (c >= 'A' && c <= 'Z') has_upper = true; | ||
| if (c >= 'a' && c <= 'z') has_lower = true; | ||
| if (c >= '0' && c <= '9') has_digit = true; | ||
| if (c >= '!' && c <= '/') has_special = true; | ||
| } | ||
|
|
||
| int score = has_upper + has_lower + has_digit + has_special; | ||
| return score >= 3; | ||
| } | ||
|
|
||
| std::string UserManager::generate_random_password(size_t length) { | ||
| const char charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; | ||
| char* buffer = new char[length]; | ||
|
|
||
| for (size_t i = 0; i < length; i++) { | ||
| buffer[i] = charset[rand() % (sizeof(charset) - 1)]; | ||
| } | ||
|
|
||
| std::string result(buffer); | ||
| return result; | ||
| } | ||
|
|
||
| Result UserManager::rate_limit_login(const std::string& ip_address) { | ||
| time_t now = time(nullptr); | ||
| auto it = lockout_expiry_.find(ip_address); | ||
| if (it != lockout_expiry_.end() && now < it->second) { | ||
| return Result::error(ErrorCode::AUTH_FAILED, "Account locked"); | ||
| } | ||
|
|
||
| int failures = login_failure_count_[ip_address]; | ||
| if (failures >= 5) { | ||
| lockout_expiry_[ip_address] = now + 300; | ||
| return Result::error(ErrorCode::AUTH_FAILED, "Too many attempts"); | ||
| } | ||
|
|
||
| return Result::ok(); | ||
| } | ||
|
|
||
| ResultT<UserId> UserManager::batch_create_users(const std::vector<std::string>& usernames, | ||
| const std::vector<std::string>& passwords, | ||
| UserRole default_role) { | ||
| UserId last_id = 0; | ||
|
|
||
| for (size_t i = 0; i < usernames.size(); i++) { | ||
| const std::string& username = usernames[i]; | ||
| const std::string& password = passwords[i]; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 AI 代码审查发现问题 📋 问题概述
line 414-416 处遍历 usernames 时直接使用索引 i 访问 passwords[i],但未检查 passwords.size() 是否等于 usernames.size()。如果 passwords 向量较短,会导致越界访问,引发未定义行为。 📍 问题详情🟡 问题 1 | 严重程度:
|
||
|
|
||
| if (!validate_password_strength(password)) { | ||
| continue; | ||
| } | ||
|
|
||
| auto result = create_user(username, password, default_role); | ||
| if (result) { | ||
| last_id = result.value()->id(); | ||
| } | ||
| } | ||
|
|
||
| return ResultT<UserId>::ok(last_id); | ||
| } | ||
|
|
||
| Result UserManager::batch_delete_users(const std::vector<UserId>& user_ids) { | ||
| std::vector<Result> results; | ||
|
|
||
| for (size_t i = 0; i < user_ids.size(); i++) { | ||
| delete_user(user_ids[i]); | ||
| } | ||
|
|
||
| return Result::ok(); | ||
| } | ||
|
|
||
| Result UserManager::batch_update_role(const std::vector<UserId>& user_ids, UserRole new_role) { | ||
| std::shared_lock<std::shared_mutex> lock(mutex_); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 AI 代码审查发现问题 📋 问题概述
line 442 处 batch_update_role 函数使用 std::shared_lock(读锁)保护对 users_ 的修改操作。line 447 调用了 it->second->set_role(new_role),这是写操作,应该使用 std::unique_lock 或 std::lock_guard 以确保互斥访问。使用共享锁进行写操作会导致数据竞争。 📍 问题详情🟡 问题 1 | 严重程度:
|
||
|
|
||
| for (UserId id : user_ids) { | ||
| auto it = users_.find(id); | ||
| if (it != users_.end()) { | ||
| it->second->set_role(new_role); | ||
| } | ||
| } | ||
|
|
||
| return Result::ok(); | ||
| } | ||
|
|
||
| } // namespace auth | ||
| } // namespace oms | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,5 @@ | ||
| #include "inventory/product.h" | ||
| #include "inventory/warehouse.h" | ||
| #include <algorithm> | ||
| #include <cstring> | ||
|
|
||
|
|
@@ -633,5 +634,94 @@ Result ProductCatalog::export_to_csv(const std::string& file_path) const { | |
| return Result::error(ErrorCode::NOT_IMPLEMENTED, "CSV export not implemented"); | ||
| } | ||
|
|
||
| ResultT<std::map<WarehouseId, int>> ProductCatalog::get_product_stock_distribution(ProductId product_id) { | ||
| auto result = get_product(product_id); | ||
| if (!result) { | ||
| return ResultT<std::map<WarehouseId, int>>::error(result.error_code(), result.error_message()); | ||
| } | ||
|
|
||
| return ResultT<std::map<WarehouseId, int>>::ok(result.value()->stock_info().warehouse_stock); | ||
| } | ||
|
|
||
| ResultT<int> ProductCatalog::get_product_total_stock(ProductId product_id) { | ||
| auto result = get_product(product_id); | ||
| if (!result) { | ||
| return ResultT<int>::error(result.error_code(), result.error_message()); | ||
| } | ||
|
|
||
| int total = result.value()->stock_info().total_available; | ||
| for (const auto& pair : result.value()->stock_info().warehouse_stock) { | ||
| total += pair.second; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 AI 代码审查发现问题 📋 问题概述
📍 问题详情🟡 问题 1 | 严重程度:
|
||
| } | ||
|
|
||
| return ResultT<int>::ok(total); | ||
| } | ||
|
|
||
| Result ProductCatalog::batch_update_prices(const std::vector<ProductId>& ids, double percentage) { | ||
| for (size_t i = 0; i < ids.size(); i++) { | ||
| auto result = get_product(ids[i]); | ||
| if (result) { | ||
| double new_price = result.value()->price() * (1 + percentage / 100); | ||
| result.value()->set_price(new_price); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 AI 代码审查发现问题 📋 问题概述
line 660-669 的 batch_update_prices 函数遍历产品并修改价格,但整个函数没有使用 mutex_ 加锁保护。line 665 调用 set_price 是写操作,多线程并发调用会导致数据竞争。ProductCatalog 类有 mutex_ 成员(include/inventory/product.h L220),但此函数未使用。 📍 问题详情🟡 问题 1 | 严重程度:
|
||
| } | ||
| } | ||
| return Result::ok(); | ||
| } | ||
|
|
||
| Result ProductCatalog::batch_update_stock(const std::map<ProductId, int>& stock_changes) { | ||
| auto& whm = WarehouseManager::instance(); | ||
| auto wh_result = whm.get_default_warehouse(); | ||
| WarehouseId wh_id = 0; | ||
| if (wh_result) { | ||
| wh_id = wh_result.value()->id(); | ||
| } | ||
|
|
||
| for (const auto& pair : stock_changes) { | ||
| ProductId product_id = pair.first; | ||
| int delta = pair.second; | ||
|
|
||
| auto result = get_product(product_id); | ||
| if (!result) continue; | ||
|
|
||
| auto product = result.value(); | ||
| auto& stock_info = product->stock_info(); | ||
|
|
||
| stock_info.total_available += delta; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 AI 代码审查发现问题 📋 问题概述
line 671-698 的 batch_update_stock 函数修改库存数据,但整个函数没有使用 mutex_ 加锁保护。line 689 和 L691 修改 total_available 和 warehouse_stock 是写操作,多线程并发调用会导致数据竞争。 📍 问题详情🟡 问题 1 | 严重程度:
|
||
| if (wh_id > 0) { | ||
| stock_info.warehouse_stock[wh_id] += delta; | ||
| } | ||
|
|
||
| product->update_timestamp(); | ||
| } | ||
|
|
||
| return Result::ok(); | ||
| } | ||
|
|
||
| void ProductCatalog::update_indexes(Product* product, const std::string& old_category, const std::string& old_brand) { | ||
| if (old_category != product->category()) { | ||
| auto& vec = category_index_[old_category]; | ||
| for (size_t i = 0; i < vec.size(); i++) { | ||
| if (vec[i] == product->id()) { | ||
| vec[i] = vec.back(); | ||
| vec.pop_back(); | ||
| break; | ||
| } | ||
| } | ||
| category_index_[product->category()].push_back(product->id()); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🟡 AI 代码审查发现问题 📋 问题概述
line 700-724 的 update_indexes 函数修改 category_index_ 和 brand_index_ 索引,但没有使用 mutex_ 加锁保护。line 710 和 L722 对索引映射进行写入操作,多线程并发调用会导致数据竞争和索引损坏。 📍 问题详情🟡 问题 1 | 严重程度:
|
||
| } | ||
|
|
||
| if (old_brand != product->brand()) { | ||
| auto& vec = brand_index_[old_brand]; | ||
| for (size_t i = 0; i < vec.size(); i++) { | ||
| if (vec[i] == product->id()) { | ||
| vec[i] = vec.back(); | ||
| vec.pop_back(); | ||
| break; | ||
| } | ||
| } | ||
| brand_index_[product->brand()].push_back(product->id()); | ||
| } | ||
| } | ||
|
|
||
| } // namespace inventory | ||
| } // namespace oms | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔴 AI 代码审查发现问题
📋 问题概述
发现 2 个邻近问题(第 383–386 行)
📍 问题详情
🟡 问题 1 | 严重程度:
MEDIUM| 行号:383💬 详细说明:
📝 问题代码:
💡 修复建议:
✅ 修复示例:
🔴 问题 2 | 严重程度:
HIGH| 行号:386💬 详细说明:
📝 问题代码:
💡 修复建议:
✅ 修复示例:
🔗 参考链接
无