|
3 | 3 | #include <Access/ExternalAuthenticators.h> |
4 | 4 | #include <Access/User.h> |
5 | 5 | #include <Access/Role.h> |
| 6 | +#include <Access/SettingsProfile.h> |
6 | 7 | #include <Access/Credentials.h> |
7 | 8 | #include <Common/Exception.h> |
8 | 9 | #include <Common/logger_useful.h> |
@@ -161,6 +162,9 @@ TokenAccessStorage::TokenAccessStorage(const String & storage_name_, AccessContr |
161 | 162 | } |
162 | 163 | common_role_names.swap(common_roles_cfg); |
163 | 164 |
|
| 165 | + if (config.has(prefix_str + "default_profile")) |
| 166 | + default_profile_name = config.getString(prefix_str + "default_profile"); |
| 167 | + |
164 | 168 | user_external_roles.clear(); |
165 | 169 | users_per_roles.clear(); |
166 | 170 | roles_per_users.clear(); |
@@ -426,6 +430,42 @@ void TokenAccessStorage::assignRolesNoLock(User & user, const std::set<String> & |
426 | 430 | user_external_roles[user_name] = external_roles; |
427 | 431 | } |
428 | 432 |
|
| 433 | +void TokenAccessStorage::assignProfileNoLock(User & user) const |
| 434 | +{ |
| 435 | + if (default_profile_name.empty()) |
| 436 | + return; |
| 437 | + |
| 438 | + const auto & user_name = user.getName(); |
| 439 | + auto & settings = user.settings; |
| 440 | + |
| 441 | + // Look up the profile ID once |
| 442 | + const auto profile_id = access_control.find<SettingsProfile>(default_profile_name); |
| 443 | + if (!profile_id) |
| 444 | + { |
| 445 | + LOG_TRACE(getLogger(), "Did not assign profile '{}' to user '{}': profile not found", default_profile_name, user_name); |
| 446 | + return; |
| 447 | + } |
| 448 | + |
| 449 | + // Check if profile is already assigned |
| 450 | + bool profile_already_assigned = false; |
| 451 | + for (const auto & element : settings) |
| 452 | + { |
| 453 | + if (element.parent_profile.has_value() && element.parent_profile == *profile_id) |
| 454 | + { |
| 455 | + profile_already_assigned = true; |
| 456 | + break; |
| 457 | + } |
| 458 | + } |
| 459 | + |
| 460 | + if (!profile_already_assigned) |
| 461 | + { |
| 462 | + SettingsProfileElement profile_element; |
| 463 | + profile_element.parent_profile = *profile_id; |
| 464 | + settings.push_back(std::move(profile_element)); |
| 465 | + LOG_TRACE(getLogger(), "Assigned profile '{}' to user '{}'", default_profile_name, user_name); |
| 466 | + } |
| 467 | +} |
| 468 | + |
429 | 469 | void TokenAccessStorage::updateAssignedRolesNoLock(const UUID & id, const String & user_name, const std::set<String> & external_roles) const |
430 | 470 | { |
431 | 471 | // Map and grant the roles from scratch only if the list of external role has changed. |
@@ -521,12 +561,25 @@ std::optional<AuthResult> TokenAccessStorage::authenticateImpl( |
521 | 561 | if (new_user) |
522 | 562 | { |
523 | 563 | assignRolesNoLock(*new_user, external_roles); |
| 564 | + assignProfileNoLock(*new_user); |
524 | 565 | id = memory_storage.insert(new_user); |
525 | 566 | } |
526 | 567 | else |
527 | 568 | { |
528 | 569 | // Just in case external_roles are changed. |
529 | 570 | updateAssignedRolesNoLock(*id, user->getName(), external_roles); |
| 571 | + |
| 572 | + // Also update profile if needed |
| 573 | + memory_storage.update(*id, [this] (const AccessEntityPtr & entity_, const UUID &) -> AccessEntityPtr |
| 574 | + { |
| 575 | + if (auto user_entity = typeid_cast<std::shared_ptr<const User>>(entity_)) |
| 576 | + { |
| 577 | + auto changed_user = typeid_cast<std::shared_ptr<User>>(user_entity->clone()); |
| 578 | + assignProfileNoLock(*changed_user); |
| 579 | + return changed_user; |
| 580 | + } |
| 581 | + return entity_; |
| 582 | + }); |
530 | 583 | } |
531 | 584 |
|
532 | 585 | if (id) |
|
0 commit comments