diff --git a/apps/user_ldap/lib/Command/TestUserSettings.php b/apps/user_ldap/lib/Command/TestUserSettings.php
index 2cd059455ca2b..3252b57c32059 100644
--- a/apps/user_ldap/lib/Command/TestUserSettings.php
+++ b/apps/user_ldap/lib/Command/TestUserSettings.php
@@ -111,6 +111,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
'ldapExpertUUIDUserAttr',
'ldapQuotaAttribute',
'ldapEmailAttribute',
+ 'ldapUserActiveState',
'ldapUserDisplayName',
'ldapUserDisplayName2',
'ldapExtStorageHomeAttribute',
diff --git a/apps/user_ldap/lib/Configuration.php b/apps/user_ldap/lib/Configuration.php
index b2e22f1b007ca..04745b6f46e92 100644
--- a/apps/user_ldap/lib/Configuration.php
+++ b/apps/user_ldap/lib/Configuration.php
@@ -27,6 +27,7 @@
* @property string $ldapTLS
* @property string $turnOffCertCheck
* @property string $ldapIgnoreNamingRules
+ * @property string $ldapUserActiveState
* @property string $ldapUserDisplayName
* @property string $ldapUserDisplayName2
* @property string $ldapUserAvatarRule
@@ -121,6 +122,7 @@ class Configuration {
'ldapTLS' => null,
'turnOffCertCheck' => null,
'ldapIgnoreNamingRules' => null,
+ 'ldapUserActiveState' => null,
'ldapUserDisplayName' => null,
'ldapUserDisplayName2' => null,
'ldapUserAvatarRule' => null,
@@ -503,6 +505,7 @@ public function getDefaults(): array {
'ldap_base_users' => '',
'ldap_base_groups' => '',
'ldap_userlist_filter' => '',
+ 'ldap_user_active_state' => '',
'ldap_user_filter_mode' => 0,
'ldap_userfilter_objectclass' => '',
'ldap_userfilter_groups' => '',
@@ -586,6 +589,7 @@ public function getConfigTranslationArray(): array {
'ldap_userfilter_objectclass' => 'ldapUserFilterObjectclass',
'ldap_userfilter_groups' => 'ldapUserFilterGroups',
'ldap_userlist_filter' => 'ldapUserFilter',
+ 'ldap_user_active_state' => 'ldapUserActiveState',
'ldap_user_filter_mode' => 'ldapUserFilterMode',
'ldap_user_avatar_rule' => 'ldapUserAvatarRule',
'ldap_login_filter' => 'ldapLoginFilter',
diff --git a/apps/user_ldap/lib/Connection.php b/apps/user_ldap/lib/Connection.php
index ea4d766fe0e84..28973e27f5233 100644
--- a/apps/user_ldap/lib/Connection.php
+++ b/apps/user_ldap/lib/Connection.php
@@ -35,6 +35,7 @@
* @property string $ldapTLS
* @property string $turnOffCertCheck
* @property string $ldapIgnoreNamingRules
+ * @property string $ldapUserActiveState
* @property string $ldapUserDisplayName
* @property string $ldapUserDisplayName2
* @property string $ldapUserAvatarRule
diff --git a/apps/user_ldap/lib/Controller/ConfigAPIController.php b/apps/user_ldap/lib/Controller/ConfigAPIController.php
index 56dde01b3c71d..a2005a32748d5 100644
--- a/apps/user_ldap/lib/Controller/ConfigAPIController.php
+++ b/apps/user_ldap/lib/Controller/ConfigAPIController.php
@@ -156,6 +156,7 @@ public function modify($configID, $configData) {
* 1
* 0
*
+ * active
* displayname
* uid
* inetOrgPerson
diff --git a/apps/user_ldap/lib/User/Manager.php b/apps/user_ldap/lib/User/Manager.php
index c6892312b0ae7..00efcb94f21cd 100644
--- a/apps/user_ldap/lib/User/Manager.php
+++ b/apps/user_ldap/lib/User/Manager.php
@@ -117,6 +117,7 @@ public function getAttributes($minimal = false) {
$this->access->getConnection()->ldapExpertUsernameAttr,
$this->access->getConnection()->ldapQuotaAttribute,
$this->access->getConnection()->ldapEmailAttribute,
+ $this->access->getConnection()->ldapUserActiveState,
$this->access->getConnection()->ldapUserDisplayName,
$this->access->getConnection()->ldapUserDisplayName2,
$this->access->getConnection()->ldapExtStorageHomeAttribute,
diff --git a/apps/user_ldap/lib/User/User.php b/apps/user_ldap/lib/User/User.php
index c1f21a0eb13de..692f1f820ae5f 100644
--- a/apps/user_ldap/lib/User/User.php
+++ b/apps/user_ldap/lib/User/User.php
@@ -170,6 +170,13 @@ public function processAttributes(array $ldapEntry): void {
}
unset($attr);
+ // active attribute
+ $attr = strtolower($this->connection->ldapUserActiveState);
+ if (isset($ldapEntry[$attr])) {
+ $this->updateUserActiveState($ldapEntry[$attr][0]);
+ }
+ unset($attr);
+
// check for cached profile data
$username = $this->getUsername(); // buffer variable, to save resource
$cacheKey = 'getUserProfile-' . $username;
@@ -730,4 +737,9 @@ public function updateExtStorageHome(?string $valueFromLDAP = null):string {
return '';
}
}
+
+ public function updateUserActiveState(string $valueFromLDAP): void {
+ $user = $this->userManager->get($this->uid);
+ $user->setEnabled($valueFromLDAP === 'TRUE');
+ }
}
diff --git a/apps/user_ldap/openapi.json b/apps/user_ldap/openapi.json
index 98afc0c3932f3..86ae47b79a173 100644
--- a/apps/user_ldap/openapi.json
+++ b/apps/user_ldap/openapi.json
@@ -538,7 +538,7 @@
"get": {
"operationId": "configapi-show",
"summary": "Get a configuration",
- "description": "Output can look like this: ok 200 OK ldaps://my.ldap.server 7770 ou=small,dc=my,dc=ldap,dc=server ou=users,ou=small,dc=my,dc=ldap,dc=server ou=small,dc=my,dc=ldap,dc=server cn=root,dc=my,dc=ldap,dc=server clearTextWithShowPassword=1 1 0 displayname uid inetOrgPerson (&(objectclass=nextcloudUser)(nextcloudEnabled=TRUE)) 1 (&(|(objectclass=nextcloudGroup))) 0 nextcloudGroup cn memberUid (&(|(objectclass=inetOrgPerson))(uid=%uid)) 0 0 1 mail 20 auto auto 1 uid;sn;givenname 0 1 uid uid 0 0 500 1 \nThis endpoint requires admin access",
+ "description": "Output can look like this: ok 200 OK ldaps://my.ldap.server 7770 ou=small,dc=my,dc=ldap,dc=server ou=users,ou=small,dc=my,dc=ldap,dc=server ou=small,dc=my,dc=ldap,dc=server cn=root,dc=my,dc=ldap,dc=server clearTextWithShowPassword=1 1 0 active displayname uid inetOrgPerson (&(objectclass=nextcloudUser)(nextcloudEnabled=TRUE)) 1 (&(|(objectclass=nextcloudGroup))) 0 nextcloudGroup cn memberUid (&(|(objectclass=inetOrgPerson))(uid=%uid)) 0 0 1 mail 20 auto auto 1 uid;sn;givenname 0 1 uid uid 0 0 500 1 \nThis endpoint requires admin access",
"tags": [
"configapi"
],
diff --git a/apps/user_ldap/src/components/SettingsTabs/AdvancedTab.vue b/apps/user_ldap/src/components/SettingsTabs/AdvancedTab.vue
index 4c8ad7ebd6e5a..e9d9658e0d7c9 100644
--- a/apps/user_ldap/src/components/SettingsTabs/AdvancedTab.vue
+++ b/apps/user_ldap/src/components/SettingsTabs/AdvancedTab.vue
@@ -72,6 +72,13 @@
:label="t('user_ldap', 'User Search Attributes')"
@change="(event) => ldapConfigProxy.ldapAttributesForUserSearch = event.target.value" />
+ ldapConfigProxy.ldapUserActiveState = event.target.value" />
+
+ ldapUserActiveState: string // Example: active
ldapUserDisplayName: string // Example: displayname
ldapUserDisplayName2: string // Example: uid
ldapUserFilterObjectclass?: string // Example: inetOrgPerson
diff --git a/apps/user_ldap/tests/User/UserTest.php b/apps/user_ldap/tests/User/UserTest.php
index ee32320e06364..9e48c10978d9f 100644
--- a/apps/user_ldap/tests/User/UserTest.php
+++ b/apps/user_ldap/tests/User/UserTest.php
@@ -787,6 +787,48 @@ public static function extStorageHomeDataProvider(): array {
];
}
+ public function testActivateUser(): void {
+ $coreUser = $this->createMock(IUser::class);
+ $coreUser->expects($this->once())
+ ->method('setEnabled')
+ ->with(true);
+
+ $this->userManager->expects($this->once())
+ ->method('get')
+ ->with($this->uid)
+ ->willReturn($coreUser);
+
+ $this->user->updateUserActiveState('TRUE');
+ }
+
+ public function testDeactivateUserCorrect(): void {
+ $coreUser = $this->createMock(IUser::class);
+ $coreUser->expects($this->once())
+ ->method('setEnabled')
+ ->with(false);
+
+ $this->userManager->expects($this->once())
+ ->method('get')
+ ->with($this->uid)
+ ->willReturn($coreUser);
+
+ $this->user->updateUserActiveState('FALSE');
+ }
+
+ public function testDeactivateUserFallback(): void {
+ $coreUser = $this->createMock(IUser::class);
+ $coreUser->expects($this->once())
+ ->method('setEnabled')
+ ->with(false);
+
+ $this->userManager->expects($this->once())
+ ->method('get')
+ ->with($this->uid)
+ ->willReturn($coreUser);
+
+ $this->user->updateUserActiveState('weird');
+ }
+
#[\PHPUnit\Framework\Attributes\DataProvider(methodName: 'extStorageHomeDataProvider')]
public function testUpdateExtStorageHome(string $expected, ?string $valueFromLDAP = null, bool $isSet = true): void {
if ($valueFromLDAP === null) {
diff --git a/openapi.json b/openapi.json
index 11a1c5a527e6b..7a62cc1a2edc1 100644
--- a/openapi.json
+++ b/openapi.json
@@ -42976,7 +42976,7 @@
"get": {
"operationId": "user_ldap-configapi-show",
"summary": "Get a configuration",
- "description": "Output can look like this: ok 200 OK ldaps://my.ldap.server 7770 ou=small,dc=my,dc=ldap,dc=server ou=users,ou=small,dc=my,dc=ldap,dc=server ou=small,dc=my,dc=ldap,dc=server cn=root,dc=my,dc=ldap,dc=server clearTextWithShowPassword=1 1 0 displayname uid inetOrgPerson (&(objectclass=nextcloudUser)(nextcloudEnabled=TRUE)) 1 (&(|(objectclass=nextcloudGroup))) 0 nextcloudGroup cn memberUid (&(|(objectclass=inetOrgPerson))(uid=%uid)) 0 0 1 mail 20 auto auto 1 uid;sn;givenname 0 1 uid uid 0 0 500 1 \nThis endpoint requires admin access",
+ "description": "Output can look like this: ok 200 OK ldaps://my.ldap.server 7770 ou=small,dc=my,dc=ldap,dc=server ou=users,ou=small,dc=my,dc=ldap,dc=server ou=small,dc=my,dc=ldap,dc=server cn=root,dc=my,dc=ldap,dc=server clearTextWithShowPassword=1 1 0 active displayname uid inetOrgPerson (&(objectclass=nextcloudUser)(nextcloudEnabled=TRUE)) 1 (&(|(objectclass=nextcloudGroup))) 0 nextcloudGroup cn memberUid (&(|(objectclass=inetOrgPerson))(uid=%uid)) 0 0 1 mail 20 auto auto 1 uid;sn;givenname 0 1 uid uid 0 0 500 1 \nThis endpoint requires admin access",
"tags": [
"user_ldap/configapi"
],