Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@
"sort-packages": true,
"audit": {
"abandoned": "report"
},
"allow-plugins": {
"phpstan/extension-installer": true
}
},
"autoload": {
Expand Down
104 changes: 104 additions & 0 deletions phpunit/functional/UserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -1857,4 +1857,108 @@ public function testUnsetUndisclosedFieldsWithPartialFields()

$this->assertEquals(['name' => 'test'], $fields);
}

public function testApplyRightRulesWithDefaultProfile()
{
$this->login();

// Create a test user with login info for authentication
$user = new \User();
$uid = $user->add([
'name' => 'test_apply_right_rules_user',
'password' => 'test_password',
'password2' => 'test_password',
]);
$this->assertGreaterThan(0, $uid);
$this->assertTrue($user->getFromDB($uid));

// Get default profile and tech profile
$default_profile = \Profile::getDefault();
$tech_profile = getItemByTypeName('Profile', 'Technician', true);
$this->assertGreaterThan(0, $default_profile);

// Remove the default profile that was automatically added during user creation
$profile_user = new \Profile_User();
$existing_profiles = \Profile_User::getForUser($uid, false);
foreach ($existing_profiles as $existing_profile) {
$profile_user->delete(['id' => $existing_profile['id']]);
}

// Verify user has no profiles
$profiles_before = \Profile_User::getForUser($uid, false);
$this->assertCount(0, $profiles_before);

// Create a right rule that assigns Technician profile based on user name
$rule_right = new \RuleRight();
$rule_id = $rule_right->add([
'name' => 'Test rule for profile assignment',
'is_active' => 1,
'sub_type' => 'RuleRight',
'match' => 'AND',
'condition' => 0,
]);
$this->assertGreaterThan(0, $rule_id);

// Add criteria: if login equals test_apply_right_rules_user
$rule_criteria = new \RuleCriteria();
$criteria_id = $rule_criteria->add([
'rules_id' => $rule_id,
'criteria' => 'LOGIN',
'condition' => 0, // is
'pattern' => 'test_apply_right_rules_user',
]);
$this->assertGreaterThan(0, $criteria_id);

// Add action: assign Technician profile on root entity
$rule_action = new \RuleAction();
$action_id = $rule_action->add([
'rules_id' => $rule_id,
'action_type' => 'assign',
'field' => 'profiles_id',
'value' => $tech_profile,
]);
$this->assertGreaterThan(0, $action_id);

// Add action: assign to root entity
$entity_action_id = $rule_action->add([
'rules_id' => $rule_id,
'action_type' => 'assign',
'field' => 'entities_id',
'value' => 0,
]);
$this->assertGreaterThan(0, $entity_action_id);

// Login as the test user to trigger rule processing
$this->login('test_apply_right_rules_user', 'test_password');

// Verify user now has the Technician profile (assigned by rule)
$profiles_after_rule = \Profile_User::getForUser($uid, false);
$this->assertCount(1, $profiles_after_rule);
$profile_after_rule = reset($profiles_after_rule);
$this->assertEquals($tech_profile, $profile_after_rule['profiles_id']);
$this->assertEquals(1, $profile_after_rule['is_dynamic']); // Profile assigned by rule is dynamic

// Now modify the rule criteria so it doesn't match anymore
$this->assertTrue($rule_criteria->update([
'id' => $criteria_id,
'pattern' => 'different_user_name', // This won't match our user
]));

// Login again to trigger rule re-processing
$this->login('test_apply_right_rules_user', 'test_password');

// Verify user now has the default profile (since rule doesn't match anymore)
$profiles_after_no_match = \Profile_User::getForUser($uid, false);
$this->assertCount(1, $profiles_after_no_match);

$profile_after_no_match = reset($profiles_after_no_match);
$this->assertEquals($default_profile, $profile_after_no_match['profiles_id']);
$this->assertEquals(0, $profile_after_no_match['entities_id']);
$this->assertEquals(1, $profile_after_no_match['is_recursive']);
$this->assertEquals(1, $profile_after_no_match['is_dynamic']);
$this->assertEquals(1, $profile_after_no_match['is_default_profile']);

// Clean up: delete the test rule
$this->assertTrue($rule_right->delete(['id' => $rule_id]));
}
}
19 changes: 19 additions & 0 deletions src/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -1417,6 +1417,25 @@ public function applyRightRules()
$right->delete($db_profile);
}
}

// Check if user has any profile left after deletion, if not add default profile
$remaining_profiles = Profile_User::getForUser($this->fields["id"], false);
if (count($remaining_profiles) == 0) {
$default_profile = Profile::getDefault();
if ($default_profile > 0) {
$affectation = [
'entities_id' => 0, // Root entity
'profiles_id' => $default_profile,
'is_recursive' => 1,
'users_id' => $this->fields['id'],
'is_dynamic' => 1,
'is_default_profile' => 1,
];
$right = new Profile_User();
$right->add($affectation);
}
}

$this->must_process_ruleright = false;
}
return $return;
Expand Down