Skip to content

Commit 16ebbee

Browse files
feat: add config header
Signed-off-by: E.S. Rosenberg a.k.a. Keeper of the Keys <es-github@rosenberg.org.il>
1 parent 35606bc commit 16ebbee

File tree

374 files changed

+1053
-1067
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

374 files changed

+1053
-1067
lines changed

apps/files_external/src/components/AddExternalStorageDialog/AddExternalStorageDialog.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ const open = defineModel<boolean>('open', { default: true })
3333
const {
3434
storage = { backendOptions: {}, mountOptions: {}, type: isAdmin ? 'system' : 'personal' },
3535
} = defineProps<{
36-
storage?: Partial<IStorage>
36+
storage?: Partial<IStorage> & { backendOptions: IStorage['backendOptions'] }
3737
}>()
3838
3939
defineEmits<{
@@ -88,7 +88,7 @@ watch(authMechanisms, () => {
8888
:label="t('files_external', 'Folder name')"
8989
required />
9090

91-
<MountOptions v-model="internalStorage.mountOptions!" />
91+
<MountOptions v-model="internalStorage.mountOptions" />
9292

9393
<ApplicableEntities
9494
v-if="isAdmin"
@@ -112,13 +112,13 @@ watch(authMechanisms, () => {
112112
required />
113113

114114
<BackendConfiguration
115-
v-if="backend && internalStorage.backendOptions"
115+
v-if="backend"
116116
v-model="internalStorage.backendOptions"
117117
:class="$style.externalStorageDialog__configuration"
118118
:configuration="backend.configuration" />
119119

120120
<AuthMechanismConfiguration
121-
v-if="authMechanism && internalStorage.backendOptions"
121+
v-if="authMechanism"
122122
v-model="internalStorage.backendOptions"
123123
:class="$style.externalStorageDialog__configuration"
124124
:authMechanism="authMechanism" />

apps/files_external/src/components/AddExternalStorageDialog/MountOptions.vue

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,17 @@ import NcButton from '@nextcloud/vue/components/NcButton'
1414
import NcCheckboxRadioSwitch from '@nextcloud/vue/components/NcCheckboxRadioSwitch'
1515
import NcIconSvgWrapper from '@nextcloud/vue/components/NcIconSvgWrapper'
1616
import NcSelect from '@nextcloud/vue/components/NcSelect'
17-
import { parseMountOptions } from '../../store/storages.ts'
1817
import { MountOptionsCheckFilesystem } from '../../types.ts'
1918
2019
const mountOptions = defineModel<Partial<IMountOptions>>({ required: true })
2120
watchEffect(() => {
2221
if (Object.keys(mountOptions.value).length === 0) {
23-
// parse and initialize with defaults if needed
24-
mountOptions.value = parseMountOptions(mountOptions.value)
22+
mountOptions.value.encrypt = true
23+
mountOptions.value.previews = true
24+
mountOptions.value.enable_sharing = false
25+
mountOptions.value.filesystem_check_changes = MountOptionsCheckFilesystem.OncePerRequest
26+
mountOptions.value.encoding_compatibility = false
27+
mountOptions.value.readonly = false
2528
}
2629
})
2730

apps/files_external/src/store/storages.ts

Lines changed: 5 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,14 @@
33
* SPDX-License-Identifier: AGPL-3.0-or-later
44
*/
55

6-
import type { IStorage } from '../types.ts'
6+
import type { IStorage } from '../types.d.ts'
77

88
import axios from '@nextcloud/axios'
99
import { loadState } from '@nextcloud/initial-state'
1010
import { addPasswordConfirmationInterceptors, PwdConfirmationMode } from '@nextcloud/password-confirmation'
1111
import { generateUrl } from '@nextcloud/router'
1212
import { defineStore } from 'pinia'
1313
import { ref, toRaw } from 'vue'
14-
import { MountOptionsCheckFilesystem } from '../types.ts'
1514

1615
const { isAdmin } = loadState<{ isAdmin: boolean }>('files_external', 'settings')
1716

@@ -31,7 +30,7 @@ export const useStorages = defineStore('files_external--storages', () => {
3130
toRaw(storage),
3231
{ confirmPassword: PwdConfirmationMode.Strict },
3332
)
34-
globalStorages.value.push(parseStorage(data))
33+
globalStorages.value.push(data)
3534
}
3635

3736
/**
@@ -46,7 +45,7 @@ export const useStorages = defineStore('files_external--storages', () => {
4645
toRaw(storage),
4746
{ confirmPassword: PwdConfirmationMode.Strict },
4847
)
49-
userStorages.value.push(parseStorage(data))
48+
userStorages.value.push(data)
5049
}
5150

5251
/**
@@ -78,7 +77,7 @@ export const useStorages = defineStore('files_external--storages', () => {
7877
{ confirmPassword: PwdConfirmationMode.Strict },
7978
)
8079

81-
overrideStorage(parseStorage(data))
80+
overrideStorage(data)
8281
}
8382

8483
/**
@@ -88,7 +87,7 @@ export const useStorages = defineStore('files_external--storages', () => {
8887
*/
8988
async function reloadStorage(storage: IStorage) {
9089
const { data } = await axios.get(getUrl(storage))
91-
overrideStorage(parseStorage(data))
90+
overrideStorage(data)
9291
}
9392

9493
// initialize the store
@@ -112,7 +111,6 @@ export const useStorages = defineStore('files_external--storages', () => {
112111
const url = `apps/files_external/${type}`
113112
const { data } = await axios.get<Record<number, IStorage>>(generateUrl(url))
114113
return Object.values(data)
115-
.map(parseStorage)
116114
}
117115

118116
/**
@@ -152,45 +150,3 @@ export const useStorages = defineStore('files_external--storages', () => {
152150
}
153151
}
154152
})
155-
156-
/**
157-
* @param storage - The storage from API
158-
*/
159-
function parseStorage(storage: IStorage) {
160-
return {
161-
...storage,
162-
mountOptions: parseMountOptions(storage.mountOptions),
163-
}
164-
}
165-
166-
/**
167-
* Parse the mount options and convert string boolean values to
168-
* actual booleans and numeric strings to numbers
169-
*
170-
* @param options - The mount options to parse
171-
*/
172-
export function parseMountOptions(options: IStorage['mountOptions']) {
173-
const mountOptions = { ...options }
174-
mountOptions.encrypt = convertBooleanOptions(mountOptions.encrypt, true)
175-
mountOptions.previews = convertBooleanOptions(mountOptions.previews, true)
176-
mountOptions.enable_sharing = convertBooleanOptions(mountOptions.enable_sharing, false)
177-
mountOptions.filesystem_check_changes = typeof mountOptions.filesystem_check_changes === 'string'
178-
? Number.parseInt(mountOptions.filesystem_check_changes)
179-
: (mountOptions.filesystem_check_changes ?? MountOptionsCheckFilesystem.OncePerRequest)
180-
mountOptions.encoding_compatibility = convertBooleanOptions(mountOptions.encoding_compatibility, false)
181-
mountOptions.readonly = convertBooleanOptions(mountOptions.readonly, false)
182-
return mountOptions
183-
}
184-
185-
/**
186-
* Convert backend encoding of boolean options
187-
*
188-
* @param option - The option value from API
189-
* @param fallback - The fallback (default) value
190-
*/
191-
function convertBooleanOptions(option: unknown, fallback = false) {
192-
if (option === undefined) {
193-
return fallback
194-
}
195-
return option === true || option === 'true' || option === '1'
196-
}

apps/files_external/src/views/ExternalStoragesSection.vue

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,7 @@ async function addStorage(storage?: Partial<IStorage>) {
5959
}
6060
newStorage.value = undefined
6161
} catch (error) {
62-
logger.error('Failed to add external storage', { error, storage })
63-
newStorage.value = { ...storage }
62+
logger.error('Failed to add external storage', { error })
6463
showDialog.value = true
6564
}
6665
}
@@ -135,8 +134,8 @@ async function addStorage(storage?: Partial<IStorage>) {
135134
</NcButton>
136135

137136
<AddExternalStorageDialog
137+
v-model="newStorage"
138138
v-model:open="showDialog"
139-
:storage="newStorage"
140139
@close="addStorage" />
141140

142141
<UserMountSettings v-if="settings.isAdmin" />

apps/user_ldap/lib/Access.php

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -704,7 +704,7 @@ private function ldap2NextcloudNames(array $ldapObjects, bool $isUsers): array {
704704
continue;
705705
}
706706
$sndName = $ldapObject[$sndAttribute][0] ?? '';
707-
$this->applyUserDisplayName($ncName, $nameByLDAP, $sndName);
707+
$this->cacheUserDisplayName($ncName, $nameByLDAP, $sndName);
708708
} elseif ($nameByLDAP !== null) {
709709
$this->cacheGroupDisplayName($ncName, $nameByLDAP);
710710
}
@@ -752,16 +752,20 @@ public function cacheGroupExists(string $gid): void {
752752
$this->connection->writeToCache('groupExists' . $gid, true);
753753
}
754754

755-
public function applyUserDisplayName(string $uid, string $displayName, string $displayName2 = ''): void {
756-
$user = $this->userManager->get($uid);
755+
/**
756+
* caches the user display name
757+
*
758+
* @param string $ocName the internal Nextcloud username
759+
* @param string $displayName the display name
760+
* @param string $displayName2 the second display name
761+
* @throws \Exception
762+
*/
763+
public function cacheUserDisplayName(string $ocName, string $displayName, string $displayName2 = ''): void {
764+
$user = $this->userManager->get($ocName);
757765
if ($user === null) {
758766
return;
759767
}
760-
$composedDisplayName = $user->composeAndStoreDisplayName($displayName, $displayName2);
761-
$this->cacheUserDisplayName($uid, $composedDisplayName);
762-
}
763-
764-
public function cacheUserDisplayName(string $ocName, string $displayName): void {
768+
$displayName = $user->composeAndStoreDisplayName($displayName, $displayName2);
765769
$cacheKeyTrunk = 'getDisplayName';
766770
$this->connection->writeToCache($cacheKeyTrunk . $ocName, $displayName);
767771
}

apps/user_ldap/lib/User/User.php

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,12 @@ public function processAttributes(array $ldapEntry): void {
119119
$displayName2 = (string)$ldapEntry[$attr][0];
120120
}
121121
if ($displayName !== '') {
122-
$composedDisplayName = $this->composeAndStoreDisplayName($displayName, $displayName2);
123-
$this->access->cacheUserDisplayName($this->getUsername(), $composedDisplayName);
122+
$this->composeAndStoreDisplayName($displayName, $displayName2);
123+
$this->access->cacheUserDisplayName(
124+
$this->getUsername(),
125+
$displayName,
126+
$displayName2
127+
);
124128
}
125129
unset($attr);
126130

@@ -130,8 +134,7 @@ public function processAttributes(array $ldapEntry): void {
130134
$attr = strtolower($this->connection->ldapEmailAttribute);
131135
if (isset($ldapEntry[$attr])) {
132136
$mailValue = 0;
133-
$emailValues = count($ldapEntry[$attr]);
134-
for ($x = 0; $x < $emailValues; $x++) {
137+
for ($x = 0; $x < count($ldapEntry[$attr]); $x++) {
135138
if (filter_var($ldapEntry[$attr][$x], FILTER_VALIDATE_EMAIL)) {
136139
$mailValue = $x;
137140
break;
@@ -454,10 +457,6 @@ public function composeAndStoreDisplayName(string $displayName, string $displayN
454457
return $displayName;
455458
}
456459

457-
public function fetchStoredDisplayName(): string {
458-
return $this->userConfig->getValueString($this->uid, 'user_ldap', 'displayName', '');
459-
}
460-
461460
/**
462461
* Stores the LDAP Username in the Database
463462
*/

apps/user_ldap/lib/User_LDAP.php

Lines changed: 23 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -262,8 +262,7 @@ public function getUsers($search = '', $limit = 10, $offset = 0) {
262262
/**
263263
* checks whether a user is still available on LDAP
264264
*
265-
* @param string|User $user either the Nextcloud user id or an instance of
266-
* that user
265+
* @param string|User $user either the Nextcloud user id or an instance of that user
267266
* @throws \Exception
268267
* @throws ServerNotAvailableException
269268
*/
@@ -422,21 +421,26 @@ public function getHome($uid) {
422421
return $path;
423422
}
424423

425-
private function getDisplayNameFromDatabase(string $uid): ?string {
426-
$user = $this->access->userManager->get($uid);
427-
if ($user instanceof User) {
428-
$displayName = $user->fetchStoredDisplayName();
429-
if ($displayName !== '') {
430-
return $displayName;
431-
}
424+
/**
425+
* get display name of the user
426+
* @param string $uid user ID of the user
427+
* @return string|false display name
428+
*/
429+
public function getDisplayName($uid) {
430+
if ($this->userPluginManager->implementsActions(Backend::GET_DISPLAYNAME)) {
431+
return $this->userPluginManager->getDisplayName($uid);
432432
}
433-
if ($user instanceof OfflineUser) {
434-
return $user->getDisplayName();
433+
434+
if (!$this->userExists($uid)) {
435+
return false;
436+
}
437+
438+
$cacheKey = 'getDisplayName' . $uid;
439+
if (!is_null($displayName = $this->access->connection->getFromCache($cacheKey))) {
440+
return $displayName;
435441
}
436-
return null;
437-
}
438442

439-
private function getDisplayNameFromLdap(string $uid): string {
443+
//Check whether the display name is configured to have a 2nd feature
440444
$additionalAttribute = $this->access->connection->ldapUserDisplayName2;
441445
$displayName2 = '';
442446
if ($additionalAttribute !== '') {
@@ -458,40 +462,16 @@ private function getDisplayNameFromLdap(string $uid): string {
458462

459463
$user = $this->access->userManager->get($uid);
460464
if ($user instanceof User) {
461-
return $user->composeAndStoreDisplayName($displayName, (string)$displayName2);
465+
$displayName = $user->composeAndStoreDisplayName($displayName, (string)$displayName2);
466+
$this->access->connection->writeToCache($cacheKey, $displayName);
462467
}
463468
if ($user instanceof OfflineUser) {
464-
return $user->getDisplayName();
469+
$displayName = $user->getDisplayName();
465470
}
466-
}
467-
468-
return '';
469-
}
470-
471-
public function getDisplayName($uid): string {
472-
if ($this->userPluginManager->implementsActions(Backend::GET_DISPLAYNAME)) {
473-
return $this->userPluginManager->getDisplayName($uid);
474-
}
475-
476-
if (!$this->userExists($uid)) {
477-
return '';
478-
}
479-
480-
$cacheKey = 'getDisplayName' . $uid;
481-
if (!is_null($displayName = $this->access->connection->getFromCache($cacheKey))) {
482471
return $displayName;
483472
}
484473

485-
if ($displayName = $this->getDisplayNameFromDatabase($uid)) {
486-
$this->access->connection->writeToCache($cacheKey, $displayName);
487-
return $displayName;
488-
}
489-
490-
if ($displayName = $this->getDisplayNameFromLdap($uid)) {
491-
$this->access->connection->writeToCache($cacheKey, $displayName);
492-
}
493-
494-
return $displayName;
474+
return null;
495475
}
496476

497477
/**
@@ -515,8 +495,7 @@ public function setDisplayName($uid, $displayName) {
515495
* @param string $search
516496
* @param int|null $limit
517497
* @param int|null $offset
518-
* @return array an array of all displayNames (value) and the corresponding
519-
* uids (key)
498+
* @return array an array of all displayNames (value) and the corresponding uids (key)
520499
*/
521500
public function getDisplayNames($search = '', $limit = null, $offset = null) {
522501
$cacheKey = 'getDisplayNames-' . $search . '-' . $limit . '-' . $offset;

build/psalm-baseline.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2605,10 +2605,16 @@
26052605
<DeprecatedInterface>
26062606
<code><![CDATA[User_LDAP]]></code>
26072607
</DeprecatedInterface>
2608+
<ImplementedReturnTypeMismatch>
2609+
<code><![CDATA[string|false]]></code>
2610+
</ImplementedReturnTypeMismatch>
26082611
<MoreSpecificImplementedParamType>
26092612
<code><![CDATA[$limit]]></code>
26102613
<code><![CDATA[$offset]]></code>
26112614
</MoreSpecificImplementedParamType>
2615+
<NullableReturnStatement>
2616+
<code><![CDATA[null]]></code>
2617+
</NullableReturnStatement>
26122618
<RedundantCondition>
26132619
<code><![CDATA[$displayName && (count($displayName) > 0)]]></code>
26142620
<code><![CDATA[is_string($dn)]]></code>

dist/AuthMechanismRsa-CX_mdruD.chunk.mjs

Lines changed: 0 additions & 2 deletions
This file was deleted.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import{f as y,q as g,u as o,o as n,g as p,I as h,w as v,j as _,t as V,y as k,s as x,c as d,F as M,C as q,E as w,G as K,h as f,r as U}from"./runtime-dom.esm-bundler-DPEdZePn.chunk.mjs";import{c as j}from"./index-BCebL___.chunk.mjs";import{a as C}from"./index-C1xmmKTZ-CGpLs37u.chunk.mjs";import{t as s}from"./translation-DoG5ZELJ-XUrtIRvk.chunk.mjs";import{g as E}from"./createElementId-DhjFt1I9-Bh_4C_f2.chunk.mjs";import{N}from"./autolink-U5pBzLgI-Bpd-_ISJ.chunk.mjs";import{N as S}from"./NcSelect-DLheQ2yp-DujwD-Lb.chunk.mjs";import{N as A}from"./NcCheckboxRadioSwitch-BMsPx74L-fxtySBP5.chunk.mjs";import{N as L}from"./NcPasswordField-uaMO2pdt-Y_frnjqT.chunk.mjs";import{_ as z}from"./TrashCanOutline-CIT5iIpm.chunk.mjs";import{C as c,a as b}from"./types-DjW25Xxr.chunk.mjs";import{l as B}from"./logger-resIultJ.chunk.mjs";const P=y({__name:"ConfigurationEntry",props:k({configKey:{},configOption:{}},{modelValue:{type:[String,Boolean],default:""},modelModifiers:{}}),emits:["update:modelValue"],setup(e){const a=g(e,"modelValue");return(t,i)=>e.configOption.type!==o(c).Boolean?(n(),p(h(e.configOption.type===o(c).Password?o(L):o(z)),{key:0,modelValue:a.value,"onUpdate:modelValue":i[0]||(i[0]=l=>a.value=l),name:e.configKey,required:!(e.configOption.flags&o(b).Optional),label:e.configOption.value,title:e.configOption.tooltip},null,8,["modelValue","name","required","label","title"])):(n(),p(o(A),{key:1,modelValue:a.value,"onUpdate:modelValue":i[1]||(i[1]=l=>a.value=l),type:"switch",title:e.configOption.tooltip},{default:v(()=>[_(V(e.configOption.value),1)]),_:1},8,["modelValue","title"]))}}),R=y({__name:"AuthMechanismRsa",props:k({authMechanism:{}},{modelValue:{required:!0},modelModifiers:{}}),emits:["update:modelValue"],setup(e){const a=g(e,"modelValue"),t=U();x(t,()=>{t.value&&(a.value.private_key="",a.value.public_key="")});async function i(){try{const{data:l}=await j.post(E("/apps/files_external/ajax/public_key.php"),{keyLength:t.value});a.value.private_key=l.data.private_key,a.value.public_key=l.data.public_key}catch(l){B.error("Error generating RSA key pair",{error:l}),C(s("files_external","Error generating key pair"))}}return(l,m)=>(n(),d("div",null,[(n(!0),d(M,null,q(e.authMechanism.configuration,(r,u)=>w((n(),p(P,{key:r.value,modelValue:a.value[u],"onUpdate:modelValue":O=>a.value[u]=O,configKey:u,configOption:r},null,8,["modelValue","onUpdate:modelValue","configKey","configOption"])),[[K,!(r.flags&o(b).Hidden)]])),128)),f(o(S),{modelValue:t.value,"onUpdate:modelValue":m[0]||(m[0]=r=>t.value=r),clearable:!1,inputLabel:o(s)("files_external","Key size"),options:[1024,2048,4096],required:""},null,8,["modelValue","inputLabel"]),f(o(N),{disabled:!t.value,wide:"",onClick:i},{default:v(()=>[_(V(o(s)("files_external","Generate keys")),1)]),_:1},8,["disabled"])]))}}),$=Object.freeze(Object.defineProperty({__proto__:null,default:R},Symbol.toStringTag,{value:"Module"}));export{$ as A,P as _};
2+
//# sourceMappingURL=AuthMechanismRsa-ClWp2M4c.chunk.mjs.map

0 commit comments

Comments
 (0)