Skip to content

Commit 4e0be0d

Browse files
committed
WIP
Signed-off-by: Louis Chemineau <louis@chmn.me>
1 parent 2ec2084 commit 4e0be0d

8 files changed

Lines changed: 132 additions & 106 deletions

File tree

apps/user_ldap/lib/Controller/ConfigAPIController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ public function modify($configID, $configData) {
139139
throw new OCSException('An issue occurred when modifying the config.');
140140
}
141141

142-
return new DataResponse();
142+
return $this->show($configID, false);
143143
}
144144

145145
/**

apps/user_ldap/src/components/SettingsTabs/GroupsTab.vue

Lines changed: 42 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,47 +7,23 @@
77
{{ t('user_ldap', 'Groups meeting these criteria are available in {instanceName}:', {instanceName}) }}
88

99
<div class="ldap-wizard__groups__line ldap-wizard__groups__filter-selection">
10-
<NcSelect v-model="ldapConfig.ldapGroupFilterObjectclass"
10+
<NcSelect :model-value="ldapGroupFilterObjectclass"
1111
class="ldap-wizard__groups__group-filter-groups__select"
12-
:options="['TODO']"
13-
:disable="allowUserFilterGroupsSelection"
12+
:options="groupObjectClasses"
13+
:disabled="ldapConfig.ldapGroupFilterMode === '1'"
1414
:input-label="t('user_ldap', 'Only these object classes:')"
15-
:multiple="true" />
15+
:multiple="true"
16+
@update:model-value="updateGroupFilterObjectclass" />
1617

1718
<!-- TODO -->
1819
<!-- <input type="text" class="ldapManyGroupsSupport ldapManyGroupsSearch hidden" placeholder="t('user_ldap', 'Search groups')"> -->
19-
<NcSelect v-model="ldapConfig.ldapGroupFilterObjectclass"
20+
<NcSelect :model-value="ldapGroupFilterGroups"
2021
class="ldap-wizard__groups__group-filter-groups__select"
21-
:options="['TODO']"
22-
:disable="allowUserFilterGroupsSelection"
22+
:options="groupGroups"
23+
:disabled="ldapConfig.ldapGroupFilterMode === '1'"
2324
:input-label="t('user_ldap', 'Only from these groups:')"
24-
:multiple="true" />
25-
</div>
26-
27-
<!-- TODO -->
28-
<div class="ldap-wizard__groups__line">
29-
<p class="ldapManyGroupsSupport hidden">
30-
<select class="ldapGroupList ldapGroupListAvailable"
31-
:multiple="true"
32-
aria-describedby="ldapGroupListAvailable_instructions"
33-
title="t('user_ldap', 'Available groups')" />
34-
</p>
35-
<p id="ldapGroupListAvailable_instructions" class="hidden-visually">
36-
{{ t('user_ldap', 'Available groups') }}
37-
</p>
38-
39-
<span>
40-
<NcButton class="ldapGroupListSelect">&gt;</NcButton><br>
41-
<NcButton class="ldapGroupListDeselect">&lt;</NcButton>
42-
</span>
43-
44-
<select class="ldapGroupList ldapGroupListSelected"
4525
:multiple="true"
46-
aria-describedby="ldapGroupListSelected_instructions"
47-
title="t('user_ldap', 'Selected groups')" />
48-
<p id="ldapGroupListSelected_instructions" class="hidden-visually">
49-
{{ t('user_ldap', 'Selected groups') }}
50-
</p>
26+
@update:model-value="updateGroupFilterGroups" />
5127
</div>
5228

5329
<div class="ldap-wizard__groups__line ldap-wizard__groups__groups-filter">
@@ -78,7 +54,7 @@
7854
</template>
7955

8056
<script lang="ts" setup>
81-
import { ref } from 'vue'
57+
import { ref, computed, watch } from 'vue'
8258
import { storeToRefs } from 'pinia'
8359
8460
import { t } from '@nextcloud/l10n'
@@ -91,12 +67,42 @@ import { useWizardStore } from '../../store/wizard'
9167
9268
const ldapConfigsStore = useLDAPConfigsStore()
9369
const wizardStore = useWizardStore()
94-
const { selectedConfig: ldapConfig } = storeToRefs(ldapConfigsStore)
70+
const { selectedConfig: ldapConfig, updatingConfig } = storeToRefs(ldapConfigsStore)
9571
9672
const instanceName = (getCapabilities() as { theming: { name:string } }).theming.name
9773
9874
const groupsCount = ref<number|undefined>(undefined)
99-
const allowUserFilterGroupsSelection = ref(false)
75+
76+
const groupObjectClasses = ref([] as string[])
77+
const groupGroups = ref([] as string[])
78+
79+
const shouldRequestLdapGroupFilter = ref(false)
80+
81+
const ldapGroupFilterObjectclass = computed(() => ldapConfig.value.ldapGroupFilterObjectclass.split(';').filter((item) => item !== ''))
82+
function updateGroupFilterObjectclass(value: string[]) {
83+
ldapConfig.value.ldapGroupFilterObjectclass = value.join(';')
84+
shouldRequestLdapGroupFilter.value = true
85+
}
86+
87+
const ldapGroupFilterGroups = computed(() => ldapConfig.value.ldapGroupFilterGroups.split(';').filter((item) => item !== ''))
88+
function updateGroupFilterGroups(value: string[]) {
89+
ldapConfig.value.ldapGroupFilterGroups = value.join(';')
90+
shouldRequestLdapGroupFilter.value = true
91+
}
92+
93+
watch(updatingConfig, async () => {
94+
if (shouldRequestLdapGroupFilter.value === true && updatingConfig.value === 0 && ldapConfig.value.ldapGroupFilterMode === '0') {
95+
const response = await wizardStore.callWizardAction('getGroupFilter')
96+
ldapConfig.value.ldapGroupFilter = response.changes.ldap_group_filter
97+
shouldRequestLdapGroupFilter.value = false
98+
}
99+
})
100+
101+
wizardStore.callWizardAction('determineGroupObjectClasses')
102+
.then((response) => { groupObjectClasses.value = response.options.ldap_groupfilter_objectclass })
103+
104+
wizardStore.callWizardAction('determineGroupsForGroups')
105+
.then((response) => { groupGroups.value = response.options.ldap_groupfilter_groups })
100106
101107
/**
102108
*

apps/user_ldap/src/components/SettingsTabs/LoginTab.vue

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,24 @@
1010
<NcCheckboxRadioSwitch :disabled="ldapConfig.ldapLoginFilterMode === '1'"
1111
:checked="ldapConfig.ldapLoginFilterUsername === '1'"
1212
:aria-label="t('user_ldap', 'Allows login against the LDAP/AD username, which is either `uid` or `sAMAccountName` and will be detected.')"
13-
@update:checked="ldapConfig.ldapLoginFilterUsername = $event ? '1' : '0'">
13+
@update:checked="updateLoginFilterUsername">
1414
{{ t('user_ldap', 'LDAP/AD Username') }}
1515
</NcCheckboxRadioSwitch>
1616

1717
<NcCheckboxRadioSwitch :disabled="ldapConfig.ldapLoginFilterMode === '1'"
1818
:checked="ldapConfig.ldapLoginFilterEmail === '1'"
1919
:aria-label="t('user_ldap', 'Allows login against an email attribute. `mail` and `mailPrimaryAddress` allowed.')"
20-
@update:checked="ldapConfig.ldapLoginFilterEmail = $event ? '1' : '0'">
20+
@update:checked="updateLoginFilterEmail">
2121
{{ t('user_ldap', 'LDAP/AD Email Address') }}
2222
</NcCheckboxRadioSwitch>
2323

24-
<NcSelect :value="selectedLoginFilterAttributes"
24+
<NcSelect :model-value="ldapLoginFilterAttributes"
2525
:close-on-select="false"
2626
:disabled="ldapConfig.ldapLoginFilterMode === '1'"
2727
:options="filteredLoginFilterOptions"
2828
:input-label="t('user_ldap', 'Other Attributes:')"
2929
:multiple="true"
30-
@input="updateLoginFilterAttributes" />
30+
@update:model-value="updateLoginFilterAttributes" />
3131
</div>
3232

3333
<div class="ldap-wizard__login__line ldap-wizard__login__user-login-filter">
@@ -62,7 +62,7 @@
6262
</template>
6363

6464
<script lang="ts" setup>
65-
import { computed, ref } from 'vue'
65+
import { computed, ref, watch } from 'vue'
6666
import { storeToRefs } from 'pinia'
6767
6868
import { t } from '@nextcloud/l10n'
@@ -77,26 +77,43 @@ import { showEnableAutomaticFilterInfo } from '../../services/ldapConfigService'
7777
const ldapConfigsStore = useLDAPConfigsStore()
7878
const wizardStore = useWizardStore()
7979
80-
const { selectedConfig: ldapConfig } = storeToRefs(ldapConfigsStore)
80+
const { selectedConfig: ldapConfig, updatingConfig } = storeToRefs(ldapConfigsStore)
8181
8282
const instanceName = (getCapabilities() as { theming: { name:string } }).theming.name
8383
const testUsername = ref('')
8484
const enableVerifyButton = ref(false)
8585
8686
const loginFilterOptions = ref<string[]>([])
87-
const selectedLoginFilterAttributes = computed(() => ldapConfig.value.ldapLoginFilterAttributes.split(';'))
88-
const filteredLoginFilterOptions = computed(() => loginFilterOptions.value.filter((option) => !selectedLoginFilterAttributes.value.includes(option)))
8987
wizardStore.callWizardAction('determineAttributes')
9088
.then(({ options }) => { loginFilterOptions.value = options.ldap_loginfilter_attributes })
9189
92-
/**
93-
*
94-
* @param value
95-
*/
96-
function updateLoginFilterAttributes(value) {
90+
const ldapLoginFilterAttributes = computed(() => ldapConfig.value.ldapLoginFilterAttributes.split(';').filter((item) => item !== ''))
91+
const filteredLoginFilterOptions = computed(() => loginFilterOptions.value.filter((option) => !ldapLoginFilterAttributes.value.includes(option)))
92+
function updateLoginFilterAttributes(value: string[]) {
9793
ldapConfig.value.ldapLoginFilterAttributes = value.join(';')
94+
shouldRequestLdapLoginFilterMode.value = true
95+
}
96+
97+
function updateLoginFilterUsername(value: string) {
98+
ldapConfig.value.ldapLoginFilterUsername = value ? '1' : '0'
99+
shouldRequestLdapLoginFilterMode.value = true
98100
}
99101
102+
function updateLoginFilterEmail(value: string) {
103+
ldapConfig.value.ldapLoginFilterEmail = value ? '1' : '0'
104+
shouldRequestLdapLoginFilterMode.value = true
105+
}
106+
107+
const shouldRequestLdapLoginFilterMode = ref(false)
108+
109+
watch(updatingConfig, async () => {
110+
if (shouldRequestLdapLoginFilterMode.value === true && updatingConfig.value === 0 && ldapConfig.value.ldapLoginFilterMode === '0') {
111+
const response = await wizardStore.callWizardAction('getUserLoginFilter')
112+
ldapConfig.value.ldapLoginFilter = response.changes.ldap_login_filter
113+
shouldRequestLdapLoginFilterMode.value = false
114+
}
115+
})
116+
100117
/**
101118
*
102119
*/

apps/user_ldap/src/components/SettingsTabs/ServerTab.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,9 @@ import Delete from 'vue-material-design-icons/Delete.vue'
8888
8989
import { t } from '@nextcloud/l10n'
9090
import { NcButton, NcTextField, NcTextArea, NcCheckboxRadioSwitch } from '@nextcloud/vue'
91+
import { showInfo } from '@nextcloud/dialogs'
9192
9293
import { useLDAPConfigsStore } from '../../store/configs'
93-
import { showInfo } from '@nextcloud/dialogs'
9494
import { useWizardStore } from '../../store/wizard'
9595
9696
const ldapConfigsStore = useLDAPConfigsStore()
@@ -132,8 +132,8 @@ async function guessBaseDN() {
132132
*/
133133
async function countInBaseDN() {
134134
const { changes: { ldap_test_base: ldapTestBase } } = await callWizardAction('countInBaseDN')
135-
showInfo(t('user_ldap', 'Found {count} users in the given Base DN.', { count: ldapTestBase }))
136-
}
135+
// TODO:use the message from wizardTabElementary.js:287
136+
showInfo(t('user_ldap', 'Found {count} entries in the given Base DN.', { count: ldapTestBase }))}
137137
138138
</script>
139139
<style lang="scss" scoped>

apps/user_ldap/src/components/SettingsTabs/UsersTab.vue

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,13 @@
77
{{ t('user_name', 'Listing and searching for users is constrained by these criteria:') }}
88

99
<div class="ldap-wizard__users__line ldap-wizard__users__user-filter-object-class">
10-
<NcSelect v-model="ldapConfig.ldapUserFilterObjectclass"
10+
<NcSelect :model-value="ldapUserFilterObjectclass"
1111
:disabled="ldapConfig.ldapUserFilterMode === '1'"
1212
class="ldap-wizard__users__user-filter-object-class__select"
13-
:options="['TODO']"
13+
:options="userObjectClasses"
1414
:input-label="t('user_name', 'Only these object classes:')"
15-
:multiple="true" />
15+
:multiple="true"
16+
@update:model-value="updateUserFilterObjectclass" />
1617
{{ t('user_name', 'The most common object classes for users are organizationalPerson, person, user, and inetOrgPerson. If you are not sure which object class to select, please consult your directory admin.') }}
1718
</div>
1819

@@ -28,42 +29,13 @@
2829
:placeholder="t('user_name', 'Search groups')"
2930
autocomplete="off" /> -->
3031

31-
<NcSelect v-model="ldapConfig.ldapUserFilterGroups"
32+
<NcSelect :model-value="ldapUserFilterGroups"
3233
class="ldap-wizard__users__user-filter-groups__select"
3334
:disabled="ldapConfig.ldapUserFilterMode === '1'"
34-
:options="['TODO']"
35-
:disable="allowUserFilterGroupsSelection"
36-
:input-label="t('user_name', 'Only these object classes:')"
37-
:multiple="true" />
38-
</div>
39-
40-
<!-- TODO -->
41-
<div class="ldap-wizard__users__line">
42-
<p class="ldapManyGroupsSupport hidden">
43-
<select class="ldapGroupList ldapGroupListAvailable"
44-
:disabled="ldapConfig.ldapUserFilterMode === '1'"
45-
:multiple="true"
46-
aria-describedby="ldapGroupListAvailable_instructions"
47-
:title="t('user_name', 'Available groups')" />
48-
</p>
49-
<p id="ldapGroupListAvailable_instructions" class="hidden-visually">
50-
{{ t('user_name', 'Available groups') }}
51-
</p>
52-
53-
<span>
54-
<NcButton class="ldapGroupListSelect">&gt;</NcButton>
55-
<NcButton class="ldapGroupListDeselect">&lt;</NcButton>
56-
</span>
57-
58-
<select class="ldapGroupList ldapGroupListSelected"
59-
:disabled="ldapConfig.ldapUserFilterMode === '1'"
35+
:options="userGroups"
36+
:input-label="t('user_name', 'Only these groups:')"
6037
:multiple="true"
61-
aria-describedby="ldapGroupListSelected_instructions"
62-
:title="t('user_name', 'Selected groups')" />
63-
64-
<p id="ldapGroupListSelected_instructions" class="hidden-visually">
65-
{{ t('user_name', 'Selected groups') }}
66-
</p>
38+
@update:model-value="updateUserFilterGroups" />
6739
</div>
6840

6941
<div class="ldap-wizard__users__line ldap-wizard__users__user-filter">
@@ -94,7 +66,7 @@
9466
</template>
9567

9668
<script lang="ts" setup>
97-
import { ref } from 'vue'
69+
import { ref, computed, watch } from 'vue'
9870
import { storeToRefs } from 'pinia'
9971
10072
import { t } from '@nextcloud/l10n'
@@ -107,13 +79,43 @@ import { showEnableAutomaticFilterInfo } from '../../services/ldapConfigService'
10779
10880
const wizardStore = useWizardStore()
10981
const ldapConfigsStore = useLDAPConfigsStore()
110-
const { selectedConfig: ldapConfig } = storeToRefs(ldapConfigsStore)
82+
const { selectedConfig: ldapConfig, updatingConfig } = storeToRefs(ldapConfigsStore)
11183
11284
const usersCount = ref<number|undefined>(undefined)
11385
114-
const allowUserFilterGroupsSelection = ref(true) // TODO
11586
const instanceName = (getCapabilities() as { theming: { name:string } }).theming.name
11687
88+
const userObjectClasses = ref([] as string[])
89+
const userGroups = ref([] as string[])
90+
91+
const shouldRequestLdapUserFilter = ref(false)
92+
93+
const ldapUserFilterObjectclass = computed(() => ldapConfig.value.ldapUserFilterObjectclass.split(';').filter((item) => item !== ''))
94+
function updateUserFilterObjectclass(value: string[]) {
95+
ldapConfig.value.ldapUserFilterObjectclass = value.join(';')
96+
shouldRequestLdapUserFilter.value = true
97+
}
98+
99+
const ldapUserFilterGroups = computed(() => ldapConfig.value.ldapUserFilterGroups.split(';').filter((item) => item !== ''))
100+
function updateUserFilterGroups(value: string[]) {
101+
ldapConfig.value.ldapUserFilterGroups = value.join(';')
102+
shouldRequestLdapUserFilter.value = true
103+
}
104+
105+
watch(updatingConfig, async () => {
106+
if (shouldRequestLdapUserFilter.value === true && updatingConfig.value === 0 && ldapConfig.value.ldapUserFilterMode === '0') {
107+
const response = await wizardStore.callWizardAction('getUserListFilter')
108+
ldapConfig.value.ldapUserFilter = response.changes.ldap_userlist_filter
109+
shouldRequestLdapUserFilter.value = false
110+
}
111+
})
112+
113+
wizardStore.callWizardAction('determineUserObjectClasses')
114+
.then((response) => { userObjectClasses.value = response.options.ldap_userfilter_objectclass })
115+
116+
wizardStore.callWizardAction('determineGroupsForUsers')
117+
.then((response) => { userGroups.value = response.options.ldap_userfilter_groups })
118+
117119
/**
118120
*
119121
*/

apps/user_ldap/src/services/ldapConfigService.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55

66
import path from 'path'
77

8+
import { DialogSeverity, getDialogBuilder, showError, showSuccess } from '@nextcloud/dialogs'
89
import axios, { AxiosError, type AxiosResponse } from '@nextcloud/axios'
910
import { getAppRootUrl, generateOcsUrl } from '@nextcloud/router'
10-
11-
import type { LDAPConfig } from '../models'
12-
import { DialogSeverity, getDialogBuilder, showError, showSuccess } from '@nextcloud/dialogs'
1311
import type { OCSResponse } from '@nextcloud/typings/ocs'
1412
import { t } from '@nextcloud/l10n'
1513

14+
import type { LDAPConfig } from '../models'
15+
1616
const AJAX_ENDPOINT = path.join(getAppRootUrl('user_ldap'), '/ajax')
1717

1818
export type WizardAction =
@@ -59,12 +59,12 @@ export async function getConfig(configId: string): Promise<LDAPConfig> {
5959
* @param config
6060
*/
6161
export async function updateConfig(configId: string, config: LDAPConfig): Promise<LDAPConfig> {
62-
const response = await axios.put(
62+
const response: AxiosResponse<OCSResponse<LDAPConfig>> = await axios.put(
6363
generateOcsUrl('apps/user_ldap/api/v1/config/{configId}', { configId }),
6464
{ configData: config },
6565
)
6666

67-
return response.data as LDAPConfig
67+
return response.data.ocs.data
6868
}
6969

7070
/**

apps/user_ldap/src/store/configs.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export const useLDAPConfigsStore = defineStore('ldap-configs', () => {
1414
const ldapConfigs = ref(loadState('user_ldap', 'ldapConfigs') as Record<string, LDAPConfig>)
1515
const selectedConfigId = ref<string>(Object.keys(ldapConfigs.value)[0])
1616
const selectedConfig = computed<LDAPConfig>(() => ldapConfigs.value[selectedConfigId.value])
17+
const updatingConfig = ref(0)
1718

1819
/**
1920
*
@@ -55,6 +56,7 @@ export const useLDAPConfigsStore = defineStore('ldap-configs', () => {
5556
ldapConfigs,
5657
selectedConfigId,
5758
selectedConfig,
59+
updatingConfig,
5860
create,
5961
copyConfig,
6062
removeConfig,

0 commit comments

Comments
 (0)