Repository: owncloud/ocis (go)

Issue:
Graph: Consistently add user attributes to LDAP add request
In `identity.LDAP.userToAddRequest` attributes are added via a map, and as maps aren't a sorted type, it makes it very hard to test the input of the mock.

Make the attribute addition predictable so that the mock doesn't need to use the Anything instance.

Pull request description:
Consistently add user attributes to AddRequest
To make the `CreateUser` flow easier to test, the attributes of the
LDAP add request need to be added consistently. This way we can
expect that argument with the mock.

This PR does the following:

* Add a method `getUserAttrTypes` that returns a static list of attr names.
* Alter `userToAddRequest` to iterate over the static list, and add the attr
  if it exists in the `attrMap`.

Closes #5390

Patch:
diff --git a/.drone.env b/.drone.env
index dd887f13f00..145b0b2f98f 100644
--- a/.drone.env
+++ b/.drone.env
@@ -1,3 +1,3 @@
 # The test runner source for UI tests
-WEB_COMMITID=f2b928be7e6ce85265868660049a4ff15caa74bc
+WEB_COMMITID=516e1ba14e83f1c1396f812fba69aa9fdadf7284
 WEB_BRANCH=master
diff --git a/docs/helpers/README.md b/docs/helpers/README.md
index 914ecd876f2..21835a9e7ee 100644
--- a/docs/helpers/README.md
+++ b/docs/helpers/README.md
@@ -1,44 +1,91 @@
 # Docs Helpers
 
-`docs/helpers` contains a small go program creating docs by extracting information from the code. It is manually started with `make docs-generate` or via the CI and has three main responsibilities:
-
-- Generate docs for envvars in config structs
-- Extract envvars that are not mentioned in config structs (aka "Rogue" envvars)
-- Generate docs for rogue envvars
-
-Output:
+   * [Introduction](#introduction)
+   * [Output Generated](#output)
+   * [Admin Doc Process](#admin-doc-process)
+   * [Branching](#branching)
+   * [Service-Dependent Output](#service-dependent-output)
+      * [Generate Envvar Docs for Config Structs](#generate-envvar-docs-for-config-structs)
+      * [Deprecation Process](#deprecation-process)
+   * [Global Envvars](#global-envvars)
+   * [Extended Envvars](#extended-envvars)
+      * [General Extended Envvars Info](#general-extended-envvars-info)
+      * [Extract Extended Envvars](#extract-extended-envvars)
+      * [Generate Extended Envvar Docs](#generate-extended-envvar-docs)
+   * [Backporting](#backporting)
+
+## Introduction
+
+`docs/helpers` contains small go programs creating docs by extracting information from the code. The `main.go` program is manually started with `make docs-generate` or via the CI. It calls the other required programs and has three main responsibilities:
+
+- Generate docs for envvars in config structs including deprecations if there are any.
+- Extract and generate docs for `extended` envvars that are not mentioned in config structs (aka "rogue" envvars).
+- Extract and generate docs for `global` envvars which occur in multiple services.
+
+## Output Generated
 
 - The generated yaml files can be found at: `docs/services/_includes` when running locally respectively in the `docs branch` after the CI has finished.
 - The generated adoc files can be found at: `docs/services/_includes/adoc` when running locally respectively in the `docs branch` after the CI has finished.
-- The file name for rouge envvars is named: `extended_configvars.adoc`.
+- The file name for global envvars is named: `global_configvars.adoc`.
+- The file name for extended envvars is named: `extended_configvars.adoc`.
 
-Admin doc process:
+## Admin Doc Process
 
-Whenever a build from the admin documentation is triggered, the files generated here are included into the build process and added in a proper manner defined by the admin documentation.
+Whenever a build from the [ocis admin](https://github.com/owncloud/docs-ocis) or any other related documentation is triggered, the files generated here are included into the build process and added in a proper manner defined by the admin documentation. The updated documentation will then show up on the [web](https://doc.owncloud.com/ocis/next/).
 
-Genreal info:
+## Branching
 
-"Rouge" envvars are variables that need to be present *before* the core or services are starting up as they depend on the info provided like path for config files etc. Therefore they are _not_ bound to services like other envvars do. 
+The following is valid for envvars and yaml files related to the doc process:
 
-It can happen that rouge envvars are found but do not need to be published as they are for internal use only. Those rouge envvars can be defined to be ignored for further processing.
+* When filing a pull request in the ocis master branch relating to docs, CI runs `make docs-generate` and copies the result into the `docs` branch of ocis. This branch is then taken as base for owncloud.dev and as reference for the [admin docs](https://doc.owncloud.com/ocis/next/).
+* When running `make docs-generate` locally, the same output is created as above but it stays in the same branch where the make command was issued.
 
-IMPORTANT:
+In both cases, `make docs-generate` removes files in the target folder `_includes` to avoid remnants. All content is recreated. 
 
-- Once a rouge envvar has been identified, it is added to the `extended_vars.yaml` file but never changed or touched by the process. There is one exception with respect to single/double quote usage. While you manually can (and will) define a text like: `"'/var/lib/ocis'"`, quotes are transformed by the process in the .yaml file to: `'''/var/lib/ocis'''`. There is no need to change this back, as the final step transforms this correctly to the adoc table.
+On a side note (unrelated to the `docs` branch), [deployment examples](https://github.com/owncloud/ocis/tree/master/deployments/examples) have their own branch related to an ocis stable version to keep the state consistent, which is necessary for the admin documentation.
 
-- Because rouge envvars do not have the same structural setup as "normal" envvars like type, description or defaults, these infos need to be provided manually one time - even if found multiple times. Any change on this info will be used on the next CI run and published on the next admin docs build.
+## Service-Dependent Output
 
-- Do not change the sort order of rouge envvar blocks as they are automatically reordered alphabetically.
+For each service available, a file named like `<service name>_configvars.adoc` is created containing a:
 
-## Generate Envvar docs for config structs
+* table on top defining deprecated envvars - if applicable
+* table containing all envvars with their name, type, default value and description
+
+The table with deprecations is always printed in the final adoc file even if there are none, but is rendered in the docs build process only if the `HasDeprecations` value is set. This value is automatically handed over via the adoc file. The template file can be found at `docs/templates/ADOC.tmpl`.
+
+### Generate Envvar Docs for Config Structs
 
 Generates docs from a template file, mainly extracting `"env"` and `"desc"` tags from the config structs.
 
 Templates can be found in `docs/helpers` folder. (Same as this `README`.) Check `.tmpl` files
 
-## Extract Rogue Envvars
+### Deprecation Process
+
+For details on deprecation see the [deprecating-variables](https://github.com/owncloud/ocis/blob/master/docs/ocis/development/deprecating-variables.md) documentation.
+
+## Global Envvars
+
+Global envvars are gathered by checking if the envvar is available in more than one service. The table created is similar to the service-dependent envvar table but additionally contains a column with all service names where this envvar occurs. The output is rendered in list form where each item is clickable and automatically points to the corresponding service page. The template file can be found at `docs/templates/ADOC_global.tmpl`.
+
+## Extended Envvars
+
+### General Extended Envvars Info
+
+"Extended" envvars are variables that need to be present *before* the core or services are starting up as they depend on the info provided like path for config files etc. Therefore they are _not_ bound to services like other envvars. 
 
-It `grep`s over the code, looking for `os.Getenv` and parses these contents to a yaml file along with the following information:
+It can happen that extended envvars are found but do not need to be published as they are for internal use only. Those envvars can be defined to be ignored for further processing.
+
+IMPORTANT:
+
+- Once a extended envvar has been identified, it is added to the `extended_vars.yaml` file found in this folder but never changed or touched by the process. There is one exception with respect to single/double quote usage. While you can (and will) manually define a text like: `"'/var/lib/ocis'"`, quotes are transformed by the process in the .yaml file to: `'''/var/lib/ocis'''`. There is no need to change this back, as the final step transforms this correctly for the adoc table.
+
+- Because extended envvars do not have the same structural setup as "normal" envvars (like type, description or defaults), this info needs to be provided manually once - even if found multiple times. Any change of this info will be noticed during the next CI run and published in the next admin docs build.
+
+- Do not change the sort order of extended envvar blocks as they are automatically reordered alphabetically.
+
+### Extract Extended Envvars
+
+The grep command parses the code, looking for `os.Getenv` and passes these contents to a yaml file along with the following information:
 ```golang
 // Variable contains all information about one rogue envvar
 type Variable struct {
@@ -70,8 +117,16 @@ This yaml file can later be manually edited to add descriptions, default values,
 
 IMPORTANT: `RawName`, `Path` and `FoundInCode` are automatically filled by the program. DO NOT EDIT THESE VALUES MANUALLY.
 
-## Generate Rogue Envvar docs
+### Generate Extended Envvar Docs
+
+The process further picks up the `yaml` file generated in the `Extract Rogue Envvars` step and renders it to an adoc file (a table is created) using a go template. The template file for this step can be found at `docs/templates/ADOC_extended.tmpl`.
+
+## Backporting
+
+The ocis repo contains branches which are necessary for the documentation. The `docs` branch is related to changes in master, necessary for owncloud.dev and the admin docs referencing master content when it comes to envvars and yaml files.
+
+When a new stable ocis release (branch) is published, like `stable-2.0`, an additional branch (including CI) is set up manually by the dev team for referencing docs content like `docs-stable-2.0` - related to envvars and yaml files only - and added to the CI.
 
-It picks up the `yaml` file generated in `Extract Rogue Envvars` step and renders it to a adoc file (table) using a go template.
+In case it is necessary to transport a change from master to a stable branch like `docs-stable-2.0`, you must backport the original changes that will create that file to the `stable-2.0` branch. The CI will then take care of creating the results in the target `docs-stable-2.0`.
 
-The adoc template file for this step can be found at `docs/templates/ADOC_global.tmpl`.
+Cases for a backport can be a typo in an envvar description you want to have fixed in a stable branch too or a file  was created after the stable branch was set up but needs to be available in that branch.
diff --git a/services/graph/pkg/identity/ldap.go b/services/graph/pkg/identity/ldap.go
index 735f4ee6a4d..460628ab6de 100644
--- a/services/graph/pkg/identity/ldap.go
+++ b/services/graph/pkg/identity/ldap.go
@@ -1026,6 +1026,20 @@ func (i *LDAP) userToLDAPAttrValues(user libregraph.User) (map[string][]string,
 	return attrs, nil
 }
 
+func (i *LDAP) getUserAttrTypes() []string {
+	return []string{
+		i.userAttributeMap.displayName,
+		i.userAttributeMap.userName,
+		i.userAttributeMap.mail,
+		i.userAttributeMap.surname,
+		i.userAttributeMap.givenName,
+		"objectClass",
+		"cn",
+		"owncloudUUID",
+		"userPassword",
+	}
+}
+
 func (i *LDAP) getUserLDAPDN(user libregraph.User) string {
 	return fmt.Sprintf("uid=%s,%s", oldap.EscapeDNAttributeValue(*user.OnPremisesSamAccountName), i.userBaseDN)
 }
@@ -1037,8 +1051,11 @@ func (i *LDAP) userToAddRequest(user libregraph.User) (*ldap.AddRequest, error)
 	if err != nil {
 		return nil, err
 	}
-	for attrType, values := range attrMap {
-		ar.Attribute(attrType, values)
+
+	for _, attrType := range i.getUserAttrTypes() {
+		if values, ok := attrMap[attrType]; ok {
+			ar.Attribute(attrType, values)
+		}
 	}
 	return ar, nil
 }
diff --git a/services/settings/ui/components/settings/SettingMultiChoice.vue b/services/settings/ui/components/settings/SettingMultiChoice.vue
index 248684e193d..d42078619c0 100644
--- a/services/settings/ui/components/settings/SettingMultiChoice.vue
+++ b/services/settings/ui/components/settings/SettingMultiChoice.vue
@@ -2,8 +2,8 @@
   <oc-select
       :clearable="false"
       :options="displayOptions"
-      :value="selectedOptions"
-      @input="onSelectedOption"
+      :model-value="selectedOption"
+      @update:modelValue="onSelectedOption"
       multiple
   />
 </template>
diff --git a/services/settings/ui/components/settings/SettingSingleChoice.vue b/services/settings/ui/components/settings/SettingSingleChoice.vue
index 6e38d5e4e66..4c57795742c 100644
--- a/services/settings/ui/components/settings/SettingSingleChoice.vue
+++ b/services/settings/ui/components/settings/SettingSingleChoice.vue
@@ -3,8 +3,8 @@
     <oc-select
         :clearable="false"
         :options="displayOptions"
-        :value="selectedOption"
-        @input="onSelectedOption"
+        :model-value="selectedOption"
+        @update:modelValue="onSelectedOption"
        />
   </div>
 </template>
diff --git a/services/web/Makefile b/services/web/Makefile
index c00ea2440b0..59757a2389c 100644
--- a/services/web/Makefile
+++ b/services/web/Makefile
@@ -1,6 +1,6 @@
 SHELL := bash
 NAME := web
-WEB_ASSETS_VERSION = v7.0.0-rc.5
+WEB_ASSETS_VERSION = v7.0.0-rc.6
 
 include ../../.make/recursion.mk
 
diff --git a/services/web/pkg/config/defaults/defaultconfig.go b/services/web/pkg/config/defaults/defaultconfig.go
index 42bc08af123..f827e68094e 100644
--- a/services/web/pkg/config/defaults/defaultconfig.go
+++ b/services/web/pkg/config/defaults/defaultconfig.go
@@ -47,7 +47,7 @@ func DefaultConfig() *config.Config {
 					ResponseType: "code",
 					Scope:        "openid profile email",
 				},
-				Apps: []string{"files", "search", "text-editor", "pdf-viewer", "external", "user-management"},
+				Apps: []string{"files", "search", "text-editor", "pdf-viewer", "external", "admin-settings"},
 				ExternalApps: []config.ExternalApp{
 					{
 						ID:   "settings",


Test patch:
diff --git a/services/graph/pkg/identity/ldap_test.go b/services/graph/pkg/identity/ldap_test.go
index e36466d17e9..92e7c156e5c 100644
--- a/services/graph/pkg/identity/ldap_test.go
+++ b/services/graph/pkg/identity/ldap_test.go
@@ -3,6 +3,7 @@ package identity
 import (
 	"context"
 	"errors"
+	"fmt"
 	"net/url"
 	"testing"
 
@@ -106,6 +107,21 @@ func TestNewLDAPBackend(t *testing.T) {
 }
 
 func TestCreateUser(t *testing.T) {
+	displayName := "DisplayName"
+	mail := "user@example"
+	userName := "user"
+	surname := "surname"
+	givenName := "givenName"
+
+	ar := ldap.NewAddRequest(fmt.Sprintf("uid=user,%s", lconfig.UserBaseDN), nil)
+	ar.Attribute(lconfig.UserDisplayNameAttribute, []string{displayName})
+	ar.Attribute(lconfig.UserNameAttribute, []string{userName})
+	ar.Attribute(lconfig.UserEmailAttribute, []string{mail})
+	ar.Attribute("sn", []string{surname})
+	ar.Attribute("givenname", []string{givenName})
+	ar.Attribute("objectClass", []string{"inetOrgPerson", "organizationalPerson", "person", "top"})
+	ar.Attribute("cn", []string{userName})
+
 	l := &mocks.Client{}
 	l.On("Search", mock.Anything).
 		Return(
@@ -113,15 +129,9 @@ func TestCreateUser(t *testing.T) {
 				Entries: []*ldap.Entry{userEntry},
 			},
 			nil)
-	l.On("Add", mock.Anything).Return(nil)
+	l.On("Add", ar).Return(nil)
 	logger := log.NewLogger(log.Level("debug"))
 
-	displayName := "DisplayName"
-	mail := "user@example"
-	userName := "user"
-	surname := "surname"
-	givenName := "givenName"
-
 	user := libregraph.NewUser()
 	user.SetDisplayName(displayName)
 	user.SetMail(mail)
diff --git a/tests/config/drone/ocis-config.json b/tests/config/drone/ocis-config.json
index 5c181dedd07..4b3e7b7b2c8 100644
--- a/tests/config/drone/ocis-config.json
+++ b/tests/config/drone/ocis-config.json
@@ -25,7 +25,8 @@
     "markdown-editor",
     "media-viewer",
     "pdf-viewer",
-    "search"
+    "search",
+    "admin-settings"
   ],
   "external_apps": [
     {