fix(user_ldap): allow editing profile fields not managed by LDAP

canEditProperty() was returning true (editable) when an LDAP attribute
was configured for a field, and false when no attribute was configured.
This is inverted: a field with an LDAP attribute mapping is owned by
LDAP and should not be user-editable, while a field with no mapping is
not sourced from LDAP and the user should be free to set it themselves.

Fixes profile fields being uneditable for all LDAP users whose admin
has not configured attribute mappings for those fields.

Assisted-by: ClaudeCode:claude-sonnet-4-6
Signed-off-by: Anna Larch <anna@nextcloud.com>
This commit is contained in:
Anna Larch 2026-06-03 09:01:39 +02:00 committed by Anna
parent 09f1bb216c
commit bbf05d3b8f
2 changed files with 44 additions and 11 deletions

View file

@ -690,17 +690,17 @@ class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, I
return match($property) {
// Display name is always set by LDAP
IAccountManager::PROPERTY_DISPLAYNAME => false,
IAccountManager::PROPERTY_EMAIL => ((string)$this->access->connection->ldapEmailAttribute !== ''),
IAccountManager::PROPERTY_PHONE => ((string)$this->access->connection->ldapAttributePhone !== ''),
IAccountManager::PROPERTY_WEBSITE => ((string)$this->access->connection->ldapAttributeWebsite !== ''),
IAccountManager::PROPERTY_ADDRESS => ((string)$this->access->connection->ldapAttributeAddress !== ''),
IAccountManager::PROPERTY_FEDIVERSE => ((string)$this->access->connection->ldapAttributeFediverse !== ''),
IAccountManager::PROPERTY_ORGANISATION => ((string)$this->access->connection->ldapAttributeOrganisation !== ''),
IAccountManager::PROPERTY_ROLE => ((string)$this->access->connection->ldapAttributeRole !== ''),
IAccountManager::PROPERTY_HEADLINE => ((string)$this->access->connection->ldapAttributeHeadline !== ''),
IAccountManager::PROPERTY_BIOGRAPHY => ((string)$this->access->connection->ldapAttributeBiography !== ''),
IAccountManager::PROPERTY_BIRTHDATE => ((string)$this->access->connection->ldapAttributeBirthDate !== ''),
IAccountManager::PROPERTY_PRONOUNS => ((string)$this->access->connection->ldapAttributePronouns !== ''),
IAccountManager::PROPERTY_EMAIL => ((string)$this->access->connection->ldapEmailAttribute === ''),
IAccountManager::PROPERTY_PHONE => ((string)$this->access->connection->ldapAttributePhone === ''),
IAccountManager::PROPERTY_WEBSITE => ((string)$this->access->connection->ldapAttributeWebsite === ''),
IAccountManager::PROPERTY_ADDRESS => ((string)$this->access->connection->ldapAttributeAddress === ''),
IAccountManager::PROPERTY_FEDIVERSE => ((string)$this->access->connection->ldapAttributeFediverse === ''),
IAccountManager::PROPERTY_ORGANISATION => ((string)$this->access->connection->ldapAttributeOrganisation === ''),
IAccountManager::PROPERTY_ROLE => ((string)$this->access->connection->ldapAttributeRole === ''),
IAccountManager::PROPERTY_HEADLINE => ((string)$this->access->connection->ldapAttributeHeadline === ''),
IAccountManager::PROPERTY_BIOGRAPHY => ((string)$this->access->connection->ldapAttributeBiography === ''),
IAccountManager::PROPERTY_BIRTHDATE => ((string)$this->access->connection->ldapAttributeBirthDate === ''),
IAccountManager::PROPERTY_PRONOUNS => ((string)$this->access->connection->ldapAttributePronouns === ''),
default => true,
};
}

View file

@ -1460,4 +1460,37 @@ class User_LDAPTest extends TestCase {
$this->assertSame($expected, $this->backend->implementsActions($actionCode));
}
public static function canEditPropertyProvider(): array {
return [
// Display name is always managed by LDAP
[\OCP\Accounts\IAccountManager::PROPERTY_DISPLAYNAME, '', false],
[\OCP\Accounts\IAccountManager::PROPERTY_DISPLAYNAME, 'cn', false],
// Fields with no LDAP attribute configured are user-editable
[\OCP\Accounts\IAccountManager::PROPERTY_EMAIL, '', true],
[\OCP\Accounts\IAccountManager::PROPERTY_PHONE, '', true],
[\OCP\Accounts\IAccountManager::PROPERTY_WEBSITE, '', true],
[\OCP\Accounts\IAccountManager::PROPERTY_ADDRESS, '', true],
[\OCP\Accounts\IAccountManager::PROPERTY_FEDIVERSE, '', true],
[\OCP\Accounts\IAccountManager::PROPERTY_ORGANISATION, '', true],
[\OCP\Accounts\IAccountManager::PROPERTY_ROLE, '', true],
[\OCP\Accounts\IAccountManager::PROPERTY_HEADLINE, '', true],
[\OCP\Accounts\IAccountManager::PROPERTY_BIOGRAPHY, '', true],
[\OCP\Accounts\IAccountManager::PROPERTY_BIRTHDATE, '', true],
[\OCP\Accounts\IAccountManager::PROPERTY_PRONOUNS, '', true],
// Fields with an LDAP attribute configured are managed by LDAP, not user-editable
[\OCP\Accounts\IAccountManager::PROPERTY_EMAIL, 'mail', false],
[\OCP\Accounts\IAccountManager::PROPERTY_PHONE, 'telephoneNumber', false],
[\OCP\Accounts\IAccountManager::PROPERTY_WEBSITE, 'labeledURI', false],
];
}
#[\PHPUnit\Framework\Attributes\DataProvider(methodName: 'canEditPropertyProvider')]
public function testCanEditProperty(string $property, string $ldapAttributeValue, bool $expected): void {
$this->connection->expects($this->any())
->method('__get')
->willReturn($ldapAttributeValue);
$this->assertSame($expected, $this->backend->canEditProperty('uid', $property));
}
}