diff --git a/changelog/unreleased/add-users-instances.md b/changelog/unreleased/add-users-instances.md new file mode 100644 index 00000000000..2ef8e64cfb9 --- /dev/null +++ b/changelog/unreleased/add-users-instances.md @@ -0,0 +1,5 @@ +Enhancement: Add users instances + +The user endpoint now returns the instances that the user is either a member or a guest of and the cross instance reference. + +https://github.com/owncloud/ocis/pull/11925 diff --git a/deployments/examples/ocis_multi/docker-compose.yml b/deployments/examples/ocis_multi/docker-compose.yml index 7e5ad88a63f..c6d9fe8440f 100644 --- a/deployments/examples/ocis_multi/docker-compose.yml +++ b/deployments/examples/ocis_multi/docker-compose.yml @@ -115,6 +115,8 @@ services: OCIS_MULTI_INSTANCE_MEMBER_CLAIM: "memberOf" OCIS_MULTI_INSTANCE_GUEST_CLAIM: "guestOf" OCIS_MULTI_INSTANCE_GUEST_ROLE: "user-light" + OCIS_LDAP_CROSS_INSTANCE_REFERENCE_TEMPLATE: "{{.Username}}@{{.Instancename}}.owncloud.test" + OCIS_LDAP_INSTANCE_URL_TEMPLATE: "https://{{.Instancename}}.owncloud.test" # Workaround needed to show external users - can be removed once fixed OCIS_SHOW_USER_EMAIL_IN_RESULTS: true PROXY_ROLE_ASSIGNMENT_OIDC_CLAIM: ownCloudRole @@ -209,6 +211,8 @@ services: OCIS_MULTI_INSTANCE_MEMBER_CLAIM: "memberOf" OCIS_MULTI_INSTANCE_GUEST_CLAIM: "guestOf" OCIS_MULTI_INSTANCE_GUEST_ROLE: "user-light" + OCIS_LDAP_CROSS_INSTANCE_REFERENCE_TEMPLATE: "{{.Username}}@{{.Instancename}}.owncloud.test" + OCIS_LDAP_INSTANCE_URL_TEMPLATE: "https://{{.Instancename}}.owncloud.test" # user filter required for multi-instance ocis # Workaround needed to show external users - can be removed once fixed OCIS_SHOW_USER_EMAIL_IN_RESULTS: true diff --git a/docs/helpers/env_vars.yaml b/docs/helpers/env_vars.yaml index 6303d84cf3d..a3a6e6ae2bb 100644 --- a/docs/helpers/env_vars.yaml +++ b/docs/helpers/env_vars.yaml @@ -6038,10 +6038,10 @@ IDM_ADMIN_USER_ID: removalVersion: "" deprecationInfo: "" IDM_CREATE_DEMO_USERS: - name: SETTINGS_SETUP_DEFAULT_ASSIGNMENTS;IDM_CREATE_DEMO_USERS + name: IDM_CREATE_DEMO_USERS defaultValue: "false" type: bool - description: The default role assignments the demo users should be setup. + description: Flag to enable or disable the creation of the demo users. introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" @@ -7882,7 +7882,7 @@ OCDAV_WEBDAV_NAMESPACE: removalVersion: "" deprecationInfo: "" OCIS_ADMIN_USER_ID: - name: OCIS_ADMIN_USER_ID;SETTINGS_ADMIN_USER_ID + name: OCIS_ADMIN_USER_ID;IDM_ADMIN_USER_ID defaultValue: "" type: string description: ID of the user that should receive admin privileges. Consider that @@ -7903,7 +7903,7 @@ OCIS_ASSET_THEMES_PATH: removalVersion: "" deprecationInfo: "" OCIS_ASYNC_UPLOADS: - name: OCIS_ASYNC_UPLOADS + name: OCIS_ASYNC_UPLOADS;SEARCH_EVENTS_ASYNC_UPLOADS defaultValue: "true" type: bool description: Enable asynchronous file uploads. @@ -7912,28 +7912,28 @@ OCIS_ASYNC_UPLOADS: removalVersion: "" deprecationInfo: "" OCIS_CACHE_AUTH_PASSWORD: - name: OCIS_CACHE_AUTH_PASSWORD;STORAGE_SYSTEM_CACHE_AUTH_PASSWORD + name: OCIS_CACHE_AUTH_PASSWORD;OCS_PRESIGNEDURL_SIGNING_KEYS_STORE_AUTH_PASSWORD defaultValue: "" type: string - description: Password for the configured store. Only applies when store type 'nats-js-kv' - is configured. + description: The password to authenticate with the store. Only applies when store + type 'nats-js-kv' is configured. introductionVersion: "5.0" deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_CACHE_AUTH_USERNAME: - name: OCIS_CACHE_AUTH_USERNAME;STORAGE_SYSTEM_CACHE_AUTH_USERNAME + name: OCIS_CACHE_AUTH_USERNAME;OCS_PRESIGNEDURL_SIGNING_KEYS_STORE_AUTH_USERNAME defaultValue: "" type: string - description: Username for the configured store. Only applies when store type 'nats-js-kv' - is configured. + description: The username to authenticate with the store. Only applies when store + type 'nats-js-kv' is configured. introductionVersion: "5.0" deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_CACHE_DATABASE: name: OCIS_CACHE_DATABASE - defaultValue: storage-system + defaultValue: cache-userinfo type: string description: The database name the configured store should use. introductionVersion: pre5.0 @@ -7941,45 +7941,43 @@ OCIS_CACHE_DATABASE: removalVersion: "" deprecationInfo: "" OCIS_CACHE_DISABLE_PERSISTENCE: - name: OCIS_CACHE_DISABLE_PERSISTENCE;STORAGE_SYSTEM_CACHE_DISABLE_PERSISTENCE - defaultValue: "false" + name: OCIS_CACHE_DISABLE_PERSISTENCE;PROXY_PRESIGNEDURL_SIGNING_KEYS_STORE_DISABLE_PERSISTENCE + defaultValue: "true" type: bool - description: Disables persistence of the cache. Only applies when store type 'nats-js-kv' - is configured. Defaults to false. + description: Disables persistence of the store. Only applies when store type 'nats-js-kv' + is configured. Defaults to true. introductionVersion: "5.0" deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_CACHE_STORE: - name: OCIS_CACHE_STORE;STORAGE_SYSTEM_CACHE_STORE - defaultValue: memory + name: OCIS_CACHE_STORE;OCS_PRESIGNEDURL_SIGNING_KEYS_STORE + defaultValue: nats-js-kv type: string - description: 'The type of the cache store. Supported values are: ''memory'', ''redis-sentinel'', - ''nats-js-kv'', ''noop''. See the text description for details.' - introductionVersion: pre5.0 + description: 'The type of the signing key store. Supported values are: ''redis-sentinel'' + and ''nats-js-kv''. See the text description for details.' + introductionVersion: "5.0" deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_CACHE_STORE_NODES: - name: OCIS_CACHE_STORE_NODES;STORAGE_SYSTEM_CACHE_STORE_NODES + name: OCIS_CACHE_STORE_NODES;OCS_PRESIGNEDURL_SIGNING_KEYS_STORE_NODES defaultValue: '[127.0.0.1:9233]' type: '[]string' - description: A list of nodes to access the configured store. This has no effect - when 'memory' store is configured. Note that the behaviour how nodes are used - is dependent on the library of the configured store. See the Environment Variable - Types description for more details. - introductionVersion: pre5.0 + description: A list of nodes to access the configured store. Note that the behaviour + how nodes are used is dependent on the library of the configured store. See the + Environment Variable Types description for more details. + introductionVersion: "5.0" deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_CACHE_TTL: - name: OCIS_CACHE_TTL;STORAGE_SYSTEM_CACHE_TTL - defaultValue: 24m0s + name: OCIS_CACHE_TTL;OCS_PRESIGNEDURL_SIGNING_KEYS_STORE_TTL + defaultValue: 12h0m0s type: Duration - description: Default time to live for user info in the user info cache. Only applied - when access tokens has no expiration. See the Environment Variable Types description - for more details. - introductionVersion: pre5.0 + description: Default time to live for signing keys. See the Environment Variable + Types description for more details. + introductionVersion: "5.0" deprecationVersion: "" removalVersion: "" deprecationInfo: "" @@ -8021,46 +8019,46 @@ OCIS_CLAIM_MANAGED_SPACES_REGEXP: removalVersion: "" deprecationInfo: "" OCIS_CORS_ALLOW_CREDENTIALS: - name: OCIS_CORS_ALLOW_CREDENTIALS;SSE_CORS_ALLOW_CREDENTIALS + name: OCIS_CORS_ALLOW_CREDENTIALS;WEBDAV_CORS_ALLOW_CREDENTIALS defaultValue: "true" type: bool description: 'Allow credentials for CORS.See following chapter for more details: *Access-Control-Allow-Credentials* at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials.' - introductionVersion: "5.0" + introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_CORS_ALLOW_HEADERS: - name: OCIS_CORS_ALLOW_HEADERS;SSE_CORS_ALLOW_HEADERS + name: OCIS_CORS_ALLOW_HEADERS;WEBDAV_CORS_ALLOW_HEADERS defaultValue: '[Authorization Origin Content-Type Accept X-Requested-With X-Request-Id - Ocs-Apirequest]' + Cache-Control]' type: '[]string' description: 'A list of allowed CORS headers. See following chapter for more details: *Access-Control-Request-Headers* at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Request-Headers. See the Environment Variable Types description for more details.' - introductionVersion: "5.0" + introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_CORS_ALLOW_METHODS: - name: OCIS_CORS_ALLOW_METHODS;SSE_CORS_ALLOW_METHODS - defaultValue: '[GET]' + name: OCIS_CORS_ALLOW_METHODS;WEBDAV_CORS_ALLOW_METHODS + defaultValue: '[GET POST PUT PATCH DELETE OPTIONS]' type: '[]string' description: 'A list of allowed CORS methods. See following chapter for more details: *Access-Control-Request-Method* at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Request-Method. See the Environment Variable Types description for more details.' - introductionVersion: "5.0" + introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_CORS_ALLOW_ORIGINS: - name: OCIS_CORS_ALLOW_ORIGINS;SSE_CORS_ALLOW_ORIGINS + name: OCIS_CORS_ALLOW_ORIGINS;WEBDAV_CORS_ALLOW_ORIGINS defaultValue: '[*]' type: '[]string' description: 'A list of allowed CORS origins. See following chapter for more details: *Access-Control-Allow-Origin* at https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin. See the Environment Variable Types description for more details.' - introductionVersion: "5.0" + introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" deprecationInfo: "" @@ -8168,16 +8166,16 @@ OCIS_EMAIL_TEMPLATE_PATH: removalVersion: "" deprecationInfo: "" OCIS_ENABLE_OCM: - name: OCIS_ENABLE_OCM;GRAPH_INCLUDE_OCM_SHAREES + name: OCIS_ENABLE_OCM defaultValue: "false" type: bool - description: Include OCM sharees when listing users. + description: Include OCM sharees when listing sharees. introductionVersion: "5.0" deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_EVENTS_AUTH_PASSWORD: - name: OCIS_EVENTS_AUTH_PASSWORD;SSE_EVENTS_AUTH_PASSWORD + name: OCIS_EVENTS_AUTH_PASSWORD;POSTPROCESSING_EVENTS_AUTH_PASSWORD defaultValue: "" type: string description: The password to authenticate with the events broker. The events broker @@ -8187,7 +8185,7 @@ OCIS_EVENTS_AUTH_PASSWORD: removalVersion: "" deprecationInfo: "" OCIS_EVENTS_AUTH_USERNAME: - name: OCIS_EVENTS_AUTH_USERNAME;SSE_EVENTS_AUTH_USERNAME + name: OCIS_EVENTS_AUTH_USERNAME;POSTPROCESSING_EVENTS_AUTH_USERNAME defaultValue: "" type: string description: The username to authenticate with the events broker. The events broker @@ -8197,43 +8195,43 @@ OCIS_EVENTS_AUTH_USERNAME: removalVersion: "" deprecationInfo: "" OCIS_EVENTS_CLUSTER: - name: OCIS_EVENTS_CLUSTER;SSE_EVENTS_CLUSTER + name: OCIS_EVENTS_CLUSTER;POSTPROCESSING_EVENTS_CLUSTER defaultValue: ocis-cluster type: string description: The clusterID of the event system. The event system is the message queuing service. It is used as message broker for the microservice architecture. Mandatory when using NATS as event system. - introductionVersion: "5.0" + introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_EVENTS_ENABLE_TLS: - name: OCIS_EVENTS_ENABLE_TLS;SSE_EVENTS_ENABLE_TLS + name: OCIS_EVENTS_ENABLE_TLS;POSTPROCESSING_EVENTS_ENABLE_TLS defaultValue: "false" type: bool description: Enable TLS for the connection to the events broker. The events broker is the ocis service which receives and delivers events between the services. - introductionVersion: "5.0" + introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_EVENTS_ENDPOINT: - name: OCIS_EVENTS_ENDPOINT;SSE_EVENTS_ENDPOINT + name: OCIS_EVENTS_ENDPOINT;POSTPROCESSING_EVENTS_ENDPOINT defaultValue: 127.0.0.1:9233 type: string description: The address of the event system. The event system is the message queuing service. It is used as message broker for the microservice architecture. - introductionVersion: "5.0" + introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_EVENTS_TLS_ROOT_CA_CERTIFICATE: - name: OCIS_EVENTS_TLS_ROOT_CA_CERTIFICATE;SSE_EVENTS_TLS_ROOT_CA_CERTIFICATE + name: OCIS_EVENTS_TLS_ROOT_CA_CERTIFICATE;POSTPROCESSING_EVENTS_TLS_ROOT_CA_CERTIFICATE defaultValue: "" type: string description: The root CA certificate used to validate the server's TLS certificate. - If provided SSE_EVENTS_TLS_INSECURE will be seen as false. - introductionVersion: "5.0" + If provided POSTPROCESSING_EVENTS_TLS_INSECURE will be seen as false. + introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" deprecationInfo: "" @@ -8270,10 +8268,10 @@ OCIS_GRPC_CLIENT_TLS_MODE: removalVersion: "" deprecationInfo: "" OCIS_GRPC_PROTOCOL: - name: OCIS_GRPC_PROTOCOL;STORAGE_SYSTEM_GRPC_PROTOCOL + name: OCIS_GRPC_PROTOCOL;AUTH_BEARER_GRPC_PROTOCOL defaultValue: "" type: string - description: The transport protocol of the GPRC service. + description: The transport protocol of the GRPC service. introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" @@ -8310,16 +8308,17 @@ OCIS_HTTP_TLS_KEY: removalVersion: "" deprecationInfo: "" OCIS_INSECURE: - name: OCIS_INSECURE;SSE_EVENTS_TLS_INSECURE + name: OCIS_INSECURE;POSTPROCESSING_EVENTS_TLS_INSECURE defaultValue: "false" type: bool - description: Whether to verify the server TLS certificates. - introductionVersion: "5.0" + description: Whether the ocis server should skip the client certificate verification + during the TLS handshake. + introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_JWT_SECRET: - name: OCIS_JWT_SECRET;STORAGE_SYSTEM_JWT_SECRET + name: OCIS_JWT_SECRET;AUTH_BEARER_JWT_SECRET defaultValue: "" type: string description: The secret to mint and validate jwt tokens. @@ -8328,7 +8327,7 @@ OCIS_JWT_SECRET: removalVersion: "" deprecationInfo: "" OCIS_KEYCLOAK_BASE_PATH: - name: OCIS_KEYCLOAK_BASE_PATH;GRAPH_KEYCLOAK_BASE_PATH + name: OCIS_KEYCLOAK_BASE_PATH;INVITATIONS_KEYCLOAK_BASE_PATH defaultValue: "" type: string description: The URL to access keycloak. @@ -8337,16 +8336,16 @@ OCIS_KEYCLOAK_BASE_PATH: removalVersion: "" deprecationInfo: "" OCIS_KEYCLOAK_CLIENT_ID: - name: OCIS_KEYCLOAK_CLIENT_ID;GRAPH_KEYCLOAK_CLIENT_ID + name: OCIS_KEYCLOAK_CLIENT_ID;INVITATIONS_KEYCLOAK_CLIENT_ID defaultValue: "" type: string - description: The client id to authenticate with keycloak. + description: The client ID to authenticate with keycloak. introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_KEYCLOAK_CLIENT_REALM: - name: OCIS_KEYCLOAK_CLIENT_REALM;GRAPH_KEYCLOAK_CLIENT_REALM + name: OCIS_KEYCLOAK_CLIENT_REALM;INVITATIONS_KEYCLOAK_CLIENT_REALM defaultValue: "" type: string description: The realm the client is defined in. @@ -8355,7 +8354,7 @@ OCIS_KEYCLOAK_CLIENT_REALM: removalVersion: "" deprecationInfo: "" OCIS_KEYCLOAK_CLIENT_SECRET: - name: OCIS_KEYCLOAK_CLIENT_SECRET;GRAPH_KEYCLOAK_CLIENT_SECRET + name: OCIS_KEYCLOAK_CLIENT_SECRET;INVITATIONS_KEYCLOAK_CLIENT_SECRET defaultValue: "" type: string description: The client secret to use in authentication. @@ -8364,7 +8363,7 @@ OCIS_KEYCLOAK_CLIENT_SECRET: removalVersion: "" deprecationInfo: "" OCIS_KEYCLOAK_INSECURE_SKIP_VERIFY: - name: OCIS_KEYCLOAK_INSECURE_SKIP_VERIFY;GRAPH_KEYCLOAK_INSECURE_SKIP_VERIFY + name: OCIS_KEYCLOAK_INSECURE_SKIP_VERIFY;INVITATIONS_KEYCLOAK_INSECURE_SKIP_VERIFY defaultValue: "false" type: bool description: Disable TLS certificate validation for Keycloak connections. Do not @@ -8374,7 +8373,7 @@ OCIS_KEYCLOAK_INSECURE_SKIP_VERIFY: removalVersion: "" deprecationInfo: "" OCIS_KEYCLOAK_USER_REALM: - name: OCIS_KEYCLOAK_USER_REALM;GRAPH_KEYCLOAK_USER_REALM + name: OCIS_KEYCLOAK_USER_REALM;INVITATIONS_KEYCLOAK_USER_REALM defaultValue: "" type: string description: The realm users are defined. @@ -8412,21 +8411,31 @@ OCIS_LDAP_CACERT: deprecationVersion: "" removalVersion: "" deprecationInfo: "" +OCIS_LDAP_CROSS_INSTANCE_REFERENCE_TEMPLATE: + name: OCIS_LDAP_CROSS_INSTANCE_REFERENCE_TEMPLATE + defaultValue: "" + type: string + description: Template for the users unique reference across oCIS instances. Requires + OCIS_MULTI_INSTANCE_ENABLED. + introductionVersion: 8.0.0 + deprecationVersion: "" + removalVersion: "" + deprecationInfo: "" OCIS_LDAP_DISABLE_USER_MECHANISM: - name: OCIS_LDAP_DISABLE_USER_MECHANISM;GRAPH_DISABLE_USER_MECHANISM + name: OCIS_LDAP_DISABLE_USER_MECHANISM;USERS_LDAP_DISABLE_USER_MECHANISM defaultValue: attribute type: string - description: An option to control the behavior for disabling users. Supported options + description: An option to control the behavior for disabling users. Valid options are 'none', 'attribute' and 'group'. If set to 'group', disabling a user via API will add the user to the configured group for disabled users, if set to 'attribute' this will be done in the ldap user entry, if set to 'none' the disable request - is not processed. Default is 'attribute'. + is not processed. introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_LDAP_DISABLED_USERS_GROUP_DN: - name: OCIS_LDAP_DISABLED_USERS_GROUP_DN;GRAPH_DISABLED_USERS_GROUP_DN + name: OCIS_LDAP_DISABLED_USERS_GROUP_DN;USERS_LDAP_DISABLED_USERS_GROUP_DN defaultValue: cn=DisabledUsersGroup,ou=groups,o=libregraph-idm type: string description: The distinguished name of the group to which added users will be classified @@ -8436,7 +8445,7 @@ OCIS_LDAP_DISABLED_USERS_GROUP_DN: removalVersion: "" deprecationInfo: "" OCIS_LDAP_GROUP_BASE_DN: - name: OCIS_LDAP_GROUP_BASE_DN;GRAPH_LDAP_GROUP_BASE_DN + name: OCIS_LDAP_GROUP_BASE_DN;USERS_LDAP_GROUP_BASE_DN defaultValue: ou=groups,o=libregraph-idm type: string description: Search base DN for looking up LDAP groups. @@ -8445,7 +8454,7 @@ OCIS_LDAP_GROUP_BASE_DN: removalVersion: "" deprecationInfo: "" OCIS_LDAP_GROUP_FILTER: - name: OCIS_LDAP_GROUP_FILTER;GRAPH_LDAP_GROUP_FILTER + name: OCIS_LDAP_GROUP_FILTER;USERS_LDAP_GROUP_FILTER defaultValue: "" type: string description: LDAP filter to add to the default filters for group searches. @@ -8454,17 +8463,17 @@ OCIS_LDAP_GROUP_FILTER: removalVersion: "" deprecationInfo: "" OCIS_LDAP_GROUP_OBJECTCLASS: - name: OCIS_LDAP_GROUP_OBJECTCLASS;GRAPH_LDAP_GROUP_OBJECTCLASS + name: OCIS_LDAP_GROUP_OBJECTCLASS;USERS_LDAP_GROUP_OBJECTCLASS defaultValue: groupOfNames type: string description: The object class to use for groups in the default group search filter - ('groupOfNames'). + like 'groupOfNames'. introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_LDAP_GROUP_SCHEMA_DISPLAYNAME: - name: OCIS_LDAP_GROUP_SCHEMA_DISPLAYNAME;AUTH_BASIC_LDAP_GROUP_SCHEMA_DISPLAYNAME + name: OCIS_LDAP_GROUP_SCHEMA_DISPLAYNAME;USERS_LDAP_GROUP_SCHEMA_DISPLAYNAME defaultValue: cn type: string description: LDAP Attribute to use for the displayname of groups (often the same @@ -8474,7 +8483,7 @@ OCIS_LDAP_GROUP_SCHEMA_DISPLAYNAME: removalVersion: "" deprecationInfo: "" OCIS_LDAP_GROUP_SCHEMA_GROUPNAME: - name: OCIS_LDAP_GROUP_SCHEMA_GROUPNAME;GRAPH_LDAP_GROUP_NAME_ATTRIBUTE + name: OCIS_LDAP_GROUP_SCHEMA_GROUPNAME;USERS_LDAP_GROUP_SCHEMA_GROUPNAME defaultValue: cn type: string description: LDAP Attribute to use for the name of groups. @@ -8483,28 +8492,28 @@ OCIS_LDAP_GROUP_SCHEMA_GROUPNAME: removalVersion: "" deprecationInfo: "" OCIS_LDAP_GROUP_SCHEMA_ID: - name: OCIS_LDAP_GROUP_SCHEMA_ID;GRAPH_LDAP_GROUP_ID_ATTRIBUTE - defaultValue: owncloudUUID + name: OCIS_LDAP_GROUP_SCHEMA_ID;USERS_LDAP_GROUP_SCHEMA_ID + defaultValue: ownclouduuid type: string - description: LDAP Attribute to use as the unique id for groups. This should be a + description: LDAP Attribute to use as the unique ID for groups. This should be a stable globally unique ID like a UUID. introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_LDAP_GROUP_SCHEMA_ID_IS_OCTETSTRING: - name: OCIS_LDAP_GROUP_SCHEMA_ID_IS_OCTETSTRING;GRAPH_LDAP_GROUP_SCHEMA_ID_IS_OCTETSTRING + name: OCIS_LDAP_GROUP_SCHEMA_ID_IS_OCTETSTRING;USERS_LDAP_GROUP_SCHEMA_ID_IS_OCTETSTRING defaultValue: "false" type: bool - description: Set this to true if the defined 'ID' attribute for groups is of the - 'OCTETSTRING' syntax. This is required when using the 'objectGUID' attribute of - Active Directory for the group ID's. + description: Set this to true if the defined 'id' attribute for groups is of the + 'OCTETSTRING' syntax. This is e.g. required when using the 'objectGUID' attribute + of Active Directory for the group ID's. introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_LDAP_GROUP_SCHEMA_MAIL: - name: OCIS_LDAP_GROUP_SCHEMA_MAIL;AUTH_BASIC_LDAP_GROUP_SCHEMA_MAIL + name: OCIS_LDAP_GROUP_SCHEMA_MAIL;USERS_LDAP_GROUP_SCHEMA_MAIL defaultValue: mail type: string description: LDAP Attribute to use for the email address of groups (can be empty). @@ -8513,7 +8522,7 @@ OCIS_LDAP_GROUP_SCHEMA_MAIL: removalVersion: "" deprecationInfo: "" OCIS_LDAP_GROUP_SCHEMA_MEMBER: - name: OCIS_LDAP_GROUP_SCHEMA_MEMBER;GRAPH_LDAP_GROUP_MEMBER_ATTRIBUTE + name: OCIS_LDAP_GROUP_SCHEMA_MEMBER;USERS_LDAP_GROUP_SCHEMA_MEMBER defaultValue: member type: string description: LDAP Attribute that is used for group members. @@ -8522,10 +8531,10 @@ OCIS_LDAP_GROUP_SCHEMA_MEMBER: removalVersion: "" deprecationInfo: "" OCIS_LDAP_GROUP_SCOPE: - name: OCIS_LDAP_GROUP_SCOPE;GRAPH_LDAP_GROUP_SEARCH_SCOPE + name: OCIS_LDAP_GROUP_SCOPE;USERS_LDAP_GROUP_SCOPE defaultValue: sub type: string - description: LDAP search scope to use when looking up groups. Supported scopes are + description: LDAP search scope to use when looking up groups. Supported values are 'base', 'one' and 'sub'. introductionVersion: pre5.0 deprecationVersion: "" @@ -8580,6 +8589,15 @@ OCIS_LDAP_INSTANCE_MAPPER_NAME_ATTRIBUTE: deprecationVersion: "" removalVersion: "" deprecationInfo: "" +OCIS_LDAP_INSTANCE_URL_TEMPLATE: + name: OCIS_LDAP_INSTANCE_URL_TEMPLATE + defaultValue: "" + type: string + description: Template for the instance URL. Requires OCIS_MULTI_INSTANCE_ENABLED. + introductionVersion: 8.0.0 + deprecationVersion: "" + removalVersion: "" + deprecationInfo: "" OCIS_LDAP_PRECISE_SEARCH_ATTRIBUTE: name: OCIS_LDAP_PRECISE_SEARCH_ATTRIBUTE defaultValue: "" @@ -8591,7 +8609,7 @@ OCIS_LDAP_PRECISE_SEARCH_ATTRIBUTE: removalVersion: "" deprecationInfo: "" OCIS_LDAP_SERVER_WRITE_ENABLED: - name: OCIS_LDAP_SERVER_WRITE_ENABLED;GRAPH_LDAP_SERVER_WRITE_ENABLED + name: OCIS_LDAP_SERVER_WRITE_ENABLED;FRONTEND_LDAP_SERVER_WRITE_ENABLED defaultValue: "true" type: bool description: Allow creating, modifying and deleting LDAP users via the GRAPH API. @@ -8668,14 +8686,14 @@ OCIS_LDAP_USER_OBJECTCLASS: removalVersion: "" deprecationInfo: "" OCIS_LDAP_USER_SCHEMA_DISPLAYNAME: - name: OCIS_LDAP_USER_SCHEMA_DISPLAYNAME;GRAPH_LDAP_USER_DISPLAYNAME_ATTRIBUTE - defaultValue: displayName + name: OCIS_LDAP_USER_SCHEMA_DISPLAYNAME;USERS_LDAP_USER_SCHEMA_DISPLAYNAME + defaultValue: displayname type: string - description: LDAP Attribute to use for the display name of users. + description: LDAP Attribute to use for the displayname of users. introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" - deprecationInfo: 'LDAP_USER_SCHEMA_DISPLAY_NAME changing name for consistency | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ' + deprecationInfo: 'LDAP_USER_SCHEMA_DISPLAY_NAME changing name for consistency | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | ' OCIS_LDAP_USER_SCHEMA_EXTERNAL_ID: name: OCIS_LDAP_USER_SCHEMA_EXTERNAL_ID;GRAPH_LDAP_EXTERNAL_ID_ATTRIBUTE defaultValue: owncloudExternalID @@ -8697,12 +8715,12 @@ OCIS_LDAP_USER_SCHEMA_ID: removalVersion: "" deprecationInfo: "" OCIS_LDAP_USER_SCHEMA_ID_IS_OCTETSTRING: - name: OCIS_LDAP_USER_SCHEMA_ID_IS_OCTETSTRING;GRAPH_LDAP_USER_SCHEMA_ID_IS_OCTETSTRING + name: OCIS_LDAP_USER_SCHEMA_ID_IS_OCTETSTRING;USERS_LDAP_USER_SCHEMA_ID_IS_OCTETSTRING defaultValue: "false" type: bool description: Set this to true if the defined 'ID' attribute for users is of the - 'OCTETSTRING' syntax. This is required when using the 'objectGUID' attribute of - Active Directory for the user ID's. + 'OCTETSTRING' syntax. This is e.g. required when using the 'objectGUID' attribute + of Active Directory for the user ID's. introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" @@ -8717,7 +8735,7 @@ OCIS_LDAP_USER_SCHEMA_MAIL: removalVersion: "" deprecationInfo: "" OCIS_LDAP_USER_SCHEMA_USER_TYPE: - name: OCIS_LDAP_USER_SCHEMA_USER_TYPE;GRAPH_LDAP_USER_TYPE_ATTRIBUTE + name: OCIS_LDAP_USER_SCHEMA_USER_TYPE;USERS_LDAP_USER_TYPE_ATTRIBUTE defaultValue: ownCloudUserType type: string description: LDAP Attribute to distinguish between 'Member' and 'Guest' users. Default @@ -8746,7 +8764,7 @@ OCIS_LDAP_USER_SCOPE: removalVersion: "" deprecationInfo: "" OCIS_LOG_COLOR: - name: OCIS_LOG_COLOR;STORAGE_SYSTEM_LOG_COLOR + name: OCIS_LOG_COLOR;WEBDAV_LOG_COLOR defaultValue: "false" type: bool description: Activates colorized log output. @@ -8755,7 +8773,7 @@ OCIS_LOG_COLOR: removalVersion: "" deprecationInfo: "" OCIS_LOG_FILE: - name: OCIS_LOG_FILE;STORAGE_SYSTEM_LOG_FILE + name: OCIS_LOG_FILE;WEBDAV_LOG_FILE defaultValue: "" type: string description: The path to the log file. Activates logging to this file if set. @@ -8764,7 +8782,7 @@ OCIS_LOG_FILE: removalVersion: "" deprecationInfo: "" OCIS_LOG_LEVEL: - name: OCIS_LOG_LEVEL;STORAGE_SYSTEM_LOG_LEVEL + name: OCIS_LOG_LEVEL;WEBDAV_LOG_LEVEL defaultValue: "" type: string description: 'The log level. Valid values are: ''panic'', ''fatal'', ''error'', @@ -8774,7 +8792,7 @@ OCIS_LOG_LEVEL: removalVersion: "" deprecationInfo: "" OCIS_LOG_PRETTY: - name: OCIS_LOG_PRETTY;STORAGE_SYSTEM_LOG_PRETTY + name: OCIS_LOG_PRETTY;WEBDAV_LOG_PRETTY defaultValue: "false" type: bool description: Activates pretty log output. @@ -8783,7 +8801,7 @@ OCIS_LOG_PRETTY: removalVersion: "" deprecationInfo: "" OCIS_MACHINE_AUTH_API_KEY: - name: OCIS_MACHINE_AUTH_API_KEY;AUTH_MACHINE_API_KEY + name: OCIS_MACHINE_AUTH_API_KEY;IDP_MACHINE_AUTH_API_KEY defaultValue: "" type: string description: Machine auth API key used to validate internal requests necessary for @@ -8793,7 +8811,7 @@ OCIS_MACHINE_AUTH_API_KEY: removalVersion: "" deprecationInfo: "" OCIS_MAX_CONCURRENCY: - name: OCIS_MAX_CONCURRENCY;USERLOG_MAX_CONCURRENCY + name: OCIS_MAX_CONCURRENCY;FRONTEND_MAX_CONCURRENCY defaultValue: "1" type: int description: Maximum number of concurrent go-routines. Higher values can potentially @@ -8830,9 +8848,9 @@ OCIS_MFA_ENABLED: name: OCIS_MFA_ENABLED defaultValue: "false" type: bool - description: Set to true to enable multi factor authentication. See the documentation - for more details. - introductionVersion: 7.3.0 + description: Enable MFA enforcement. If enabled users need to complete MFA before + they can access specific paths + introductionVersion: Balch deprecationVersion: "" removalVersion: "" deprecationInfo: "" @@ -8867,7 +8885,7 @@ OCIS_MULTI_INSTANCE_INSTANCEID: name: OCIS_MULTI_INSTANCE_INSTANCEID defaultValue: "" type: string - description: The unique ID of this instance. + description: The unique id of this instance introductionVersion: 8.0.0 deprecationVersion: "" removalVersion: "" @@ -8903,16 +8921,16 @@ OCIS_OIDC_CLIENT_ID: removalVersion: "" deprecationInfo: "" OCIS_OIDC_ISSUER: - name: OCIS_URL;OCIS_OIDC_ISSUER;WEB_OIDC_AUTHORITY + name: OCIS_URL;OCIS_OIDC_ISSUER;IDP_ISS defaultValue: https://localhost:9200 type: string - description: URL of the OIDC issuer. It defaults to URL of the builtin IDP. + description: The OIDC issuer URL to use. introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_PASSWORD_POLICY_BANNED_PASSWORDS_LIST: - name: OCIS_PASSWORD_POLICY_BANNED_PASSWORDS_LIST;SHARING_PASSWORD_POLICY_BANNED_PASSWORDS_LIST + name: OCIS_PASSWORD_POLICY_BANNED_PASSWORDS_LIST;FRONTEND_PASSWORD_POLICY_BANNED_PASSWORDS_LIST defaultValue: "" type: string description: Path to the 'banned passwords list' file. This only impacts public @@ -8922,7 +8940,7 @@ OCIS_PASSWORD_POLICY_BANNED_PASSWORDS_LIST: removalVersion: "" deprecationInfo: "" OCIS_PASSWORD_POLICY_DISABLED: - name: OCIS_PASSWORD_POLICY_DISABLED;SHARING_PASSWORD_POLICY_DISABLED + name: OCIS_PASSWORD_POLICY_DISABLED;FRONTEND_PASSWORD_POLICY_DISABLED defaultValue: "false" type: bool description: Disable the password policy. Defaults to false if not set. @@ -8931,7 +8949,7 @@ OCIS_PASSWORD_POLICY_DISABLED: removalVersion: "" deprecationInfo: "" OCIS_PASSWORD_POLICY_MIN_CHARACTERS: - name: OCIS_PASSWORD_POLICY_MIN_CHARACTERS;SHARING_PASSWORD_POLICY_MIN_CHARACTERS + name: OCIS_PASSWORD_POLICY_MIN_CHARACTERS;FRONTEND_PASSWORD_POLICY_MIN_CHARACTERS defaultValue: "8" type: int description: Define the minimum password length. Defaults to 8 if not set. @@ -8940,7 +8958,7 @@ OCIS_PASSWORD_POLICY_MIN_CHARACTERS: removalVersion: "" deprecationInfo: "" OCIS_PASSWORD_POLICY_MIN_DIGITS: - name: OCIS_PASSWORD_POLICY_MIN_DIGITS;SHARING_PASSWORD_POLICY_MIN_DIGITS + name: OCIS_PASSWORD_POLICY_MIN_DIGITS;FRONTEND_PASSWORD_POLICY_MIN_DIGITS defaultValue: "1" type: int description: Define the minimum number of digits. Defaults to 1 if not set. @@ -8949,7 +8967,7 @@ OCIS_PASSWORD_POLICY_MIN_DIGITS: removalVersion: "" deprecationInfo: "" OCIS_PASSWORD_POLICY_MIN_LOWERCASE_CHARACTERS: - name: OCIS_PASSWORD_POLICY_MIN_LOWERCASE_CHARACTERS;SHARING_PASSWORD_POLICY_MIN_LOWERCASE_CHARACTERS + name: OCIS_PASSWORD_POLICY_MIN_LOWERCASE_CHARACTERS;FRONTEND_PASSWORD_POLICY_MIN_LOWERCASE_CHARACTERS defaultValue: "1" type: int description: Define the minimum number of uppercase letters. Defaults to 1 if not @@ -8959,7 +8977,7 @@ OCIS_PASSWORD_POLICY_MIN_LOWERCASE_CHARACTERS: removalVersion: "" deprecationInfo: "" OCIS_PASSWORD_POLICY_MIN_SPECIAL_CHARACTERS: - name: OCIS_PASSWORD_POLICY_MIN_SPECIAL_CHARACTERS;SHARING_PASSWORD_POLICY_MIN_SPECIAL_CHARACTERS + name: OCIS_PASSWORD_POLICY_MIN_SPECIAL_CHARACTERS;FRONTEND_PASSWORD_POLICY_MIN_SPECIAL_CHARACTERS defaultValue: "1" type: int description: Define the minimum number of characters from the special characters @@ -8969,7 +8987,7 @@ OCIS_PASSWORD_POLICY_MIN_SPECIAL_CHARACTERS: removalVersion: "" deprecationInfo: "" OCIS_PASSWORD_POLICY_MIN_UPPERCASE_CHARACTERS: - name: OCIS_PASSWORD_POLICY_MIN_UPPERCASE_CHARACTERS;SHARING_PASSWORD_POLICY_MIN_UPPERCASE_CHARACTERS + name: OCIS_PASSWORD_POLICY_MIN_UPPERCASE_CHARACTERS;FRONTEND_PASSWORD_POLICY_MIN_UPPERCASE_CHARACTERS defaultValue: "1" type: int description: Define the minimum number of lowercase letters. Defaults to 1 if not @@ -8979,54 +8997,54 @@ OCIS_PASSWORD_POLICY_MIN_UPPERCASE_CHARACTERS: removalVersion: "" deprecationInfo: "" OCIS_PERSISTENT_STORE: - name: OCIS_PERSISTENT_STORE;COLLABORATION_STORE + name: OCIS_PERSISTENT_STORE;POSTPROCESSING_STORE defaultValue: nats-js-kv type: string - description: 'The type of the store. Supported values are: ''memory'', ''nats-js-kv'', - ''redis-sentinel'', ''noop''. See the text description for details.' - introductionVersion: 7.0.0 + description: 'The type of the store. Supported values are: ''memory'', ''redis-sentinel'', + ''nats-js-kv'', ''noop''. See the text description for details.' + introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_PERSISTENT_STORE_AUTH_PASSWORD: - name: OCIS_PERSISTENT_STORE_AUTH_PASSWORD;COLLABORATION_STORE_AUTH_PASSWORD + name: OCIS_PERSISTENT_STORE_AUTH_PASSWORD;POSTPROCESSING_STORE_AUTH_PASSWORD defaultValue: "" type: string description: The password to authenticate with the store. Only applies when store type 'nats-js-kv' is configured. - introductionVersion: 7.0.0 + introductionVersion: "5.0" deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_PERSISTENT_STORE_AUTH_USERNAME: - name: OCIS_PERSISTENT_STORE_AUTH_USERNAME;COLLABORATION_STORE_AUTH_USERNAME + name: OCIS_PERSISTENT_STORE_AUTH_USERNAME;POSTPROCESSING_STORE_AUTH_USERNAME defaultValue: "" type: string description: The username to authenticate with the store. Only applies when store type 'nats-js-kv' is configured. - introductionVersion: 7.0.0 + introductionVersion: "5.0" deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_PERSISTENT_STORE_NODES: - name: OCIS_PERSISTENT_STORE_NODES;COLLABORATION_STORE_NODES + name: OCIS_PERSISTENT_STORE_NODES;POSTPROCESSING_STORE_NODES defaultValue: '[127.0.0.1:9233]' type: '[]string' description: A list of nodes to access the configured store. This has no effect when 'memory' store is configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details. - introductionVersion: 7.0.0 + introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_PERSISTENT_STORE_TTL: - name: OCIS_PERSISTENT_STORE_TTL;COLLABORATION_STORE_TTL - defaultValue: 30m0s + name: OCIS_PERSISTENT_STORE_TTL;POSTPROCESSING_STORE_TTL + defaultValue: 0s type: Duration - description: Time to live for events in the store. Defaults to '30m' (30 minutes). - See the Environment Variable Types description for more details. - introductionVersion: 7.0.0 + description: Time to live for events in the store. See the Environment Variable + Types description for more details. + introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" deprecationInfo: "" @@ -9043,7 +9061,7 @@ OCIS_REVA_GATEWAY: name: OCIS_REVA_GATEWAY defaultValue: com.owncloud.api.gateway type: string - description: The CS3 gateway endpoint. + description: CS3 gateway used to look up user metadata introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" @@ -9071,7 +9089,7 @@ OCIS_REVA_GATEWAY_TLS_MODE: removalVersion: "" deprecationInfo: "" OCIS_SERVICE_ACCOUNT_ID: - name: OCIS_SERVICE_ACCOUNT_ID;USERLOG_SERVICE_ACCOUNT_ID + name: OCIS_SERVICE_ACCOUNT_ID;NOTIFICATIONS_SERVICE_ACCOUNT_ID defaultValue: "" type: string description: The ID of the service account the service should use. See the 'auth-service' @@ -9081,7 +9099,7 @@ OCIS_SERVICE_ACCOUNT_ID: removalVersion: "" deprecationInfo: "" OCIS_SERVICE_ACCOUNT_SECRET: - name: OCIS_SERVICE_ACCOUNT_SECRET;USERLOG_SERVICE_ACCOUNT_SECRET + name: OCIS_SERVICE_ACCOUNT_SECRET;NOTIFICATIONS_SERVICE_ACCOUNT_SECRET defaultValue: "" type: string description: The service account secret. @@ -9090,7 +9108,7 @@ OCIS_SERVICE_ACCOUNT_SECRET: removalVersion: "" deprecationInfo: "" OCIS_SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD: - name: OCIS_SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD;SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD + name: OCIS_SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD defaultValue: "true" type: bool description: Set this to true if you want to enforce passwords on all public shares. @@ -9099,11 +9117,11 @@ OCIS_SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD: removalVersion: "" deprecationInfo: "" OCIS_SHARING_PUBLIC_WRITEABLE_SHARE_MUST_HAVE_PASSWORD: - name: OCIS_SHARING_PUBLIC_WRITEABLE_SHARE_MUST_HAVE_PASSWORD;SHARING_PUBLIC_WRITEABLE_SHARE_MUST_HAVE_PASSWORD + name: OCIS_SHARING_PUBLIC_WRITEABLE_SHARE_MUST_HAVE_PASSWORD defaultValue: "false" type: bool - description: Set this to true if you want to enforce passwords on Uploader, Editor - or Contributor shares. + description: Set this to true if you want to enforce passwords for writable shares. + Only effective if the setting for 'passwords on all public shares' is set to false. introductionVersion: "5.0" deprecationVersion: "" removalVersion: "" @@ -9151,7 +9169,7 @@ OCIS_SYSTEM_USER_ID: removalVersion: "" deprecationInfo: "" OCIS_SYSTEM_USER_IDP: - name: OCIS_SYSTEM_USER_IDP;SETTINGS_SYSTEM_USER_IDP + name: OCIS_SYSTEM_USER_IDP;SHARING_PUBLIC_CS3_SYSTEM_USER_IDP defaultValue: internal type: string description: IDP of the oCIS STORAGE-SYSTEM system user. @@ -9160,7 +9178,7 @@ OCIS_SYSTEM_USER_IDP: removalVersion: "" deprecationInfo: "" OCIS_TRACING_COLLECTOR: - name: OCIS_TRACING_COLLECTOR;STORAGE_SYSTEM_TRACING_COLLECTOR + name: OCIS_TRACING_COLLECTOR;WEBDAV_TRACING_COLLECTOR defaultValue: "" type: string description: The HTTP endpoint for sending spans directly to a collector, i.e. http://jaeger-collector:14268/api/traces. @@ -9170,7 +9188,7 @@ OCIS_TRACING_COLLECTOR: removalVersion: "" deprecationInfo: "" OCIS_TRACING_ENABLED: - name: OCIS_TRACING_ENABLED;STORAGE_SYSTEM_TRACING_ENABLED + name: OCIS_TRACING_ENABLED;WEBDAV_TRACING_ENABLED defaultValue: "false" type: bool description: Activates tracing. @@ -9179,7 +9197,7 @@ OCIS_TRACING_ENABLED: removalVersion: "" deprecationInfo: "" OCIS_TRACING_ENDPOINT: - name: OCIS_TRACING_ENDPOINT;STORAGE_SYSTEM_TRACING_ENDPOINT + name: OCIS_TRACING_ENDPOINT;WEBDAV_TRACING_ENDPOINT defaultValue: "" type: string description: The endpoint of the tracing agent. @@ -9188,7 +9206,7 @@ OCIS_TRACING_ENDPOINT: removalVersion: "" deprecationInfo: "" OCIS_TRACING_TYPE: - name: OCIS_TRACING_TYPE;STORAGE_SYSTEM_TRACING_TYPE + name: OCIS_TRACING_TYPE;WEBDAV_TRACING_TYPE defaultValue: "" type: string description: The type of tracing. Defaults to '', which is the same as 'jaeger'. @@ -9207,7 +9225,7 @@ OCIS_TRANSFER_SECRET: removalVersion: "" deprecationInfo: "" OCIS_TRANSLATION_PATH: - name: OCIS_TRANSLATION_PATH;USERLOG_TRANSLATION_PATH + name: OCIS_TRANSLATION_PATH;NOTIFICATIONS_TRANSLATION_PATH defaultValue: "" type: string description: (optional) Set this to a path with custom translations to overwrite @@ -9218,19 +9236,19 @@ OCIS_TRANSLATION_PATH: removalVersion: "" deprecationInfo: "" OCIS_URL: - name: OCIS_URL;OCIS_OIDC_ISSUER;WEB_OIDC_AUTHORITY - defaultValue: https://localhost:9200 + name: OCIS_URL;OCIS_PUBLIC_URL + defaultValue: https://127.0.0.1:9200 type: string - description: URL of the OIDC issuer. It defaults to URL of the builtin IDP. + description: URL, where oCIS is reachable for users. introductionVersion: pre5.0 deprecationVersion: "" removalVersion: "" deprecationInfo: "" OCIS_USER_SEARCH_DISPLAYED_ATTRIBUTES: - name: OCIS_USER_SEARCH_DISPLAYED_ATTRIBUTES + name: OCIS_USER_SEARCH_DISPLAYED_ATTRIBUTES;FRONTEND_USER_SEARCH_DISPLAYED_ATTRIBUTES defaultValue: '[]' type: '[]string' - description: The attributes to display in the user search results. + description: A list of user attributes to display in the user search results. introductionVersion: 7.3.0 deprecationVersion: "" removalVersion: "" diff --git a/go.mod b/go.mod index cd662331e50..0e02a49d0fd 100644 --- a/go.mod +++ b/go.mod @@ -65,7 +65,7 @@ require ( github.com/onsi/gomega v1.38.3 github.com/open-policy-agent/opa v1.10.1 github.com/orcaman/concurrent-map v1.0.0 - github.com/owncloud/libre-graph-api-go v1.0.5-0.20251107084958-31937a4ea3f1 + github.com/owncloud/libre-graph-api-go v1.0.5-0.20260116104114-10074a92be64 github.com/owncloud/reva/v2 v2.0.0-20260116122933-81e6e21256eb github.com/pkg/errors v0.9.1 github.com/pkg/xattr v0.4.12 diff --git a/go.sum b/go.sum index 17c31250d6b..9f417c2b3e3 100644 --- a/go.sum +++ b/go.sum @@ -738,8 +738,8 @@ github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+ github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/orcaman/concurrent-map v1.0.0 h1:I/2A2XPCb4IuQWcQhBhSwGfiuybl/J0ev9HDbW65HOY= github.com/orcaman/concurrent-map v1.0.0/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI= -github.com/owncloud/libre-graph-api-go v1.0.5-0.20251107084958-31937a4ea3f1 h1:uW3BUPdaAhti2aP8x3Vb79vzmqAgDaWZ0yrW+4ujjU8= -github.com/owncloud/libre-graph-api-go v1.0.5-0.20251107084958-31937a4ea3f1/go.mod h1:z61VMGAJRtR1nbgXWiNoCkxUXP1B3Je9rMuJbnGd+Og= +github.com/owncloud/libre-graph-api-go v1.0.5-0.20260116104114-10074a92be64 h1:z9djjzd+leAy6QZpi8dLy3OVjc/um+1XAGk1SJEvwE8= +github.com/owncloud/libre-graph-api-go v1.0.5-0.20260116104114-10074a92be64/go.mod h1:z61VMGAJRtR1nbgXWiNoCkxUXP1B3Je9rMuJbnGd+Og= github.com/owncloud/reva/v2 v2.0.0-20260116122933-81e6e21256eb h1:G4YhVvtdJDEE0fhV0sWMUDpcpV5WqQNdfLw9xNMfkFI= github.com/owncloud/reva/v2 v2.0.0-20260116122933-81e6e21256eb/go.mod h1:nDBXQivlwd4Vf5UD/oDT0RakSXy0GJPI1LsyHMm5IpI= github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw= diff --git a/services/graph/pkg/config/config.go b/services/graph/pkg/config/config.go index 215103bae5d..c62b3a1893b 100644 --- a/services/graph/pkg/config/config.go +++ b/services/graph/pkg/config/config.go @@ -95,13 +95,15 @@ type LDAP struct { RequireExternalID bool `yaml:"require_external_id" env:"GRAPH_LDAP_REQUIRE_EXTERNAL_ID" desc:"If enabled, the 'OCIS_LDAP_USER_SCHEMA_EXTERNAL_ID' is used as primary identifier for the provisioning API." introductionVersion:"8.0.0"` // Multi-Instance Only - UserMemberAttribute string `yaml:"user_member_attribute" env:"OCIS_LDAP_USER_MEMBER_ATTRIBUTE" desc:"LDAP Attribute to signal the user is member of an instance. Requires OCIS_MULTI_INSTANCE_ENABLED." introductionVersion:"8.0.0"` - UserGuestAttribute string `yaml:"user_guest_attribute" env:"OCIS_LDAP_USER_GUEST_ATTRIBUTE" desc:"LDAP Attribute to signal the user is guest of an instance. Requires OCIS_MULTI_INSTANCE_ENABLED." introductionVersion:"8.0.0"` - PreciseSearchAttribute string `yaml:"precise_search_attribute" env:"OCIS_LDAP_PRECISE_SEARCH_ATTRIBUTE" desc:"LDAP Attribute to be used for searching users on other instances. Requires OCIS_MULTI_INSTANCE_ENABLED." introductionVersion:"8.0.0"` - InstanceMapperEnabled bool `yaml:"instance_mapper_enabled" env:"OCIS_LDAP_INSTANCE_MAPPER_ENABLED" desc:"The InstanceMapper allows mapping instance names (user readable) to instance IDs (machine readable) based on an LDAP query. See other _INSTANCE_MAPPER_ env vars. Requires OCIS_MULTI_INSTANCE_ENABLED." introductionVersion:"8.0.0"` - InstanceMapperBaseDN string `yaml:"instance_mapper_base_dn" env:"OCIS_LDAP_INSTANCE_MAPPER_BASE_DN" desc:"BaseDN of the 'instancename to instanceid' mapper in LDAP. Requires OCIS_MULTI_INSTANCE_ENABLED." introductionVersion:"8.0.0"` - InstanceMapperNameAttribute string `yaml:"instance_mapper_name_attribute" env:"OCIS_LDAP_INSTANCE_MAPPER_NAME_ATTRIBUTE" desc:"LDAP Attribute of the instance name. Requires OCIS_MULTI_INSTANCE_ENABLED." introductionVersion:"8.0.0"` - InstanceMapperIDAttribute string `yaml:"instance_mapper_id_attribute" env:"OCIS_LDAP_INSTANCE_MAPPER_ID_ATTRIBUTE" desc:"LDAP Attribute of the instance ID. Requires OCIS_MULTI_INSTANCE_ENABLED." introductionVersion:"8.0.0"` + UserMemberAttribute string `yaml:"user_member_attribute" env:"OCIS_LDAP_USER_MEMBER_ATTRIBUTE" desc:"LDAP Attribute to signal the user is member of an instance. Requires OCIS_MULTI_INSTANCE_ENABLED." introductionVersion:"8.0.0"` + UserGuestAttribute string `yaml:"user_guest_attribute" env:"OCIS_LDAP_USER_GUEST_ATTRIBUTE" desc:"LDAP Attribute to signal the user is guest of an instance. Requires OCIS_MULTI_INSTANCE_ENABLED." introductionVersion:"8.0.0"` + PreciseSearchAttribute string `yaml:"precise_search_attribute" env:"OCIS_LDAP_PRECISE_SEARCH_ATTRIBUTE" desc:"LDAP Attribute to be used for searching users on other instances. Requires OCIS_MULTI_INSTANCE_ENABLED." introductionVersion:"8.0.0"` + InstanceMapperEnabled bool `yaml:"instance_mapper_enabled" env:"OCIS_LDAP_INSTANCE_MAPPER_ENABLED" desc:"The InstanceMapper allows mapping instance names (user readable) to instance IDs (machine readable) based on an LDAP query. See other _INSTANCE_MAPPER_ env vars. Requires OCIS_MULTI_INSTANCE_ENABLED." introductionVersion:"8.0.0"` + InstanceMapperBaseDN string `yaml:"instance_mapper_base_dn" env:"OCIS_LDAP_INSTANCE_MAPPER_BASE_DN" desc:"BaseDN of the 'instancename to instanceid' mapper in LDAP. Requires OCIS_MULTI_INSTANCE_ENABLED." introductionVersion:"8.0.0"` + InstanceMapperNameAttribute string `yaml:"instance_mapper_name_attribute" env:"OCIS_LDAP_INSTANCE_MAPPER_NAME_ATTRIBUTE" desc:"LDAP Attribute of the instance name. Requires OCIS_MULTI_INSTANCE_ENABLED." introductionVersion:"8.0.0"` + InstanceMapperIDAttribute string `yaml:"instance_mapper_id_attribute" env:"OCIS_LDAP_INSTANCE_MAPPER_ID_ATTRIBUTE" desc:"LDAP Attribute of the instance ID. Requires OCIS_MULTI_INSTANCE_ENABLED." introductionVersion:"8.0.0"` + CrossInstanceReferenceTemplate string `yaml:"cross_instance_reference_template" env:"OCIS_LDAP_CROSS_INSTANCE_REFERENCE_TEMPLATE" desc:"Template for the users unique reference across oCIS instances. Requires OCIS_MULTI_INSTANCE_ENABLED." introductionVersion:"8.0.0"` + InstanceURLTemplate string `yaml:"instance_url_template" env:"OCIS_LDAP_INSTANCE_URL_TEMPLATE" desc:"Template for the instance URL. Requires OCIS_MULTI_INSTANCE_ENABLED." introductionVersion:"8.0.0"` } // LDAPEducationConfig represents the LDAP configuration for education related resources diff --git a/services/graph/pkg/identity/ldap.go b/services/graph/pkg/identity/ldap.go index 09768111d78..138bb393ecb 100644 --- a/services/graph/pkg/identity/ldap.go +++ b/services/graph/pkg/identity/ldap.go @@ -8,6 +8,7 @@ import ( "slices" "strconv" "strings" + "text/template" "time" "github.com/CiscoM31/godata" @@ -78,27 +79,29 @@ type LDAP struct { conn ldap.Client // multi instance only - userMemberAttribute string - userGuestAttribute string - preciseSearchAttribute string - instanceMapperEnabled bool - instanceMapperBaseDN string - instanceMapperNameAttribute string - instanceMapperIDAttribute string + preciseSearchAttribute string + instanceMapperEnabled bool + instanceMapperBaseDN string + instanceMapperNameAttribute string + instanceMapperIDAttribute string + crossInstanceReferenceTemplate *template.Template + instanceURLTemplate *template.Template } type userAttributeMap struct { - displayName string - id string - mail string - userName string - givenName string - surname string - accountEnabled string - userType string - identities string - lastSignIn string - externalID string + displayName string + id string + mail string + userName string + givenName string + surname string + accountEnabled string + userType string + identities string + lastSignIn string + externalID string + userMemberAttribute string + userGuestAttribute string } type ldapAttributeValues map[string][]string @@ -124,17 +127,19 @@ func NewLDAPBackend(lc ldap.Client, config config.LDAP, logger *log.Logger, inst return nil, errors.New("invalid user attribute mappings") } uam := userAttributeMap{ - displayName: config.UserDisplayNameAttribute, - id: config.UserIDAttribute, - mail: config.UserEmailAttribute, - userName: config.UserNameAttribute, - accountEnabled: config.UserEnabledAttribute, - givenName: givenNameAttribute, - surname: surNameAttribute, - userType: config.UserTypeAttribute, - identities: identitiesAttribute, - lastSignIn: lastSignAttribute, - externalID: config.ExternalIDAttribute, + displayName: config.UserDisplayNameAttribute, + id: config.UserIDAttribute, + mail: config.UserEmailAttribute, + userName: config.UserNameAttribute, + accountEnabled: config.UserEnabledAttribute, + givenName: givenNameAttribute, + surname: surNameAttribute, + userType: config.UserTypeAttribute, + identities: identitiesAttribute, + lastSignIn: lastSignAttribute, + externalID: config.ExternalIDAttribute, + userMemberAttribute: config.UserMemberAttribute, + userGuestAttribute: config.UserGuestAttribute, } if config.GroupNameAttribute == "" || config.GroupIDAttribute == "" { @@ -166,37 +171,53 @@ func NewLDAPBackend(lc ldap.Client, config config.LDAP, logger *log.Logger, inst return nil, fmt.Errorf("error configuring disable user mechanism: %w", err) } + var crossInstanceReferenceTemplate *template.Template + if instanceID != "" { + crossInstanceReferenceTemplate, err = template.New("crossInstanceReferenceTemplate").Parse(config.CrossInstanceReferenceTemplate) + if err != nil { + return nil, fmt.Errorf("error parsing cross instance reference template: %w", err) + } + } + + var instanceURLTemplate *template.Template + if instanceID != "" { + instanceURLTemplate, err = template.New("instanceURLTemplate").Parse(config.InstanceURLTemplate) + if err != nil { + return nil, fmt.Errorf("error parsing instance URL template: %w", err) + } + } + return &LDAP{ - useServerUUID: config.UseServerUUID, - usePwModifyExOp: config.UsePasswordModExOp, - userBaseDN: config.UserBaseDN, - userFilter: config.UserFilter, - userObjectClass: config.UserObjectClass, - userIDisOctetString: config.UserIDIsOctetString, - userScope: userScope, - userAttributeMap: uam, - groupBaseDN: config.GroupBaseDN, - groupCreateBaseDN: config.GroupCreateBaseDN, - groupFilter: config.GroupFilter, - groupObjectClass: config.GroupObjectClass, - groupIDisOctetString: config.GroupIDIsOctetString, - groupScope: groupScope, - groupAttributeMap: gam, - educationConfig: educationConfig, - disableUserMechanism: disableMechanismType, - localUserDisableGroupDN: config.LdapDisabledUsersGroupDN, - logger: logger, - conn: lc, - writeEnabled: config.WriteEnabled, - refintEnabled: config.RefintEnabled, - useExternalID: config.RequireExternalID, - userMemberAttribute: config.UserMemberAttribute, - userGuestAttribute: config.UserGuestAttribute, - preciseSearchAttribute: config.PreciseSearchAttribute, - instanceMapperEnabled: config.InstanceMapperEnabled, - instanceMapperBaseDN: config.InstanceMapperBaseDN, - instanceMapperNameAttribute: config.InstanceMapperNameAttribute, - instanceMapperIDAttribute: config.InstanceMapperIDAttribute, + useServerUUID: config.UseServerUUID, + usePwModifyExOp: config.UsePasswordModExOp, + userBaseDN: config.UserBaseDN, + userFilter: config.UserFilter, + userObjectClass: config.UserObjectClass, + userIDisOctetString: config.UserIDIsOctetString, + userScope: userScope, + userAttributeMap: uam, + groupBaseDN: config.GroupBaseDN, + groupCreateBaseDN: config.GroupCreateBaseDN, + groupFilter: config.GroupFilter, + groupObjectClass: config.GroupObjectClass, + groupIDisOctetString: config.GroupIDIsOctetString, + groupScope: groupScope, + groupAttributeMap: gam, + educationConfig: educationConfig, + disableUserMechanism: disableMechanismType, + localUserDisableGroupDN: config.LdapDisabledUsersGroupDN, + logger: logger, + conn: lc, + writeEnabled: config.WriteEnabled, + refintEnabled: config.RefintEnabled, + useExternalID: config.RequireExternalID, + preciseSearchAttribute: config.PreciseSearchAttribute, + instanceMapperEnabled: config.InstanceMapperEnabled, + instanceMapperBaseDN: config.InstanceMapperBaseDN, + instanceMapperNameAttribute: config.InstanceMapperNameAttribute, + instanceMapperIDAttribute: config.InstanceMapperIDAttribute, + crossInstanceReferenceTemplate: crossInstanceReferenceTemplate, + instanceURLTemplate: instanceURLTemplate, }, nil } @@ -434,7 +455,7 @@ func (i *LDAP) AddUser(ctx context.Context, id string, instanceID string) (libre return libregraph.User{}, err } mr := ldap.ModifyRequest{DN: e.DN} - mr.Add(i.userGuestAttribute, []string{instanceID}) + mr.Add(i.userAttributeMap.userGuestAttribute, []string{instanceID}) if err := i.conn.Modify(&mr); err != nil { i.logger.Error().Err(err).Str("userid", id).Str("instanceid", instanceID).Msg("error adding user") return libregraph.User{}, err @@ -581,7 +602,7 @@ func (i *LDAP) getPreciseLDAPUser(uniqueID string, instanceID string) (*ldap.Ent uid := ldap.EscapeFilter(uniqueID) filter := fmt.Sprintf("(%s=%s)", i.userAttributeMap.id, uid) if iid := ldap.EscapeFilter(instanceID); iid != "" { - filter = fmt.Sprintf("(&(%s=%s)(|(%s=%s)(%s=%s)))", i.preciseSearchAttribute, uid, i.userMemberAttribute, iid, i.userGuestAttribute, iid) + filter = fmt.Sprintf("(&(%s=%s)(|(%s=%s)(%s=%s)))", i.preciseSearchAttribute, uid, i.userAttributeMap.userMemberAttribute, iid, i.userAttributeMap.userGuestAttribute, iid) } return i.getLDAPUserByFilter(filter, "") // no user filter for precise search } @@ -917,49 +938,114 @@ func (i *LDAP) createUserModelFromLDAP(e *ldap.Entry) *libregraph.User { } surname := e.GetEqualFoldAttributeValue(i.userAttributeMap.surname) - if id != "" && opsan != "" { - user := &libregraph.User{ - DisplayName: e.GetEqualFoldAttributeValue(i.userAttributeMap.displayName), - Mail: pointerOrNil(e.GetEqualFoldAttributeValue(i.userAttributeMap.mail)), - OnPremisesSamAccountName: opsan, - Id: &id, - GivenName: pointerOrNil(e.GetEqualFoldAttributeValue(i.userAttributeMap.givenName)), - Surname: &surname, - AccountEnabled: booleanOrNil(e.GetEqualFoldAttributeValue(i.userAttributeMap.accountEnabled)), - ExternalID: pointerOrNil(e.GetEqualFoldAttributeValue(i.userAttributeMap.externalID)), - } + if id == "" || opsan == "" { + i.logger.Warn().Str("dn", e.DN).Msg("Invalid User. Missing username or id attribute") + return nil + } - userType := e.GetEqualFoldAttributeValue(i.userAttributeMap.userType) - if userType == "" { - userType = UserTypeMember - } - user.SetUserType(userType) - var identities []libregraph.ObjectIdentity - for _, identityStr := range e.GetEqualFoldAttributeValues(i.userAttributeMap.identities) { - parts := strings.SplitN(identityStr, "$", 3) - identity := libregraph.NewObjectIdentity() - identity.SetIssuer(strings.TrimSpace(parts[1])) - identity.SetIssuerAssignedId(strings.TrimSpace(parts[2])) - identities = append(identities, *identity) - } - if len(identities) > 0 { - user.SetIdentities(identities) - } + user := &libregraph.User{ + DisplayName: e.GetEqualFoldAttributeValue(i.userAttributeMap.displayName), + Mail: pointerOrNil(e.GetEqualFoldAttributeValue(i.userAttributeMap.mail)), + OnPremisesSamAccountName: opsan, + Id: &id, + GivenName: pointerOrNil(e.GetEqualFoldAttributeValue(i.userAttributeMap.givenName)), + Surname: &surname, + AccountEnabled: booleanOrNil(e.GetEqualFoldAttributeValue(i.userAttributeMap.accountEnabled)), + ExternalID: pointerOrNil(e.GetEqualFoldAttributeValue(i.userAttributeMap.externalID)), + } - lastSignIn, err := i.getLastSignTime(e) - switch { - case err == nil: - signinActivity := libregraph.SignInActivity{ - LastSuccessfulSignInDateTime: lastSignIn, - } - user.SetSignInActivity(signinActivity) - case !errors.Is(err, errNotSet): - i.logger.Warn().Err(err).Str("dn", e.DN).Msg("Error getting last signin timestamp") + userType := e.GetEqualFoldAttributeValue(i.userAttributeMap.userType) + if userType == "" { + userType = UserTypeMember + } + user.SetUserType(userType) + var identities []libregraph.ObjectIdentity + for _, identityStr := range e.GetEqualFoldAttributeValues(i.userAttributeMap.identities) { + parts := strings.SplitN(identityStr, "$", 3) + identity := libregraph.NewObjectIdentity() + identity.SetIssuer(strings.TrimSpace(parts[1])) + identity.SetIssuerAssignedId(strings.TrimSpace(parts[2])) + identities = append(identities, *identity) + } + if len(identities) > 0 { + user.SetIdentities(identities) + } + + lastSignIn, err := i.getLastSignTime(e) + switch { + case err == nil: + signinActivity := libregraph.SignInActivity{ + LastSuccessfulSignInDateTime: lastSignIn, } + user.SetSignInActivity(signinActivity) + case !errors.Is(err, errNotSet): + i.logger.Warn().Err(err).Str("dn", e.DN).Msg("Error getting last signin timestamp") + } + + if i.instanceURLTemplate == nil || i.crossInstanceReferenceTemplate == nil { return user } - i.logger.Warn().Str("dn", e.DN).Msg("Invalid User. Missing username or id attribute") - return nil + + for _, instance := range e.GetEqualFoldAttributeValues(i.userAttributeMap.userMemberAttribute) { + instanceName, err := i.getInstanceName(instance) + if err != nil { + i.logger.Warn().Err(err).Str("dn", e.DN).Msg("Error getting instance name") + continue + } + + instanceURL := &strings.Builder{} + if err := i.instanceURLTemplate.Execute(instanceURL, map[string]string{ + "Instancename": instanceName, + }); err != nil { + i.logger.Warn().Err(err).Str("dn", e.DN).Msg("Error executing instance URL template") + continue + } + + isPrimary := true + user.Instances = append(user.Instances, libregraph.Instance{ + Url: pointerOrNil(instanceURL.String()), + Primary: &isPrimary, + }) + + if user.CrossInstanceReference != nil { + continue + } + + crossInstanceReference := &strings.Builder{} + if err := i.crossInstanceReferenceTemplate.Execute(crossInstanceReference, map[string]string{ + "Username": user.GetOnPremisesSamAccountName(), + "Instancename": instanceName, + }); err != nil { + i.logger.Warn().Err(err).Str("dn", e.DN).Msg("Error executing cross instance reference template") + return user + } + + user.CrossInstanceReference = pointerOrNil(crossInstanceReference.String()) + } + + for _, instance := range e.GetEqualFoldAttributeValues(i.userAttributeMap.userGuestAttribute) { + instanceName, err := i.getInstanceName(instance) + if err != nil { + i.logger.Warn().Err(err).Str("dn", e.DN).Msg("Error getting instance name") + continue + } + + instanceURL := &strings.Builder{} + if err := i.instanceURLTemplate.Execute(instanceURL, map[string]string{ + "Instancename": instanceName, + }); err != nil { + i.logger.Warn().Err(err).Str("dn", e.DN).Msg("Error executing instance URL template") + continue + } + + isPrimary := false + user.Instances = append(user.Instances, libregraph.Instance{ + Url: pointerOrNil(instanceURL.String()), + Primary: &isPrimary, + }) + } + + return user } func (i *LDAP) userToLDAPAttrValues(user libregraph.User) (map[string][]string, error) { @@ -1042,6 +1128,8 @@ func (i *LDAP) getUserAttrTypesForSearch() []string { i.userAttributeMap.identities, i.userAttributeMap.lastSignIn, i.userAttributeMap.externalID, + i.userAttributeMap.userMemberAttribute, + i.userAttributeMap.userGuestAttribute, } } @@ -1429,41 +1517,49 @@ func (i *LDAP) oDataFilterToLDAPFilter(filter *godata.ParseNode) (string, error) return fmt.Sprintf("(%s<=%s)", i.userAttributeMap.lastSignIn, ldap.EscapeFilter(ldapDateTime)), nil } -func (i *LDAP) getInstanceID(instancename string) (string, error) { - if instancename == "" || !i.instanceMapperEnabled { - return instancename, nil +func (i *LDAP) getInstance(searchValue, searchAttribute, resultAttribute string) (string, error) { + if searchValue == "" || !i.instanceMapperEnabled { + return searchValue, nil } searchRequest := ldap.NewSearchRequest( i.instanceMapperBaseDN, ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 1, 0, false, - fmt.Sprintf("(%s=%s)", i.instanceMapperNameAttribute, instancename), - []string{i.instanceMapperIDAttribute}, + fmt.Sprintf("(%s=%s)", searchAttribute, searchValue), + []string{resultAttribute}, nil, ) res, err := i.conn.Search(searchRequest) if err != nil { - i.logger.Error().Err(err).Str("backend", "ldap").Str("dn", i.instanceMapperBaseDN).Str("instancename", instancename).Str("attribute", i.instanceMapperIDAttribute).Msg("Search instance by name failed") + i.logger.Error().Err(err).Str("backend", "ldap").Str("dn", i.instanceMapperBaseDN).Str("searchValue", searchValue).Str("searchAttribute", searchAttribute).Str("resultAttribute", resultAttribute).Msg("Search instance failed") return "", errorcode.New(errorcode.ItemNotFound, "instanceid search failed") } if len(res.Entries) == 0 { // expected behaviour - we log debug in case something is fishy. This log can be removed when the feature proves stable - i.logger.Debug().Str("backend", "ldap").Str("dn", i.instanceMapperBaseDN).Str("instancename", instancename).Interface("result", res).Msg("Search instance by name empty") + i.logger.Debug().Str("backend", "ldap").Str("dn", i.instanceMapperBaseDN).Str("searchValue", searchValue).Interface("result", res).Msg("Search instance empty") return "", ErrNotFound } if len(res.Entries) > 1 { - i.logger.Error().Str("backend", "ldap").Str("dn", i.instanceMapperBaseDN).Str("instancename", instancename).Interface("result", res).Msg("Search instance by name returned multiple responses.") + i.logger.Error().Str("backend", "ldap").Str("dn", i.instanceMapperBaseDN).Str("searchValue", searchValue).Interface("result", res).Msg("Search instance returned multiple responses.") return "", errorcode.New(errorcode.ItemNotFound, "instanceid search returned multiple responses") } if len(res.Entries[0].Attributes) == 0 || len(res.Entries[0].Attributes[0].Values) == 0 { - i.logger.Error().Str("backend", "ldap").Str("dn", i.instanceMapperBaseDN).Str("instancename", instancename).Interface("result", res).Msg("Search instance by name returned malformed response") + i.logger.Error().Str("backend", "ldap").Str("dn", i.instanceMapperBaseDN).Str("searchValue", searchValue).Interface("result", res).Msg("Search instance returned malformed response") return "", errorcode.New(errorcode.ItemNotFound, "instanceid search response malformed") } return res.Entries[0].Attributes[0].Values[0], nil } +func (i *LDAP) getInstanceID(instancename string) (string, error) { + return i.getInstance(instancename, i.instanceMapperNameAttribute, i.instanceMapperIDAttribute) +} + +func (i *LDAP) getInstanceName(instanceID string) (string, error) { + return i.getInstance(instanceID, i.instanceMapperIDAttribute, i.instanceMapperNameAttribute) +} + func isLastSuccessFullSignInDateTimeFilter(node *godata.ParseNode) bool { if node.Token.Type != godata.ExpressionTokenNav { return false diff --git a/services/graph/pkg/identity/ldap_test.go b/services/graph/pkg/identity/ldap_test.go index 334d0040366..b653ba8a1c0 100644 --- a/services/graph/pkg/identity/ldap_test.go +++ b/services/graph/pkg/identity/ldap_test.go @@ -73,7 +73,21 @@ var invalidUserEntry = ldap.NewEntry("uid=user", var logger = log.NewLogger(log.Level("debug")) -var ldapUserAttributes = []string{"displayname", "entryUUID", "mail", "uid", "sn", "givenname", "userEnabledAttribute", "userTypeAttribute", "oCExternalIdentity", "oCLastSignInTimestamp", "externalID"} +var ldapUserAttributes = []string{ + "displayname", + "entryUUID", + "mail", + "uid", + "sn", + "givenname", + "userEnabledAttribute", + "userTypeAttribute", + "oCExternalIdentity", + "oCLastSignInTimestamp", + "externalID", + "", // UserMemberAttribute + "", // UserGuestAttribute +} func TestNewLDAPBackend(t *testing.T) { l := &mocks.Client{} diff --git a/vendor/github.com/owncloud/libre-graph-api-go/README.md b/vendor/github.com/owncloud/libre-graph-api-go/README.md index 24eec7c89c4..8ece75f91d3 100644 --- a/vendor/github.com/owncloud/libre-graph-api-go/README.md +++ b/vendor/github.com/owncloud/libre-graph-api-go/README.md @@ -85,9 +85,13 @@ Class | Method | HTTP request | Description *DriveItemApi* | [**GetDriveItem**](docs/DriveItemApi.md#getdriveitem) | **Get** /v1beta1/drives/{drive-id}/items/{item-id} | Get a DriveItem. *DriveItemApi* | [**UpdateDriveItem**](docs/DriveItemApi.md#updatedriveitem) | **Patch** /v1beta1/drives/{drive-id}/items/{item-id} | Update a DriveItem. *DrivesApi* | [**CreateDrive**](docs/DrivesApi.md#createdrive) | **Post** /v1.0/drives | Create a new drive of a specific type +*DrivesApi* | [**CreateDriveBeta**](docs/DrivesApi.md#createdrivebeta) | **Post** /v1beta1/drives | Create a new drive of a specific type. Alias for '/v1.0/drives', the difference is that grantedtoV2 is used and roles contain unified roles instead of cs3 roles. *DrivesApi* | [**DeleteDrive**](docs/DrivesApi.md#deletedrive) | **Delete** /v1.0/drives/{drive-id} | Delete a specific space +*DrivesApi* | [**DeleteDriveBeta**](docs/DrivesApi.md#deletedrivebeta) | **Delete** /v1beta1/drives/{drive-id} | Delete a specific space. Alias for '/v1.0/drives'. *DrivesApi* | [**GetDrive**](docs/DrivesApi.md#getdrive) | **Get** /v1.0/drives/{drive-id} | Get drive by id +*DrivesApi* | [**GetDriveBeta**](docs/DrivesApi.md#getdrivebeta) | **Get** /v1beta1/drives/{drive-id} | Get drive by id. Alias for '/v1.0/drives', the difference is that grantedtoV2 is used and roles contain unified roles instead of cs3 roles *DrivesApi* | [**UpdateDrive**](docs/DrivesApi.md#updatedrive) | **Patch** /v1.0/drives/{drive-id} | Update the drive +*DrivesApi* | [**UpdateDriveBeta**](docs/DrivesApi.md#updatedrivebeta) | **Patch** /v1beta1/drives/{drive-id} | Update the drive. Alias for '/v1.0/drives', the difference is that grantedtoV2 is used and roles contain unified roles instead of cs3 roles *DrivesGetDrivesApi* | [**ListAllDrives**](docs/DrivesGetDrivesApi.md#listalldrives) | **Get** /v1.0/drives | Get all available drives *DrivesGetDrivesApi* | [**ListAllDrivesBeta**](docs/DrivesGetDrivesApi.md#listalldrivesbeta) | **Get** /v1beta1/drives | Alias for '/v1.0/drives', the difference is that grantedtoV2 is used and roles contain unified roles instead of cs3 roles *DrivesPermissionsApi* | [**CreateLink**](docs/DrivesPermissionsApi.md#createlink) | **Post** /v1beta1/drives/{drive-id}/items/{item-id}/createLink | Create a sharing link for a DriveItem @@ -217,6 +221,7 @@ Class | Method | HTTP request | Description - [Identity](docs/Identity.md) - [IdentitySet](docs/IdentitySet.md) - [Image](docs/Image.md) + - [Instance](docs/Instance.md) - [ItemReference](docs/ItemReference.md) - [MemberReference](docs/MemberReference.md) - [ObjectIdentity](docs/ObjectIdentity.md) diff --git a/vendor/github.com/owncloud/libre-graph-api-go/api_drives.go b/vendor/github.com/owncloud/libre-graph-api-go/api_drives.go index a13d47a8ecc..1c142dd9840 100644 --- a/vendor/github.com/owncloud/libre-graph-api-go/api_drives.go +++ b/vendor/github.com/owncloud/libre-graph-api-go/api_drives.go @@ -140,6 +140,124 @@ func (a *DrivesApiService) CreateDriveExecute(r ApiCreateDriveRequest) (*Drive, return localVarReturnValue, localVarHTTPResponse, nil } +type ApiCreateDriveBetaRequest struct { + ctx context.Context + ApiService *DrivesApiService + drive *Drive +} + +// New space property values +func (r ApiCreateDriveBetaRequest) Drive(drive Drive) ApiCreateDriveBetaRequest { + r.drive = &drive + return r +} + +func (r ApiCreateDriveBetaRequest) Execute() (*Drive, *http.Response, error) { + return r.ApiService.CreateDriveBetaExecute(r) +} + +/* +CreateDriveBeta Create a new drive of a specific type. Alias for '/v1.0/drives', the difference is that grantedtoV2 is used and roles contain unified roles instead of cs3 roles. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @return ApiCreateDriveBetaRequest +*/ +func (a *DrivesApiService) CreateDriveBeta(ctx context.Context) ApiCreateDriveBetaRequest { + return ApiCreateDriveBetaRequest{ + ApiService: a, + ctx: ctx, + } +} + +// Execute executes the request +// +// @return Drive +func (a *DrivesApiService) CreateDriveBetaExecute(r ApiCreateDriveBetaRequest) (*Drive, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPost + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *Drive + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "DrivesApiService.CreateDriveBeta") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/v1beta1/drives" + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.drive == nil { + return localVarReturnValue, nil, reportError("drive is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.drive + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + var v OdataError + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + type ApiDeleteDriveRequest struct { ctx context.Context ApiService *DrivesApiService @@ -248,6 +366,114 @@ func (a *DrivesApiService) DeleteDriveExecute(r ApiDeleteDriveRequest) (*http.Re return localVarHTTPResponse, nil } +type ApiDeleteDriveBetaRequest struct { + ctx context.Context + ApiService *DrivesApiService + driveId string + ifMatch *string +} + +// ETag +func (r ApiDeleteDriveBetaRequest) IfMatch(ifMatch string) ApiDeleteDriveBetaRequest { + r.ifMatch = &ifMatch + return r +} + +func (r ApiDeleteDriveBetaRequest) Execute() (*http.Response, error) { + return r.ApiService.DeleteDriveBetaExecute(r) +} + +/* +DeleteDriveBeta Delete a specific space. Alias for '/v1.0/drives'. + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param driveId key: id of drive + @return ApiDeleteDriveBetaRequest +*/ +func (a *DrivesApiService) DeleteDriveBeta(ctx context.Context, driveId string) ApiDeleteDriveBetaRequest { + return ApiDeleteDriveBetaRequest{ + ApiService: a, + ctx: ctx, + driveId: driveId, + } +} + +// Execute executes the request +func (a *DrivesApiService) DeleteDriveBetaExecute(r ApiDeleteDriveBetaRequest) (*http.Response, error) { + var ( + localVarHTTPMethod = http.MethodDelete + localVarPostBody interface{} + formFiles []formFile + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "DrivesApiService.DeleteDriveBeta") + if err != nil { + return nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/v1beta1/drives/{drive-id}" + localVarPath = strings.Replace(localVarPath, "{"+"drive-id"+"}", url.PathEscape(parameterValueToString(r.driveId, "driveId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + if r.ifMatch != nil { + parameterAddToHeaderOrQuery(localVarHeaderParams, "If-Match", r.ifMatch, "simple", "") + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + var v OdataError + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarHTTPResponse, newErr + } + + return localVarHTTPResponse, nil +} + type ApiGetDriveRequest struct { ctx context.Context ApiService *DrivesApiService @@ -358,6 +584,116 @@ func (a *DrivesApiService) GetDriveExecute(r ApiGetDriveRequest) (*Drive, *http. return localVarReturnValue, localVarHTTPResponse, nil } +type ApiGetDriveBetaRequest struct { + ctx context.Context + ApiService *DrivesApiService + driveId string +} + +func (r ApiGetDriveBetaRequest) Execute() (*Drive, *http.Response, error) { + return r.ApiService.GetDriveBetaExecute(r) +} + +/* +GetDriveBeta Get drive by id. Alias for '/v1.0/drives', the difference is that grantedtoV2 is used and roles contain unified roles instead of cs3 roles + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param driveId key: id of drive + @return ApiGetDriveBetaRequest +*/ +func (a *DrivesApiService) GetDriveBeta(ctx context.Context, driveId string) ApiGetDriveBetaRequest { + return ApiGetDriveBetaRequest{ + ApiService: a, + ctx: ctx, + driveId: driveId, + } +} + +// Execute executes the request +// +// @return Drive +func (a *DrivesApiService) GetDriveBetaExecute(r ApiGetDriveBetaRequest) (*Drive, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodGet + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *Drive + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "DrivesApiService.GetDriveBeta") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/v1beta1/drives/{drive-id}" + localVarPath = strings.Replace(localVarPath, "{"+"drive-id"+"}", url.PathEscape(parameterValueToString(r.driveId, "driveId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + var v OdataError + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} + type ApiUpdateDriveRequest struct { ctx context.Context ApiService *DrivesApiService @@ -479,3 +815,125 @@ func (a *DrivesApiService) UpdateDriveExecute(r ApiUpdateDriveRequest) (*Drive, return localVarReturnValue, localVarHTTPResponse, nil } + +type ApiUpdateDriveBetaRequest struct { + ctx context.Context + ApiService *DrivesApiService + driveId string + driveUpdate *DriveUpdate +} + +// New space values +func (r ApiUpdateDriveBetaRequest) DriveUpdate(driveUpdate DriveUpdate) ApiUpdateDriveBetaRequest { + r.driveUpdate = &driveUpdate + return r +} + +func (r ApiUpdateDriveBetaRequest) Execute() (*Drive, *http.Response, error) { + return r.ApiService.UpdateDriveBetaExecute(r) +} + +/* +UpdateDriveBeta Update the drive. Alias for '/v1.0/drives', the difference is that grantedtoV2 is used and roles contain unified roles instead of cs3 roles + + @param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background(). + @param driveId key: id of drive + @return ApiUpdateDriveBetaRequest +*/ +func (a *DrivesApiService) UpdateDriveBeta(ctx context.Context, driveId string) ApiUpdateDriveBetaRequest { + return ApiUpdateDriveBetaRequest{ + ApiService: a, + ctx: ctx, + driveId: driveId, + } +} + +// Execute executes the request +// +// @return Drive +func (a *DrivesApiService) UpdateDriveBetaExecute(r ApiUpdateDriveBetaRequest) (*Drive, *http.Response, error) { + var ( + localVarHTTPMethod = http.MethodPatch + localVarPostBody interface{} + formFiles []formFile + localVarReturnValue *Drive + ) + + localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "DrivesApiService.UpdateDriveBeta") + if err != nil { + return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()} + } + + localVarPath := localBasePath + "/v1beta1/drives/{drive-id}" + localVarPath = strings.Replace(localVarPath, "{"+"drive-id"+"}", url.PathEscape(parameterValueToString(r.driveId, "driveId")), -1) + + localVarHeaderParams := make(map[string]string) + localVarQueryParams := url.Values{} + localVarFormParams := url.Values{} + if r.driveUpdate == nil { + return localVarReturnValue, nil, reportError("driveUpdate is required and must be specified") + } + + // to determine the Content-Type header + localVarHTTPContentTypes := []string{"application/json"} + + // set Content-Type header + localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes) + if localVarHTTPContentType != "" { + localVarHeaderParams["Content-Type"] = localVarHTTPContentType + } + + // to determine the Accept header + localVarHTTPHeaderAccepts := []string{"application/json"} + + // set Accept header + localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts) + if localVarHTTPHeaderAccept != "" { + localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept + } + // body params + localVarPostBody = r.driveUpdate + req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles) + if err != nil { + return localVarReturnValue, nil, err + } + + localVarHTTPResponse, err := a.client.callAPI(req) + if err != nil || localVarHTTPResponse == nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + localVarBody, err := io.ReadAll(localVarHTTPResponse.Body) + localVarHTTPResponse.Body.Close() + localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody)) + if err != nil { + return localVarReturnValue, localVarHTTPResponse, err + } + + if localVarHTTPResponse.StatusCode >= 300 { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: localVarHTTPResponse.Status, + } + var v OdataError + err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr.error = err.Error() + return localVarReturnValue, localVarHTTPResponse, newErr + } + newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v) + newErr.model = v + return localVarReturnValue, localVarHTTPResponse, newErr + } + + err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type")) + if err != nil { + newErr := &GenericOpenAPIError{ + body: localVarBody, + error: err.Error(), + } + return localVarReturnValue, localVarHTTPResponse, newErr + } + + return localVarReturnValue, localVarHTTPResponse, nil +} diff --git a/vendor/github.com/owncloud/libre-graph-api-go/model_instance.go b/vendor/github.com/owncloud/libre-graph-api-go/model_instance.go new file mode 100644 index 00000000000..df07d2fbb6c --- /dev/null +++ b/vendor/github.com/owncloud/libre-graph-api-go/model_instance.go @@ -0,0 +1,162 @@ +/* +Libre Graph API + +Libre Graph is a free API for cloud collaboration inspired by the MS Graph API. + +API version: v1.0.4 +*/ + +// Code generated by OpenAPI Generator (https://openapi-generator.tech); DO NOT EDIT. + +package libregraph + +import ( + "encoding/json" +) + +// checks if the Instance type satisfies the MappedNullable interface at compile time +var _ MappedNullable = &Instance{} + +// Instance An oCIS instance that the user is either a member or a guest of. +type Instance struct { + // The URL of the oCIS instance. + Url *string `json:"url,omitempty"` + // Whether the instance is the user's primary instance. + Primary *bool `json:"primary,omitempty"` +} + +// NewInstance instantiates a new Instance object +// This constructor will assign default values to properties that have it defined, +// and makes sure properties required by API are set, but the set of arguments +// will change when the set of required properties is changed +func NewInstance() *Instance { + this := Instance{} + return &this +} + +// NewInstanceWithDefaults instantiates a new Instance object +// This constructor will only assign default values to properties that have it defined, +// but it doesn't guarantee that properties required by API are set +func NewInstanceWithDefaults() *Instance { + this := Instance{} + return &this +} + +// GetUrl returns the Url field value if set, zero value otherwise. +func (o *Instance) GetUrl() string { + if o == nil || IsNil(o.Url) { + var ret string + return ret + } + return *o.Url +} + +// GetUrlOk returns a tuple with the Url field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Instance) GetUrlOk() (*string, bool) { + if o == nil || IsNil(o.Url) { + return nil, false + } + return o.Url, true +} + +// HasUrl returns a boolean if a field has been set. +func (o *Instance) HasUrl() bool { + if o != nil && !IsNil(o.Url) { + return true + } + + return false +} + +// SetUrl gets a reference to the given string and assigns it to the Url field. +func (o *Instance) SetUrl(v string) { + o.Url = &v +} + +// GetPrimary returns the Primary field value if set, zero value otherwise. +func (o *Instance) GetPrimary() bool { + if o == nil || IsNil(o.Primary) { + var ret bool + return ret + } + return *o.Primary +} + +// GetPrimaryOk returns a tuple with the Primary field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *Instance) GetPrimaryOk() (*bool, bool) { + if o == nil || IsNil(o.Primary) { + return nil, false + } + return o.Primary, true +} + +// HasPrimary returns a boolean if a field has been set. +func (o *Instance) HasPrimary() bool { + if o != nil && !IsNil(o.Primary) { + return true + } + + return false +} + +// SetPrimary gets a reference to the given bool and assigns it to the Primary field. +func (o *Instance) SetPrimary(v bool) { + o.Primary = &v +} + +func (o Instance) MarshalJSON() ([]byte, error) { + toSerialize, err := o.ToMap() + if err != nil { + return []byte{}, err + } + return json.Marshal(toSerialize) +} + +func (o Instance) ToMap() (map[string]interface{}, error) { + toSerialize := map[string]interface{}{} + if !IsNil(o.Url) { + toSerialize["url"] = o.Url + } + if !IsNil(o.Primary) { + toSerialize["primary"] = o.Primary + } + return toSerialize, nil +} + +type NullableInstance struct { + value *Instance + isSet bool +} + +func (v NullableInstance) Get() *Instance { + return v.value +} + +func (v *NullableInstance) Set(val *Instance) { + v.value = val + v.isSet = true +} + +func (v NullableInstance) IsSet() bool { + return v.isSet +} + +func (v *NullableInstance) Unset() { + v.value = nil + v.isSet = false +} + +func NewNullableInstance(val *Instance) *NullableInstance { + return &NullableInstance{value: val, isSet: true} +} + +func (v NullableInstance) MarshalJSON() ([]byte, error) { + return json.Marshal(v.value) +} + +func (v *NullableInstance) UnmarshalJSON(src []byte) error { + v.isSet = true + return json.Unmarshal(src, &v.value) +} diff --git a/vendor/github.com/owncloud/libre-graph-api-go/model_user.go b/vendor/github.com/owncloud/libre-graph-api-go/model_user.go index e286502d51c..c130c4295e2 100644 --- a/vendor/github.com/owncloud/libre-graph-api-go/model_user.go +++ b/vendor/github.com/owncloud/libre-graph-api-go/model_user.go @@ -52,6 +52,10 @@ type User struct { SignInActivity *SignInActivity `json:"signInActivity,omitempty"` // A unique identifier assigned to the user by the organization. ExternalID *string `json:"externalID,omitempty"` + // A unique reference to the user. This is used to query the user from a different oCIS instance connected to the same identity provider. + CrossInstanceReference *string `json:"crossInstanceReference,omitempty"` + // oCIS instances that the user is either a member or a guest of. + Instances []Instance `json:"instances,omitempty"` } type _User User @@ -603,6 +607,70 @@ func (o *User) SetExternalID(v string) { o.ExternalID = &v } +// GetCrossInstanceReference returns the CrossInstanceReference field value if set, zero value otherwise. +func (o *User) GetCrossInstanceReference() string { + if o == nil || IsNil(o.CrossInstanceReference) { + var ret string + return ret + } + return *o.CrossInstanceReference +} + +// GetCrossInstanceReferenceOk returns a tuple with the CrossInstanceReference field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *User) GetCrossInstanceReferenceOk() (*string, bool) { + if o == nil || IsNil(o.CrossInstanceReference) { + return nil, false + } + return o.CrossInstanceReference, true +} + +// HasCrossInstanceReference returns a boolean if a field has been set. +func (o *User) HasCrossInstanceReference() bool { + if o != nil && !IsNil(o.CrossInstanceReference) { + return true + } + + return false +} + +// SetCrossInstanceReference gets a reference to the given string and assigns it to the CrossInstanceReference field. +func (o *User) SetCrossInstanceReference(v string) { + o.CrossInstanceReference = &v +} + +// GetInstances returns the Instances field value if set, zero value otherwise. +func (o *User) GetInstances() []Instance { + if o == nil || IsNil(o.Instances) { + var ret []Instance + return ret + } + return o.Instances +} + +// GetInstancesOk returns a tuple with the Instances field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *User) GetInstancesOk() ([]Instance, bool) { + if o == nil || IsNil(o.Instances) { + return nil, false + } + return o.Instances, true +} + +// HasInstances returns a boolean if a field has been set. +func (o *User) HasInstances() bool { + if o != nil && !IsNil(o.Instances) { + return true + } + + return false +} + +// SetInstances gets a reference to the given []Instance and assigns it to the Instances field. +func (o *User) SetInstances(v []Instance) { + o.Instances = v +} + func (o User) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { @@ -660,6 +728,12 @@ func (o User) ToMap() (map[string]interface{}, error) { if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } + if !IsNil(o.CrossInstanceReference) { + toSerialize["crossInstanceReference"] = o.CrossInstanceReference + } + if !IsNil(o.Instances) { + toSerialize["instances"] = o.Instances + } return toSerialize, nil } diff --git a/vendor/github.com/owncloud/libre-graph-api-go/model_user_update.go b/vendor/github.com/owncloud/libre-graph-api-go/model_user_update.go index 8295815f5c7..bf6f8906c34 100644 --- a/vendor/github.com/owncloud/libre-graph-api-go/model_user_update.go +++ b/vendor/github.com/owncloud/libre-graph-api-go/model_user_update.go @@ -50,6 +50,10 @@ type UserUpdate struct { SignInActivity *SignInActivity `json:"signInActivity,omitempty"` // A unique identifier assigned to the user by the organization. ExternalID *string `json:"externalID,omitempty"` + // A unique reference to the user. This is used to query the user from a different oCIS instance connected to the same identity provider. + CrossInstanceReference *string `json:"crossInstanceReference,omitempty"` + // oCIS instances that the user is either a member or a guest of. + Instances []Instance `json:"instances,omitempty"` } // NewUserUpdate instantiates a new UserUpdate object @@ -613,6 +617,70 @@ func (o *UserUpdate) SetExternalID(v string) { o.ExternalID = &v } +// GetCrossInstanceReference returns the CrossInstanceReference field value if set, zero value otherwise. +func (o *UserUpdate) GetCrossInstanceReference() string { + if o == nil || IsNil(o.CrossInstanceReference) { + var ret string + return ret + } + return *o.CrossInstanceReference +} + +// GetCrossInstanceReferenceOk returns a tuple with the CrossInstanceReference field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *UserUpdate) GetCrossInstanceReferenceOk() (*string, bool) { + if o == nil || IsNil(o.CrossInstanceReference) { + return nil, false + } + return o.CrossInstanceReference, true +} + +// HasCrossInstanceReference returns a boolean if a field has been set. +func (o *UserUpdate) HasCrossInstanceReference() bool { + if o != nil && !IsNil(o.CrossInstanceReference) { + return true + } + + return false +} + +// SetCrossInstanceReference gets a reference to the given string and assigns it to the CrossInstanceReference field. +func (o *UserUpdate) SetCrossInstanceReference(v string) { + o.CrossInstanceReference = &v +} + +// GetInstances returns the Instances field value if set, zero value otherwise. +func (o *UserUpdate) GetInstances() []Instance { + if o == nil || IsNil(o.Instances) { + var ret []Instance + return ret + } + return o.Instances +} + +// GetInstancesOk returns a tuple with the Instances field value if set, nil otherwise +// and a boolean to check if the value has been set. +func (o *UserUpdate) GetInstancesOk() ([]Instance, bool) { + if o == nil || IsNil(o.Instances) { + return nil, false + } + return o.Instances, true +} + +// HasInstances returns a boolean if a field has been set. +func (o *UserUpdate) HasInstances() bool { + if o != nil && !IsNil(o.Instances) { + return true + } + + return false +} + +// SetInstances gets a reference to the given []Instance and assigns it to the Instances field. +func (o *UserUpdate) SetInstances(v []Instance) { + o.Instances = v +} + func (o UserUpdate) MarshalJSON() ([]byte, error) { toSerialize, err := o.ToMap() if err != nil { @@ -674,6 +742,12 @@ func (o UserUpdate) ToMap() (map[string]interface{}, error) { if !IsNil(o.ExternalID) { toSerialize["externalID"] = o.ExternalID } + if !IsNil(o.CrossInstanceReference) { + toSerialize["crossInstanceReference"] = o.CrossInstanceReference + } + if !IsNil(o.Instances) { + toSerialize["instances"] = o.Instances + } return toSerialize, nil } diff --git a/vendor/modules.txt b/vendor/modules.txt index 96f4675ce60..8183c187458 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1310,7 +1310,7 @@ github.com/opentracing/opentracing-go/log # github.com/orcaman/concurrent-map v1.0.0 ## explicit github.com/orcaman/concurrent-map -# github.com/owncloud/libre-graph-api-go v1.0.5-0.20251107084958-31937a4ea3f1 +# github.com/owncloud/libre-graph-api-go v1.0.5-0.20260116104114-10074a92be64 ## explicit; go 1.18 github.com/owncloud/libre-graph-api-go # github.com/owncloud/reva/v2 v2.0.0-20260116122933-81e6e21256eb