Compare commits

...

119 Commits

Author SHA1 Message Date
amrita
31fa450980 add env 2025-04-16 14:56:57 +05:45
amrita-shrestha
e734f735ad cache go and cache 2025-04-16 14:37:38 +05:45
amrita-shrestha
9e78188f9a update root dir 2025-04-16 14:37:37 +05:45
Jannik Stehle
873ad0f5b4 Merge pull request #677 from opencloud-eu/ci/release-plugin-stable-workflow
ci: make release plugin compatible with stable branch workflow
2025-04-16 09:50:05 +02:00
Jannik Stehle
39a499fc01 ci: make release plugin compatible with stable branch workflow
Introduces the 2 configs `getLatestTag` and `useLatestRelease` to make the `ready-release-go` plugin fully compatible with our stable branch workflow.
2025-04-16 07:22:56 +02:00
Jannik Stehle
77b103bec0 Merge pull request #665 from opencloud-eu/feat/remove-unused-color-tokens
feat(web): remove old and unused color tokens
2025-04-15 13:28:49 +02:00
Viktor Scharf
fe5309a4a2 Merge pull request #611 from opencloud-eu/deleteUnneededContainer
[full-ci] delete unneeded containers and directories
2025-04-15 11:00:05 +02:00
Jörn Friedrich Dreyer
78bacea4f6 Merge pull request #671 from opencloud-eu/fix-670
fix deployment: do not create demo accounts when using keycloak
2025-04-15 10:47:48 +02:00
Viktor Scharf
945c04d448 Merge pull request #574 from jnweiger/main
Feat: install.sh now honors OC_BASE_DIR and OC_HOST
2025-04-15 10:27:27 +02:00
Artur Neumann
f208268bad delete unneeded containers and directories 2025-04-15 10:17:08 +02:00
Jörn Friedrich Dreyer
186072998a fixx deployment: do not create demo accounts when using keycloak
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
2025-04-15 09:57:29 +02:00
Viktor Scharf
7276ce1340 Merge pull request #618 from opencloud-eu/remove-code-duplication-starlark
[full-ci]Remove code duplication from starlark
2025-04-15 09:34:10 +02:00
amrita-shrestha
f23fe92fcd remove event duplication 2025-04-15 11:47:22 +05:45
Jürgen Weigert
ad377042dc fix mkdir to use -p 2025-04-14 18:25:01 +02:00
Jürgen Weigert
6af2ecfdde avoid useless mkdir calls 2025-04-14 18:20:01 +02:00
Jannik Stehle
f6a6b9689e feat(web): remove old and unused color tokens
These tokens are not being used anymore since we recently switched to material design.
2025-04-14 16:06:18 +02:00
Viktor Scharf
7f36d68cfc Merge pull request #652 from opencloud-eu/updatetestdoc
update test docs
2025-04-14 15:52:44 +02:00
Viktor Scharf
90d2f17315 Merge pull request #663 from opencloud-eu/ldap-manager
fix: make ldap manager login work with rootdn
2025-04-14 15:52:32 +02:00
Michael Barz
ea8507cc9f fix: make ldap manager login work with rootdn 2025-04-14 14:58:41 +02:00
Viktor Scharf
a5ebc0adec Update README.md 2025-04-14 14:29:04 +02:00
Viktor Scharf
a95d75813c update test doc 2025-04-14 13:33:05 +02:00
Viktor Scharf
b1268f49c3 Merge pull request #660 from opencloud-eu/chaeckClamavReadyBeforeStartingServer
Check that clamav is ready before the server run
2025-04-14 13:31:20 +02:00
Viktor Scharf
2babc5a48b check clamav ready before server run 2025-04-14 13:00:04 +02:00
Ralf Haferkamp
be13bac7f7 Merge pull request #637 from opencloud-eu/dependabot/go_modules/github.com/onsi/ginkgo/v2-2.23.4
build(deps): bump github.com/onsi/ginkgo/v2 from 2.23.3 to 2.23.4
2025-04-10 09:04:48 +02:00
Alex
f2ee327295 chore: move dev docs to opencloud-eu/docs repo (#635) 2025-04-09 17:20:40 +02:00
dependabot[bot]
94f5162633 build(deps): bump github.com/onsi/ginkgo/v2 from 2.23.3 to 2.23.4
Bumps [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo) from 2.23.3 to 2.23.4.
- [Release notes](https://github.com/onsi/ginkgo/releases)
- [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/ginkgo/compare/v2.23.3...v2.23.4)

---
updated-dependencies:
- dependency-name: github.com/onsi/ginkgo/v2
  dependency-version: 2.23.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-09 14:47:19 +00:00
Viktor Scharf
7e9a7d8099 example Ldap setup (#569)
* ldap setup

* run ldap in the opencloud full

* set admin user

* feat: use the shared LDAP schema and new phpldapadmin

* chore: change dc to match opencloud domain

---------

Co-authored-by: Michael Barz <michael.barz@zeitgestalten.eu>
2025-04-09 16:31:27 +02:00
Alex
a4164da9ed fix: web dev docs broken links (#633) 2025-04-09 13:55:34 +02:00
Alex
6386dd4e18 feat: add dev docs for web (#623)
Co-authored-by: Jannik Stehle <50302941+JammingBen@users.noreply.github.com>
Co-authored-by: Benedikt Kulmann <b.kulmann@opencloud.eu>
2025-04-09 13:36:26 +02:00
Ralf Haferkamp
32a28c47d9 Merge pull request #603 from opencloud-eu/dependabot/go_modules/github.com/coreos/go-oidc/v3-3.14.1
build(deps): bump github.com/coreos/go-oidc/v3 from 3.13.0 to 3.14.1
2025-04-09 07:59:55 +02:00
Ralf Haferkamp
7eae811b18 Merge pull request #604 from opencloud-eu/dependabot/npm_and_yarn/services/idp/typescript-5.8.3
build(deps-dev): bump typescript from 5.7.3 to 5.8.3 in /services/idp
2025-04-09 07:59:21 +02:00
Ralf Haferkamp
9b1a79f7d7 Merge pull request #619 from opencloud-eu/fixInbucketSetup
fix inbucket setup
2025-04-08 16:39:55 +02:00
Ralf Haferkamp
3ca9a59aaa Merge pull request #601 from opencloud-eu/feat/revert-0c2da6e
revert: completely remove "edition" from capabilities
2025-04-08 16:10:16 +02:00
Viktor Scharf
58932bbe99 fix inbucket setup 2025-04-08 14:39:21 +02:00
Anja Barz
cf2318d607 improve the info about storage path (#617) 2025-04-08 11:26:43 +02:00
Viktor Scharf
8a3aeb5b98 chore: bump version to v2.1.0 (#614) 2025-04-08 10:58:32 +02:00
Jannik Stehle
d07608758b test: remove capability check for edition
This check doesn't make sense anymore since the edition is empty in the capabilities if not set manually.
2025-04-08 10:06:22 +02:00
Artur Neumann
56753d5c46 Merge pull request #594 from opencloud-eu/fixUsingWrapper
[full-ci] only use wrapper when requested
2025-04-08 13:13:53 +05:45
OpenCloud Devops
58671abc6a 🎉 Release 2.1.0 (#504)
* 🎉 Release 2.0.1

* 🎉 Release 2.1.0

* 🎉 Release 2.1.0

* 🎉 Release 2.1.0

* 🎉 Release 2.1.0

* 🎉 Release 2.1.0

* 🎉 Release 2.1.0

* 🎉 Release 2.1.0

* 🎉 Release 2.1.0

* 🎉 Release 2.1.0

* 🎉 Release 2.1.0

* 🎉 Release 2.1.0

* 🎉 Release 2.1.0

* 🎉 Release 2.1.0

* 🎉 Release 2.1.0

* 🎉 Release 2.1.0

* 🎉 Release 2.1.0

* 🎉 Release 2.1.0

* 🎉 Release 2.1.0

* 🎉 Release 2.1.0

* 🎉 Release 2.1.0

* 🎉 Release 2.1.0

* 🎉 Release 2.1.0

* 🎉 Release 2.1.0
2025-04-07 19:59:00 +02:00
Viktor Scharf
5410caea4d Merge pull request #559 from fschade/antivirus-truncate-mode
feat(antivirus): add partial scanning mode
2025-04-07 19:08:40 +02:00
Michael Stingl
d2d33e4d48 Harmonize Keycloak Client Configurations with Built-in IdP (#589)
* Harmonize Keycloak client configurations with built-in IdP

This change makes the Keycloak client configurations consistent with the built-in IdP:

1. Standardized client IDs to match built-in IdP:
   - web (unchanged)
   - OpenCloudDesktop (was random ID)
   - OpenCloudAndroid (was random ID)
   - OpenCloudIOS (was random ID)
   - Cyberduck (simplified ID)

2. Updated domain names to use .eu consistently:
   - Changed from opencloud.com to opencloud.eu for mobile apps
   - Changed from hardcoded domains to templated {{OC_URL}} values

3. Updated redirect URIs to match built-in IdP format:
   - Added specific callback paths for web client
   - Removed wildcarded ports for desktop client

4. Changed mobile/desktop clients to public clients (equivalent to native app type)

5. Enhanced docker-entrypoint-override.sh to handle {{OC_URL}} template variables

These changes ensure a consistent authentication experience regardless of
whether users are using the built-in IdP or Keycloak.

* Harmonize Keycloak client configuration with client JSONs

Update the realm configuration to match the client configuration JSON files:

1. Update client IDs to match client JSON files:
   - Changed 'xdXOt13JKxym1B1QcEncf2XDkLAexMBFwiT9j6EfhhHFJhs2KM9jbjTmf8JBXE69' to 'OpenCloudDesktop'
   - Changed 'e4rAsNUSIUs0lF4nbv9FmCeUkTlV9GdgTLDH1b5uie7syb90SzEVrbN7HIpmWJeD' to 'OpenCloudAndroid'
   - Changed 'mxd5OQDk6es5LzOzRvidJNfXLUZS2oN3oUFeXPP8LpPrhx3UroJFduGEYIBOxkY1' to 'OpenCloudIOS'

2. Fix additional client properties:
   - Fix client names: Use proper capitalization for all clients
   - Fix OAuth redirect URIs for Android and iOS to use .eu domain
   - Fix Desktop URIs by removing wildcard asterisks
   - Update post-logout redirect URIs to match client JSONs
   - Set publicClient flag to true for all mobile/desktop clients

These changes ensure that when the realm is imported during deployment,
the client configurations will match the client JSONs exactly.

* Update web client configuration in Keycloak realm

Harmonize the web client configuration in the realm:
- Add 'OpenCloud Web App' client name
- Change URLs to use {{OC_URL}} template variables
- Update redirect URIs to use specific paths instead of wildcard
- Set backchannel logout URL to use templated URL

This completes the harmonization of all client configurations in the realm.

* Revert template variable approach in Keycloak configuration

Reverted templating changes to match upstream conventions:

1. Removed template variable handling from docker-entrypoint-override.sh
   - Removed {{OC_URL}} replacement, keeping only domain replacement

This maintains compatibility with the upstream approach of using direct URLs
with domain substitution instead of template variables.

* Fix remaining old client ID references in role mappings

Updated the remaining references to old client IDs in the role mappings section:
- xdXOt13JKxym1B1QcEncf2XDkLAexMBFwiT9j6EfhhHFJhs2KM9jbjTmf8JBXE69 → OpenCloudDesktop
- e4rAsNUSIUs0lF4nbv9FmCeUkTlV9GdgTLDH1b5uie7syb90SzEVrbN7HIpmWJeD → OpenCloudAndroid
- mxd5OQDk6es5LzOzRvidJNfXLUZS2oN3oUFeXPP8LpPrhx3UroJFduGEYIBOxkY1 → OpenCloudIOS

This ensures all client ID references throughout the realm configuration are
consistent and use the simplified IDs.
2025-04-07 17:54:13 +02:00
dependabot[bot]
7c040b0b9d build(deps-dev): bump typescript from 5.7.3 to 5.8.3 in /services/idp
Bumps [typescript](https://github.com/microsoft/TypeScript) from 5.7.3 to 5.8.3.
- [Release notes](https://github.com/microsoft/TypeScript/releases)
- [Changelog](https://github.com/microsoft/TypeScript/blob/main/azure-pipelines.release-publish.yml)
- [Commits](https://github.com/microsoft/TypeScript/commits)

---
updated-dependencies:
- dependency-name: typescript
  dependency-version: 5.8.3
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-07 15:35:44 +00:00
Florian Schade
bd1fc8a70b feat(antivirus): add partial scan mode
- Introduced partial mode for antivirus scanning to handle large files efficiently.
- Introduced clamAV scan timeout
2025-04-07 17:09:04 +02:00
dependabot[bot]
882894d0e2 build(deps): bump github.com/coreos/go-oidc/v3 from 3.13.0 to 3.14.1
Bumps [github.com/coreos/go-oidc/v3](https://github.com/coreos/go-oidc) from 3.13.0 to 3.14.1.
- [Release notes](https://github.com/coreos/go-oidc/releases)
- [Commits](https://github.com/coreos/go-oidc/compare/v3.13.0...v3.14.1)

---
updated-dependencies:
- dependency-name: github.com/coreos/go-oidc/v3
  dependency-version: 3.14.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-07 14:55:35 +00:00
Jannik Stehle
8290d8bf9d Revert "Completely remove "edition" from capabilities"
This reverts commit 0c2da6e8fd.
2025-04-07 16:41:34 +02:00
Viktor Scharf
a86c6ea708 Merge pull request #599 from opencloud-eu/revaBump2.30
[full-ci] reva bump 2.31.0
2025-04-07 16:32:14 +02:00
Viktor Scharf
d7391a5bd5 update to 2.31.0 2025-04-07 15:58:20 +02:00
Viktor Scharf
45c3234332 reva bump 2.30.0 2025-04-07 14:51:46 +02:00
Ralf Haferkamp
d06cca6fab Merge pull request #571 from opencloud-eu/dependabot/go_modules/github.com/go-playground/validator/v10-10.26.0
build(deps): bump github.com/go-playground/validator/v10 from 10.25.0 to 10.26.0
2025-04-07 12:58:56 +02:00
Ralf Haferkamp
a2b6ebf750 Merge pull request #567 from opencloud-eu/dependabot/go_modules/github.com/nats-io/nats.go-1.41.0
build(deps): bump github.com/nats-io/nats.go from 1.39.1 to 1.41.0
2025-04-07 12:58:23 +02:00
Artur Neumann
077c3c0268 only use wrapper when requested 2025-04-07 16:34:19 +05:45
Viktor Scharf
382c4228e2 Merge pull request #592 from opencloud-eu/removeUnneededParentheses
[full-ci] Remove unneeded parentheses
2025-04-07 12:25:23 +02:00
Artur Neumann
e849dc345c Merge pull request #591 from opencloud-eu/removeUnneededVar
[full-ci] remove unneeded variables
2025-04-07 14:31:58 +05:45
Artur Neumann
0179d0e1ae Merge pull request #596 from opencloud-eu/fixVirusLangTest
[full-ci] fix expected spanish string in test
2025-04-07 13:19:02 +05:45
Artur Neumann
87def992c8 fix expected spanish string in test 2025-04-07 12:40:48 +05:45
Artur Neumann
c31d42bc7e remove unneeded parentheses 2025-04-07 11:53:17 +05:45
Artur Neumann
862e306260 remove unneeded variables 2025-04-07 11:46:00 +05:45
Jürgen Weigert
56636cc9c4 Update deployments/examples/bare-metal-simple/README.md 2025-04-06 23:01:48 +02:00
Jürgen Weigert
a484237fcc Update deployments/examples/bare-metal-simple/README.md
Co-authored-by: Klaas Freitag <kraft@freisturz.de>
2025-04-06 22:39:42 +02:00
Juergen Weigert
a98c63846c Support OC_HOST for remote access. 2025-04-06 14:27:07 +02:00
Jürgen Weigert
6fc05f592b Feat: install.sh now honors OC_BASE_DIR 2025-04-05 15:13:05 +02:00
dependabot[bot]
7c5fb08262 build(deps): bump github.com/go-playground/validator/v10
Bumps [github.com/go-playground/validator/v10](https://github.com/go-playground/validator) from 10.25.0 to 10.26.0.
- [Release notes](https://github.com/go-playground/validator/releases)
- [Commits](https://github.com/go-playground/validator/compare/v10.25.0...v10.26.0)

---
updated-dependencies:
- dependency-name: github.com/go-playground/validator/v10
  dependency-version: 10.26.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-04 15:02:22 +00:00
Benedikt Kulmann
2174942a93 Merge pull request #570 from opencloud-eu/bump-web-2.2.0
[full-ci] chore(web): bump web to v2.2.0
2025-04-04 13:31:08 +02:00
Benedikt Kulmann
a325586c85 chore(web): bump web to v2.2.0 2025-04-04 12:04:44 +02:00
dependabot[bot]
9ec6e3eebf build(deps): bump github.com/nats-io/nats.go from 1.39.1 to 1.41.0
Bumps [github.com/nats-io/nats.go](https://github.com/nats-io/nats.go) from 1.39.1 to 1.41.0.
- [Release notes](https://github.com/nats-io/nats.go/releases)
- [Commits](https://github.com/nats-io/nats.go/compare/v1.39.1...v1.41.0)

---
updated-dependencies:
- dependency-name: github.com/nats-io/nats.go
  dependency-version: 1.41.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-04 10:00:11 +00:00
Jörn Friedrich Dreyer
b5d87db137 Merge pull request #565 from aduffeck/fix-item-trashed-sse
Simplify item-trashed SSEs. Also fixes it for coll. posix fs.
2025-04-04 11:49:09 +02:00
Ralf Haferkamp
ec3555e348 Merge pull request #563 from rhafer/example-smtp-fixes
fix(opencloud_full): add missing SMTP env vars
2025-04-04 11:30:56 +02:00
Ralf Haferkamp
b1d08cb542 Merge pull request #566 from opencloud-eu/dependabot/go_modules/github.com/onsi/gomega-1.37.0
build(deps): bump github.com/onsi/gomega from 1.36.3 to 1.37.0
2025-04-04 09:29:52 +02:00
dependabot[bot]
8278c079e4 build(deps): bump github.com/onsi/gomega from 1.36.3 to 1.37.0
Bumps [github.com/onsi/gomega](https://github.com/onsi/gomega) from 1.36.3 to 1.37.0.
- [Release notes](https://github.com/onsi/gomega/releases)
- [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md)
- [Commits](https://github.com/onsi/gomega/compare/v1.36.3...v1.37.0)

---
updated-dependencies:
- dependency-name: github.com/onsi/gomega
  dependency-version: 1.37.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-03 14:22:38 +00:00
André Duffeck
b0f3ab6252 Simplify item-trashed SSEs. Also fixes it for coll. posix fs. 2025-04-03 15:13:11 +02:00
Ralf Haferkamp
56c387cfa0 Merge pull request #564 from rhafer/allowed-labels
ci: Allow the `Type:DevOps` label
2025-04-03 14:22:06 +02:00
Ralf Haferkamp
95ae1ea32a ci: Allow the Type:DevOps label 2025-04-03 14:16:51 +02:00
Ralf Haferkamp
43677a0cd2 Merge pull request #561 from rhafer/woodpecker-enable-excludes
Revert "Disable the 'exclude' patterns on the path conditional for now"
2025-04-03 14:10:52 +02:00
Ralf Haferkamp
f25e191a46 fix(opencloud_full): add missing SMTP env vars
The compose example lacked support for setting various SMTP related
config vars. Even though some of them where present in the '.env' file.

Closes: #511
2025-04-03 14:05:04 +02:00
Ralf Haferkamp
4372244eeb Merge pull request #557 from opencloud-eu/dependabot/go_modules/golang.org/x/net-0.38.0
build(deps): bump golang.org/x/net from 0.37.0 to 0.38.0
2025-04-03 13:13:55 +02:00
Ralf Haferkamp
8a8523c922 Revert "Disable the 'exclude' patterns on the path conditional for now"
This reverts commit 1a54b4ce90. The
exclude feature has been fixed in woodpecker 3.5.0

Partial fixes: https://github.com/opencloud-eu/qa/issues/37
2025-04-03 09:46:38 +02:00
dependabot[bot]
dea654edbc build(deps): bump golang.org/x/net from 0.37.0 to 0.38.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.37.0 to 0.38.0.
- [Commits](https://github.com/golang/net/compare/v0.37.0...v0.38.0)

---
updated-dependencies:
- dependency-name: golang.org/x/net
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-03 06:53:12 +00:00
Ralf Haferkamp
c2c0e61d5e Merge pull request #542 from opencloud-eu/dependabot/npm_and_yarn/services/idp/eslint-plugin-jsx-a11y-6.10.2
build(deps-dev): bump eslint-plugin-jsx-a11y from 6.9.0 to 6.10.2 in /services/idp
2025-04-02 17:02:43 +02:00
dependabot[bot]
c45b725182 build(deps-dev): bump eslint-plugin-jsx-a11y in /services/idp
Bumps [eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y) from 6.9.0 to 6.10.2.
- [Release notes](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/releases)
- [Changelog](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/compare/v6.9.0...v6.10.2)

---
updated-dependencies:
- dependency-name: eslint-plugin-jsx-a11y
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-02 14:11:23 +00:00
Ralf Haferkamp
e5e2626a11 Merge pull request #541 from opencloud-eu/dependabot/npm_and_yarn/services/idp/web-vitals-4.2.4
build(deps): bump web-vitals from 3.5.2 to 4.2.4 in /services/idp
2025-04-02 16:09:38 +02:00
dependabot[bot]
6fcb47ce11 build(deps): bump web-vitals from 3.5.2 to 4.2.4 in /services/idp
Bumps [web-vitals](https://github.com/GoogleChrome/web-vitals) from 3.5.2 to 4.2.4.
- [Changelog](https://github.com/GoogleChrome/web-vitals/blob/main/CHANGELOG.md)
- [Commits](https://github.com/GoogleChrome/web-vitals/compare/v3.5.2...v4.2.4)

---
updated-dependencies:
- dependency-name: web-vitals
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-02 13:26:12 +00:00
Ralf Haferkamp
9949d4a57a Merge pull request #508 from opencloud-eu/dependabot/go_modules/github.com/open-policy-agent/opa-1.3.0
build(deps): bump github.com/open-policy-agent/opa from 1.2.0 to 1.3.0
2025-04-02 15:24:15 +02:00
Alex
d02c854971 fix: full deployment tika description is wrong (#553) 2025-04-02 14:55:59 +02:00
Alex
91c2624c04 fix: traefik credentials (#555) 2025-04-02 14:45:34 +02:00
dependabot[bot]
0636d906ac build(deps): bump github.com/open-policy-agent/opa from 1.2.0 to 1.3.0
Bumps [github.com/open-policy-agent/opa](https://github.com/open-policy-agent/opa) from 1.2.0 to 1.3.0.
- [Release notes](https://github.com/open-policy-agent/opa/releases)
- [Changelog](https://github.com/open-policy-agent/opa/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-policy-agent/opa/compare/v1.2.0...v1.3.0)

---
updated-dependencies:
- dependency-name: github.com/open-policy-agent/opa
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-04-02 12:36:26 +00:00
Ralf Haferkamp
2609d0e589 Merge pull request #549 from opencloud-eu/fix-daily-version
fix: correct daily version
2025-04-02 09:48:51 +02:00
Michael Barz
4bbd46d238 fix: correct daily version 2025-04-02 09:17:05 +02:00
Andre Duffeck
90b67351cf Merge pull request #546 from aduffeck/do-not-watch-in-dataproviders
Enable scan/watch in the storageprovider only
2025-04-02 09:04:13 +02:00
dependabot[bot]
3bcef42910 build(deps): bump github.com/urfave/cli/v2 from 2.27.5 to 2.27.6 (#509)
Bumps [github.com/urfave/cli/v2](https://github.com/urfave/cli) from 2.27.5 to 2.27.6.
- [Release notes](https://github.com/urfave/cli/releases)
- [Changelog](https://github.com/urfave/cli/blob/main/docs/CHANGELOG.md)
- [Commits](https://github.com/urfave/cli/compare/v2.27.5...v2.27.6)

---
updated-dependencies:
- dependency-name: github.com/urfave/cli/v2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-04-01 20:54:05 +02:00
André Duffeck
09818a9d7e Adapt command to changed signature 2025-04-01 15:04:53 +02:00
Jannik Stehle
3625eebe64 Merge pull request #545 from opencloud-eu/chore/bump-unzip-to-v1.0.2
chore: bump unzip extension to v1.0.2
2025-04-01 14:49:00 +02:00
André Duffeck
054c87b3fd Enable scan/watch in the storageprovider only 2025-04-01 14:46:20 +02:00
Jannik Stehle
b4a607965f chore: bump unzip extension to v1.0.2 2025-04-01 13:42:28 +02:00
Alex
37d6cd653d fix: typo in dev docs (#540) 2025-03-31 14:23:19 +02:00
Benedikt Kulmann
ff91a5014f Merge pull request #538 from opencloud-eu/change-favicon-to-svg
feat: support svg as icon
2025-03-31 13:03:09 +02:00
Alex Ackermann
1eb7683176 feat: support svg as icon 2025-03-31 12:04:48 +02:00
Alex
c73a552d52 feat: change theme.json primary color (#536) 2025-03-31 11:20:16 +02:00
Viktor Scharf
822de1ad8e Merge pull request #535 from opencloud-eu/addKeycloakDomainTokeycloackYaml
fix keycloak example #465
2025-03-31 10:44:12 +02:00
Viktor Scharf
874601ab8f fix keycloak example #465 2025-03-31 10:24:03 +02:00
Michael Barz
965a626a01 feat: add labels bot (#513) 2025-03-28 17:41:11 +01:00
Viktor Scharf
86354e6917 Merge pull request #465 from opencloud-eu/addKeycloakExample
add keycloak example
2025-03-28 15:24:40 +01:00
Alex
537b7056eb fix: remove generated api docs, as they aren't compatible with docusaurus (#512) 2025-03-28 15:19:57 +01:00
Viktor Scharf
495cb289e7 fix 2025-03-27 16:08:09 +01:00
Jörn Friedrich Dreyer
dd30b5b53b Merge pull request #506 from opencloud-eu/update-generated-code
update generated code
2025-03-27 15:47:14 +01:00
Florian Schade
034b5d2c4e chore: add generated artifacts 2025-03-27 14:54:24 +01:00
Viktor Scharf
ec43da4ed1 Merge branch 'main' into addKeycloakExample 2025-03-27 11:52:24 +01:00
Viktor Scharf
cb243448cc move keycloak setup to opencloud_full 2025-03-27 11:45:46 +01:00
Jörn Friedrich Dreyer
9feb51dd0d Merge pull request #494 from opencloud-eu/reduce-mem-allocation-in-graph
graph: reduce memory allocations
2025-03-27 11:06:57 +01:00
Jörn Friedrich Dreyer
8c5af66b1f graph: reduce memory allocations
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
2025-03-27 10:09:45 +01:00
Jörn Friedrich Dreyer
f0e62323cb update generated code
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
2025-03-27 10:06:45 +01:00
Artur Neumann
2ffbb1f201 Merge pull request #505 from opencloud-eu/fixTypoDeployment
fix tiny typo
2025-03-27 14:35:22 +05:45
Artur Neumann
1607135488 fix tiny typo 2025-03-27 14:27:54 +05:45
Viktor Scharf
85327e659c Merge pull request #503 from opencloud-eu/updateversionInbareMetal
update version in bare metal
2025-03-27 08:48:09 +01:00
dependabot[bot]
97ff296340 build(deps): bump google.golang.org/protobuf from 1.36.5 to 1.36.6 (#498)
Bumps google.golang.org/protobuf from 1.36.5 to 1.36.6.

---
updated-dependencies:
- dependency-name: google.golang.org/protobuf
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-27 08:31:43 +01:00
Viktor Scharf
18e81d441a update version in bare metal 2025-03-27 07:29:00 +01:00
Michael Barz
806fb8f1c4 chore: bump version 2025-03-26 21:27:47 +01:00
Michael Barz
c3e0fcc967 fix: do not overwrite github release 2025-03-26 21:09:27 +01:00
Viktor Scharf
26e172cfad posix as system driver 2025-03-24 17:09:04 +01:00
Viktor Scharf
90e2221164 add keycloak example 2025-03-24 17:03:35 +01:00
277 changed files with 15004 additions and 3823 deletions

28
.github/workflows/labels.yml vendored Normal file
View File

@@ -0,0 +1,28 @@
name: Require Pull Request Labels
on:
pull_request:
types: [opened, labeled, unlabeled, synchronize]
jobs:
label:
runs-on: ubuntu-latest
permissions:
issues: write
pull-requests: write
steps:
- uses: mheap/github-action-required-labels@v5
with:
mode: minimum
count: 1
labels: |
Type:Bug
Type:Enhancement
Type:Feature
Type:Breaking-Change
Type:Test
Type:Documentation
Type:Maintenance
Type:Security
Type:Dependencies
Type:DevOps
dependencies
add_comment: true

View File

@@ -18,21 +18,20 @@ SOURCES ?= $(shell find . -name "*.go" -type f -not -path "./node_modules/*")
TAGS ?=
ifndef OUTPUT
ifneq ($(DRONE_TAG),)
OUTPUT ?= $(subst v,,$(DRONE_TAG))
ifneq ($(CI_COMMIT_TAG),)
OUTPUT ?= $(subst v,,$(CI_COMMIT_TAG))
else
OUTPUT ?= testing
endif
endif
ifndef VERSION
ifneq ($(DRONE_TAG),)
VERSION ?= $(subst v,,$(DRONE_TAG))
else
STRING ?= $(shell git rev-parse --short HEAD)
endif
ifeq ($(VERSION), daily)
STRING ?= $(shell git rev-parse --short HEAD)
else ifeq ($(VERSION),)
STRING ?= $(shell git rev-parse --short HEAD)
endif
ifndef DATE
DATE := $(shell date -u '+%Y%m%d')
endif

View File

@@ -1,3 +1,3 @@
# The test runner source for UI tests
WEB_COMMITID=4f68c1e1dbcc88839e42c17c57f31dec243d7bd0
WEB_COMMITID=25629bf0d846051ec0ed6f56ddbeb1a4de6f9ba0
WEB_BRANCH=main

View File

@@ -23,7 +23,6 @@ OC_CI_ALPINE = "owncloudci/alpine:latest"
OC_CI_BAZEL_BUILDIFIER = "owncloudci/bazel-buildifier:latest"
OC_CI_CLAMAVD = "owncloudci/clamavd"
OC_CI_DRONE_ANSIBLE = "owncloudci/drone-ansible:latest"
OC_CI_DRONE_SKIP_PIPELINE = "owncloudci/drone-skip-pipeline"
OC_CI_GOLANG = "docker.io/golang:1.24"
OC_CI_NODEJS = "owncloudci/nodejs:%s"
OC_CI_PHP = "owncloudci/php:%s"
@@ -32,18 +31,12 @@ OC_CS3_API_VALIDATOR = "opencloudeu/cs3api-validator:latest"
OC_LITMUS = "owncloudci/litmus:latest"
OC_UBUNTU = "owncloud/ubuntu:20.04"
ONLYOFFICE_DOCUMENT_SERVER = "onlyoffice/documentserver:7.5.1"
PLUGINS_CODACY = "plugins/codacy:1"
PLUGINS_DOCKER_BUILDX = "woodpeckerci/plugin-docker-buildx:latest"
PLUGINS_GH_PAGES = "plugins/gh-pages:1"
PLUGINS_GITHUB_RELEASE = "woodpeckerci/plugin-release"
PLUGINS_GIT_ACTION = "plugins/git-action:1"
PLUGINS_GIT_PUSH = "appleboy/drone-git-push"
PLUGINS_MANIFEST = "plugins/manifest:1"
PLUGINS_S3 = "plugins/s3:1"
PLUGINS_S3_CACHE = "plugins/s3-cache:1"
PLUGINS_SLACK = "plugins/slack:1"
REDIS = "redis:6-alpine"
SONARSOURCE_SONAR_SCANNER_CLI = "sonarsource/sonar-scanner-cli:11.0"
READY_RELEASE_GO = "woodpeckerci/plugin-ready-release-go:latest"
DEFAULT_PHP_VERSION = "8.2"
@@ -55,11 +48,8 @@ dirs = {
"zip": "/woodpecker/src/github.com/opencloud-eu/opencloud/zip",
"webZip": "/woodpecker/src/github.com/opencloud-eu/opencloud/zip/web.tar.gz",
"webPnpmZip": "/woodpecker/src/github.com/opencloud-eu/opencloud/zip/web-pnpm.tar.gz",
"baseGo": "/go/src/github.com/opencloud-eu/opencloud",
"gobinTar": "go-bin.tar.gz",
"gobinTarPath": "/go/src/github.com/opencloud-eu/opencloud/go-bin.tar.gz",
"opencloudConfig": "tests/config/woodpecker/opencloud-config.json",
"ocis": "/woodpecker/src/github.com/opencloud-eu/opencloud/srv/app/tmp/ocis",
"opencloudRevaDataRoot": "/woodpecker/src/github.com/opencloud-eu/opencloud/srv/app/tmp/ocis/owncloud/data",
"multiServiceOcBaseDataPath": "/woodpecker/src/github.com/opencloud-eu/opencloud/multiServiceData",
"ocWrapper": "/woodpecker/src/github.com/opencloud-eu/opencloud/tests/ocwrapper",
@@ -78,6 +68,19 @@ FED_OC_SERVER_NAME = "federation-opencloud-server"
OC_FED_URL = "https://%s:10200" % FED_OC_SERVER_NAME
OC_FED_DOMAIN = "%s:10200" % FED_OC_SERVER_NAME
event = {
"base": {
"event": ["push", "manual"],
"branch": "main",
},
"pull_request": {
"event": "pull_request",
},
"tag": {
"event": "tag",
},
}
# configuration
config = {
"cs3ApiTests": {
@@ -345,14 +348,6 @@ config = {
GRAPH_AVAILABLE_ROLES = "b1e2218d-eef8-4d4c-b82d-0f1a1b48f3b5,a8d5fe5e-96e3-418d-825b-534dbdf22b99,fb6c3e19-e378-47e5-b277-9732f9de6e21,58c63c02-1d89-4572-916a-870abc5a1b7d,2d00ce52-1fc2-4dbc-8b95-a73b73395f5a,1c996275-f1c9-4e71-abdf-a42f6495e960,312c0871-5ef7-4b3a-85b6-0e4074c64049,aa97fe03-7980-45ac-9e50-b325749fd7e6,63e64e19-8d43-42ec-a738-2b6af2610efa"
# workspace for pipeline to cache Go dependencies between steps of a pipeline
# to be used in combination with stepVolumeGo
workspace = \
{
"base": "/go",
"path": "src/github.com/opencloud-eu/opencloud/",
}
# minio mc environment variables
MINIO_MC_ENV = {
"CACHE_BUCKET": {
@@ -416,8 +411,6 @@ def main(ctx):
none
"""
pipelines = []
build_release_helpers = \
readyReleaseGo() + \
docs()
@@ -431,8 +424,8 @@ def main(ctx):
test_pipelines = \
codestyle(ctx) + \
checkGherkinLint(ctx) + \
checkTestSuitesInExpectedFailures(ctx) + \
checkGherkinLint() + \
checkTestSuitesInExpectedFailures() + \
buildWebCache(ctx) + \
getGoBinForTesting(ctx) + \
buildOpencloudBinaryForTesting(ctx) + \
@@ -474,7 +467,7 @@ def main(ctx):
),
)
pipelineSanityChecks(ctx, pipelines)
pipelineSanityChecks(pipelines)
return pipelines
def cachePipeline(name, steps):
@@ -487,9 +480,7 @@ def cachePipeline(name, steps):
"event": ["push", "manual"],
"branch": ["main", "stable-*"],
},
{
"event": "pull_request",
},
event["pull_request"],
],
}
@@ -547,6 +538,7 @@ def getGoBinForTesting(ctx):
"steps": checkGoBinCache() +
cacheGoBin(),
"when": [
event["tag"],
{
"event": ["push", "manual"],
"branch": ["main", "stable-*"],
@@ -557,11 +549,7 @@ def getGoBinForTesting(ctx):
"exclude": skipIfUnchanged(ctx, "unit-tests"),
},
},
{
"event": "tag",
},
],
"workspace": workspace,
}]
def checkGoBinCache():
@@ -570,7 +558,7 @@ def checkGoBinCache():
"image": MINIO_MC,
"environment": MINIO_MC_ENV,
"commands": [
"bash -x %s/tests/config/woodpecker/check_go_bin_cache.sh %s %s" % (dirs["baseGo"], dirs["baseGo"], dirs["gobinTar"]),
"bash -x %s/tests/config/woodpecker/check_go_bin_cache.sh %s %s" % (dirs["base"], dirs["base"], dirs["gobinTar"]),
],
}]
@@ -588,12 +576,13 @@ def cacheGoBin():
},
{
"name": "archive-go-bin",
"image": OC_UBUNTU,
"image": OC_CI_GOLANG,
"commands": [
". ./.env",
"if $BIN_CACHE_FOUND; then exit 0; fi",
"tar -czvf %s /go/bin" % dirs["gobinTarPath"],
"tar -czvf %s/%s /go/bin " % (dirs["base"], dirs["gobinTar"]),
],
"environment": CI_HTTP_PROXY_ENV,
},
{
"name": "cache-go-bin",
@@ -604,10 +593,10 @@ def cacheGoBin():
"if $BIN_CACHE_FOUND; then exit 0; fi",
# .bingo folder will change after 'bingo-get'
# so get the stored hash of a .bingo folder
"BINGO_HASH=$(cat %s/.bingo_hash)" % dirs["baseGo"],
"BINGO_HASH=$(cat %s/.bingo_hash)" % dirs["base"],
# cache using the minio client to the public bucket (long term bucket)
"mc alias set s3 $MC_HOST $AWS_ACCESS_KEY_ID $AWS_SECRET_ACCESS_KEY",
"mc cp -r %s s3/$CACHE_BUCKET/opencloud/go-bin/$BINGO_HASH" % (dirs["gobinTarPath"]),
"mc cp -r %s/%s s3/$CACHE_BUCKET/opencloud/go-bin/$BINGO_HASH" % (dirs["base"], dirs["gobinTar"]),
],
},
]
@@ -619,22 +608,32 @@ def restoreGoBinCache():
"image": MINIO_MC,
"environment": MINIO_MC_ENV,
"commands": [
"BINGO_HASH=$(cat %s/.bingo/* | sha256sum | cut -d ' ' -f 1)" % dirs["baseGo"],
"BINGO_HASH=$(cat %s/.bingo/* | sha256sum | cut -d ' ' -f 1)" % dirs["base"],
"mc alias set s3 $MC_HOST $AWS_ACCESS_KEY_ID $AWS_SECRET_ACCESS_KEY",
"mc cp -r -a s3/$CACHE_BUCKET/opencloud/go-bin/$BINGO_HASH/%s %s" % (dirs["gobinTar"], dirs["baseGo"]),
"mc cp -r -a s3/$CACHE_BUCKET/opencloud/go-bin/$BINGO_HASH/%s %s" % (dirs["gobinTar"], dirs["base"]),
],
},
{
"name": "extract-go-bin-cache",
"image": OC_UBUNTU,
"image": OC_CI_GOLANG,
"commands": [
"tar -xvmf %s -C /" % dirs["gobinTarPath"],
"tar -xvmf %s/%s -C %s" % (dirs["base"], dirs["gobinTar"], dirs["base"]),
],
},
]
def testOpencloud(ctx):
steps = restoreGoBinCache() + makeGoGenerate("") + [
# environment = CI_HTTP_PROXY_ENV
# environment["GOBIN"] = "/woodpecker/src/github.com/opencloud-eu/opencloud/go/bin"
steps = restoreGoBinCache() + [
{
"name": "generate-go",
"image": OC_CI_GOLANG,
"commands": [
"for i in $(seq 3); do %s go-generate && break || sleep 1; done" % make,
],
"environment": CI_HTTP_PROXY_ENV,
},
{
"name": "golangci-lint",
"image": OC_CI_GOLANG,
@@ -680,10 +679,7 @@ def testOpencloud(ctx):
"name": "linting_and_unitTests",
"steps": steps,
"when": [
{
"event": ["push", "manual"],
"branch": "main",
},
event["base"],
{
"event": "pull_request",
"path": {
@@ -692,7 +688,6 @@ def testOpencloud(ctx):
},
],
"depends_on": getPipelineNames(getGoBinForTesting(ctx)),
"workspace": workspace,
}
def scanOpencloud(ctx):
@@ -711,10 +706,7 @@ def scanOpencloud(ctx):
"name": "go-vulnerability-scanning",
"steps": steps,
"when": [
{
"event": ["push", "manual"],
"branch": "main",
},
event["base"],
{
"event": "pull_request",
"path": {
@@ -722,8 +714,6 @@ def scanOpencloud(ctx):
},
},
],
"depends_on": getPipelineNames(getGoBinForTesting(ctx)),
"workspace": workspace,
}
def buildOpencloudBinaryForTesting(ctx):
@@ -734,10 +724,7 @@ def buildOpencloudBinaryForTesting(ctx):
build() +
rebuildBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBinPath"]),
"when": [
{
"event": ["push", "manual"],
"branch": "main",
},
event["base"],
{
"event": "pull_request",
"path": {
@@ -745,7 +732,6 @@ def buildOpencloudBinaryForTesting(ctx):
},
},
],
"workspace": workspace,
}]
def vendorbinCodestyle(phpVersion):
@@ -772,7 +758,7 @@ def vendorbinCodesniffer(phpVersion):
],
}]
def checkTestSuitesInExpectedFailures(ctx):
def checkTestSuitesInExpectedFailures():
return [{
"name": "check-suites-in-expected-failures",
"steps": [
@@ -784,14 +770,10 @@ def checkTestSuitesInExpectedFailures(ctx):
],
},
],
"when": [
{
"event": "pull_request",
},
],
"when": [event["pull_request"]],
}]
def checkGherkinLint(ctx):
def checkGherkinLint():
return [{
"name": "check-gherkin-standard",
"steps": [
@@ -804,11 +786,7 @@ def checkGherkinLint(ctx):
],
},
],
"when": [
{
"event": "pull_request",
},
],
"when": [event["pull_request"]],
}]
def codestyle(ctx):
@@ -869,10 +847,7 @@ def codestyle(ctx):
],
"depends_on": [],
"when": [
{
"event": ["push", "manual"],
"branch": "main",
},
event["base"],
{
"event": "pull_request",
"path": {
@@ -926,23 +901,20 @@ def localApiTestPipeline(ctx):
"steps": restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBinPath"]) +
(tikaService() if params["tikaNeeded"] else []) +
(waitForServices("online-offices", ["collabora:9980", "onlyoffice:443", "fakeoffice:8080"]) if params["collaborationServiceNeeded"] else []) +
opencloudServer(storage, params["accounts_hash_difficulty"], extra_server_environment = params["extraServerEnvironment"], with_wrapper = True, tika_enabled = params["tikaNeeded"]) +
(waitForClamavService() if params["antivirusNeeded"] else []) +
(waitForEmailService() if params["emailNeeded"] else []) +
opencloudServer(storage, params["accounts_hash_difficulty"], extra_server_environment = params["extraServerEnvironment"], with_wrapper = True, tika_enabled = params["tikaNeeded"]) +
(opencloudServer(storage, params["accounts_hash_difficulty"], deploy_type = "federation", extra_server_environment = params["extraServerEnvironment"]) if params["federationServer"] else []) +
((wopiCollaborationService("fakeoffice") + wopiCollaborationService("collabora") + wopiCollaborationService("onlyoffice")) if params["collaborationServiceNeeded"] else []) +
(openCloudHealthCheck("wopi", ["wopi-collabora:9304", "wopi-onlyoffice:9304", "wopi-fakeoffice:9304"]) if params["collaborationServiceNeeded"] else []) +
localApiTests(ctx, name, params["suites"], storage, params["extraEnvironment"], run_with_remote_php) +
localApiTests(name, params["suites"], storage, params["extraEnvironment"], run_with_remote_php) +
logRequests(),
"services": (emailService() if params["emailNeeded"] else []) +
(clamavService() if params["antivirusNeeded"] else []) +
((fakeOffice() + collaboraService() + onlyofficeService()) if params["collaborationServiceNeeded"] else []),
"depends_on": getPipelineNames(buildOpencloudBinaryForTesting(ctx)),
"when": [
{
"event": ["push", "manual"],
"branch": "main",
},
event["base"],
{
"event": "pull_request",
"path": {
@@ -954,9 +926,9 @@ def localApiTestPipeline(ctx):
pipelines.append(pipeline)
return pipelines
def localApiTests(ctx, name, suites, storage = "decomposed", extra_environment = {}, with_remote_php = False):
def localApiTests(name, suites, storage = "decomposed", extra_environment = {}, with_remote_php = False):
test_dir = "%s/tests/acceptance" % dirs["base"]
expected_failures_file = "%s/expected-failures-localAPI-on-decomposed-storage.md" % (test_dir)
expected_failures_file = "%s/expected-failures-localAPI-on-decomposed-storage.md" % test_dir
environment = {
"TEST_SERVER_URL": OC_URL,
@@ -990,7 +962,7 @@ def cs3ApiTests(ctx, storage, accounts_hash_difficulty = 4):
return {
"name": "cs3ApiTests-%s" % storage,
"steps": restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBinPath"]) +
opencloudServer(storage, accounts_hash_difficulty, [], [], "cs3api_validator") +
opencloudServer(storage, accounts_hash_difficulty, deploy_type = "cs3api_validator") +
[
{
"name": "cs3ApiTests",
@@ -1005,10 +977,7 @@ def cs3ApiTests(ctx, storage, accounts_hash_difficulty = 4):
],
"depends_on": getPipelineNames(buildOpencloudBinaryForTesting(ctx)),
"when": [
{
"event": ["push", "manual"],
"branch": "main",
},
event["base"],
{
"event": "pull_request",
"path": {
@@ -1036,7 +1005,6 @@ def wopiValidatorTests(ctx, storage, wopiServerType, accounts_hash_difficulty =
]
validatorTests = []
wopiServer = []
extra_server_environment = {}
if wopiServerType == "cs3":
@@ -1122,10 +1090,7 @@ def wopiValidatorTests(ctx, storage, wopiServerType, accounts_hash_difficulty =
validatorTests,
"depends_on": getPipelineNames(buildOpencloudBinaryForTesting(ctx)),
"when": [
{
"event": ["push", "manual"],
"branch": "main",
},
event["base"],
{
"event": "pull_request",
"path": {
@@ -1176,10 +1141,7 @@ def coreApiTests(ctx, part_number = 1, number_of_parts = 1, with_remote_php = Fa
"services": redisForOCStorage(storage),
"depends_on": getPipelineNames(buildOpencloudBinaryForTesting(ctx)),
"when": [
{
"event": ["push", "manual"],
"branch": "main",
},
event["base"],
{
"event": "pull_request",
"path": {
@@ -1204,7 +1166,7 @@ def apiTests(ctx):
for runPart in range(1, config["apiTests"]["numberOfParts"] + 1):
for run_with_remote_php in defaults["withRemotePhp"]:
if (not debugPartsEnabled or (debugPartsEnabled and runPart in debugParts)):
if not debugPartsEnabled or (debugPartsEnabled and runPart in debugParts):
pipelines.append(coreApiTests(ctx, runPart, config["apiTests"]["numberOfParts"], run_with_remote_php))
return pipelines
@@ -1226,10 +1188,7 @@ def e2eTestPipeline(ctx):
}
e2e_trigger = [
{
"event": ["push", "manual"],
"branch": "main",
},
event["base"],
{
"event": "pull_request",
"path": {
@@ -1244,10 +1203,10 @@ def e2eTestPipeline(ctx):
pipelines = []
if ("skip-e2e" in ctx.build.title.lower()):
if "skip-e2e" in ctx.build.title.lower():
return pipelines
if (ctx.build.event == "tag"):
if ctx.build.event == "tag":
return pipelines
storage = "posix"
@@ -1335,10 +1294,7 @@ def multiServiceE2ePipeline(ctx):
}
e2e_trigger = [
{
"event": ["push", "manual"],
"branch": "main",
},
event["base"],
{
"event": "pull_request",
"path": {
@@ -1347,11 +1303,11 @@ def multiServiceE2ePipeline(ctx):
},
]
if ("skip-e2e" in ctx.build.title.lower()):
if "skip-e2e" in ctx.build.title.lower():
return pipelines
# run this pipeline only for cron jobs and full-ci PRs
if (not "full-ci" in ctx.build.title.lower() and ctx.build.event != "cron"):
if not "full-ci" in ctx.build.title.lower() and ctx.build.event != "cron":
return pipelines
storage = "posix"
@@ -1455,7 +1411,7 @@ def multiServiceE2ePipeline(ctx):
})
return pipelines
def uploadTracingResult(ctx):
def uploadTracingResult():
return [{
"name": "upload-tracing-result",
"image": PLUGINS_S3,
@@ -1549,7 +1505,7 @@ def dockerReleases(ctx):
def dockerRelease(ctx, repo, build_type):
build_args = [
"REVISION=%s" % (ctx.build.commit),
"REVISION=%s" % ctx.build.commit,
"VERSION=%s" % (ctx.build.ref.replace("refs/tags/", "") if ctx.build.event == "tag" else "daily"),
]
@@ -1582,11 +1538,7 @@ def dockerRelease(ctx, repo, build_type):
"from_secret": "ci_http_proxy",
},
},
"when": [
{
"event": ["pull_request"],
},
],
"when": [event["pull_request"]],
},
{
"name": "build-and-push",
@@ -1628,31 +1580,21 @@ def dockerRelease(ctx, repo, build_type):
],
},
"when": [
{
"event": ["push", "manual"],
"branch": "main",
},
{
"event": "tag",
},
event["base"],
event["tag"],
],
},
],
"depends_on": depends_on,
"when": [
{
"event": ["push", "manual"],
"branch": "main",
},
event["base"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "build-docker"),
},
},
{
"event": "tag",
},
event["tag"],
],
}
@@ -1686,13 +1628,8 @@ def binaryRelease(ctx, arch, depends_on = []):
"make -C opencloud release-finish",
],
"when": [
{
"event": ["push", "manual"],
"branch": "main",
},
{
"event": "tag",
},
event["base"],
event["tag"],
],
},
{
@@ -1706,35 +1643,29 @@ def binaryRelease(ctx, arch, depends_on = []):
"opencloud/dist/release/*",
],
"title": ctx.build.ref.replace("refs/tags/v", ""),
"overwrite": True,
"prerelease": len(ctx.build.ref.split("-")) > 1,
},
"when": [
{
"event": "tag",
},
event["tag"],
],
},
],
"depends_on": depends_on,
"when": [
{
"event": ["push", "manual"],
"branch": "main",
},
event["base"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "build-binary"),
},
},
{
"event": "tag",
},
event["tag"],
],
}
def licenseCheck(ctx):
environment = CI_HTTP_PROXY_ENV
environment["GOBIN"] = "/woodpecker/src/github.com/opencloud-eu/opencloud/go/bin"
return {
"name": "check-licenses",
"steps": restoreGoBinCache() + [
@@ -1755,7 +1686,7 @@ def licenseCheck(ctx):
{
"name": "go-check-licenses",
"image": OC_CI_GOLANG,
"environment": CI_HTTP_PROXY_ENV,
"environment": environment,
"commands": [
"make ci-go-check-licenses",
],
@@ -1763,7 +1694,7 @@ def licenseCheck(ctx):
{
"name": "go-save-licenses",
"image": OC_CI_GOLANG,
"environment": CI_HTTP_PROXY_ENV,
"environment": environment,
"commands": [
"make ci-go-save-licenses",
],
@@ -1786,29 +1717,18 @@ def licenseCheck(ctx):
"third-party-licenses.tar.gz",
],
"title": ctx.build.ref.replace("refs/tags/v", ""),
"overwrite": True,
"prerelease": len(ctx.build.ref.split("-")) > 1,
},
"when": [
{
"event": "tag",
},
event["tag"],
],
},
],
"when": [
{
"event": ["push", "manual"],
"branch": "main",
},
{
"event": "pull_request",
},
{
"event": "tag",
},
event["base"],
event["pull_request"],
event["tag"],
],
"workspace": workspace,
}
def readyReleaseGo():
@@ -1827,12 +1747,7 @@ def readyReleaseGo():
},
},
],
"when": [
{
"event": ["push", "manual"],
"branch": "main",
},
],
"when": [event["base"]],
}]
def releaseDockerReadme(repo, build_type):
@@ -1850,7 +1765,7 @@ def releaseDockerReadme(repo, build_type):
"from_secret": "docker_password",
},
"PUSHRM_TARGET": repo,
"PUSHRM_SHORT": "Docker images for %s" % (repo),
"PUSHRM_SHORT": "Docker images for %s" % repo,
"PUSHRM_FILE": "README.md",
},
},
@@ -1868,13 +1783,8 @@ def releaseDockerReadme(repo, build_type):
},
],
"when": [
{
"event": ["push", "manual"],
"branch": "main",
},
{
"event": "tag",
},
event["base"],
event["tag"],
],
}
@@ -1910,17 +1820,17 @@ def makeNodeGenerate(module):
if module == "":
make = "make"
else:
make = "make -C %s" % (module)
make = "make -C %s" % module
return [
{
"name": "generate nodejs",
"name": "generate-nodejs",
"image": OC_CI_NODEJS % DEFAULT_NODEJS_VERSION,
"environment": {
"CHROMEDRIVER_SKIP_DOWNLOAD": True, # install fails on arm and chromedriver is a test only dependency
},
"commands": [
"pnpm config set store-dir ./.pnpm-store",
"for i in $(seq 3); do %s node-generate-prod && break || sleep 1; done" % (make),
"for i in $(seq 3); do %s node-generate-prod && break || sleep 1; done" % make,
],
},
]
@@ -1929,13 +1839,13 @@ def makeGoGenerate(module):
if module == "":
make = "make"
else:
make = "make -C %s" % (module)
make = "make -C %s" % module
return [
{
"name": "generate go",
"name": "generate-go",
"image": OC_CI_GOLANG,
"commands": [
"for i in $(seq 3); do %s go-generate && break || sleep 1; done" % (make),
"for i in $(seq 3); do %s go-generate && break || sleep 1; done" % make,
],
"environment": CI_HTTP_PROXY_ENV,
},
@@ -1967,20 +1877,18 @@ def notify(ctx):
"event": ["push", "manual"],
"branch": ["main", "release-*"],
},
{
"event": "tag",
},
event["tag"],
],
"runs_on": status,
}
def opencloudServer(storage = "decomposed", accounts_hash_difficulty = 4, volumes = [], depends_on = [], deploy_type = "", extra_server_environment = {}, with_wrapper = False, tika_enabled = False):
def opencloudServer(storage = "decomposed", accounts_hash_difficulty = 4, depends_on = [], deploy_type = "", extra_server_environment = {}, with_wrapper = False, tika_enabled = False):
user = "0:0"
container_name = OC_SERVER_NAME
environment = {
"OC_URL": OC_URL,
"OC_CONFIG_DIR": "/root/.opencloud/config", # needed for checking config later
"STORAGE_USERS_DRIVER": "%s" % (storage),
"STORAGE_USERS_DRIVER": "%s" % storage,
"PROXY_ENABLE_BASIC_AUTH": True,
"WEB_UI_CONFIG_FILE": "%s/%s" % (dirs["base"], dirs["opencloudConfig"]),
"OC_LOG_LEVEL": "error",
@@ -2070,20 +1978,27 @@ def opencloudServer(storage = "decomposed", accounts_hash_difficulty = 4, volume
# That will allow OpenCloud to use whatever its built-in default is.
# Otherwise pass in a value from 4 to about 11 or 12 (default 4, for making regular tests fast)
# The high values cause lots of CPU to be used when hashing passwords, and really slow down the tests.
if (accounts_hash_difficulty != "default"):
if accounts_hash_difficulty != "default":
environment["ACCOUNTS_HASH_DIFFICULTY"] = accounts_hash_difficulty
for item in extra_server_environment:
environment[item] = extra_server_environment[item]
wrapper_commands = [
"make -C %s build" % dirs["ocWrapper"],
server_commands = [
"env | sort",
"%s/bin/ocwrapper serve --bin %s --url %s --admin-username admin --admin-password admin" % (dirs["ocWrapper"], dirs["opencloudBin"], environment["OC_URL"]),
]
if with_wrapper:
server_commands += [
"make -C %s build" % dirs["ocWrapper"],
"%s/bin/ocwrapper serve --bin %s --url %s --admin-username admin --admin-password admin" % (dirs["ocWrapper"], dirs["opencloudBin"], environment["OC_URL"]),
]
else:
server_commands += [
"%s server" % dirs["opencloudBin"],
]
wait_for_opencloud = {
"name": "wait-for-%s" % (container_name),
"name": "wait-for-%s" % container_name,
"image": OC_CI_ALPINE,
"commands": [
# wait for opencloud-server to be ready (5 minutes)
@@ -2107,7 +2022,7 @@ def opencloudServer(storage = "decomposed", accounts_hash_difficulty = 4, volume
"%s init --insecure true" % dirs["opencloudBin"],
"cat $OC_CONFIG_DIR/opencloud.yaml",
"cp tests/config/woodpecker/app-registry.yaml $OC_CONFIG_DIR/app-registry.yaml",
] + (wrapper_commands),
] + server_commands,
}
steps = [
@@ -2179,11 +2094,6 @@ def build():
]
def skipIfUnchanged(ctx, type):
## FIXME: the 'exclude' feature (https://woodpecker-ci.org/docs/usage/workflow-syntax#path) does not seem to provide
# what we need. It seems to skip the build as soon as one of the changed files matches an exclude pattern, we only
# want to skip of ALL changed files match. So skip this condition for now:
return []
if "full-ci" in ctx.build.title.lower() or ctx.build.event == "tag" or ctx.build.event == "cron":
return []
@@ -2213,8 +2123,6 @@ def skipIfUnchanged(ctx, type):
skip = base + unit + acceptance
elif type == "cache":
skip = base
else:
return []
return skip
@@ -2246,13 +2154,13 @@ def example_deploys(ctx):
deploys = []
for config in configs:
deploys.append(deploy(ctx, config, rebuild))
deploys.append(deploy(config, rebuild))
return deploys
def deploy(ctx, config, rebuild):
def deploy(config, rebuild):
return {
"name": "deploy_%s" % (config),
"name": "deploy_%s" % config,
"steps": [
{
"name": "clone continuous deployment playbook",
@@ -2267,7 +2175,7 @@ def deploy(ctx, config, rebuild):
"image": OC_CI_DRONE_ANSIBLE,
"failure": "ignore",
"environment": {
"CONTINUOUS_DEPLOY_SERVERS_CONFIG": "../%s" % (config),
"CONTINUOUS_DEPLOY_SERVERS_CONFIG": "../%s" % config,
"REBUILD": rebuild,
"HCLOUD_API_TOKEN": {
"from_secret": "hcloud_api_token",
@@ -2288,13 +2196,8 @@ def deploy(ctx, config, rebuild):
},
],
"when": [
{
"event": ["push", "manual"],
"branch": "main",
},
{
"event": "tag",
},
event["base"],
event["tag"],
],
}
@@ -2324,11 +2227,7 @@ def checkStarlark():
},
],
"depends_on": [],
"when": [
{
"event": "pull_request",
},
],
"when": [event["pull_request"]],
}]
def genericCache(name, action, mounts, cache_path):
@@ -2357,7 +2256,7 @@ def genericCache(name, action, mounts, cache_path):
"secret_key": {
"from_secret": "cache_s3_secret_key",
},
"filename": "%s.tar" % (name),
"filename": "%s.tar" % name,
"path": cache_path,
"fallback_path": cache_path,
},
@@ -2388,13 +2287,8 @@ def genericCachePurge(flush_path):
},
],
"when": [
{
"event": ["push", "manual"],
"branch": "main",
},
{
"event": "pull_request",
},
event["base"],
event["pull_request"],
],
"runs_on": ["success", "failure"],
}
@@ -2402,7 +2296,7 @@ def genericCachePurge(flush_path):
def genericBuildArtifactCache(ctx, name, action, path):
if action == "rebuild" or action == "restore":
cache_path = "%s/%s/%s" % ("cache", repo_slug, ctx.build.commit + "-${CI_PIPELINE_NUMBER}")
name = "%s_build_artifact_cache" % (name)
name = "%s_build_artifact_cache" % name
return genericCache(name, action, [path], cache_path)
if action == "purge":
@@ -2419,14 +2313,13 @@ def rebuildBuildArtifactCache(ctx, name, path):
def purgeBuildArtifactCache(ctx):
return genericBuildArtifactCache(ctx, "", "purge", [])
def pipelineSanityChecks(ctx, pipelines):
def pipelineSanityChecks(pipelines):
"""pipelineSanityChecks helps the CI developers to find errors before running it
These sanity checks are only executed on when converting starlark to yaml.
Error outputs are only visible when the conversion is done with the woodpecker cli.
Args:
ctx: woodpecker passes a context with information which the pipeline can be adapted to
pipelines: pipelines to be checked, normally you should run this on the return value of main()
Returns:
@@ -2438,7 +2331,7 @@ def pipelineSanityChecks(ctx, pipelines):
for pipeline in pipelines:
pipeline_name = pipeline["name"]
if len(pipeline_name) > max_name_length:
print("Error: pipeline name %s is longer than 50 characters" % (pipeline_name))
print("Error: pipeline name %s is longer than 50 characters" % pipeline_name)
for step in pipeline["steps"]:
step_name = step["name"]
@@ -2489,7 +2382,7 @@ def pipelineSanityChecks(ctx, pipelines):
def litmus(ctx, storage):
pipelines = []
if (config["litmus"] == False):
if not config["litmus"]:
return pipelines
environment = {
@@ -2574,10 +2467,7 @@ def litmus(ctx, storage):
"services": redisForOCStorage(storage),
"depends_on": getPipelineNames(buildOpencloudBinaryForTesting(ctx)),
"when": [
{
"event": ["push", "manual"],
"branch": "main",
},
event["base"],
{
"event": "pull_request",
"path": {

View File

@@ -1,16 +0,0 @@
---
when:
- event: ["push", "manual"]
branch: main
steps:
- name: devdocs
image: codeberg.org/xfix/plugin-codeberg-pages-deploy:1
settings:
folder: docs
branch: docs
git_config_email: ${CI_COMMIT_AUTHOR_EMAIL}
git_config_name: ${CI_COMMIT_AUTHOR}
ssh_key:
from_secret: ssh_key

View File

@@ -1,5 +1,46 @@
# Changelog
## [2.1.0](https://github.com/opencloud-eu/opencloud/releases/tag/v2.1.0) - 2025-04-07
### ❤️ Thanks to all contributors! ❤️
@AlexAndBear, @JammingBen, @ScharfViktor, @aduffeck, @butonic, @fschade, @individual-it, @kulmann, @micbar, @michaelstingl, @rhafer
### 🐛 Bug Fixes
- feat(antivirus): add partial scanning mode [[#559](https://github.com/opencloud-eu/opencloud/pull/559)]
- Simplify item-trashed SSEs. Also fixes it for coll. posix fs. [[#565](https://github.com/opencloud-eu/opencloud/pull/565)]
- fix(opencloud_full): add missing SMTP env vars [[#563](https://github.com/opencloud-eu/opencloud/pull/563)]
- fix: full deployment tika description is wrong [[#553](https://github.com/opencloud-eu/opencloud/pull/553)]
- fix: traefik credentials [[#555](https://github.com/opencloud-eu/opencloud/pull/555)]
- Enable scan/watch in the storageprovider only [[#546](https://github.com/opencloud-eu/opencloud/pull/546)]
- fix: typo in dev docs [[#540](https://github.com/opencloud-eu/opencloud/pull/540)]
### 📈 Enhancement
- [full-ci] reva bump 2.31.0 [[#599](https://github.com/opencloud-eu/opencloud/pull/599)]
- feat: support svg as icon [[#538](https://github.com/opencloud-eu/opencloud/pull/538)]
- feat: change theme.json primary color [[#536](https://github.com/opencloud-eu/opencloud/pull/536)]
- graph: reduce memory allocations [[#494](https://github.com/opencloud-eu/opencloud/pull/494)]
### ✅ Tests
- [full-ci] fix expected spanish string in test [[#596](https://github.com/opencloud-eu/opencloud/pull/596)]
- Revert "Disable the 'exclude' patterns on the path conditional for now" [[#561](https://github.com/opencloud-eu/opencloud/pull/561)]
### 📦️ Dependencies
- build(deps): bump github.com/go-playground/validator/v10 from 10.25.0 to 10.26.0 [[#571](https://github.com/opencloud-eu/opencloud/pull/571)]
- build(deps): bump github.com/nats-io/nats.go from 1.39.1 to 1.41.0 [[#567](https://github.com/opencloud-eu/opencloud/pull/567)]
- [full-ci] chore(web): bump web to v2.2.0 [[#570](https://github.com/opencloud-eu/opencloud/pull/570)]
- build(deps): bump github.com/onsi/gomega from 1.36.3 to 1.37.0 [[#566](https://github.com/opencloud-eu/opencloud/pull/566)]
- build(deps): bump golang.org/x/net from 0.37.0 to 0.38.0 [[#557](https://github.com/opencloud-eu/opencloud/pull/557)]
- build(deps-dev): bump eslint-plugin-jsx-a11y from 6.9.0 to 6.10.2 in /services/idp [[#542](https://github.com/opencloud-eu/opencloud/pull/542)]
- build(deps): bump web-vitals from 3.5.2 to 4.2.4 in /services/idp [[#541](https://github.com/opencloud-eu/opencloud/pull/541)]
- build(deps): bump github.com/open-policy-agent/opa from 1.2.0 to 1.3.0 [[#508](https://github.com/opencloud-eu/opencloud/pull/508)]
- build(deps): bump github.com/urfave/cli/v2 from 2.27.5 to 2.27.6 [[#509](https://github.com/opencloud-eu/opencloud/pull/509)]
- fix keycloak example #465 [[#535](https://github.com/opencloud-eu/opencloud/pull/535)]
## [2.0.0](https://github.com/opencloud-eu/opencloud/releases/tag/v2.0.0) - 2025-03-26
### ❤️ Thanks to all contributors! ❤️

View File

@@ -26,14 +26,26 @@ This script should **NOT** be run as user root.
Set the environment variable `OC_VERSION` to the version you want
to download. If not set, there is a reasonable default.
## Data Location
Set the environment variable `OC_BASE_DIR` to a directory where the
`data` and `config` subdirectories shall be located. Per default,
both configuration and storage data are within a sandbox subdirectory
in the current working directory.
## Server Address
Set the environment variable `OC_HOST` to the fully qualified hostname
of this server to allow remote accesse. Default: `localhost`.
# Example
Call
```
OC_VERSION="1.0.0" ./install.sh
OC_VERSION="2.0.0" ./install.sh
```
to install the OpenCloud version 1.0.0
to install the OpenCloud version 2.0.0
There is also a hosted version of this script that makes it even
easier:

View File

@@ -37,7 +37,7 @@ function backup_file () {
# URL pattern of the download file
# https://github.com/opencloud-eu/opencloud/releases/download/v1.0.0/opencloud-1.0.0-linux-amd64
dlversion="${OC_VERSION:-1.1.0}"
dlversion="${OC_VERSION:-2.0.0}"
dlurl="https://github.com/opencloud-eu/opencloud/releases/download/v${dlversion}/"
sandbox="opencloud-sandbox-${dlversion}"
@@ -69,14 +69,14 @@ echo "Downloading ${dlurl}/${dlfile}"
curl -L -o "${dlfile}" --progress-bar "${dlurl}/${dlfile}"
chmod 755 ${dlfile}
mkdir data config
export OC_CONFIG_DIR="$(pwd)/config"
export OC_BASE_DATA_PATH="$(pwd)/data"
basedir="${OC_BASE_DIR:-$(pwd)}"
export OC_CONFIG_DIR="$basedir/config"
export OC_BASE_DATA_PATH="$basedir/data"
mkdir -p "$OC_CONFIG_DIR" "$OC_BASE_DATA_PATH"
# It is bound to localhost for now to deal with non existing routes
# to certain host names for example in WSL
host="localhost"
host="${OC_HOST:-localhost}"
./${dlfile} init --insecure yes --ap admin

View File

@@ -17,7 +17,9 @@ TRAEFIK_DASHBOARD=
# Defaults to "traefik.opencloud.test"
TRAEFIK_DOMAIN=
# Basic authentication for the traefik dashboard.
# Defaults to user "admin" and password "admin" (written as: "admin:admin").
# Defaults to user "admin" and password "admin" (written as: "admin:$2y$05$KDHu3xq92SPaO3G8Ybkc7edd51pPLJcG1nWk3lmlrIdANQ/B6r5pq").
# To create user:password pair, it's possible to use this command:
# echo $(htpasswd -nB user) | sed -e s/\\$/\\$\\$/g
TRAEFIK_BASIC_AUTH_USERS=
# Email address for obtaining LetsEncrypt certificates.
# Needs only be changed if this is a public facing server.
@@ -62,6 +64,8 @@ LOG_LEVEL=
# LOG_PRETTY=true
#
# Define the openCloud storage location. Set the paths for config and data to a local path.
# Ensure that the configuration and data directories are owned by the user and group with ID 1000:1000.
# This matches the default user inside the container and avoids permission issues when accessing files.
# Note that especially the data directory can grow big.
# Leaving it default stores data in docker internal volumes.
# OC_CONFIG_DIR=/your/local/opencloud/config
@@ -98,8 +102,8 @@ MINIO_DOMAIN=
# Note: the leading colon is required to enable the service.
#DECOMPOSED=:decomposed.yml
# Define SMPT settings if you would like to send OpenCloud email notifications.
#
# Define SMTP settings if you would like to send OpenCloud email notifications.
#
# NOTE: when configuring Inbucket, these settings have no effect, see inbucket.yml for details.
# SMTP host to connect to.
SMTP_HOST=
@@ -114,6 +118,8 @@ SMTP_USERNAME=
SMTP_PASSWORD=
# Authentication method for the SMTP communication.
SMTP_AUTHENTICATION=
# Encryption method for the SMTP communication. Possible values are 'starttls', 'ssltls' and 'none'
SMTP_TRANSPORT_ENCRYPTION=
# Allow insecure connections to the SMTP server. Defaults to false.
SMTP_INSECURE=
@@ -157,7 +163,7 @@ COMPANION_ONEDRIVE_SECRET=
## Default Enabled Services ##
### Apache Tika Content Analysis Toolkit ###
# Tika (search) is enabled by default, comment if not required.
# Tika (search) is disabled by default due to performance reasons.
# Note: the leading colon is required to enable the service.
#TIKA=:tika.yml
# Set the desired docker image tag or digest.
@@ -210,6 +216,13 @@ COLLABORA_SSL_VERIFICATION=false
# envvar in the OpenCloud Settings above by adding 'antivirus' to the list.
# Note: the leading colon is required to enable the service.
#CLAMAV=:clamav.yml
# The maximum scan size the virus scanner can handle, needs adjustment in the scanner config as well.
# Usable common abbreviations: [KB, KiB, MB, MiB, GB, GiB, TB, TiB, PB, PiB, EB, EiB], example: 2GB.
# Defaults to "100MB"
#ANTIVIRUS_MAX_SCAN_SIZE=
# Usable modes: partial, skip.
# Defaults to "partial"
#ANTIVIRUS_MAX_SCAN_SIZE_MODE=
# Image version of the ClamAV container.
# Defaults to "latest"
CLAMAV_DOCKER_TAG=
@@ -237,8 +250,31 @@ INBUCKET_DOMAIN=
# Path separator for supplemental compose files specified in COMPOSE_FILE.
COMPOSE_PATH_SEPARATOR=:
### Keycloak Settings ###
# Note: the leading colon is required to enable the service.
#KEYCLOAK=:keycloak.yml
# Domain for Keycloak. Defaults to "keycloak.opencloud.test".
KEYCLOAK_DOMAIN=
# Realm which to be used with OpenCloud. Defaults to "OpenCloud"
KEYCLOAK_REALM=
# Admin user login name. Defaults to "admin"
KEYCLOAK_ADMIN_USER=
# Admin user login password. Defaults to "admin"
KEYCLOAK_ADMIN_PASSWORD=
### Ldap Settings ###
# Note: the leading colon is required to enable the service.
#LDAP=:ldap.yml
# Password of LDAP user "cn=admin,dc=opencloud,dc=eu". Defaults to "admin"
LDAP_ADMIN_PASSWORD=
# LDAP manager
# login with uid ldapadmin and password
#LDAP_MANAGER=:../shared/config/ldap/docker-compose.yml
# LDAP manager domain. Defaults to "ldap.opencloud.test"
LDAP_MANAGER_DOMAIN=
## IMPORTANT ##
# This MUST be the last line as it assembles the supplemental compose files to be used.
# ALL supplemental configs must be added here, whether commented or not.
# Each var must either be empty or contain :path/file.yml
COMPOSE_FILE=docker-compose.yml${OPENCLOUD:-}${TIKA:-}${DECOMPOSEDS3:-}${DECOMPOSEDS3_MINIO:-}${DECOMPOSED:-}${COLLABORA:-}${MONITORING:-}${IMPORTER:-}${CLAMAV:-}${ONLYOFFICE:-}${INBUCKET:-}${EXTENSIONS:-}${UNZIP:-}${DRAWIO:-}${JSONVIEWER:-}${PROGRESSBARS:-}${EXTERNALSITES:-}
COMPOSE_FILE=docker-compose.yml${OPENCLOUD:-}${TIKA:-}${DECOMPOSEDS3:-}${DECOMPOSEDS3_MINIO:-}${DECOMPOSED:-}${COLLABORA:-}${MONITORING:-}${IMPORTER:-}${CLAMAV:-}${ONLYOFFICE:-}${INBUCKET:-}${EXTENSIONS:-}${UNZIP:-}${DRAWIO:-}${JSONVIEWER:-}${PROGRESSBARS:-}${EXTERNALSITES:-}${KEYCLOAK:-}${LDAP:-}${LDAP_MANAGER:-}

View File

@@ -4,6 +4,8 @@ services:
environment:
ANTIVIRUS_SCANNER_TYPE: "clamav"
ANTIVIRUS_CLAMAV_SOCKET: "/var/run/clamav/clamd.sock"
ANTIVIRUS_MAX_SCAN_SIZE_MODE: ${ANTIVIRUS_MAX_SCAN_SIZE_MODE:-partial}
ANTIVIRUS_MAX_SCAN_SIZE: ${ANTIVIRUS_MAX_SCAN_SIZE:-100MB}
# the antivirus service needs manual startup, see .env and opencloud.yaml for START_ADDITIONAL_SERVICES
# configure the antivirus service
POSTPROCESSING_STEPS: "virusscan"

View File

@@ -0,0 +1,63 @@
{
"clientId": "OpenCloudAndroid",
"name": "OpenCloud Android App",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [
"oc://android.opencloud.eu"
],
"webOrigins": [],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": true,
"serviceAccountsEnabled": false,
"publicClient": true,
"frontchannelLogout": false,
"protocol": "openid-connect",
"attributes": {
"saml.assertion.signature": "false",
"saml.force.post.binding": "false",
"saml.multivalued.roles": "false",
"saml.encrypt": "false",
"post.logout.redirect.uris": "oc://android.opencloud.eu",
"backchannel.logout.revoke.offline.tokens": "false",
"saml.server.signature": "false",
"saml.server.signature.keyinfo.ext": "false",
"exclude.session.state.from.auth.response": "false",
"backchannel.logout.session.required": "true",
"client_credentials.use_refresh_token": "false",
"saml_force_name_id_format": "false",
"saml.client.signature": "false",
"tls.client.certificate.bound.access.tokens": "false",
"saml.authnstatement": "false",
"display.on.consent.screen": "false",
"saml.onetimeuse.condition": "false"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": [
"web-origins",
"profile",
"roles",
"groups",
"basic",
"email"
],
"optionalClientScopes": [
"address",
"phone",
"offline_access",
"microprofile-jwt"
],
"access": {
"view": true,
"configure": true,
"manage": true
}
}

View File

@@ -0,0 +1,64 @@
{
"clientId": "OpenCloudDesktop",
"name": "OpenCloud Desktop Client",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [
"http://127.0.0.1",
"http://localhost"
],
"webOrigins": [],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": true,
"serviceAccountsEnabled": false,
"publicClient": true,
"frontchannelLogout": false,
"protocol": "openid-connect",
"attributes": {
"saml.assertion.signature": "false",
"saml.force.post.binding": "false",
"saml.multivalued.roles": "false",
"saml.encrypt": "false",
"post.logout.redirect.uris": "+",
"backchannel.logout.revoke.offline.tokens": "false",
"saml.server.signature": "false",
"saml.server.signature.keyinfo.ext": "false",
"exclude.session.state.from.auth.response": "false",
"backchannel.logout.session.required": "true",
"client_credentials.use_refresh_token": "false",
"saml_force_name_id_format": "false",
"saml.client.signature": "false",
"tls.client.certificate.bound.access.tokens": "false",
"saml.authnstatement": "false",
"display.on.consent.screen": "false",
"saml.onetimeuse.condition": "false"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": [
"web-origins",
"profile",
"roles",
"groups",
"basic",
"email"
],
"optionalClientScopes": [
"address",
"phone",
"offline_access",
"microprofile-jwt"
],
"access": {
"view": true,
"configure": true,
"manage": true
}
}

View File

@@ -0,0 +1,63 @@
{
"clientId": "OpenCloudIOS",
"name": "OpenCloud iOS App",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [
"oc://ios.opencloud.eu"
],
"webOrigins": [],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": true,
"serviceAccountsEnabled": false,
"publicClient": true,
"frontchannelLogout": false,
"protocol": "openid-connect",
"attributes": {
"saml.assertion.signature": "false",
"saml.force.post.binding": "false",
"saml.multivalued.roles": "false",
"saml.encrypt": "false",
"post.logout.redirect.uris": "oc://ios.opencloud.eu",
"backchannel.logout.revoke.offline.tokens": "false",
"saml.server.signature": "false",
"saml.server.signature.keyinfo.ext": "false",
"exclude.session.state.from.auth.response": "false",
"backchannel.logout.session.required": "true",
"client_credentials.use_refresh_token": "false",
"saml_force_name_id_format": "false",
"saml.client.signature": "false",
"tls.client.certificate.bound.access.tokens": "false",
"saml.authnstatement": "false",
"display.on.consent.screen": "false",
"saml.onetimeuse.condition": "false"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": [
"web-origins",
"profile",
"roles",
"groups",
"basic",
"email"
],
"optionalClientScopes": [
"address",
"phone",
"offline_access",
"microprofile-jwt"
],
"access": {
"view": true,
"configure": true,
"manage": true
}
}

View File

@@ -0,0 +1,66 @@
{
"clientId": "Cyberduck",
"name": "Cyberduck",
"description": "File transfer utility client",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [
"x-cyberduck-action:oauth",
"x-mountainduck-action:oauth"
],
"webOrigins": [],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": true,
"serviceAccountsEnabled": false,
"publicClient": true,
"frontchannelLogout": false,
"protocol": "openid-connect",
"attributes": {
"saml.assertion.signature": "false",
"saml.force.post.binding": "false",
"saml.multivalued.roles": "false",
"saml.encrypt": "false",
"oauth2.device.authorization.grant.enabled": "false",
"backchannel.logout.revoke.offline.tokens": "false",
"saml.server.signature": "false",
"saml.server.signature.keyinfo.ext": "false",
"exclude.session.state.from.auth.response": "false",
"oidc.ciba.grant.enabled": "false",
"backchannel.logout.session.required": "true",
"client_credentials.use_refresh_token": "false",
"saml_force_name_id_format": "false",
"saml.client.signature": "false",
"tls.client.certificate.bound.access.tokens": "false",
"saml.authnstatement": "false",
"display.on.consent.screen": "false",
"saml.onetimeuse.condition": "false"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": [
"web-origins",
"profile",
"roles",
"groups",
"basic",
"email"
],
"optionalClientScopes": [
"address",
"phone",
"offline_access",
"microprofile-jwt"
],
"access": {
"view": true,
"configure": true,
"manage": true
}
}

View File

@@ -0,0 +1,74 @@
{
"clientId": "web",
"name": "OpenCloud Web App",
"description": "",
"rootUrl": "{{OC_URL}}",
"adminUrl": "{{OC_URL}}",
"baseUrl": "",
"surrogateAuthRequired": false,
"enabled": true,
"alwaysDisplayInConsole": false,
"clientAuthenticatorType": "client-secret",
"redirectUris": [
"{{OC_URL}}/",
"{{OC_URL}}/oidc-callback.html",
"{{OC_URL}}/oidc-silent-redirect.html"
],
"webOrigins": [
"{{OC_URL}}"
],
"notBefore": 0,
"bearerOnly": false,
"consentRequired": false,
"standardFlowEnabled": true,
"implicitFlowEnabled": false,
"directAccessGrantsEnabled": true,
"serviceAccountsEnabled": false,
"publicClient": true,
"frontchannelLogout": false,
"protocol": "openid-connect",
"attributes": {
"saml.assertion.signature": "false",
"saml.force.post.binding": "false",
"saml.multivalued.roles": "false",
"saml.encrypt": "false",
"post.logout.redirect.uris": "+",
"oauth2.device.authorization.grant.enabled": "false",
"backchannel.logout.revoke.offline.tokens": "false",
"saml.server.signature": "false",
"saml.server.signature.keyinfo.ext": "false",
"exclude.session.state.from.auth.response": "false",
"oidc.ciba.grant.enabled": "false",
"backchannel.logout.url": "{{OC_URL}}/backchannel_logout",
"backchannel.logout.session.required": "true",
"client_credentials.use_refresh_token": "false",
"saml_force_name_id_format": "false",
"saml.client.signature": "false",
"tls.client.certificate.bound.access.tokens": "false",
"saml.authnstatement": "false",
"display.on.consent.screen": "false",
"saml.onetimeuse.condition": "false"
},
"authenticationFlowBindingOverrides": {},
"fullScopeAllowed": true,
"nodeReRegistrationTimeout": -1,
"defaultClientScopes": [
"web-origins",
"profile",
"roles",
"groups",
"basic",
"email"
],
"optionalClientScopes": [
"address",
"phone",
"offline_access",
"microprofile-jwt"
],
"access": {
"view": true,
"configure": true,
"manage": true
}
}

View File

@@ -0,0 +1,8 @@
#!/bin/bash
printenv
# replace openCloud domain in keycloak realm import
mkdir /opt/keycloak/data/import
sed -e "s/cloud.opencloud.test/${OC_DOMAIN}/g" /opt/keycloak/data/import-dist/opencloud-realm.json > /opt/keycloak/data/import/opencloud-realm.json
# run original docker-entrypoint
/opt/keycloak/bin/kc.sh "$@"

View File

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,9 @@
#!/bin/bash
printenv
if [ ! -f /opt/bitnami/openldap/share/openldap.key ]
then
openssl req -x509 -newkey rsa:4096 -keyout /opt/bitnami/openldap/share/openldap.key -out /opt/bitnami/openldap/share/openldap.crt -sha256 -days 365 -batch -nodes
fi
# run original docker-entrypoint
/opt/bitnami/scripts/openldap/entrypoint.sh "$@"

View File

@@ -0,0 +1,20 @@
dn: dc=opencloud,dc=eu
objectClass: organization
objectClass: dcObject
dc: opencloud
o: openCloud
dn: ou=users,dc=opencloud,dc=eu
objectClass: organizationalUnit
ou: users
dn: cn=admin,dc=opencloud,dc=eu
objectClass: inetOrgPerson
objectClass: person
cn: admin
sn: admin
uid: ldapadmin
dn: ou=groups,dc=opencloud,dc=eu
objectClass: organizationalUnit
ou: groups

View File

@@ -0,0 +1,125 @@
# Start dn with uid (user identifier / login), not cn (Firstname + Surname)
dn: uid=alan,ou=users,dc=opencloud,dc=eu
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: openCloudUser
objectClass: person
objectClass: posixAccount
objectClass: top
uid: alan
givenName: Alan
sn: Turing
cn: alan
displayName: Alan Turing
description: An English mathematician, computer scientist, logician, cryptanalyst, philosopher and theoretical biologist. He was highly influential in the development of theoretical computer science, providing a formalisation of the concepts of algorithm and computation with the Turing machine.
mail: alan@example.org
uidNumber: 20000
gidNumber: 30000
homeDirectory: /home/alan
openCloudUUID: b1f74ec4-dd7e-11ef-a543-03775734d0f7
userPassword:: e1NTSEF9Y2ZMdVlqMTBDUFpLWE44VC9mQ0FzYnFHQmtyZExJeGg=
dn: uid=lynn,ou=users,dc=opencloud,dc=eu
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: openCloudUser
objectClass: person
objectClass: posixAccount
objectClass: top
uid: lynn
givenName: Lynn
sn: Conway
cn: lynn
displayName: Lynn Conway
description: An American computer scientist, electrical engineer, and transgender activist.
mail: lynn@example.org
uidNumber: 20001
gidNumber: 30000
homeDirectory: /home/lynn
openCloudUserEnabled: TRUE
openCloudUUID: 60708dda-e897-11ef-919f-bbb7437d6ec2
userPassword:: e1NTSEF9Y2ZMdVlqMTBDUFpLWE44VC9mQ0FzYnFHQmtyZExJeGg=
dn: uid=mary,ou=users,dc=opencloud,dc=eu
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: openCloudUser
objectClass: person
objectClass: posixAccount
objectClass: top
uid: mary
givenName: Mary
sn: Kenneth Keller
cn: mary
displayName: Mary Kenneth Keller
description: Mary Kenneth Keller of the Sisters of Charity of the Blessed Virgin Mary was a pioneer in computer science.
mail: mary@example.org
uidNumber: 20002
gidNumber: 30000
homeDirectory: /home/mary
openCloudUserEnabled: TRUE
openCloudUUID: 056fc874-dd7f-11ef-ba84-af6fca4b7289
userPassword:: e1NTSEF9Y2ZMdVlqMTBDUFpLWE44VC9mQ0FzYnFHQmtyZExJeGg=
dn: uid=margaret,ou=users,dc=opencloud,dc=eu
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: openCloudUser
objectClass: person
objectClass: posixAccount
objectClass: top
uid: margaret
givenName: Margaret
sn: Hamilton
cn: margaret
displayName: Margaret Hamilton
description: A director of the Software Engineering Division of the MIT Instrumentation Laboratory, which developed on-board flight software for NASA's Apollo program.
mail: margaret@example.org
uidNumber: 20003
gidNumber: 30000
homeDirectory: /home/margaret
openCloudUserEnabled: TRUE
openCloudUUID: 801abee4-dd7f-11ef-a324-83f55a754b62
userPassword:: e1NTSEF9Y2ZMdVlqMTBDUFpLWE44VC9mQ0FzYnFHQmtyZExJeGg=
dn: uid=dennis,ou=users,dc=opencloud,dc=eu
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: openCloudUser
objectClass: person
objectClass: posixAccount
objectClass: top
uid: dennis
givenName: Dennis
sn: Ritchie
cn: dennis
displayName: Dennis Ritchie
description: American computer scientist. He created the C programming language and the Unix operating system and B language with long-time colleague Ken Thompson.
mail: dennis@example.org
uidNumber: 20004
gidNumber: 30000
homeDirectory: /home/dennis
openCloudUserEnabled: TRUE
openCloudUUID: cd88bf9a-dd7f-11ef-a609-7f78deb2345f
userPassword:: e1NTSEF9Y2ZMdVlqMTBDUFpLWE44VC9mQ0FzYnFHQmtyZExJeGg=
dn: uid=admin,ou=users,dc=opencloud,dc=eu
objectClass: inetOrgPerson
objectClass: organizationalPerson
objectClass: openCloudUser
objectClass: person
objectClass: posixAccount
objectClass: top
uid: admin
givenName: Admin
sn: Admin
cn: admin
displayName: Admin
description: An admin for this OpenCloud instance.
mail: admin@example.org
uidNumber: 20005
gidNumber: 30000
homeDirectory: /home/admin
openCloudUserEnabled: TRUE
openCloudUUID: f7fc96f6-ceb4-4387-bd69-07a6d7992973
userPassword:: e1NTSEF9UWhmaFB3dERydTUydURoWFFObDRMbzVIckI3TkI5Nmo==

View File

@@ -0,0 +1,88 @@
dn: cn=users,ou=groups,dc=opencloud,dc=eu
objectClass: groupOfNames
objectClass: openCloudObject
objectClass: top
cn: users
description: Users
openCloudUUID: 509a9dcd-bb37-4f4f-a01a-19dca27d9cfa
member: uid=alan,ou=users,dc=opencloud,dc=eu
member: uid=mary,ou=users,dc=opencloud,dc=eu
member: uid=margaret,ou=users,dc=opencloud,dc=eu
member: uid=dennis,ou=users,dc=opencloud,dc=eu
member: uid=lynn,ou=users,dc=opencloud,dc=eu
member: uid=admin,ou=users,dc=opencloud,dc=eu
dn: cn=chess-lovers,ou=groups,dc=opencloud,dc=eu
objectClass: groupOfNames
objectClass: openCloudObject
objectClass: top
cn: chess-lovers
description: Chess lovers
openCloudUUID: 9d31ec04-dd80-11ef-ac47-a38ba68cc36d
member: uid=alan,ou=users,dc=opencloud,dc=eu
dn: cn=machine-lovers,ou=groups,dc=opencloud,dc=eu
objectClass: groupOfNames
objectClass: openCloudObject
objectClass: top
cn: machine-lovers
description: Machine Lovers
openCloudUUID: d901562a-dd80-11ef-a510-fba1ed43fb21
member: uid=alan,ou=users,dc=opencloud,dc=eu
dn: cn=bible-readers,ou=groups,dc=opencloud,dc=eu
objectClass: groupOfNames
objectClass: openCloudObject
objectClass: top
cn: bible-readers
description: Bible readers
openCloudUUID: 2fc6ba22-dd81-11ef-89e6-e3eff494a998
member: uid=mary,ou=users,dc=opencloud,dc=eu
dn: cn=apollos,ou=groups,dc=opencloud,dc=eu
objectClass: groupOfNames
objectClass: openCloudObject
objectClass: top
cn: apollos
description: Contributors to the Appollo mission
openCloudUUID: 6f9bab36-dd94-11ef-a252-dbbdd20299dd
member: uid=margaret,ou=users,dc=opencloud,dc=eu
dn: cn=unix-lovers,ou=groups,dc=opencloud,dc=eu
objectClass: groupOfNames
objectClass: openCloudObject
objectClass: top
cn: unix-lovers
description: Unix lovers
openCloudUUID: 75bc3882-dd94-11ef-ad60-335f3df6cef3
member: uid=dennis,ou=users,dc=opencloud,dc=eu
dn: cn=basic-haters,ou=groups,dc=opencloud,dc=eu
objectClass: groupOfNames
objectClass: openCloudObject
objectClass: top
cn: basic-haters
description: Haters of the Basic programming language
openCloudUUID: a4eb2c12-dd94-11ef-9ebe-eb96f938d517
member: uid=dennis,ou=users,dc=opencloud,dc=eu
dn: cn=vlsi-lovers,ou=groups,dc=opencloud,dc=eu
objectClass: groupOfNames
objectClass: openCloudObject
objectClass: top
cn: vlsi-lovers
description: Lovers of VLSI microchip design
openCloudUUID: 914ce3de-e899-11ef-9a4b-732fbb2acc42
member: uid=lynn,ou=users,dc=opencloud,dc=eu
dn: cn=programmers,ou=groups,dc=opencloud,dc=eu
objectClass: groupOfNames
objectClass: openCloudObject
objectClass: top
cn: programmers
description: Computer Programmers
openCloudUUID: ce4aa240-dd94-11ef-82b8-4f4828849072
member: uid=alan,ou=users,dc=opencloud,dc=eu
member: uid=margaret,ou=users,dc=opencloud,dc=eu
member: uid=dennis,ou=users,dc=opencloud,dc=eu
member: uid=lynn,ou=users,dc=opencloud,dc=eu

View File

@@ -7,6 +7,7 @@ directives:
- 'https://${COMPANION_DOMAIN|companion.opencloud.test}/'
- 'wss://${COMPANION_DOMAIN|companion.opencloud.test}/'
- 'https://raw.githubusercontent.com/opencloud-eu/awesome-apps/'
- 'https://${KEYCLOAK_DOMAIN|keycloak.opencloud.test}/'
default-src:
- '''none'''
font-src:

View File

@@ -0,0 +1,77 @@
---
services:
traefik:
networks:
opencloud-net:
aliases:
- ${KEYCLOAK_DOMAIN:-keycloak.opencloud.test}
opencloud:
environment:
# Keycloak IDP specific configuration
PROXY_AUTOPROVISION_ACCOUNTS: "true"
PROXY_ROLE_ASSIGNMENT_DRIVER: "oidc"
OC_OIDC_ISSUER: https://${KEYCLOAK_DOMAIN:-keycloak.opencloud.test}/realms/${KEYCLOAK_REALM:-openCloud}
PROXY_OIDC_REWRITE_WELLKNOWN: "true"
WEB_OIDC_CLIENT_ID: ${OC_OIDC_CLIENT_ID:-web}
PROXY_USER_OIDC_CLAIM: "preferred_username"
PROXY_USER_CS3_CLAIM: "username"
OC_EXCLUDE_RUN_SERVICES: "idp"
# admin and demo accounts must be created in Keycloak
OC_ADMIN_USER_ID: ""
SETTINGS_SETUP_DEFAULT_ASSIGNMENTS: "false"
GRAPH_ASSIGN_DEFAULT_USER_ROLE: "false"
GRAPH_USERNAME_MATCH: "none"
KEYCLOAK_DOMAIN: ${KEYCLOAK_DOMAIN:-keycloak.opencloud.test}
postgres:
image: postgres:alpine
networks:
opencloud-net:
volumes:
- keycloak_postgres_data:/var/lib/postgresql/data
environment:
POSTGRES_DB: keycloak
POSTGRES_USER: keycloak
POSTGRES_PASSWORD: keycloak
logging:
driver: ${LOG_DRIVER:-local}
restart: always
keycloak:
image: quay.io/keycloak/keycloak:25.0.0
networks:
opencloud-net:
command: ["start", "--proxy=edge", "--spi-connections-http-client-default-disable-trust-manager=${INSECURE:-false}", "--import-realm"]
entrypoint: ["/bin/sh", "/opt/keycloak/bin/docker-entrypoint-override.sh"]
volumes:
- "./config/keycloak/docker-entrypoint-override.sh:/opt/keycloak/bin/docker-entrypoint-override.sh"
- "./config/keycloak/opencloud-realm.dist.json:/opt/keycloak/data/import-dist/opencloud-realm.json"
environment:
OC_DOMAIN: ${OC_DOMAIN:-cloud.opencloud.test}
KC_HOSTNAME: ${KEYCLOAK_DOMAIN:-keycloak.opencloud.test}
KC_DB: postgres
KC_DB_URL: "jdbc:postgresql://postgres:5432/keycloak"
KC_DB_USERNAME: keycloak
KC_DB_PASSWORD: keycloak
KC_FEATURES: impersonation
KEYCLOAK_ADMIN: ${KEYCLOAK_ADMIN_USER:-admin}
KEYCLOAK_ADMIN_PASSWORD: ${KEYCLOAK_ADMIN_PASSWORD:-admin}
labels:
- "traefik.enable=true"
- "traefik.http.routers.keycloak.entrypoints=https"
- "traefik.http.routers.keycloak.rule=Host(`${KEYCLOAK_DOMAIN:-keycloak.opencloud.test}`)"
- "traefik.http.routers.keycloak.tls.certresolver=http"
- "traefik.http.routers.keycloak.service=keycloak"
- "traefik.http.services.keycloak.loadbalancer.server.port=8080"
depends_on:
- postgres
logging:
driver: ${LOG_DRIVER:-local}
restart: always
volumes:
keycloak_postgres_data:

View File

@@ -0,0 +1,62 @@
---
services:
traefik:
networks:
opencloud-net:
opencloud:
environment:
# Ldap IDP specific configuration
OC_LDAP_URI: ldaps://ldap-server:1636
OC_LDAP_INSECURE: "true"
OC_LDAP_BIND_DN: "cn=admin,dc=opencloud,dc=eu"
OC_LDAP_BIND_PASSWORD: ${LDAP_ADMIN_PASSWORD:-admin}
OC_LDAP_GROUP_BASE_DN: "ou=groups,dc=opencloud,dc=eu"
OC_LDAP_GROUP_FILTER: "(objectclass=opencloudobject)"
OC_LDAP_GROUP_OBJECTCLASS: "groupOfNames"
OC_LDAP_USER_BASE_DN: "ou=users,dc=opencloud,dc=eu"
OC_LDAP_USER_FILTER: "(objectclass=openclouduser)"
OC_LDAP_USER_OBJECTCLASS: "inetOrgPerson"
LDAP_LOGIN_ATTRIBUTES: "uid"
OC_ADMIN_USER_ID: "f7fc96f6-ceb4-4387-bd69-07a6d7992973"
IDP_LDAP_LOGIN_ATTRIBUTE: "uid"
IDP_LDAP_UUID_ATTRIBUTE: "openclouduuid"
IDP_LDAP_UUID_ATTRIBUTE_TYPE: binary
GRAPH_LDAP_SERVER_WRITE_ENABLED: "true" # assuming the external ldap is writable
GRAPH_LDAP_REFINT_ENABLED: "true" # osixia has refint enabled.
# OC_RUN_SERVICES specifies to start all services except glauth, idm and accounts. These are replaced by external services
OC_EXCLUDE_RUN_SERVICES: idm
ldap-server:
image: bitnami/openldap:2.6
networks:
opencloud-net:
entrypoint: ["/bin/sh", "/opt/bitnami/scripts/openldap/docker-entrypoint-override.sh", "/opt/bitnami/scripts/openldap/run.sh" ]
environment:
BITNAMI_DEBUG: true
LDAP_TLS_VERIFY_CLIENT: never
LDAP_ENABLE_TLS: "yes"
LDAP_TLS_CA_FILE: /opt/bitnami/openldap/share/openldap.crt
LDAP_TLS_CERT_FILE: /opt/bitnami/openldap/share/openldap.crt
LDAP_TLS_KEY_FILE: /opt/bitnami/openldap/share/openldap.key
LDAP_ROOT: "dc=opencloud,dc=eu"
LDAP_ADMIN_PASSWORD: ${LDAP_ADMIN_PASSWORD:-admin}
ports:
- "127.0.0.1:389:1389"
- "127.0.0.1:636:1636"
volumes:
- ./config/ldap/ldif:/ldifs
- ../shared/config/ldap/schemas/10_opencloud_schema.ldif:/schemas/10_opencloud_schema.ldif
- ./config/ldap/docker-entrypoint-override.sh:/opt/bitnami/scripts/openldap/docker-entrypoint-override.sh
- ldap-certs:/opt/bitnami/openldap/share
- ldap-data:/bitnami/openldap
logging:
driver: ${LOG_DRIVER:-local}
restart: always
volumes:
ldap-certs:
ldap-data:
networks:
opencloud-net:

View File

@@ -41,7 +41,11 @@ services:
NOTIFICATIONS_SMTP_PORT: "${SMTP_PORT}"
NOTIFICATIONS_SMTP_SENDER: "${SMTP_SENDER:-OpenCloud notifications <notifications@${OC_DOMAIN:-cloud.opencloud.test}>}"
NOTIFICATIONS_SMTP_USERNAME: "${SMTP_USERNAME}"
NOTIFICATIONS_SMTP_PASSWORD: "${SMTP_PASSWORD}"
NOTIFICATIONS_SMTP_INSECURE: "${SMTP_INSECURE}"
NOTIFICATIONS_SMTP_AUTHENTICATION: "${SMTP_AUTHENTICATION}"
NOTIFICATIONS_SMTP_ENCRYPTION: "${SMTP_TRANSPORT_ENCRYPTION:-none}"
FRONTEND_ARCHIVER_MAX_SIZE: "10000000000"
# make the registry available to the app provider containers
MICRO_REGISTRY_ADDRESS: 127.0.0.1:9233
NATS_NATS_HOST: 0.0.0.0

View File

@@ -6,12 +6,10 @@ services:
condition: service_completed_successfully
unzip-init:
image: opencloudeu/web-extensions:unzip-1.0.0
image: opencloudeu/web-extensions:unzip-1.0.2
user: root
volumes:
- opencloud-apps:/apps
entrypoint:
- /bin/sh
command: ["-c", "cp -R /usr/share/nginx/html/unzip/ /apps"]

View File

@@ -0,0 +1,24 @@
---
# This file can be used to be added to the opencloud_full example
# to browse the LDAP server with a web interface.
# This is not a production ready setup.
services:
ldap-manager:
image: phpldapadmin/phpldapadmin:latest
networks:
opencloud-net:
environment:
LDAP_HOST: ldap-server
LDAP_PORT: 1389
LDAP_LOGIN_OBJECTCLASS: "inetOrgPerson"
APP_URL: "https://${LDAP_MANAGER_DOMAIN:-ldap.opencloud.test}"
labels:
- "traefik.enable=true"
- "traefik.http.routers.ldap-manager.entrypoints=https"
- "traefik.http.routers.ldap-manager.rule=Host(`${LDAP_MANAGER_DOMAIN:-ldap.opencloud.test}`)"
- "traefik.http.routers.ldap-manager.tls.certresolver=http"
- "traefik.http.routers.ldap-manager.service=ldap-manager"
- "traefik.http.services.ldap-manager.loadbalancer.server.port=8080"
logging:
driver: ${LOG_DRIVER:-local}
restart: always

View File

@@ -1,17 +0,0 @@
---
sidebar_position: 1
id: intro
title: OpenCloud Developer Docs
custom_edit_url: https://github.com/opencloud-eu/opencloud/edit/main/docs/intro.md
---
# Welcome
Welcome to the OpenCloud Developer Documentation.
Please be patient, we are working on the content.
If you want to contribute to the dev docs, please visit [OpenCloud on Github](https://github.com/opencloud-eu/).
Contents will be transferred, during the build process.

37
go.mod
View File

@@ -13,7 +13,7 @@ require (
github.com/beevik/etree v1.5.0
github.com/blevesearch/bleve/v2 v2.4.4
github.com/cenkalti/backoff v2.2.1+incompatible
github.com/coreos/go-oidc/v3 v3.13.0
github.com/coreos/go-oidc/v3 v3.14.1
github.com/cs3org/go-cs3apis v0.0.0-20241105092511-3ad35d174fc1
github.com/davidbyttow/govips/v2 v2.16.0
github.com/dhowden/tag v0.0.0-20240417053706-3d75831295e8
@@ -33,7 +33,7 @@ require (
github.com/go-micro/plugins/v4/store/nats-js-kv v0.0.0-20240726082623-6831adfdcdc4
github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus v1.2.0
github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry v1.2.0
github.com/go-playground/validator/v10 v10.25.0
github.com/go-playground/validator/v10 v10.26.0
github.com/gofrs/uuid v4.4.0+incompatible
github.com/golang-jwt/jwt/v5 v5.2.2
github.com/golang/protobuf v1.5.4
@@ -56,14 +56,14 @@ require (
github.com/mna/pigeon v1.3.0
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
github.com/nats-io/nats-server/v2 v2.11.0
github.com/nats-io/nats.go v1.39.1
github.com/nats-io/nats.go v1.41.0
github.com/oklog/run v1.1.0
github.com/olekukonko/tablewriter v0.0.5
github.com/onsi/ginkgo v1.16.5
github.com/onsi/ginkgo/v2 v2.23.3
github.com/onsi/gomega v1.36.3
github.com/open-policy-agent/opa v1.2.0
github.com/opencloud-eu/reva/v2 v2.29.1
github.com/onsi/ginkgo/v2 v2.23.4
github.com/onsi/gomega v1.37.0
github.com/open-policy-agent/opa v1.3.0
github.com/opencloud-eu/reva/v2 v2.31.0
github.com/orcaman/concurrent-map v1.0.0
github.com/owncloud/libre-graph-api-go v1.0.5-0.20240829135935-80dc00d6f5ea
github.com/pkg/errors v0.9.1
@@ -82,9 +82,9 @@ require (
github.com/test-go/testify v1.1.4
github.com/thejerf/suture/v4 v4.0.6
github.com/tidwall/gjson v1.18.0
github.com/tus/tusd/v2 v2.7.1
github.com/tus/tusd/v2 v2.8.0
github.com/unrolled/secure v1.16.0
github.com/urfave/cli/v2 v2.27.5
github.com/urfave/cli/v2 v2.27.6
github.com/xhit/go-simple-mail/v2 v2.16.0
go-micro.dev/v4 v4.11.0
go.etcd.io/bbolt v1.4.0
@@ -99,14 +99,14 @@ require (
golang.org/x/crypto v0.36.0
golang.org/x/exp v0.0.0-20250210185358-939b2ce775ac
golang.org/x/image v0.25.0
golang.org/x/net v0.37.0
golang.org/x/net v0.38.0
golang.org/x/oauth2 v0.28.0
golang.org/x/sync v0.12.0
golang.org/x/term v0.30.0
golang.org/x/text v0.23.0
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb
google.golang.org/grpc v1.71.0
google.golang.org/protobuf v1.36.5
google.golang.org/grpc v1.71.1
google.golang.org/protobuf v1.36.6
gopkg.in/yaml.v2 v2.4.0
gotest.tools/v3 v3.5.2
stash.kopano.io/kgol/rndm v1.1.2
@@ -216,7 +216,7 @@ require (
github.com/gomodule/redigo v1.9.2 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/go-tpm v0.9.3 // indirect
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 // indirect
github.com/google/renameio/v2 v2.0.0 // indirect
github.com/gookit/color v1.5.4 // indirect
github.com/gookit/goutil v0.6.15 // indirect
@@ -237,7 +237,7 @@ require (
github.com/juliangruber/go-intersect v1.1.0 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/klauspost/cpuid/v2 v2.2.9 // indirect
github.com/klauspost/cpuid/v2 v2.2.10 // indirect
github.com/leodido/go-urn v1.4.0 // indirect
github.com/libregraph/oidc-go v1.1.0 // indirect
github.com/longsleep/go-metrics v1.0.0 // indirect
@@ -246,7 +246,7 @@ require (
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/mattn/go-sqlite3 v1.14.24 // indirect
github.com/mattn/go-sqlite3 v1.14.27 // indirect
github.com/maxymania/go-system v0.0.0-20170110133659-647cc364bf0b // indirect
github.com/mendsley/gojwk v0.0.0-20141217222730-4d5ec6e58103 // indirect
github.com/miekg/dns v1.1.57 // indirect
@@ -254,7 +254,7 @@ require (
github.com/minio/crc64nvme v1.0.1 // indirect
github.com/minio/highwayhash v1.0.3 // indirect
github.com/minio/md5-simd v1.1.2 // indirect
github.com/minio/minio-go/v7 v7.0.88 // indirect
github.com/minio/minio-go/v7 v7.0.89 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
@@ -318,14 +318,15 @@ require (
go.opentelemetry.io/otel/metric v1.35.0 // indirect
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/automaxprocs v1.6.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.23.0 // indirect
golang.org/x/mod v0.24.0 // indirect
golang.org/x/sys v0.31.0 // indirect
golang.org/x/sys v0.32.0 // indirect
golang.org/x/time v0.11.0 // indirect
golang.org/x/tools v0.31.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 // indirect
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb // indirect
gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect

86
go.sum
View File

@@ -222,8 +222,8 @@ github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3h
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-oidc/v3 v3.13.0 h1:M66zd0pcc5VxvBNM4pB331Wrsanby+QomQYjN8HamW8=
github.com/coreos/go-oidc/v3 v3.13.0/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU=
github.com/coreos/go-oidc/v3 v3.14.1 h1:9ePWwfdwC4QKRlCXsJGou56adA/owXczOzwKdOumLqk=
github.com/coreos/go-oidc/v3 v3.14.1/go.mod h1:HaZ3szPaZ0e4r6ebqvsLWlk2Tn+aejfmrfah6hnSYEU=
github.com/coreos/go-semver v0.3.0 h1:wkHLiw0WNATZnSG7epLsujiMCgPAc9xhjJ4tgnAxmfM=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
@@ -258,8 +258,8 @@ github.com/deckarep/golang-set v1.8.0/go.mod h1:5nI87KwE7wgsBU1F4GKAw2Qod7p5kyS3
github.com/deepmap/oapi-codegen v1.3.11/go.mod h1:suMvK7+rKlx3+tpa8ByptmvoXbAV70wERKTOGH3hLp0=
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f h1:U5y3Y5UE0w7amNe7Z5G/twsBW0KEalRQXZzf8ufSh9I=
github.com/desertbit/timer v0.0.0-20180107155436-c41aec40b27f/go.mod h1:xH/i4TFMt8koVQZ6WFms69WAsDWr2XsYL3Hkl7jkoLE=
github.com/dgraph-io/badger/v4 v4.5.1 h1:7DCIXrQjo1LKmM96YD+hLVJ2EEsyyoWxJfpdd56HLps=
github.com/dgraph-io/badger/v4 v4.5.1/go.mod h1:qn3Be0j3TfV4kPbVoK0arXCD1/nr1ftth6sbL5jxdoA=
github.com/dgraph-io/badger/v4 v4.6.0 h1:acOwfOOZ4p1dPRnYzvkVm7rUk2Y21TgPVepCy5dJdFQ=
github.com/dgraph-io/badger/v4 v4.6.0/go.mod h1:KSJ5VTuZNC3Sd+YhvVjk2nYua9UZnnTr/SkXvdtiPgI=
github.com/dgraph-io/ristretto v0.2.0 h1:XAfl+7cmoUDWW/2Lx8TGZQjjxIQ2Ley9DSf52dru4WE=
github.com/dgraph-io/ristretto v0.2.0/go.mod h1:8uBHCU/PBV4Ag0CJrP47b9Ofby5dqWNh4FicAdoqFNU=
github.com/dgraph-io/ristretto/v2 v2.1.0 h1:59LjpOJLNDULHh8MC4UaegN52lC4JnO2dITsie/Pa8I=
@@ -411,8 +411,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.25.0 h1:5Dh7cjvzR7BRZadnsVOzPhWsrwUr0nmsZJxEAnFLNO8=
github.com/go-playground/validator/v10 v10.25.0/go.mod h1:GGzBIJMuE98Ic/kJsBXbz1x/7cByt++cQ+YOuDM5wus=
github.com/go-playground/validator/v10 v10.26.0 h1:SP05Nqhjcvz81uJaRfEV0YBSSSGMc/iMaVtFbr3Sw2k=
github.com/go-playground/validator/v10 v10.26.0/go.mod h1:I5QpIEbmr8On7W0TktmJAumgzX4CA1XNl4ZmDuVHKKo=
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
github.com/go-resty/resty/v2 v2.1.1-0.20191201195748-d7b97669fe48/go.mod h1:dZGr0i9PLlaaTD4H/hoZIDjQ+r6xq8mgbRzHZf7f2J8=
@@ -504,8 +504,8 @@ github.com/gomodule/redigo v1.9.2 h1:HrutZBLhSIU8abiSfW8pj8mPhOyMYjZT/wcA4/L9L9s
github.com/gomodule/redigo v1.9.2/go.mod h1:KsU3hiK/Ay8U42qpaJk+kuNa3C+spxapWpM+ywhcgtw=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/flatbuffers v24.12.23+incompatible h1:ubBKR94NR4pXUCY/MUsRVzd9umNW7ht7EG9hHfS9FX8=
github.com/google/flatbuffers v24.12.23+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q=
github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
@@ -540,8 +540,8 @@ github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad h1:a6HEuzUHeKH6hwfN/ZoQgRgVIWFJljSWa/zetS2WTvg=
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144=
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/renameio/v2 v2.0.0 h1:UifI23ZTGY8Tt29JbYFiuyIU3eX+RNFtUwefq9qAhxg=
github.com/google/renameio/v2 v2.0.0/go.mod h1:BtmJXm5YlszgC+TD4HOEEUFgkJP3nLxehU6hfe7jRt4=
@@ -689,8 +689,8 @@ github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHU
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.2.9 h1:66ze0taIn2H33fBvCkXuv9BmCwDfafmiIVpKV9kKGuY=
github.com/klauspost/cpuid/v2 v2.2.9/go.mod h1:rqkxqrZ1EhYM9G+hXH7YdowN5R5RGN6NK4QwQ3WMXF8=
github.com/klauspost/cpuid/v2 v2.2.10 h1:tBs3QSyvjDyFTq3uoc/9xFpCuOsJQFNPiAhYdw2skhE=
github.com/klauspost/cpuid/v2 v2.2.10/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
github.com/kobergj/gowebdav v0.0.0-20250102091030-aa65266db202 h1:A1xJ2NKgiYFiaHiLl9B5yw/gUBACSs9crDykTS3GuQI=
github.com/kobergj/gowebdav v0.0.0-20250102091030-aa65266db202/go.mod h1:bHA7t77X/QFExdeAnDzK6vKM34kEZAcE1OX4MfiwjkE=
github.com/kobergj/plugins/v4/store/nats-js-kv v0.0.0-20240807130109-f62bb67e8c90 h1:pfI8Z5yavO6fU6vDGlWhZ4BgDlvj8c6xB7J57HfTPwA=
@@ -768,8 +768,8 @@ github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc=
github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM=
github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mattn/go-sqlite3 v1.14.27 h1:drZCnuvf37yPfs95E5jd9s3XhdVWLal+6BOK6qrv6IU=
github.com/mattn/go-sqlite3 v1.14.27/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=
github.com/mattn/go-tty v0.0.0-20180219170247-931426f7535a/go.mod h1:XPvLUNfbS4fJH25nqRHfWLMa1ONC8Amw+mIA639KxkE=
github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
@@ -789,8 +789,8 @@ github.com/minio/highwayhash v1.0.3 h1:kbnuUMoHYyVl7szWjSxJnxw11k2U709jqFPPmIUyD
github.com/minio/highwayhash v1.0.3/go.mod h1:GGYsuwP/fPD6Y9hMiXuapVvlIUEhFhMTh0rxU3ik1LQ=
github.com/minio/md5-simd v1.1.2 h1:Gdi1DZK69+ZVMoNHRXJyNcxrMA4dSxoYHZSQbirFg34=
github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEpN+20RM=
github.com/minio/minio-go/v7 v7.0.88 h1:v8MoIJjwYxOkehp+eiLIuvXk87P2raUtoU5klrAAshs=
github.com/minio/minio-go/v7 v7.0.88/go.mod h1:33+O8h0tO7pCeCWwBVa07RhVVfB/3vS4kEX7rwYKmIg=
github.com/minio/minio-go/v7 v7.0.89 h1:hx4xV5wwTUfyv8LarhJAwNecnXpoTsj9v3f3q/ZkiJU=
github.com/minio/minio-go/v7 v7.0.89/go.mod h1:2rFnGAp02p7Dddo1Fq4S2wYOfpF0MUTSeLTRC90I204=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
@@ -829,8 +829,8 @@ github.com/nats-io/jwt/v2 v2.7.3 h1:6bNPK+FXgBeAqdj4cYQ0F8ViHRbi7woQLq4W29nUAzE=
github.com/nats-io/jwt/v2 v2.7.3/go.mod h1:GvkcbHhKquj3pkioy5put1wvPxs78UlZ7D/pY+BgZk4=
github.com/nats-io/nats-server/v2 v2.11.0 h1:fdwAT1d6DZW/4LUz5rkvQUe5leGEwjjOQYntzVRKvjE=
github.com/nats-io/nats-server/v2 v2.11.0/go.mod h1:leXySghbdtXSUmWem8K9McnJ6xbJOb0t9+NQ5HTRZjI=
github.com/nats-io/nats.go v1.39.1 h1:oTkfKBmz7W047vRxV762M67ZdXeOtUgvbBaNoQ+3PPk=
github.com/nats-io/nats.go v1.39.1/go.mod h1:MgRb8oOdigA6cYpEPhXJuRVH6UE/V4jblJ2jQ27IXYM=
github.com/nats-io/nats.go v1.41.0 h1:PzxEva7fflkd+n87OtQTXqCTyLfIIMFJBpyccHLE2Ko=
github.com/nats-io/nats.go v1.41.0/go.mod h1:wV73x0FSI/orHPSYoyMeJB+KajMDoWyXmFaRrrYaaTo=
github.com/nats-io/nkeys v0.4.10 h1:glmRrpCmYLHByYcePvnTBEAwawwapjCPMjy2huw20wc=
github.com/nats-io/nkeys v0.4.10/go.mod h1:OjRrnIKnWBFl+s4YK5ChQfvHP2fxqZexrKJoVVyWB3U=
github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
@@ -856,17 +856,17 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W
github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/ginkgo/v2 v2.23.3 h1:edHxnszytJ4lD9D5Jjc4tiDkPBZ3siDeJJkUZJJVkp0=
github.com/onsi/ginkgo/v2 v2.23.3/go.mod h1:zXTP6xIp3U8aVuXN8ENK9IXRaTjFnpVB9mGmaSRvxnM=
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.36.3 h1:hID7cr8t3Wp26+cYnfcjR6HpJ00fdogN6dqZ1t6IylU=
github.com/onsi/gomega v1.36.3/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
github.com/open-policy-agent/opa v1.2.0 h1:88NDVCM0of1eO6Z4AFeL3utTEtMuwloFmWWU7dRV1z0=
github.com/open-policy-agent/opa v1.2.0/go.mod h1:30euUmOvuBoebRCcJ7DMF42bRBOPznvt0ACUMYDUGVY=
github.com/opencloud-eu/reva/v2 v2.29.1 h1:SgB2zn8d/3UWwFiJ0pUs85aDKJJ36JoKnyRM+iW+VoI=
github.com/opencloud-eu/reva/v2 v2.29.1/go.mod h1:+nkCU7w6E6cyNSsKRYj1rb0cCI7QswEQ7KOPljctebM=
github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
github.com/open-policy-agent/opa v1.3.0 h1:zVvQvQg+9+FuSRBt4LgKNzJwsWl/c85kD5jPozJTydY=
github.com/open-policy-agent/opa v1.3.0/go.mod h1:t9iPNhaplD2qpiBqeudzJtEX3fKHK8zdA29oFvofAHo=
github.com/opencloud-eu/reva/v2 v2.31.0 h1:UVgeb0hSPoaDdqcKSJ7XZAhXCtHaVK9qm/JtFtJM/7U=
github.com/opencloud-eu/reva/v2 v2.31.0/go.mod h1:8MT1a/WJASZZhlSMC0oeE3ECQdjqFw3BUiiAIZ/JR8I=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
@@ -911,6 +911,8 @@ github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndr
github.com/pquerna/cachecontrol v0.2.0 h1:vBXSNuE5MYP9IJ5kjsdo8uq+w41jSPgvba2DEnkRx9k=
github.com/pquerna/cachecontrol v0.2.0/go.mod h1:NrUG3Z7Rdu85UNR3vm7SOsl1nFIeSiQnrHV5K9mBcUI=
github.com/pquerna/otp v1.3.0/go.mod h1:dkJfzwRKNiegxyNb54X/3fLwhCynbMspSyWKnvi1AEg=
github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g=
github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U=
github.com/prometheus/alertmanager v0.28.1 h1:BK5pCoAtaKg01BYRUJhEDV1tqJMEtYBGzPw8QdvnnvA=
github.com/prometheus/alertmanager v0.28.1/go.mod h1:0StpPUDDHi1VXeM7p2yYfeZgLVi/PPlt39vo9LQUHxM=
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
@@ -1098,13 +1100,13 @@ github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208/go.mod h1:BzWtXXrXz
github.com/transip/gotransip/v6 v6.2.0/go.mod h1:pQZ36hWWRahCUXkFWlx9Hs711gLd8J4qdgLdRzmtY+g=
github.com/trustelem/zxcvbn v1.0.1 h1:mp4JFtzdDYGj9WYSD3KQSkwwUumWNFzXaAjckaTYpsc=
github.com/trustelem/zxcvbn v1.0.1/go.mod h1:zonUyKeh7sw6psPf/e3DtRqkRyZvAbOfjNz/aO7YQ5s=
github.com/tus/tusd/v2 v2.7.1 h1:TGJjhv9RYXDmsTz8ug/qSd9vQpmD0Ik0G0IPo80Qmc0=
github.com/tus/tusd/v2 v2.7.1/go.mod h1:PLdIMQ/ge+5ADgGKcL3FgTaPs+7wB0JIiI5HQXAiJE8=
github.com/tus/tusd/v2 v2.8.0 h1:X2jGxQ05jAW4inDd2ogmOKqwnb4c/D0lw2yhgHayWyU=
github.com/tus/tusd/v2 v2.8.0/go.mod h1:3/zEOVQQIwmJhvNam8phV4x/UQt68ZmZiTzeuJUNhVo=
github.com/uber-go/atomic v1.3.2/go.mod h1:/Ct5t2lcmbJ4OSe/waGBoaVvVqtO0bmtfVNex1PFV8g=
github.com/urfave/cli v1.22.4/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
github.com/urfave/cli/v2 v2.27.5 h1:WoHEJLdsXr6dDWoJgMq/CboDmyY/8HMMH1fTECbih+w=
github.com/urfave/cli/v2 v2.27.5/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
github.com/urfave/cli/v2 v2.27.6 h1:VdRdS98FNhKZ8/Az8B7MTyGQmpIr36O1EHybx/LaZ4g=
github.com/urfave/cli/v2 v2.27.6/go.mod h1:3Sevf16NykTbInEnD0yKkjDAeZDS0A6bzhBH5hrMvTQ=
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
@@ -1177,6 +1179,8 @@ go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0 h1:1fTNlAIJZGWLP5FVu0f
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.35.0/go.mod h1:zjPK58DtkqQFn+YUMbx0M2XV3QgKU0gS9LeGohREyK4=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0 h1:m639+BofXTvcY1q8CGs4ItwQarYtJPOWmVobfM1HpVI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.35.0/go.mod h1:LjReUci/F4BUyv+y4dwnq3h/26iNOeC3wAIqgvTIZVo=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0 h1:xJ2qHD0C1BeYVTLLR9sX12+Qb95kfeD/byKj6Ky1pXg=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.35.0/go.mod h1:u5BF1xyjstDowA1R5QAO9JHzqK+ublenEW/dyqTjBVk=
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
@@ -1192,6 +1196,8 @@ go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
@@ -1328,8 +1334,8 @@ golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4=
golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c=
golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8=
golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -1440,8 +1446,8 @@ golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.31.0 h1:ioabZlmFYtWhL+TRYpcnNlLwhyxaM9kWTDEmfnprqik=
golang.org/x/sys v0.31.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/sys v0.32.0 h1:s77OFDvIQeibCmezSnk/q6iAfkdiQaJi4VzroCFrN20=
golang.org/x/sys v0.32.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
@@ -1597,8 +1603,8 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc
google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697 h1:ToEetK57OidYuqD4Q5w+vfEnPvPpuTwedCNVohYJfNk=
google.golang.org/genproto v0.0.0-20241118233622-e639e219e697/go.mod h1:JJrvXBWRZaFMxBufik1a4RpFw4HhgVtBBWQeQgUj2cc=
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb h1:ITgPrl429bc6+2ZraNSzMDk3I95nmQln2fuPstKwFDE=
google.golang.org/genproto v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:sAo5UzpjUwgFBCzupwhcLcxHVDK7vG5IqI30YnwX2eE=
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb h1:p31xT4yrYrSM/G4Sn2+TNUkVhFCbG9y8itM2S6Th950=
google.golang.org/genproto/googleapis/api v0.0.0-20250303144028-a0af3efb3deb/go.mod h1:jbe3Bkdp+Dh2IrslsFCklNhweNTBgSYanP1UXhJDhKg=
google.golang.org/genproto/googleapis/rpc v0.0.0-20250303144028-a0af3efb3deb h1:TLPQVbx1GJ8VKZxz52VAxl1EBgKXXbTiU9Fc5fZeLn4=
@@ -1618,8 +1624,8 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji
google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.71.0 h1:kF77BGdPTQ4/JZWMlb9VpJ5pa25aqvVqogsxNHHdeBg=
google.golang.org/grpc v1.71.0/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
google.golang.org/grpc v1.71.1 h1:ffsFWr7ygTUscGPI0KKK6TLrGz0476KUvvsbqWK0rPI=
google.golang.org/grpc v1.71.1/go.mod h1:H0GRtasmQOh9LkFoCPDu3ZrwUtD1YGE+b2vYBYd/8Ec=
google.golang.org/grpc/examples v0.0.0-20211102180624-670c133e568e h1:m7aQHHqd0q89mRwhwS9Bx2rjyl/hsFAeta+uGrHsQaU=
google.golang.org/grpc/examples v0.0.0-20211102180624-670c133e568e/go.mod h1:gID3PKrg7pWKntu9Ss6zTLJ0ttC0X9IHgREOCZwbCVU=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
@@ -1636,8 +1642,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.36.5 h1:tPhr+woSbjfYvY6/GPufUoYizxw1cF/yFoxJ2fmpwlM=
google.golang.org/protobuf v1.36.5/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/cenkalti/backoff.v1 v1.1.0 h1:Arh75ttbsvlpVA7WtVpH4u9h6Zl46xuptxqLxPiSo4Y=
gopkg.in/cenkalti/backoff.v1 v1.1.0/go.mod h1:J6Vskwqd+OMVJl8C33mmtxTBs2gyzfv7UDAkHu8BrjI=

View File

@@ -2716,7 +2716,7 @@ var (
// errMaxExprCnt is used to signal that the maximum number of
// expressions have been parsed.
errMaxExprCnt = errors.New("max number of expresssions parsed")
errMaxExprCnt = errors.New("max number of expressions parsed")
)
// Option is a function that can set an option on the parser. It returns

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v2.53.0. DO NOT EDIT.
// Code generated by mockery v2.53.2. DO NOT EDIT.
package mocks

View File

@@ -16,7 +16,7 @@ var (
// LatestTag is the latest released version plus the dev meta version.
// Will be overwritten by the release pipeline
// Needs a manual change for every tagged release
LatestTag = "1.1.0+dev"
LatestTag = "2.1.0+dev"
// Date indicates the build date.
// This has been removed, it looks like you can only replace static strings with recent go versions
@@ -46,18 +46,17 @@ func GetString() string {
// Parsed returns a semver Version
func Parsed() (version *semver.Version) {
versionToParse := LatestTag
if Tag != "" {
// use the placeholder version if the tag is empty or when we are creating a daily build
if Tag != "" && Tag != "daily" {
versionToParse = Tag
}
version, err := semver.NewVersion(versionToParse)
// We have no semver version but a commitid
if err != nil {
// this should never happen
if err != nil {
return &semver.Version{}
}
return &semver.Version{}
}
if String != "" {
// We have no tagged version but a commitid
nVersion, err := version.SetMetadata(String)
if err != nil {
return &semver.Version{}

View File

@@ -1,49 +1,124 @@
export default {
changeTypes: [
{
title: '💥 Breaking changes',
labels: ['breaking', 'Type:Breaking-Change'],
bump: 'major',
weight: 3
},
{
title: '🔒 Security',
labels: ['security', 'Type:Security'],
bump: 'patch',
weight: 2
},
{
title: '✨ Features',
labels: ['feature', 'Type:Feature'],
bump: 'minor',
weight: 1
},
{
title: '📈 Enhancement',
labels: ['enhancement', 'refactor', 'Type:Enhancement'],
bump: 'minor'
},
{
title: '🐛 Bug Fixes',
labels: ['bug', 'Type:Bug'],
bump: 'patch'
},
{
title: '📚 Documentation',
labels: ['docs', 'documentation', 'Type:Documentation'],
bump: 'patch'
},
{
title: '✅ Tests',
labels: ['test', 'tests', 'Type:Test'],
bump: 'patch'
},
{
title: '📦️ Dependencies',
labels: ['dependency', 'dependencies', 'Type:Dependencies'],
bump: 'patch',
weight: -1
}
],
useVersionPrefixV: true,
}
changeTypes: [
{
title: "💥 Breaking changes",
labels: ["breaking", "Type:Breaking-Change"],
bump: "major",
weight: 3,
},
{
title: "🔒 Security",
labels: ["security", "Type:Security"],
bump: "patch",
weight: 2,
},
{
title: "✨ Features",
labels: ["feature", "Type:Feature"],
bump: "minor",
weight: 1,
},
{
title: "📈 Enhancement",
labels: ["enhancement", "refactor", "Type:Enhancement"],
bump: "minor",
},
{
title: "🐛 Bug Fixes",
labels: ["bug", "Type:Bug"],
bump: "patch",
},
{
title: "📚 Documentation",
labels: ["docs", "documentation", "Type:Documentation"],
bump: "patch",
},
{
title: "✅ Tests",
labels: ["test", "tests", "Type:Test"],
bump: "patch",
},
{
title: "📦️ Dependencies",
labels: ["dependency", "dependencies", "Type:Dependencies"],
bump: "patch",
weight: -1,
},
],
useVersionPrefixV: true,
getLatestTag: ({ exec }) => {
// the plugin uses the latest tag to determine the next version
// and the changes that are included in the upcoming release.
const branch = getBranch(exec);
let tags = getTags(exec);
if (branch.startsWith("stable-")) {
const [_, majorAndMinor] = branch.split("-");
// we only care about tags that are within the range of the current stable branch.
// e.g. if the branch is stable-1.2, we only care about tags that are v1.2.x.
const matchingTags = tags.filter((t) =>
t.startsWith(`v${majorAndMinor}`)
);
if (matchingTags.length) {
tags = matchingTags;
}
}
return tags.pop() || "v0.0.0";
},
useLatestRelease: ({ exec, nextVersion }) => {
// check if the release should be marked as latest release on GitHub.
const tags = getTags(exec);
const latestTag = tags.pop() || "v0.0.0";
return compareVersions(latestTag, nextVersion) === -1;
},
};
const parseVersion = (tag: string) => {
const version = tag.startsWith("v") ? tag.slice(1) : tag;
const [main, pre] = version.split("-");
const [major, minor, patch] = main.split(".").map(Number);
return { major, minor, patch, pre };
};
const getBranch = (exec: any): string => {
return exec("git rev-parse --abbrev-ref HEAD", {
silent: true,
}).stdout.trim();
};
const getTags = (exec: any) => {
exec("git fetch --tags", { silent: true });
const tagsOutput = exec("git tag", { silent: true }).stdout.trim();
const tags: string[] = tagsOutput ? tagsOutput.split("\n") : [];
return tags.filter((tag) => tag.startsWith("v")).sort(compareVersions);
};
const compareVersions = (a: string, b: string) => {
const va = parseVersion(a);
const vb = parseVersion(b);
if (va.major !== vb.major) {
return va.major - vb.major;
}
if (va.minor !== vb.minor) {
return va.minor - vb.minor;
}
if (va.patch !== vb.patch) {
return va.patch - vb.patch;
}
if (va.pre && !vb.pre) {
return -1;
}
if (!va.pre && vb.pre) {
return 1;
}
if (va.pre && vb.pre) {
return va.pre.localeCompare(vb.pre);
}
return 0;
};

View File

@@ -4,7 +4,10 @@ The `antivirus` service is responsible for scanning files for viruses.
## Memory Considerations
The antivirus service can consume considerably amounts of memory. This is relevant to provide or define sufficient memory for the deployment selected. To avoid out of memory (OOM) situations, the following equation gives a rough overview based on experiences made. The memory calculation comes without any guarantee, is intended as overview only and subject of change.
The antivirus service can consume considerable amounts of memory.
This is relevant to provide or define sufficient memory for the deployment selected.
To avoid out of memory (OOM) situations, the following equation gives a rough overview based on experiences made.
The memory calculation comes without any guarantee, is intended as overview only and subject of change.
`memory limit` = `max file size` x `workers` x `factor 8 - 14`
@@ -19,17 +22,31 @@ With:
### Antivirus Scanner Type
The antivirus service currently supports [ICAP](https://tools.ietf.org/html/rfc3507) and [ClamAV](http://www.clamav.net/index.html) as antivirus scanners. The `ANTIVIRUS_SCANNER_TYPE` environment variable is used to select the scanner. The detailed configuration for each scanner heavily depends on the scanner type selected. See the environment variables for more details.
The antivirus service currently supports [ICAP](https://tools.ietf.org/html/rfc3507) and [ClamAV](http://www.clamav.net/index.html) as antivirus scanners.
The `ANTIVIRUS_SCANNER_TYPE` environment variable is used to select the scanner.
The detailed configuration for each scanner heavily depends on the scanner type selected.
See the environment variables for more details.
- For `icap`, only scanners using the `X-Infection-Found` header are currently supported.
- For `clamav` only local sockets can currently be configured.
### Maximum Scan Size
Several factors can make it necessary to limit the maximum filesize the antivirus service will use for scanning. Use the `ANTIVIRUS_MAX_SCAN_SIZE` environment variable to scan only a given amount of bytes. Obviously, it is recommended to scan the whole file, but several factors like scanner type and version, bandwidth, performance issues, etc. might make a limit necessary.
Several factors can make it necessary to limit the maximum filesize the antivirus service uses for scanning.
Use the `ANTIVIRUS_MAX_SCAN_SIZE` environment variable to scan only a given number of bytes,
or to skip the whole resource.
Even if it's recommended to scan the whole file, several factors like scanner type and version,
bandwidth, performance issues, etc. might make a limit necessary.
In such cases, the antivirus the max scan size mode can be handy, the following modes are available:
- `partial`: The file is scanned up to the given size. The rest of the file is not scanned. This is the default mode `ANTIVIRUS_MAX_SCAN_SIZE=partial`
- `skip`: The file is skipped and not scanned. `ANTIVIRUS_MAX_SCAN_SIZE=skip`
**IMPORTANT**
> Streaming of files to the virus scan service still [needs to be implemented](https://github.com/owncloud/ocis/issues/6803). To prevent OOM errors `ANTIVIRUS_MAX_SCAN_SIZE` needs to be set lower than available ram.
> Streaming of files to the virus scan service still [needs to be implemented](https://github.com/owncloud/ocis/issues/6803).
> To prevent OOM errors `ANTIVIRUS_MAX_SCAN_SIZE` needs to be set lower than available ram and or the maximum file size that can be scanned by the virus scanner.
### Antivirus Workers
@@ -41,7 +58,7 @@ The antivirus service allows three different ways of handling infected files. Th
- `delete`: (default): Infected files will be deleted immediately, further postprocessing is cancelled.
- `abort`: (advanced option): Infected files will be kept, further postprocessing is cancelled. Files can be manually retrieved and inspected by an admin. To identify the file for further investigation, the antivirus service logs the abort/infected state including the file ID. The file is located in the `storage/users/uploads` folder of the OpenCloud data directory and persists until it is manually deleted by the admin via the [Manage Unfinished Uploads](https://github.com/opencloud-eu/opencloud/tree/main/services/storage-users#manage-unfinished-uploads) command.
- `continue`: (obviously not recommended): Infected files will be marked via metadata as infected but postprocessing continues normally. Note: Infected Files are moved to their final destination and therefore not prevented from download which includes the risk of spreading viruses.
- `continue`: (not recommended): Infected files will be marked via metadata as infected, but postprocessing continues normally. Note: Infected Files are moved to their final destination and therefore not prevented from download, which includes the risk of spreading viruses.
In all cases, a log entry is added declaring the infection and handling method and a notification via the `userlog` service sent.

View File

@@ -45,7 +45,7 @@ func Server(cfg *config.Config) *cli.Command {
{
svc, err := service.NewAntivirus(cfg, logger, traceProvider)
if err != nil {
return err
return cli.Exit(err.Error(), 1)
}
gr.Add(svc.Run, func(_ error) {

View File

@@ -5,6 +5,26 @@ import (
"time"
)
// ScannerType gives info which scanner is used
type ScannerType string
const (
// ScannerTypeClamAV defines that clamav is used
ScannerTypeClamAV ScannerType = "clamav"
// ScannerTypeICap defines that icap is used
ScannerTypeICap ScannerType = "icap"
)
// MaxScanSizeMode defines the mode of handling files that exceed the maximum scan size
type MaxScanSizeMode string
const (
// MaxScanSizeModeSkip defines that files that are bigger than the max scan size will be skipped
MaxScanSizeModeSkip MaxScanSizeMode = "skip"
// MaxScanSizeModePartial defines that only the file up to the max size will be used
MaxScanSizeModePartial MaxScanSizeMode = "partial"
)
// Config combines all available configuration parts.
type Config struct {
File string
@@ -20,8 +40,9 @@ type Config struct {
Events Events
Workers int `yaml:"workers" env:"ANTIVIRUS_WORKERS" desc:"The number of concurrent go routines that fetch events from the event queue." introductionVersion:"1.0.0"`
Scanner Scanner
MaxScanSize string `yaml:"max-scan-size" env:"ANTIVIRUS_MAX_SCAN_SIZE" desc:"The maximum scan size the virus scanner can handle. Only this many bytes of a file will be scanned. 0 means unlimited and is the default. Usable common abbreviations: [KB, KiB, MB, MiB, GB, GiB, TB, TiB, PB, PiB, EB, EiB], example: 2GB." introductionVersion:"1.0.0"`
Scanner Scanner
MaxScanSize string `yaml:"max-scan-size" env:"ANTIVIRUS_MAX_SCAN_SIZE" desc:"The maximum scan size the virus scanner can handle.0 means unlimited. Usable common abbreviations: [KB, KiB, MB, MiB, GB, GiB, TB, TiB, PB, PiB, EB, EiB], example: 2GB." introductionVersion:"1.0.0"`
MaxScanSizeMode MaxScanSizeMode `yaml:"max-scan-size-mode" env:"ANTIVIRUS_MAX_SCAN_SIZE_MODE" desc:"Defines the mode of handling files that exceed the maximum scan size. Supported options are: 'skip', which skips files that are bigger than the max scan size, and 'truncate' (default), which only uses the file up to the max size." introductionVersion:"2.1.0"`
Context context.Context `json:"-" yaml:"-"`
@@ -62,7 +83,7 @@ type Events struct {
// Scanner provides configuration options for the virus scanner
type Scanner struct {
Type string `yaml:"type" env:"ANTIVIRUS_SCANNER_TYPE" desc:"The antivirus scanner to use. Supported values are 'clamav' and 'icap'." introductionVersion:"1.0.0"`
Type ScannerType `yaml:"type" env:"ANTIVIRUS_SCANNER_TYPE" desc:"The antivirus scanner to use. Supported values are 'clamav' and 'icap'." introductionVersion:"1.0.0"`
ClamAV ClamAV // only if Type == clamav
ICAP ICAP // only if Type == icap
@@ -70,7 +91,8 @@ type Scanner struct {
// ClamAV provides configuration option for clamav
type ClamAV struct {
Socket string `yaml:"socket" env:"ANTIVIRUS_CLAMAV_SOCKET" desc:"The socket clamav is running on. Note the default value is an example which needs adaption according your OS." introductionVersion:"1.0.0"`
Socket string `yaml:"socket" env:"ANTIVIRUS_CLAMAV_SOCKET" desc:"The socket clamav is running on. Note the default value is an example which needs adaption according your OS." introductionVersion:"1.0.0"`
Timeout time.Duration `yaml:"scan_timeout" env:"ANTIVIRUS_CLAMAV_SCAN_TIMEOUT" desc:"Scan timeout for the ClamAV client. Defaults to '5m' (5 minutes). See the Environment Variable Types description for more details." introductionVersion:"2.1.0"`
}
// ICAP provides configuration options for icap

View File

@@ -30,10 +30,15 @@ func DefaultConfig() *config.Config {
},
Workers: 10,
InfectedFileHandling: "delete",
// defaults from clamav sample conf: MaxScanSize=400M, MaxFileSize=100M, StreamMaxLength=100M
// https://github.com/Cisco-Talos/clamav/blob/main/etc/clamd.conf.sample
MaxScanSize: "100MB",
MaxScanSizeMode: config.MaxScanSizeModePartial,
Scanner: config.Scanner{
Type: "clamav",
Type: config.ScannerTypeClamAV,
ClamAV: config.ClamAV{
Socket: "/run/clamav/clamd.ctl",
Socket: "/run/clamav/clamd.ctl",
Timeout: 5 * time.Minute,
},
ICAP: config.ICAP{
URL: "icap://127.0.0.1:1344",
@@ -57,4 +62,9 @@ func EnsureDefaults(cfg *config.Config) {
// Sanitize sanitizes the configuration
func Sanitize(cfg *config.Config) {
defaultConfig := DefaultConfig()
if cfg.MaxScanSize == "" {
cfg.MaxScanSize = defaultConfig.MaxScanSize
}
}

View File

@@ -1,34 +1,51 @@
package scanners
import (
"fmt"
"time"
"github.com/dutchcoders/go-clamd"
)
// NewClamAV returns a Scanner talking to clamAV via socket
func NewClamAV(socket string) *ClamAV {
return &ClamAV{
clamd: clamd.NewClamd(socket),
func NewClamAV(socket string, timeout time.Duration) (*ClamAV, error) {
c := clamd.NewClamd(socket)
if err := c.Ping(); err != nil {
return nil, fmt.Errorf("%w: %w", ErrScannerNotReachable, err)
}
return &ClamAV{
clamd: clamd.NewClamd(socket),
timeout: timeout,
}, nil
}
// ClamAV is a Scanner based on clamav
type ClamAV struct {
clamd *clamd.Clamd
clamd *clamd.Clamd
timeout time.Duration
}
// Scan to fulfill Scanner interface
func (s ClamAV) Scan(in Input) (Result, error) {
ch, err := s.clamd.ScanStream(in.Body, make(chan bool))
abort := make(chan bool, 1)
defer close(abort)
ch, err := s.clamd.ScanStream(in.Body, abort)
if err != nil {
return Result{}, err
}
r := <-ch
return Result{
Infected: r.Status == clamd.RES_FOUND,
Description: r.Description,
ScanTime: time.Now(),
}, nil
select {
case <-time.After(s.timeout):
abort <- true
return Result{}, fmt.Errorf("%w: %s", ErrScanTimeout, in.Url)
case s := <-ch:
return Result{
Infected: s.Status == clamd.RES_FOUND,
Description: s.Description,
ScanTime: time.Now(),
}, nil
}
}

View File

@@ -0,0 +1,120 @@
package scanners_test
import (
"context"
"net"
"os"
"path/filepath"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/opencloud-eu/opencloud/services/antivirus/pkg/scanners"
)
func newUnixListener(t testing.TB, lc net.ListenConfig, v ...string) net.Listener {
d, err := os.MkdirTemp("", "")
assert.NoError(t, err)
t.Cleanup(func() {
require.NoError(t, os.RemoveAll(d))
})
nl, err := lc.Listen(context.Background(), "unix", filepath.Join(d, "sock"))
require.NoError(t, err)
go func() {
i := 0
for {
if len(v) == i {
break
}
conn, err := nl.Accept()
require.NoError(t, err)
time.Sleep(100 * time.Millisecond)
_, err = conn.Write([]byte(v[i]))
require.NoError(t, err)
require.NoError(t, conn.Close())
i++
}
}()
return nl
}
func TestNewClamAV(t *testing.T) {
t.Run("returns a scanner", func(t *testing.T) {
ul := newUnixListener(t, net.ListenConfig{}, "PONG\n")
defer func() {
assert.NoError(t, ul.Close())
}()
done := make(chan bool, 1)
go func() {
_, err := scanners.NewClamAV(ul.Addr().String(), 10*time.Second)
assert.NoError(t, err)
done <- true
}()
assert.True(t, <-done)
})
t.Run("fails if scanner is not pingable", func(t *testing.T) {
_, err := scanners.NewClamAV("", 0)
assert.ErrorIs(t, err, scanners.ErrScannerNotReachable)
})
}
func TestNewClamAV_Scan(t *testing.T) {
t.Run("returns a result", func(t *testing.T) {
ul := newUnixListener(t, net.ListenConfig{}, "PONG\n", "stream: Win.Test.EICAR_HDB-1 FOUND\n")
defer func() {
assert.NoError(t, ul.Close())
}()
done := make(chan bool, 1)
go func() {
scanner, err := scanners.NewClamAV(ul.Addr().String(), 10*time.Second)
assert.NoError(t, err)
result, err := scanner.Scan(scanners.Input{Body: strings.NewReader("DATA")})
assert.NoError(t, err)
assert.Equal(t, result.Description, "Win.Test.EICAR_HDB-1")
assert.True(t, result.Infected)
done <- true
}()
assert.True(t, <-done)
})
t.Run("aborts after a certain time", func(t *testing.T) {
ul := newUnixListener(t, net.ListenConfig{}, "PONG\n", "stream: Win.Test.EICAR_HDB-1 FOUND\n")
defer func() {
assert.NoError(t, ul.Close())
}()
done := make(chan bool, 1)
go func() {
scanner, err := scanners.NewClamAV(ul.Addr().String(), 10*time.Second)
assert.NoError(t, err)
result, err := scanner.Scan(scanners.Input{Body: strings.NewReader("DATA")})
assert.NoError(t, err)
assert.Equal(t, result.Description, "Win.Test.EICAR_HDB-1")
assert.True(t, result.Infected)
done <- true
}()
assert.True(t, <-done)
})
}

View File

@@ -1,21 +1,31 @@
package scanners
import (
"errors"
"io"
"time"
)
// The Result is the common scan result to all scanners
type Result struct {
Infected bool
ScanTime time.Time
Description string
}
var (
// ErrScanTimeout is returned when a scan times out
ErrScanTimeout = errors.New("time out waiting for clamav to respond while scanning")
// ErrScannerNotReachable is returned when the scanner is not reachable
ErrScannerNotReachable = errors.New("failed to reach the scanner")
)
// The Input is the common input to all scanners
type Input struct {
Body io.Reader
Size int64
Url string
Name string
}
type (
// The Result is the common scan result to all scanners
Result struct {
Infected bool
ScanTime time.Time
Description string
}
// The Input is the common input to all scanners
Input struct {
Body io.Reader
Size int64
Url string
Name string
}
)

View File

@@ -9,6 +9,7 @@ import (
"io"
"net/http"
"os"
"slices"
"sync"
"time"
@@ -37,38 +38,44 @@ type Scanner interface {
}
// NewAntivirus returns a service implementation for Service.
func NewAntivirus(c *config.Config, l log.Logger, tp trace.TracerProvider) (Antivirus, error) {
func NewAntivirus(cfg *config.Config, logger log.Logger, tracerProvider trace.TracerProvider) (Antivirus, error) {
var scanner Scanner
var err error
switch c.Scanner.Type {
switch cfg.Scanner.Type {
default:
return Antivirus{}, fmt.Errorf("unknown av scanner: '%s'", c.Scanner.Type)
case "clamav":
scanner = scanners.NewClamAV(c.Scanner.ClamAV.Socket)
case "icap":
scanner, err = scanners.NewICAP(c.Scanner.ICAP.URL, c.Scanner.ICAP.Service, c.Scanner.ICAP.Timeout)
return Antivirus{}, fmt.Errorf("unknown av scanner: '%s'", cfg.Scanner.Type)
case config.ScannerTypeClamAV:
scanner, err = scanners.NewClamAV(cfg.Scanner.ClamAV.Socket, cfg.Scanner.ClamAV.Timeout)
case config.ScannerTypeICap:
scanner, err = scanners.NewICAP(cfg.Scanner.ICAP.URL, cfg.Scanner.ICAP.Service, cfg.Scanner.ICAP.Timeout)
}
if err != nil {
return Antivirus{}, err
}
av := Antivirus{c: c, l: l, tp: tp, s: scanner, client: rhttp.GetHTTPClient(rhttp.Insecure(true))}
av := Antivirus{config: cfg, log: logger, tracerProvider: tracerProvider, scanner: scanner, client: rhttp.GetHTTPClient(rhttp.Insecure(true))}
switch o := events.PostprocessingOutcome(c.InfectedFileHandling); o {
case events.PPOutcomeContinue, events.PPOutcomeAbort, events.PPOutcomeDelete:
av.o = o
switch mode := cfg.MaxScanSizeMode; mode {
case config.MaxScanSizeModeSkip, config.MaxScanSizeModePartial:
break
default:
return av, fmt.Errorf("unknown infected file handling '%s'", o)
return av, fmt.Errorf("unknown max scan size mode '%s'", cfg.MaxScanSizeMode)
}
if c.MaxScanSize != "" {
b, err := bytesize.Parse(c.MaxScanSize)
switch outcome := events.PostprocessingOutcome(cfg.InfectedFileHandling); outcome {
case events.PPOutcomeContinue, events.PPOutcomeAbort, events.PPOutcomeDelete:
av.outcome = outcome
default:
return av, fmt.Errorf("unknown infected file handling '%s'", outcome)
}
if cfg.MaxScanSize != "" {
b, err := bytesize.Parse(cfg.MaxScanSize)
if err != nil {
return av, err
}
av.m = b.Bytes()
av.maxScanSize = b.Bytes()
}
return av, nil
@@ -76,23 +83,23 @@ func NewAntivirus(c *config.Config, l log.Logger, tp trace.TracerProvider) (Anti
// Antivirus defines implements the business logic for Service.
type Antivirus struct {
c *config.Config
l log.Logger
s Scanner
o events.PostprocessingOutcome
m uint64
tp trace.TracerProvider
config *config.Config
log log.Logger
scanner Scanner
outcome events.PostprocessingOutcome
maxScanSize uint64
tracerProvider trace.TracerProvider
client *http.Client
}
// Run runs the service
func (av Antivirus) Run() error {
evtsCfg := av.c.Events
eventsCfg := av.config.Events
var rootCAPool *x509.CertPool
if av.c.Events.TLSRootCACertificate != "" {
rootCrtFile, err := os.Open(evtsCfg.TLSRootCACertificate)
if av.config.Events.TLSRootCACertificate != "" {
rootCrtFile, err := os.Open(eventsCfg.TLSRootCACertificate)
if err != nil {
return err
}
@@ -104,10 +111,10 @@ func (av Antivirus) Run() error {
rootCAPool = x509.NewCertPool()
rootCAPool.AppendCertsFromPEM(certBytes.Bytes())
av.c.Events.TLSInsecure = false
av.config.Events.TLSInsecure = false
}
natsStream, err := stream.NatsFromConfig(av.c.Service.Name, false, stream.NatsConfig(av.c.Events))
natsStream, err := stream.NatsFromConfig(av.config.Service.Name, false, stream.NatsConfig(av.config.Events))
if err != nil {
return err
}
@@ -118,7 +125,7 @@ func (av Antivirus) Run() error {
}
wg := sync.WaitGroup{}
for i := 0; i < av.c.Workers; i++ {
for i := 0; i < av.config.Workers; i++ {
wg.Add(1)
go func() {
defer wg.Done()
@@ -127,11 +134,11 @@ func (av Antivirus) Run() error {
if err != nil {
switch {
case errors.Is(err, ErrFatal):
av.l.Fatal().Err(err).Msg("fatal error - exiting")
av.log.Fatal().Err(err).Msg("fatal error - exiting")
case errors.Is(err, ErrEvent):
av.l.Error().Err(err).Msg("continuing")
av.log.Error().Err(err).Msg("continuing")
default:
av.l.Fatal().Err(err).Msg("unknown error - exiting")
av.log.Fatal().Err(err).Msg("unknown error - exiting")
}
}
}
@@ -143,20 +150,20 @@ func (av Antivirus) Run() error {
}
func (av Antivirus) processEvent(e events.Event, s events.Publisher) error {
ctx := e.GetTraceContext(context.Background())
ctx, span := av.tp.Tracer("antivirus").Start(ctx, "processEvent")
ctx, span := av.tracerProvider.Tracer("antivirus").Start(e.GetTraceContext(context.Background()), "processEvent")
defer span.End()
av.l.Info().Str("traceID", span.SpanContext().TraceID().String()).Msg("TraceID")
av.log.Info().Str("traceID", span.SpanContext().TraceID().String()).Msg("TraceID")
ev := e.Event.(events.StartPostprocessingStep)
if ev.StepToStart != events.PPStepAntivirus {
return nil
}
if av.c.DebugScanOutcome != "" {
av.l.Warn().Str("antivir, clamav", ">>>>>>> ANTIVIRUS_DEBUG_SCAN_OUTCOME IS SET NO ACTUAL VIRUS SCAN IS PERFORMED!").Send()
if av.config.DebugScanOutcome != "" {
av.log.Warn().Str("antivir, clamav", ">>>>>>> ANTIVIRUS_DEBUG_SCAN_OUTCOME IS SET NO ACTUAL VIRUS SCAN IS PERFORMED!").Send()
if err := events.Publish(ctx, s, events.PostprocessingStepFinished{
FinishedStep: events.PPStepAntivirus,
Outcome: events.PostprocessingOutcome(av.c.DebugScanOutcome),
Outcome: events.PostprocessingOutcome(av.config.DebugScanOutcome),
UploadID: ev.UploadID,
ExecutingUser: ev.ExecutingUser,
Filename: ev.Filename,
@@ -167,13 +174,14 @@ func (av Antivirus) processEvent(e events.Event, s events.Publisher) error {
ResourceID: ev.ResourceID,
},
}); err != nil {
av.l.Fatal().Err(err).Str("uploadid", ev.UploadID).Interface("resourceID", ev.ResourceID).Msg("cannot publish events - exiting")
av.log.Fatal().Err(err).Str("uploadid", ev.UploadID).Interface("resourceID", ev.ResourceID).Msg("cannot publish events - exiting")
return fmt.Errorf("%w: cannot publish events", ErrFatal)
}
return fmt.Errorf("%w: no actual virus scan performed", ErrEvent)
}
av.l.Debug().Str("uploadid", ev.UploadID).Str("filename", ev.Filename).Msg("Starting virus scan.")
av.log.Debug().Str("uploadid", ev.UploadID).Str("filename", ev.Filename).Msg("Starting virus scan.")
var errmsg string
start := time.Now()
res, err := av.process(ev)
@@ -185,17 +193,17 @@ func (av Antivirus) processEvent(e events.Event, s events.Publisher) error {
var outcome events.PostprocessingOutcome
switch {
case res.Infected:
outcome = av.o
outcome = av.outcome
case !res.Infected && err == nil:
outcome = events.PPOutcomeContinue
case err != nil:
outcome = events.PPOutcomeRetry
default:
// Not sure what this is about. abort.
// Not sure what this is about. Abort.
outcome = events.PPOutcomeAbort
}
av.l.Info().Str("uploadid", ev.UploadID).Interface("resourceID", ev.ResourceID).Str("virus", res.Description).Str("outcome", string(outcome)).Str("filename", ev.Filename).Str("user", ev.ExecutingUser.GetId().GetOpaqueId()).Bool("infected", res.Infected).Dur("duration", duration).Msg("File scanned")
av.log.Info().Str("uploadid", ev.UploadID).Interface("resourceID", ev.ResourceID).Str("virus", res.Description).Str("outcome", string(outcome)).Str("filename", ev.Filename).Str("user", ev.ExecutingUser.GetId().GetOpaqueId()).Bool("infected", res.Infected).Dur("duration", duration).Msg("File scanned")
if err := events.Publish(ctx, s, events.PostprocessingStepFinished{
FinishedStep: events.PPStepAntivirus,
Outcome: outcome,
@@ -210,7 +218,7 @@ func (av Antivirus) processEvent(e events.Event, s events.Publisher) error {
ErrorMsg: errmsg,
},
}); err != nil {
av.l.Fatal().Err(err).Str("uploadid", ev.UploadID).Interface("resourceID", ev.ResourceID).Msg("cannot publish events - exiting")
av.log.Fatal().Err(err).Str("uploadid", ev.UploadID).Interface("resourceID", ev.ResourceID).Msg("cannot publish events - exiting")
return fmt.Errorf("%w: %s", ErrFatal, err)
}
return nil
@@ -218,11 +226,24 @@ func (av Antivirus) processEvent(e events.Event, s events.Publisher) error {
// process the scan
func (av Antivirus) process(ev events.StartPostprocessingStep) (scanners.Result, error) {
if ev.Filesize == 0 || (0 < av.m && av.m < ev.Filesize) {
av.l.Info().Str("uploadid", ev.UploadID).Uint64("limit", av.m).Uint64("filesize", ev.Filesize).Msg("Skipping file to be virus scanned because its file size is higher than the defined limit.")
return scanners.Result{
ScanTime: time.Now(),
}, nil
if ev.Filesize == 0 {
av.log.Info().Str("uploadid", ev.UploadID).Msg("Skipping file to be virus scanned, file size is 0.")
return scanners.Result{ScanTime: time.Now()}, nil
}
headers := make(map[string]string)
switch {
case av.maxScanSize == 0:
// there is no size limit
break
case av.config.MaxScanSizeMode == config.MaxScanSizeModeSkip && ev.Filesize > av.maxScanSize:
// skip the file if it is bigger than the max scan size
av.log.Info().Str("uploadid", ev.UploadID).Uint64("filesize", ev.Filesize).
Msg("Skipping file to be virus scanned, file size is bigger than max scan size.")
return scanners.Result{ScanTime: time.Now()}, nil
case av.config.MaxScanSizeMode == config.MaxScanSizeModePartial && ev.Filesize > av.maxScanSize:
// set the range header to only download the first maxScanSize bytes
headers["Range"] = fmt.Sprintf("bytes=0-%d", av.maxScanSize-1)
}
var err error
@@ -230,56 +251,61 @@ func (av Antivirus) process(ev events.StartPostprocessingStep) (scanners.Result,
switch ev.UploadID {
default:
rrc, err = av.downloadViaToken(ev.URL)
rrc, err = av.downloadViaToken(ev.URL, headers)
case "":
rrc, err = av.downloadViaReva(ev.URL, ev.Token, ev.RevaToken)
rrc, err = av.downloadViaReva(ev.URL, ev.Token, ev.RevaToken, headers)
}
if err != nil {
av.l.Error().Err(err).Str("uploadid", ev.UploadID).Msg("error downloading file")
av.log.Error().Err(err).Str("uploadid", ev.UploadID).Msg("error downloading file")
return scanners.Result{}, err
}
defer rrc.Close()
av.l.Debug().Str("uploadid", ev.UploadID).Msg("Downloaded file successfully, starting virusscan")
defer func() {
_ = rrc.Close()
}()
res, err := av.s.Scan(scanners.Input{Body: rrc, Size: int64(ev.Filesize), Url: ev.URL, Name: ev.Filename})
av.log.Debug().Str("uploadid", ev.UploadID).Msg("Downloaded file successfully, starting virusscan")
res, err := av.scanner.Scan(scanners.Input{Body: rrc, Size: int64(ev.Filesize), Url: ev.URL, Name: ev.Filename})
if err != nil {
av.l.Error().Err(err).Str("uploadid", ev.UploadID).Msg("error scanning file")
av.log.Error().Err(err).Str("uploadid", ev.UploadID).Msg("error scanning file")
}
return res, err
}
// download will download the file
func (av Antivirus) downloadViaToken(url string) (io.ReadCloser, error) {
func (av Antivirus) downloadViaToken(url string, headers map[string]string) (io.ReadCloser, error) {
req, err := http.NewRequest(http.MethodGet, url, nil)
if err != nil {
return nil, err
}
return av.doDownload(req)
return av.doDownload(req, headers)
}
// download will download the file
func (av Antivirus) downloadViaReva(url string, dltoken string, revatoken string) (io.ReadCloser, error) {
ctx := ctxpkg.ContextSetToken(context.Background(), revatoken)
req, err := rhttp.NewRequest(ctx, http.MethodGet, url, nil)
func (av Antivirus) downloadViaReva(url string, dltoken string, revatoken string, headers map[string]string) (io.ReadCloser, error) {
req, err := rhttp.NewRequest(ctxpkg.ContextSetToken(context.Background(), revatoken), http.MethodGet, url, nil)
if err != nil {
return nil, err
}
req.Header.Set("X-Reva-Transfer", dltoken)
return av.doDownload(req)
return av.doDownload(req, headers)
}
func (av Antivirus) doDownload(req *http.Request) (io.ReadCloser, error) {
func (av Antivirus) doDownload(req *http.Request, headers map[string]string) (io.ReadCloser, error) {
for k, v := range headers {
req.Header.Add(k, v)
}
res, err := av.client.Do(req)
if err != nil {
return nil, err
}
if res.StatusCode != http.StatusOK {
res.Body.Close()
if !slices.Contains([]int{http.StatusOK, http.StatusPartialContent}, res.StatusCode) {
_ = res.Body.Close()
return nil, fmt.Errorf("unexpected status code from Download %v", res.StatusCode)
}

View File

@@ -11,7 +11,6 @@ import (
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
group "github.com/cs3org/go-cs3apis/cs3/identity/group/v1beta1"
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
"go.opentelemetry.io/otel/trace"
@@ -219,33 +218,16 @@ func processShareEvent(ctx context.Context, ref *provider.Reference, gwc gateway
// custom logic for item trashed event
func processItemTrashedEvent(ctx context.Context, ref *provider.Reference, gwc gateway.GatewayAPIClient, initiatorid string, itemID *provider.ResourceId) ([]string, FileEvent, error) {
resp, err := gwc.ListRecycle(ctx, &provider.ListRecycleRequest{
Ref: ref,
Key: itemID.GetOpaqueId(),
})
if err != nil {
return nil, FileEvent{}, err
}
if resp.GetStatus().GetCode() != rpc.Code_CODE_OK {
return nil, FileEvent{}, fmt.Errorf("error listing recycle: %s", resp.GetStatus().GetMessage())
data := FileEvent{
ItemID: storagespace.FormatResourceID(itemID),
// TODO: check with web if parentID is needed
// ParentItemID: storagespace.FormatResourceID(*item.GetRef().GetResourceId()),
SpaceID: storagespace.FormatStorageID(itemID.GetStorageId(), itemID.GetSpaceId()),
InitiatorID: initiatorid,
}
for _, item := range resp.GetRecycleItems() {
if item.GetKey() == itemID.GetOpaqueId() {
data := FileEvent{
ItemID: storagespace.FormatResourceID(itemID),
// TODO: check with web if parentID is needed
// ParentItemID: storagespace.FormatResourceID(*item.GetRef().GetResourceId()),
SpaceID: storagespace.FormatStorageID(itemID.GetStorageId(), itemID.GetSpaceId()),
InitiatorID: initiatorid,
}
users, err := utils.GetSpaceMembers(ctx, itemID.GetSpaceId(), gwc, utils.ViewerRole)
return users, data, err
}
}
return nil, FileEvent{}, errors.New("item not found in recycle bin")
users, err := utils.GetSpaceMembers(ctx, itemID.GetSpaceId(), gwc, utils.ViewerRole)
return users, data, err
}
// adds share related data to the FileEvent

View File

@@ -34,6 +34,7 @@ type Config struct {
EnableFederatedSharingIncoming bool `yaml:"enable_federated_sharing_incoming" env:"OC_ENABLE_OCM;FRONTEND_ENABLE_FEDERATED_SHARING_INCOMING" desc:"Changing this value is NOT supported. Enables support for incoming federated sharing for clients. The backend behaviour is not changed." introductionVersion:"1.0.0"`
EnableFederatedSharingOutgoing bool `yaml:"enable_federated_sharing_outgoing" env:"OC_ENABLE_OCM;FRONTEND_ENABLE_FEDERATED_SHARING_OUTGOING" desc:"Changing this value is NOT supported. Enables support for outgoing federated sharing for clients. The backend behaviour is not changed." introductionVersion:"1.0.0"`
SearchMinLength int `yaml:"search_min_length" env:"FRONTEND_SEARCH_MIN_LENGTH" desc:"Minimum number of characters to enter before a client should start a search for Share receivers. This setting can be used to customize the user experience if e.g too many results are displayed." introductionVersion:"1.0.0"`
Edition string `yaml:"edition" env:"OC_EDITION;FRONTEND_EDITION" desc:"Edition of OpenCloud. Used for branding purposes." introductionVersion:"1.0.0"`
DisableSSE bool `yaml:"disable_sse" env:"OC_DISABLE_SSE;FRONTEND_DISABLE_SSE" desc:"When set to true, clients are informed that the Server-Sent Events endpoint is not accessible." introductionVersion:"1.0.0"`
DefaultLinkPermissions int `yaml:"default_link_permissions" env:"FRONTEND_DEFAULT_LINK_PERMISSIONS" desc:"Defines the default permissions a link is being created with. Possible values are 0 (= internal link, for instance members only) and 1 (= public link with viewer permissions). Defaults to 1." introductionVersion:"1.0.0"`

View File

@@ -87,6 +87,7 @@ func DefaultConfig() *config.Config {
DefaultUploadProtocol: "tus",
DefaultLinkPermissions: 1,
SearchMinLength: 3,
Edition: "",
Checksums: config.Checksums{
SupportedTypes: []string{"sha1", "md5", "adler32"},
PreferredUploadType: "sha1",

View File

@@ -208,6 +208,7 @@ func FrontendConfigFromStruct(cfg *config.Config, logger log.Logger) (map[string
"needsDbUpgrade": false,
"version": version.Legacy,
"versionstring": version.LegacyString,
"edition": cfg.Edition,
"productname": "OpenCloud",
"product": "OpenCloud",
"productversion": version.GetString(),

View File

@@ -83,6 +83,7 @@ func NewDriveItemPermissionsService(logger log.Logger, gatewaySelector pool.Sele
gatewaySelector: gatewaySelector,
identityCache: identityCache,
config: config,
availableRoles: unifiedrole.GetRoles(unifiedrole.RoleFilterIDs(config.UnifiedRoles.AvailableRoles...)),
},
}, nil
}

View File

@@ -441,7 +441,6 @@ var _ = Describe("DriveItemPermissionsService", func() {
})
It("returns role denied", func() {
statResponse.Info.PermissionSet = roleconversions.NewManagerRole().CS3ResourcePermissions()
cfg.UnifiedRoles.AvailableRoles = []string{unifiedrole.UnifiedRoleViewerID, unifiedrole.UnifiedRoleDeniedID, unifiedrole.UnifiedRoleManagerID}
listSharesResponse.Shares = []*collaboration.Share{
{
Id: &collaboration.ShareId{OpaqueId: "1"},
@@ -465,11 +464,15 @@ var _ = Describe("DriveItemPermissionsService", func() {
}
listPublicSharesResponse.Share = []*link.PublicShare{}
cfg = defaults.FullDefaultConfig()
cfg.UnifiedRoles.AvailableRoles = []string{unifiedrole.UnifiedRoleViewerID, unifiedrole.UnifiedRoleDeniedID, unifiedrole.UnifiedRoleManagerID}
service, err := svc.NewDriveItemPermissionsService(log.NewLogger(), gatewaySelector, cache, cfg)
gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil)
gatewayClient.On("ListShares", mock.Anything, mock.Anything).Return(listSharesResponse, nil)
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gatewayClient.On("ListPublicShares", mock.Anything, mock.Anything).Return(listPublicSharesResponse, nil)
permissions, err := driveItemPermissionsService.ListPermissions(context.Background(), itemID, false, false)
permissions, err := service.ListPermissions(context.Background(), itemID, false, false)
Expect(err).ToNot(HaveOccurred())
Expect(len(permissions.LibreGraphPermissionsActionsAllowedValues)).ToNot(BeZero())
Expect(len(permissions.LibreGraphPermissionsRolesAllowedValues)).ToNot(BeZero())

View File

@@ -46,6 +46,7 @@ type BaseGraphService struct {
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
identityCache identity.IdentityCache
config *config.Config
availableRoles []*libregraph.UnifiedRoleDefinition
}
func (g BaseGraphService) getSpaceRootPermissions(ctx context.Context, spaceID *storageprovider.StorageSpaceId) ([]libregraph.Permission, error) {
@@ -86,8 +87,7 @@ func (g BaseGraphService) CS3ReceivedSharesToDriveItems(ctx context.Context, rec
return nil, err
}
availableRoles := unifiedrole.GetRoles(unifiedrole.RoleFilterIDs(g.config.UnifiedRoles.AvailableRoles...))
return cs3ReceivedSharesToDriveItems(ctx, g.logger, gatewayClient, g.identityCache, receivedShares, availableRoles)
return cs3ReceivedSharesToDriveItems(ctx, g.logger, gatewayClient, g.identityCache, receivedShares, g.availableRoles)
}
func (g BaseGraphService) CS3ReceivedOCMSharesToDriveItems(ctx context.Context, receivedShares []*ocm.ReceivedShare) ([]libregraph.DriveItem, error) {
@@ -96,8 +96,7 @@ func (g BaseGraphService) CS3ReceivedOCMSharesToDriveItems(ctx context.Context,
return nil, err
}
availableRoles := unifiedrole.GetRoles(unifiedrole.RoleFilterIDs(g.config.UnifiedRoles.AvailableRoles...))
return cs3ReceivedOCMSharesToDriveItems(ctx, g.logger, gatewayClient, g.identityCache, receivedShares, availableRoles)
return cs3ReceivedOCMSharesToDriveItems(ctx, g.logger, gatewayClient, g.identityCache, receivedShares, g.availableRoles)
}
func (g BaseGraphService) cs3SpacePermissionsToLibreGraph(ctx context.Context, space *storageprovider.StorageSpace, apiVersion APIVersion) []libregraph.Permission {
@@ -196,9 +195,8 @@ func (g BaseGraphService) cs3SpacePermissionsToLibreGraph(ctx context.Context, s
p.SetExpirationDateTime(time.Unix(int64(exp.GetSeconds()), int64(exp.GetNanos())))
}
availableRoles := unifiedrole.GetRoles(unifiedrole.RoleFilterIDs(g.config.UnifiedRoles.AvailableRoles...))
if role := unifiedrole.CS3ResourcePermissionsToRole(
availableRoles,
g.availableRoles,
perm,
unifiedrole.UnifiedRoleConditionDrive,
false,
@@ -601,7 +599,7 @@ func (g BaseGraphService) cs3UserShareToPermission(ctx context.Context, share *c
perm.SetCreatedDateTime(cs3TimestampToTime(share.GetCtime()))
}
role := unifiedrole.CS3ResourcePermissionsToRole(
unifiedrole.GetRoles(unifiedrole.RoleFilterIDs(g.config.UnifiedRoles.AvailableRoles...)),
g.availableRoles,
share.GetPermissions().GetPermissions(),
roleCondition,
false,
@@ -689,9 +687,8 @@ func (g BaseGraphService) cs3OCMShareToPermission(ctx context.Context, share *oc
}
}
availableRoles := unifiedrole.GetRoles(unifiedrole.RoleFilterIDs(g.config.UnifiedRoles.AvailableRoles...))
role := unifiedrole.CS3ResourcePermissionsToRole(
availableRoles,
g.availableRoles,
permissions,
roleCondition,
true,

View File

@@ -14,7 +14,7 @@ import (
// GetRoleDefinitions a list of permission roles than can be used when sharing with users or groups
func (g Graph) GetRoleDefinitions(w http.ResponseWriter, r *http.Request) {
render.Status(r, http.StatusOK)
render.JSON(w, r, unifiedrole.GetRoles(unifiedrole.RoleFilterIDs(g.config.UnifiedRoles.AvailableRoles...)))
render.JSON(w, r, g.availableRoles)
}
// GetRoleDefinition a permission role than can be used when sharing with users or groups

View File

@@ -31,6 +31,7 @@ import (
"github.com/opencloud-eu/opencloud/services/graph/pkg/identity"
"github.com/opencloud-eu/opencloud/services/graph/pkg/identity/ldap"
graphm "github.com/opencloud-eu/opencloud/services/graph/pkg/middleware"
"github.com/opencloud-eu/opencloud/services/graph/pkg/unifiedrole"
)
const (
@@ -148,6 +149,7 @@ func NewService(opts ...Option) (Graph, error) { //nolint:maintidx
identityCache: identityCache,
gatewaySelector: options.GatewaySelector,
config: options.Config,
availableRoles: unifiedrole.GetRoles(unifiedrole.RoleFilterIDs(options.Config.UnifiedRoles.AvailableRoles...)),
},
mux: m,
specialDriveItemsCache: spacePropertiesCache,

View File

@@ -10,7 +10,6 @@ import (
libregraph "github.com/owncloud/libre-graph-api-go"
"github.com/opencloud-eu/opencloud/services/graph/pkg/errorcode"
"github.com/opencloud-eu/opencloud/services/graph/pkg/unifiedrole"
)
// ListSharedWithMe lists the files shared with the current user.
@@ -40,8 +39,7 @@ func (g Graph) listSharedWithMe(ctx context.Context) ([]libregraph.DriveItem, er
g.logger.Error().Err(err).Msg("listing shares failed")
return nil, err
}
availableRoles := unifiedrole.GetRoles(unifiedrole.RoleFilterIDs(g.config.UnifiedRoles.AvailableRoles...))
driveItems, err := cs3ReceivedSharesToDriveItems(ctx, g.logger, gatewayClient, g.identityCache, listReceivedSharesResponse.GetShares(), availableRoles)
driveItems, err := cs3ReceivedSharesToDriveItems(ctx, g.logger, gatewayClient, g.identityCache, listReceivedSharesResponse.GetShares(), g.availableRoles)
if err != nil {
g.logger.Error().Err(err).Msg("could not convert received shares to drive items")
return nil, err
@@ -53,7 +51,7 @@ func (g Graph) listSharedWithMe(ctx context.Context) ([]libregraph.DriveItem, er
g.logger.Error().Err(err).Msg("listing shares failed")
return nil, err
}
ocmDriveItems, err := cs3ReceivedOCMSharesToDriveItems(ctx, g.logger, gatewayClient, g.identityCache, listReceivedOCMSharesResponse.GetShares(), availableRoles)
ocmDriveItems, err := cs3ReceivedOCMSharesToDriveItems(ctx, g.logger, gatewayClient, g.identityCache, listReceivedOCMSharesResponse.GetShares(), g.availableRoles)
if err != nil {
g.logger.Error().Err(err).Msg("could not convert received ocm shares to drive items")
return nil, err

View File

@@ -17,15 +17,16 @@ node-generate-prod: assets
.PHONY: assets
assets: pnpm-build \
assets/identifier/static \
assets/identifier/static/favicon.ico \
assets/identifier/static/favicon.svg \
assets/identifier/static/icon-lilac.svg
assets/identifier/static:
mkdir -p assets/identifier/static
.PHONY: assets/identifier/static/favicon.ico # force overwrite
assets/identifier/static/favicon.ico:
cp src/images/favicon.ico assets/identifier/static/favicon.ico
.PHONY: assets/identifier/static/favicon.svg # force overwrite
assets/identifier/static/favicon.svg:
cp src/images/favicon.svg assets/identifier/static/favicon.svg
rm assets/identifier/static/favicon.ico
.PHONY: assets/identifier/static/icon-lilac.svg
assets/identifier/static/icon-lilac.svg:

View File

@@ -102,7 +102,7 @@
"redux-logger": "^3.0.6",
"redux-thunk": "^2.4.2",
"render-if": "^0.1.1",
"web-vitals": "^3.5.2"
"web-vitals": "^4.2.4"
},
"devDependencies": {
"@babel/core": "7.26.10",
@@ -125,7 +125,7 @@
"eslint-plugin-i18next": "^6.1.1",
"eslint-plugin-import": "^2.30.0",
"eslint-plugin-jest": "^24.7.0",
"eslint-plugin-jsx-a11y": "^6.9.0",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-react": "^7.37.2",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-testing-library": "^3.10.2",
@@ -148,7 +148,7 @@
"resolve-url-loader": "^5.0.0",
"sass-loader": "^16.0.4",
"source-map-explorer": "^2.5.3",
"typescript": "^5.7.3",
"typescript": "^5.8.3",
"url-loader": "4.1.1",
"webpack": "5.96.1",
"webpack-manifest-plugin": "5.0.0",

View File

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="theme-color" content="#1b223d">
<link rel="shortcut icon" href="%PUBLIC_URL%/static/favicon.ico" type="image/x-icon">
<link rel="icon" href="%PUBLIC_URL%/static/favicon.svg" type="image/svg+xml">
<meta property="csp-nonce" content="__CSP_NONCE__">
<title>Sign in - OpenCloud</title>
</head>

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.dev/svgjs" width="512" height="512"><svg id="SvgjsSvg1001" xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><rect x=".02" y="0" width="512" height="512" fill="#20434f"></rect><polygon points="255.98 342.75 271.89 333.57 271.89 267.12 329.08 234.1 329.08 215.78 313.18 206.6 255.6 239.84 198.83 207.06 182.93 216.24 182.93 234.56 240.12 267.58 240.12 333.59 255.98 342.75" fill="#e2baff"></polygon><polygon points="401.95 150.82 256 66.56 256 66.56 256 66.56 110.05 150.82 110.05 187.5 256 103.24 401.95 187.5 401.95 150.82" fill="#e2baff"></polygon><polygon points="401.95 324.5 256 408.76 110.06 324.5 110.06 361.17 256 445.43 256 445.43 256 445.43 401.95 361.17 401.95 324.5" fill="#e2baff"></polygon></svg><style>@media (prefers-color-scheme: light) { :root { filter: none; } }
@media (prefers-color-scheme: dark) { :root { filter: none; } }
</style></svg>

After

Width:  |  Height:  |  Size: 1015 B

View File

@@ -77,6 +77,7 @@ func Server(cfg *config.Config) *cli.Command {
ocdav.Product(cfg.Status.Product),
ocdav.Version(cfg.Status.Version),
ocdav.VersionString(cfg.Status.VersionString),
ocdav.Edition(cfg.Status.Edition),
ocdav.MachineAuthAPIKey(cfg.MachineAuthAPIKey),
ocdav.Broker(broker.NoOp{}),
// ocdav.FavoriteManager() // FIXME needs a proper persistence implementation https://github.com/owncloud/ocis/issues/1228

View File

@@ -81,4 +81,5 @@ type Status struct {
Product string
ProductName string
ProductVersion string
Edition string `yaml:"edition" env:"OC_EDITION;OCDAV_EDITION" desc:"Edition of OpenCloud. Used for branding purposes." introductionVersion:"1.0.0"`
}

View File

@@ -92,6 +92,7 @@ func DefaultConfig() *config.Config {
ProductVersion: version.GetString(),
Product: "OpenCloud",
ProductName: "OpenCloud",
Edition: "",
},
}
}

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v2.53.0. DO NOT EDIT.
// Code generated by mockery v2.53.2. DO NOT EDIT.
package mocks

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v2.53.0. DO NOT EDIT.
// Code generated by mockery v2.53.2. DO NOT EDIT.
package mocks

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v2.53.0. DO NOT EDIT.
// Code generated by mockery v2.53.2. DO NOT EDIT.
package mocks

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v2.53.0. DO NOT EDIT.
// Code generated by mockery v2.53.2. DO NOT EDIT.
package mocks

View File

@@ -1,4 +1,4 @@
// Code generated by mockery v2.53.0. DO NOT EDIT.
// Code generated by mockery v2.53.2. DO NOT EDIT.
package mocks

View File

@@ -108,7 +108,7 @@ func ListUploadSessions(cfg *config.Config) *cli.Command {
var fsStream events.Stream
if cfg.Driver == "posix" {
// We need to init the posix driver with 'scanfs' disabled
drivers["posix"] = revaconfig.Posix(cfg, false)
drivers["posix"] = revaconfig.Posix(cfg, false, false)
// Also posix refuses to start without an events stream
fsStream, err = event.NewStream(cfg)
if err != nil {

View File

@@ -85,7 +85,7 @@ func Local(cfg *config.Config) map[string]interface{} {
}
// Posix is the config mapping for the Posix storage driver
func Posix(cfg *config.Config, enableFSScan bool) map[string]interface{} {
func Posix(cfg *config.Config, enableFSScan, enableFSWatch bool) map[string]interface{} {
return map[string]interface{}{
"root": cfg.Drivers.Posix.Root,
"personalspacepath_template": cfg.Drivers.Posix.PersonalSpacePathTemplate,
@@ -137,7 +137,7 @@ func Posix(cfg *config.Config, enableFSScan bool) map[string]interface{} {
"use_space_groups": cfg.Drivers.Posix.UseSpaceGroups,
"enable_fs_revisions": cfg.Drivers.Posix.EnableFSRevisions,
"scan_fs": enableFSScan,
"watch_fs": cfg.Drivers.Posix.WatchFS,
"watch_fs": enableFSWatch,
"watch_type": cfg.Drivers.Posix.WatchType,
"watch_path": cfg.Drivers.Posix.WatchPath,
"watch_folder_kafka_brokers": cfg.Drivers.Posix.WatchFolderKafkaBrokers,

View File

@@ -16,7 +16,7 @@ func StorageProviderDrivers(cfg *config.Config) map[string]interface{} {
"decomposed": DecomposedNoEvents(cfg),
"s3": S3(cfg),
"decomposeds3": DecomposedS3NoEvents(cfg),
"posix": Posix(cfg, true),
"posix": Posix(cfg, true, cfg.Drivers.Posix.WatchFS),
"ocis": Decomposed(cfg), // deprecated: use decomposed
"s3ng": DecomposedS3NoEvents(cfg), // deprecated: use decomposeds3
@@ -36,7 +36,7 @@ func DataProviderDrivers(cfg *config.Config) map[string]interface{} {
"decomposed": Decomposed(cfg),
"s3": S3(cfg),
"decomposeds3": DecomposedS3(cfg),
"posix": Posix(cfg, false),
"posix": Posix(cfg, false, false),
"ocis": Decomposed(cfg), // deprecated: use decomposed
"s3ng": DecomposedS3NoEvents(cfg), // deprecated: use decomposeds3

View File

@@ -1,6 +1,6 @@
SHELL := bash
NAME := web
WEB_ASSETS_VERSION = v2.1.0
WEB_ASSETS_VERSION = v2.2.0
WEB_ASSETS_BRANCH = main
ifneq (, $(shell command -v go 2> /dev/null)) # suppress `command not found warnings` for non go targets in CI

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.dev/svgjs" width="512" height="512"><svg id="SvgjsSvg1001" xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><rect x=".02" y="0" width="512" height="512" fill="#20434f"></rect><polygon points="255.98 342.75 271.89 333.57 271.89 267.12 329.08 234.1 329.08 215.78 313.18 206.6 255.6 239.84 198.83 207.06 182.93 216.24 182.93 234.56 240.12 267.58 240.12 333.59 255.98 342.75" fill="#e2baff"></polygon><polygon points="401.95 150.82 256 66.56 256 66.56 256 66.56 110.05 150.82 110.05 187.5 256 103.24 401.95 187.5 401.95 150.82" fill="#e2baff"></polygon><polygon points="401.95 324.5 256 408.76 110.06 324.5 110.06 361.17 256 445.43 256 445.43 256 445.43 401.95 361.17 401.95 324.5" fill="#e2baff"></polygon></svg><style>@media (prefers-color-scheme: light) { :root { filter: none; } }
@media (prefers-color-scheme: dark) { :root { filter: none; } }
</style></svg>

After

Width:  |  Height:  |  Size: 1015 B

View File

@@ -43,7 +43,7 @@
}
},
"logo": "themes/opencloud-dev/assets/logo.svg",
"favicon": "themes/opencloud-dev/assets/favicon.jpg"
"favicon": "themes/opencloud-dev/assets/favicon.svg"
},
"themes": [
{

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:svgjs="http://svgjs.dev/svgjs" width="512" height="512"><svg id="SvgjsSvg1001" xmlns="http://www.w3.org/2000/svg" width="512" height="512" viewBox="0 0 512 512"><rect x=".02" y="0" width="512" height="512" fill="#20434f"></rect><polygon points="255.98 342.75 271.89 333.57 271.89 267.12 329.08 234.1 329.08 215.78 313.18 206.6 255.6 239.84 198.83 207.06 182.93 216.24 182.93 234.56 240.12 267.58 240.12 333.59 255.98 342.75" fill="#e2baff"></polygon><polygon points="401.95 150.82 256 66.56 256 66.56 256 66.56 110.05 150.82 110.05 187.5 256 103.24 401.95 187.5 401.95 150.82" fill="#e2baff"></polygon><polygon points="401.95 324.5 256 408.76 110.06 324.5 110.06 361.17 256 445.43 256 445.43 256 445.43 401.95 361.17 401.95 324.5" fill="#e2baff"></polygon></svg><style>@media (prefers-color-scheme: light) { :root { filter: none; } }
@media (prefers-color-scheme: dark) { :root { filter: none; } }
</style></svg>

After

Width:  |  Height:  |  Size: 1015 B

View File

@@ -50,7 +50,7 @@
"web": {
"defaults": {
"logo": "themes/opencloud/assets/logo.svg",
"favicon": "themes/opencloud/assets/favicon.ico",
"favicon": "themes/opencloud/assets/favicon.svg",
"designTokens": {
"breakpoints": {
"xsmall-max": "",
@@ -94,9 +94,9 @@
"label": "Light Theme",
"designTokens": {
"roles": {
"primary": "#07677F",
"primary": "#E2BAFF",
"surfaceTint": "#07677F",
"onPrimary": "#FFFFFF",
"onPrimary": "#19353F",
"primaryContainer": "#B7EAFF",
"onPrimaryContainer": "#001F28",
"secondary": "#20434f",
@@ -147,17 +147,6 @@
"onChrome": "#ffffff"
},
"colorPalette": {
"background-accentuate": "rgba(255, 255, 5, 0.1)",
"background-default": "#ffffff",
"background-highlight": "#f1f3f4",
"background-hover": "#f4e5ff",
"background-muted": "#f8f8f8",
"background-secondary": "#ffffff",
"background-chrome": "#20434F",
"background-sidebar": "#F1F3F4",
"border": "#ecebee",
"color-components-apptopbar-background": "transparent",
"color-components-apptopbar-border": "#ceddee",
"icon-archive": "#fbbe54",
"icon-audio": "#700460",
"icon-document": "#3b44a6",
@@ -167,46 +156,7 @@
"icon-pdf": "#ec0d47",
"icon-presentation": "#ee6b3b",
"icon-spreadsheet": "#15c286",
"icon-video": "#045459",
"input-bg": "#ffffff",
"input-border": "#396676",
"input-text-default": "#19353f",
"input-text-muted": "#20434f",
"swatch-brand-contrast": "#19353f",
"swatch-brand-default": "#E2BAFF",
"swatch-brand-hover": "#f4e5ff",
"swatch-brand-muted": "#CA8DF5",
"swatch-primary-contrast": "#ffffff",
"swatch-primary-default": "#20434f",
"swatch-primary-gradient": "#20434f",
"swatch-primary-gradient-hover": "#20434f",
"swatch-primary-hover": "#20434f",
"swatch-primary-muted": "#20434f",
"swatch-primary-muted-hover": "#20434f",
"swatch-passive-contrast": "#ffffff",
"swatch-passive-default": "#19353f",
"swatch-passive-hover": "#19353f",
"swatch-passive-hover-outline": "#ffffff",
"swatch-passive-muted": "#19353f",
"swatch-inverse-contrast": "#19353f",
"swatch-inverse-default": "#ffffff",
"swatch-inverse-hover": "#ffffff",
"swatch-inverse-muted": "#dadada",
"swatch-danger-contrast": "#ffffff",
"swatch-danger-default": "#ba1a1a",
"swatch-danger-hover": "#b12b2b",
"swatch-danger-muted": "rgb(204, 117, 117)",
"swatch-success-contrast": "#ffffff",
"swatch-success-default": "rgb(3, 84, 63)",
"swatch-success-hover": "#023b2c",
"swatch-success-muted": "rgb(83, 150, 10)",
"swatch-warning-contrast": "#ffffff",
"swatch-warning-default": "rgb(183, 76, 27)",
"swatch-warning-hover": "#a04318",
"swatch-warning-muted": "rgba(183, 76, 27, .5)",
"text-default": "#19353f",
"text-inverse": "#ffffff",
"text-muted": "#19353f"
"icon-video": "#045459"
}
}
}

View File

@@ -466,7 +466,7 @@ ANTIVIRUS_SCANNER_TYPE="clamav" \
ANTIVIRUS_CLAMAV_SOCKET="tcp://host.docker.internal:3310" \
POSTPROCESSING_STEPS="virusscan" \
OC_ASYNC_UPLOADS=true \
OC_ADD_RUN_SERVICES="antivirus"
OC_ADD_RUN_SERVICES="antivirus" \
opencloud/bin/opencloud server
```
@@ -474,7 +474,7 @@ Note:
The value for `ANTIVIRUS_CLAMAV_SOCKET` is an example which needs adaption according your OS.
For antivirus running localy on Linux OS, use `ANTIVIRUS_CLAMAV_SOCKET= "/var/run/clamav/clamd.ctl"`.
For antivirus running localy on Mac OS, use `ANTIVIRUS_CLAMAV_SOCKET= "/tmp/clamd.socket"`.
For antivirus running localy on Mac OS, use `ANTIVIRUS_CLAMAV_SOCKET= "/tmp/clamd.sock"`.
For antivirus running with docker, use `ANTIVIRUS_CLAMAV_SOCKET= "tcp://host.docker.internal:3310"`
#### Run the Acceptance Test
@@ -576,7 +576,7 @@ make -C opencloud dev-docker
```
### Choose STORAGE_DRIVER
By default, the system uses `decomposed` storage. However, you can override this by setting the `STORAGE_DRIVER` environment variable.
By default, the system uses `posix` storage. However, you can override this by setting the `STORAGE_DRIVER` environment variable.
### Run a script that starts the openCloud server in the docker and runs the API tests locally (for debugging purposes)

View File

@@ -214,6 +214,11 @@ class CapabilitiesContext implements Context {
$this->featureContext->theHTTPStatusCodeShouldBe(200, '', $response);
$responseXmlObject = HttpRequestHelper::getResponseXml($response, __METHOD__)->data->capabilities;
$edition = $this->getParameterValueFromXml(
$responseXmlObject,
'core',
'status@@@edition'
);
$product = $this->getParameterValueFromXml(
$responseXmlObject,
@@ -238,6 +243,7 @@ class CapabilitiesContext implements Context {
);
}
$jsonExpectedDecoded['edition'] = $edition;
$jsonExpectedDecoded['product'] = $product;
$jsonExpectedDecoded['productname'] = $productName;

View File

@@ -2042,6 +2042,17 @@ class FeatureContext extends BehatVariablesContext {
);
}
/**
* @return string
*/
public function getEditionFromStatus(): string {
$decodedResponse = $this->getJsonDecodedStatusPhp();
if (isset($decodedResponse['edition'])) {
return $decodedResponse['edition'];
}
return '';
}
/**
* @return string|null
*/
@@ -2271,6 +2282,14 @@ class FeatureContext extends BehatVariablesContext {
],
"parameter" => []
],
[
"code" => "%edition%",
"function" => [
$this,
"getEditionFromStatus"
],
"parameter" => []
],
[
"code" => "%version%",
"function" => [

View File

@@ -193,7 +193,6 @@
- [apiServiceAvailability/serviceAvailabilityCheck.feature:125](https://github.com/opencloud-eu/opencloud/blob/main/tests/acceptance/features/apiServiceAvailability/serviceAvailabilityCheck.feature#L125)
#### [Skip tests for different languages](https://github.com/opencloud-eu/opencloud/issues/183)
- [apiAntivirus/antivirus.feature:311](https://github.com/opencloud-eu/opencloud/blob/main/tests/acceptance/features/apiAntivirus/antivirus.feature#L311)
- [apiActivities/activities.feature:2598](https://github.com/opencloud-eu/opencloud/blob/main/tests/acceptance/features/apiActivities/activities.feature#L2598)

View File

@@ -308,7 +308,7 @@ Feature: antivirus
| dav-path-version | language | subject | message |
| old | es | Virus encontrado | Virus encontrado en aFileWithVirus.txt. La subida no ha sido posible. Virus: Eicar-Signature |
| new | es | Virus encontrado | Virus encontrado en aFileWithVirus.txt. La subida no ha sido posible. Virus: Eicar-Signature |
| spaces | es | Virus encontrado | Virus encontrado en aFileWithVirus.txt. La subida no ha sido posible. Eicar-Signature |
| spaces | es | Virus encontrado | Virus encontrado en aFileWithVirus.txt. La subida no ha sido posible. Virus: Eicar-Signature |
| old | de | Virus gefunden | In aFileWithVirus.txt wurde potenziell schädlicher Code gefunden. Das Hochladen wurde abgebrochen. Grund: Eicar-Signature |
| new | de | Virus gefunden | In aFileWithVirus.txt wurde potenziell schädlicher Code gefunden. Das Hochladen wurde abgebrochen. Grund: Eicar-Signature |
| spaces | de | Virus gefunden | In aFileWithVirus.txt wurde potenziell schädlicher Code gefunden. Das Hochladen wurde abgebrochen. Grund: Eicar-Signature |

View File

@@ -193,12 +193,17 @@ Feature: capabilities
"status": {
"type": "object",
"required": [
"edition",
"product",
"productname",
"version",
"versionstring"
],
"properties": {
"edition": {
"type": "string",
"enum": ["%edition%"]
},
"product": {
"type": "string",
"enum": ["%productname%"]
@@ -225,6 +230,7 @@ Feature: capabilities
"type": "object",
"required": [
"string",
"edition",
"product"
],
"properties": {
@@ -232,6 +238,10 @@ Feature: capabilities
"type": "string",
"enum": ["%versionstring%"]
},
"edition": {
"type": "string",
"enum": ["%edition%"]
},
"product": {
"type": "string",
"enum": ["%productname%"]

View File

@@ -47,6 +47,7 @@ Feature: default capabilities for normal user
"required": [
"version",
"versionstring",
"edition",
"productname"
],
"properties": {
@@ -56,6 +57,9 @@ Feature: default capabilities for normal user
"versionstring": {
"const": "%versionstring%"
},
"edition": {
"const": "%edition%"
},
"productname": {
"const": "%productname%"
}

View File

@@ -8,5 +8,5 @@ Feature: Status
When the administrator requests status.php
Then the status.php response should include
"""
{"installed":true,"maintenance":false,"needsDbUpgrade":false,"version":"$CURRENT_VERSION","versionstring":"$CURRENT_VERSION_STRING","productname":"$PRODUCTNAME","product":"$PRODUCT"}
{"installed":true,"maintenance":false,"needsDbUpgrade":false,"version":"$CURRENT_VERSION","versionstring":"$CURRENT_VERSION_STRING","edition":"$EDITION","productname":"$PRODUCTNAME","product":"$PRODUCT"}
"""

View File

@@ -4,7 +4,7 @@
export LOCAL_TEST=true
export START_EMAIL=true
export WITH_WRAPPER=true
export STORAGE_DRIVER=${STORAGE_DRIVER:-decomposed}
export STORAGE_DRIVER=${STORAGE_DRIVER:-posix}
export TEST_ROOT_PATH="/drone/src/tests"
# LOCAL TEST WITHOUT EXTRA ENVS

View File

@@ -7,15 +7,13 @@
ROOT_PATH="$1"
if [ -z "$1" ]; then
ROOT_PATH="/drone/src"
ROOT_PATH="/woodpecker/src/github.com/opencloud-eu/opencloud"
fi
BINGO_DIR="$ROOT_PATH/.bingo"
# generate hash of a .bingo folder
BINGO_HASH=$(cat "$BINGO_DIR"/* | sha256sum | cut -d ' ' -f 1)
URL="$CACHE_ENDPOINT/$CACHE_BUCKET/opencloud/go-bin/$BINGO_HASH/$2"
mc alias set s3 "$MC_HOST" "$AWS_ACCESS_KEY_ID" "$AWS_SECRET_ACCESS_KEY"
if mc ls --json s3/"$CACHE_BUCKET"/opencloud/go-bin/"$BINGO_HASH"/$2 | grep "\"status\":\"success\""; then

View File

@@ -0,0 +1,102 @@
version: "2"
linters:
default: all
disable:
- asasalint
- asciicheck
- bidichk
- bodyclose
- canonicalheader
- containedctx
- contextcheck
- copyloopvar
- cyclop
- decorder
- depguard
- dogsled
- dupl
- dupword
- durationcheck
- err113
- errcheck
- errchkjson
- errname
- errorlint
- exhaustive
- exhaustruct
- exptostd
- fatcontext
- forbidigo
- forcetypeassert
- funlen
- ginkgolinter
- gocheckcompilerdirectives
- gochecknoglobals
- gochecknoinits
- gochecksumtype
- gocognit
- goconst
- gocritic
- gocyclo
- godot
- godox
- goheader
- gomoddirectives
- gomodguard
- goprintffuncname
- gosec
- gosmopolitan
- govet
- grouper
- iface
- importas
- inamedparam
- ineffassign
- interfacebloat
- intrange
- ireturn
- lll
- loggercheck
- maintidx
- makezero
- mirror
- misspell
- mnd
- musttag
- nakedret
- nestif
- nilerr
- nilnesserr
- nilnil
- nlreturn
- noctx
- nolintlint
- nonamedreturns
- nosprintfhostport
- paralleltest
- perfsprint
- prealloc
- predeclared
- promlinter
- protogetter
- reassign
- recvcheck
- revive
- rowserrcheck
- sloglint
- spancheck
- sqlclosecheck
- staticcheck
- tagalign
- tagliatelle
- testableexamples
- testifylint
- testpackage
- thelper
- tparallel
- unparam
- varnamelen
- whitespace
- wrapcheck
- wsl
- zerologlint

View File

@@ -3,7 +3,7 @@ GOCMD=go
linters-install:
@golangci-lint --version >/dev/null 2>&1 || { \
echo "installing linting tools..."; \
curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s v1.41.1; \
curl -sfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh| sh -s v2.0.2; \
}
lint: linters-install

View File

@@ -1,7 +1,6 @@
Package validator
=================
<img align="right" src="logo.png">[![Join the chat at https://gitter.im/go-playground/validator](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/go-playground/validator?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
![Project status](https://img.shields.io/badge/version-10.25.0-green.svg)
<img align="right" src="logo.png">![Project status](https://img.shields.io/badge/version-10.25.0-green.svg)
[![Build Status](https://github.com/go-playground/validator/actions/workflows/workflow.yml/badge.svg)](https://github.com/go-playground/validator/actions)
[![Coverage Status](https://coveralls.io/repos/go-playground/validator/badge.svg?branch=master&service=github)](https://coveralls.io/github/go-playground/validator?branch=master)
[![Go Report Card](https://goreportcard.com/badge/github.com/go-playground/validator)](https://goreportcard.com/report/github.com/go-playground/validator)
@@ -173,6 +172,7 @@ validate := validator.New(validator.WithRequiredStructEnabled())
| spicedb | SpiceDb ObjectID/Permission/Type |
| datetime | Datetime |
| e164 | e164 formatted phone number |
| ein | U.S. Employeer Identification Number |
| email | E-mail String
| eth_addr | Ethereum Address |
| hexadecimal | Hexadecimal String |

View File

@@ -9,6 +9,7 @@ import (
"fmt"
"io/fs"
"net"
"net/mail"
"net/url"
"os"
"reflect"
@@ -242,6 +243,7 @@ var (
"mongodb_connection_string": isMongoDBConnectionString,
"cron": isCron,
"spicedb": isSpiceDB,
"ein": isEIN,
}
)
@@ -258,7 +260,7 @@ func parseOneOfParam2(s string) []string {
oneofValsCacheRWLock.Lock()
vals = splitParamsRegex().FindAllString(s, -1)
for i := 0; i < len(vals); i++ {
vals[i] = strings.Replace(vals[i], "'", "", -1)
vals[i] = strings.ReplaceAll(vals[i], "'", "")
}
oneofValsCache[s] = vals
oneofValsCacheRWLock.Unlock()
@@ -1376,7 +1378,6 @@ func isEqIgnoreCase(fl FieldLevel) bool {
param := fl.Param()
switch field.Kind() {
case reflect.String:
return strings.EqualFold(field.String(), param)
}
@@ -1606,7 +1607,6 @@ func isImage(fl FieldLevel) bool {
case reflect.String:
filePath := field.String()
fileInfo, err := os.Stat(filePath)
if err != nil {
return false
}
@@ -1619,7 +1619,9 @@ func isImage(fl FieldLevel) bool {
if err != nil {
return false
}
defer file.Close()
defer func() {
_ = file.Close()
}()
mime, err := mimetype.DetectReader(file)
if err != nil {
@@ -1635,7 +1637,6 @@ func isImage(fl FieldLevel) bool {
// isFilePath is the validation function for validating if the current field's value is a valid file path.
func isFilePath(fl FieldLevel) bool {
var exists bool
var err error
@@ -1695,6 +1696,10 @@ func isE164(fl FieldLevel) bool {
// isEmail is the validation function for validating if the current field's value is a valid email address.
func isEmail(fl FieldLevel) bool {
_, err := mail.ParseAddress(fl.Field().String())
if err != nil {
return false
}
return emailRegex().MatchString(fl.Field().String())
}
@@ -2227,7 +2232,6 @@ func isGt(fl FieldLevel) bool {
case reflect.Struct:
if field.Type().ConvertibleTo(timeType) {
return field.Convert(timeType).Interface().(time.Time).After(time.Now().UTC())
}
}
@@ -2464,7 +2468,6 @@ func isLt(fl FieldLevel) bool {
case reflect.Struct:
if field.Type().ConvertibleTo(timeType) {
return field.Convert(timeType).Interface().(time.Time).Before(time.Now().UTC())
}
}
@@ -2644,7 +2647,6 @@ func isDir(fl FieldLevel) bool {
// isDirPath is the validation function for validating if the current field's value is a valid directory.
func isDirPath(fl FieldLevel) bool {
var exists bool
var err error
@@ -2957,6 +2959,12 @@ func isCveFormat(fl FieldLevel) bool {
// a valid dns RFC 1035 label, defined in RFC 1035.
func isDnsRFC1035LabelFormat(fl FieldLevel) bool {
val := fl.Field().String()
size := len(val)
if size > 63 {
return false
}
return dnsRegexRFC1035Label().MatchString(val)
}
@@ -3060,3 +3068,14 @@ func isCron(fl FieldLevel) bool {
cronString := fl.Field().String()
return cronRegex().MatchString(cronString)
}
// isEIN is the validation function for validating if the current field's value is a valid U.S. Employer Identification Number (EIN)
func isEIN(fl FieldLevel) bool {
field := fl.Field()
if field.Len() != 10 {
return false
}
return einRegex().MatchString(field.String())
}

View File

@@ -309,7 +309,7 @@ func (v *Validate) parseFieldTagsRecursive(tag string, fieldName string, alias s
}
if len(vals) > 1 {
current.param = strings.Replace(strings.Replace(vals[1], utf8HexComma, ",", -1), utf8Pipe, "|", -1)
current.param = strings.ReplaceAll(strings.ReplaceAll(vals[1], utf8HexComma, ","), utf8Pipe, "|")
}
}
current.isBlockEnd = true

View File

@@ -959,7 +959,7 @@ Although an empty string is a valid base64 URL safe value, this will report
an empty string as an error, if you wish to accept an empty string as valid
you can use this with the omitempty tag.
Usage: base64url
Usage: base64rawurl
# Bitcoin Address
@@ -1134,6 +1134,12 @@ This validates that a string value contains a valid longitude.
Usage: longitude
# Employeer Identification Number EIN
This validates that a string value contains a valid U.S. Employer Identification Number.
Usage: ein
# Social Security Number SSN
This validates that a string value contains a valid U.S. Social Security Number.

View File

@@ -69,7 +69,7 @@ const (
splitParamsRegexString = `'[^']*'|\S+`
bicRegexString = `^[A-Za-z]{6}[A-Za-z0-9]{2}([A-Za-z0-9]{3})?$`
semverRegexString = `^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$` // numbered capture groups https://semver.org/
dnsRegexStringRFC1035Label = "^[a-z]([-a-z0-9]*[a-z0-9]){0,62}$"
dnsRegexStringRFC1035Label = "^[a-z]([-a-z0-9]*[a-z0-9])?$"
cveRegexString = `^CVE-(1999|2\d{3})-(0[^0]\d{2}|0\d[^0]\d{1}|0\d{2}[^0]|[1-9]{1}\d{3,})$` // CVE Format Id https://cve.mitre.org/cve/identifiers/syntaxchange.html
mongodbIdRegexString = "^[a-f\\d]{24}$"
mongodbConnStringRegexString = "^mongodb(\\+srv)?:\\/\\/(([a-zA-Z\\d]+):([a-zA-Z\\d$:\\/?#\\[\\]@]+)@)?(([a-z\\d.-]+)(:[\\d]+)?)((,(([a-z\\d.-]+)(:(\\d+))?))*)?(\\/[a-zA-Z-_]{1,64})?(\\?(([a-zA-Z]+)=([a-zA-Z\\d]+))(&(([a-zA-Z\\d]+)=([a-zA-Z\\d]+))?)*)?$"
@@ -77,6 +77,7 @@ const (
spicedbIDRegexString = `^(([a-zA-Z0-9/_|\-=+]{1,})|\*)$`
spicedbPermissionRegexString = "^([a-z][a-z0-9_]{1,62}[a-z0-9])?$"
spicedbTypeRegexString = "^([a-z][a-z0-9_]{1,61}[a-z0-9]/)?[a-z][a-z0-9_]{1,62}[a-z0-9]$"
einRegexString = "^(\\d{2}-\\d{7})$"
)
func lazyRegexCompile(str string) func() *regexp.Regexp {
@@ -160,4 +161,5 @@ var (
spicedbIDRegex = lazyRegexCompile(spicedbIDRegexString)
spicedbPermissionRegex = lazyRegexCompile(spicedbPermissionRegexString)
spicedbTypeRegex = lazyRegexCompile(spicedbTypeRegexString)
einRegex = lazyRegexCompile(einRegexString)
)

View File

@@ -46,9 +46,9 @@ type StructLevel interface {
//
// NOTES:
//
// fieldName and altName get appended to the existing namespace that
// validator is on. e.g. pass 'FirstName' or 'Names[0]' depending
// on the nesting
// fieldName and structFieldName get appended to the existing
// namespace that validator is on. e.g. pass 'FirstName' or
// 'Names[0]' depending on the nesting
//
// tag can be an existing validation tag or just something you make up
// and process on the flip side it's up to you.

View File

@@ -217,17 +217,18 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
var err error
var t string
var f64 float64
var digits uint64
var kind reflect.Kind
if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:]))
}
fn := func() (err error) {
if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:]))
}
f64, err := strconv.ParseFloat(fe.Param(), 64)
if err != nil {
goto END
f64, err = strconv.ParseFloat(fe.Param(), 64)
return
}
kind = fe.Kind()
@@ -240,6 +241,11 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var c string
err = fn()
if err != nil {
goto END
}
c, err = ut.C("min-string-character", f64, digits, ut.FmtNumber(f64, digits))
if err != nil {
goto END
@@ -250,6 +256,11 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
case reflect.Slice, reflect.Map, reflect.Array:
var c string
err = fn()
if err != nil {
goto END
}
c, err = ut.C("min-items-item", f64, digits, ut.FmtNumber(f64, digits))
if err != nil {
goto END
@@ -258,6 +269,16 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
t, err = ut.T("min-items", fe.Field(), c)
default:
if fe.Type() == reflect.TypeOf(time.Duration(0)) {
t, err = ut.T("min-number", fe.Field(), fe.Param())
goto END
}
err = fn()
if err != nil {
goto END
}
t, err = ut.T("min-number", fe.Field(), ut.FmtNumber(f64, digits))
}
@@ -305,17 +326,18 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
customTransFunc: func(ut ut.Translator, fe validator.FieldError) string {
var err error
var t string
var f64 float64
var digits uint64
var kind reflect.Kind
if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:]))
}
fn := func() (err error) {
if idx := strings.Index(fe.Param(), "."); idx != -1 {
digits = uint64(len(fe.Param()[idx+1:]))
}
f64, err := strconv.ParseFloat(fe.Param(), 64)
if err != nil {
goto END
f64, err = strconv.ParseFloat(fe.Param(), 64)
return
}
kind = fe.Kind()
@@ -328,6 +350,11 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
var c string
err = fn()
if err != nil {
goto END
}
c, err = ut.C("max-string-character", f64, digits, ut.FmtNumber(f64, digits))
if err != nil {
goto END
@@ -338,6 +365,11 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
case reflect.Slice, reflect.Map, reflect.Array:
var c string
err = fn()
if err != nil {
goto END
}
c, err = ut.C("max-items-item", f64, digits, ut.FmtNumber(f64, digits))
if err != nil {
goto END
@@ -346,6 +378,16 @@ func RegisterDefaultTranslations(v *validator.Validate, trans ut.Translator) (er
t, err = ut.T("max-items", fe.Field(), c)
default:
if fe.Type() == reflect.TypeOf(time.Duration(0)) {
t, err = ut.T("max-number", fe.Field(), fe.Param())
goto END
}
err = fn()
if err != nil {
goto END
}
t, err = ut.T("max-number", fe.Field(), ut.FmtNumber(f64, digits))
}

View File

@@ -1,5 +1,4 @@
# This is an example goreleaser.yaml file with some sane defaults.
# Make sure to check the documentation at http://goreleaser.com
version: 2
builds:
-
@@ -27,16 +26,7 @@ builds:
archives:
-
id: cpuid
name_template: "cpuid-{{ .Os }}_{{ .Arch }}_{{ .Version }}"
replacements:
aix: AIX
darwin: OSX
linux: Linux
windows: Windows
386: i386
amd64: x86_64
freebsd: FreeBSD
netbsd: NetBSD
name_template: "cpuid-{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
format_overrides:
- goos: windows
format: zip
@@ -44,8 +34,6 @@ archives:
- LICENSE
checksum:
name_template: 'checksums.txt'
snapshot:
name_template: "{{ .Tag }}-next"
changelog:
sort: asc
filters:
@@ -58,7 +46,7 @@ changelog:
nfpms:
-
file_name_template: "cpuid_package_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
file_name_template: "cpuid_package_{{ .Os }}_{{ .Arch }}{{ if .Arm }}v{{ .Arm }}{{ end }}"
vendor: Klaus Post
homepage: https://github.com/klauspost/cpuid
maintainer: Klaus Post <klauspost@gmail.com>
@@ -67,8 +55,3 @@ nfpms:
formats:
- deb
- rpm
replacements:
darwin: Darwin
linux: Linux
freebsd: FreeBSD
amd64: x86_64

View File

@@ -282,7 +282,9 @@ Exit Code 1
| AMXINT8 | Tile computational operations on 8-bit integers |
| AMXFP16 | Tile computational operations on FP16 numbers |
| AMXFP8 | Tile computational operations on FP8 numbers |
| AMXCOMPLEX | Tile computational operations on complex numbers |
| AMXTILE | Tile architecture |
| AMXTF32 | Matrix Multiplication of TF32 Tiles into Packed Single Precision Tile |
| APX_F | Intel APX |
| AVX | AVX functions |
| AVX10 | If set the Intel AVX10 Converged Vector ISA is supported |
@@ -480,12 +482,16 @@ Exit Code 1
| DCPOP | Data cache clean to Point of Persistence (DC CVAP) |
| EVTSTRM | Generic timer |
| FCMA | Floatin point complex number addition and multiplication |
| FHM | FMLAL and FMLSL instructions |
| FP | Single-precision and double-precision floating point |
| FPHP | Half-precision floating point |
| GPA | Generic Pointer Authentication |
| JSCVT | Javascript-style double->int convert (FJCVTZS) |
| LRCPC | Weaker release consistency (LDAPR, etc) |
| PMULL | Polynomial Multiply instructions (PMULL/PMULL2) |
| RNDR | Random Number instructions |
| TLB | Outer Shareable and TLB range maintenance instructions |
| TS | Flag manipulation instructions |
| SHA1 | SHA-1 instructions (SHA1C, etc) |
| SHA2 | SHA-2 instructions (SHA256H, etc) |
| SHA3 | SHA-3 instructions (EOR3, RAXI, XAR, BCAX) |

View File

@@ -83,6 +83,8 @@ const (
AMXINT8 // Tile computational operations on 8-bit integers
AMXFP8 // Tile computational operations on FP8 numbers
AMXTILE // Tile architecture
AMXTF32 // Tile architecture
AMXCOMPLEX // Matrix Multiplication of TF32 Tiles into Packed Single Precision Tile
APX_F // Intel APX
AVX // AVX functions
AVX10 // If set the Intel AVX10 Converged Vector ISA is supported
@@ -282,12 +284,16 @@ const (
DCPOP // Data cache clean to Point of Persistence (DC CVAP)
EVTSTRM // Generic timer
FCMA // Floatin point complex number addition and multiplication
FHM // FMLAL and FMLSL instructions
FP // Single-precision and double-precision floating point
FPHP // Half-precision floating point
GPA // Generic Pointer Authentication
JSCVT // Javascript-style double->int convert (FJCVTZS)
LRCPC // Weaker release consistency (LDAPR, etc)
PMULL // Polynomial Multiply instructions (PMULL/PMULL2)
RNDR // Random Number instructions
TLB // Outer Shareable and TLB range maintenance instructions
TS // Flag manipulation instructions
SHA1 // SHA-1 instructions (SHA1C, etc)
SHA2 // SHA-2 instructions (SHA256H, etc)
SHA3 // SHA-3 instructions (EOR3, RAXI, XAR, BCAX)
@@ -532,7 +538,7 @@ func (c CPUInfo) Ia32TscAux() uint32 {
return ecx
}
// SveLengths returns arm SVE vector and predicate lengths.
// SveLengths returns arm SVE vector and predicate lengths in bits.
// Will return 0, 0 if SVE is not enabled or otherwise unable to detect.
func (c CPUInfo) SveLengths() (vl, pl uint64) {
if !c.Has(SVE) {
@@ -1284,6 +1290,8 @@ func support() flagSet {
// CPUID.(EAX=7, ECX=1).EDX
fs.setIf(edx1&(1<<4) != 0, AVXVNNIINT8)
fs.setIf(edx1&(1<<5) != 0, AVXNECONVERT)
fs.setIf(edx1&(1<<7) != 0, AMXTF32)
fs.setIf(edx1&(1<<8) != 0, AMXCOMPLEX)
fs.setIf(edx1&(1<<10) != 0, AVXVNNIINT16)
fs.setIf(edx1&(1<<14) != 0, PREFETCHI)
fs.setIf(edx1&(1<<19) != 0, AVX10)

View File

@@ -157,6 +157,10 @@ func addInfo(c *CPUInfo, safe bool) {
// x--------------------------------------------------x
// | Name | bits | visible |
// |--------------------------------------------------|
// | RNDR | [63-60] | y |
// |--------------------------------------------------|
// | TLB | [59-56] | y |
// |--------------------------------------------------|
// | TS | [55-52] | y |
// |--------------------------------------------------|
// | FHM | [51-48] | y |
@@ -182,12 +186,10 @@ func addInfo(c *CPUInfo, safe bool) {
// | AES | [7-4] | y |
// x--------------------------------------------------x
// if instAttrReg0&(0xf<<52) != 0 {
// fmt.Println("TS")
// }
// if instAttrReg0&(0xf<<48) != 0 {
// fmt.Println("FHM")
// }
f.setIf(instAttrReg0&(0xf<<60) != 0, RNDR)
f.setIf(instAttrReg0&(0xf<<56) != 0, TLB)
f.setIf(instAttrReg0&(0xf<<52) != 0, TS)
f.setIf(instAttrReg0&(0xf<<48) != 0, FHM)
f.setIf(instAttrReg0&(0xf<<44) != 0, ASIMDDP)
f.setIf(instAttrReg0&(0xf<<40) != 0, SM4)
f.setIf(instAttrReg0&(0xf<<36) != 0, SM3)

View File

@@ -17,223 +17,229 @@ func _() {
_ = x[AMXINT8-7]
_ = x[AMXFP8-8]
_ = x[AMXTILE-9]
_ = x[APX_F-10]
_ = x[AVX-11]
_ = x[AVX10-12]
_ = x[AVX10_128-13]
_ = x[AVX10_256-14]
_ = x[AVX10_512-15]
_ = x[AVX2-16]
_ = x[AVX512BF16-17]
_ = x[AVX512BITALG-18]
_ = x[AVX512BW-19]
_ = x[AVX512CD-20]
_ = x[AVX512DQ-21]
_ = x[AVX512ER-22]
_ = x[AVX512F-23]
_ = x[AVX512FP16-24]
_ = x[AVX512IFMA-25]
_ = x[AVX512PF-26]
_ = x[AVX512VBMI-27]
_ = x[AVX512VBMI2-28]
_ = x[AVX512VL-29]
_ = x[AVX512VNNI-30]
_ = x[AVX512VP2INTERSECT-31]
_ = x[AVX512VPOPCNTDQ-32]
_ = x[AVXIFMA-33]
_ = x[AVXNECONVERT-34]
_ = x[AVXSLOW-35]
_ = x[AVXVNNI-36]
_ = x[AVXVNNIINT8-37]
_ = x[AVXVNNIINT16-38]
_ = x[BHI_CTRL-39]
_ = x[BMI1-40]
_ = x[BMI2-41]
_ = x[CETIBT-42]
_ = x[CETSS-43]
_ = x[CLDEMOTE-44]
_ = x[CLMUL-45]
_ = x[CLZERO-46]
_ = x[CMOV-47]
_ = x[CMPCCXADD-48]
_ = x[CMPSB_SCADBS_SHORT-49]
_ = x[CMPXCHG8-50]
_ = x[CPBOOST-51]
_ = x[CPPC-52]
_ = x[CX16-53]
_ = x[EFER_LMSLE_UNS-54]
_ = x[ENQCMD-55]
_ = x[ERMS-56]
_ = x[F16C-57]
_ = x[FLUSH_L1D-58]
_ = x[FMA3-59]
_ = x[FMA4-60]
_ = x[FP128-61]
_ = x[FP256-62]
_ = x[FSRM-63]
_ = x[FXSR-64]
_ = x[FXSROPT-65]
_ = x[GFNI-66]
_ = x[HLE-67]
_ = x[HRESET-68]
_ = x[HTT-69]
_ = x[HWA-70]
_ = x[HYBRID_CPU-71]
_ = x[HYPERVISOR-72]
_ = x[IA32_ARCH_CAP-73]
_ = x[IA32_CORE_CAP-74]
_ = x[IBPB-75]
_ = x[IBPB_BRTYPE-76]
_ = x[IBRS-77]
_ = x[IBRS_PREFERRED-78]
_ = x[IBRS_PROVIDES_SMP-79]
_ = x[IBS-80]
_ = x[IBSBRNTRGT-81]
_ = x[IBSFETCHSAM-82]
_ = x[IBSFFV-83]
_ = x[IBSOPCNT-84]
_ = x[IBSOPCNTEXT-85]
_ = x[IBSOPSAM-86]
_ = x[IBSRDWROPCNT-87]
_ = x[IBSRIPINVALIDCHK-88]
_ = x[IBS_FETCH_CTLX-89]
_ = x[IBS_OPDATA4-90]
_ = x[IBS_OPFUSE-91]
_ = x[IBS_PREVENTHOST-92]
_ = x[IBS_ZEN4-93]
_ = x[IDPRED_CTRL-94]
_ = x[INT_WBINVD-95]
_ = x[INVLPGB-96]
_ = x[KEYLOCKER-97]
_ = x[KEYLOCKERW-98]
_ = x[LAHF-99]
_ = x[LAM-100]
_ = x[LBRVIRT-101]
_ = x[LZCNT-102]
_ = x[MCAOVERFLOW-103]
_ = x[MCDT_NO-104]
_ = x[MCOMMIT-105]
_ = x[MD_CLEAR-106]
_ = x[MMX-107]
_ = x[MMXEXT-108]
_ = x[MOVBE-109]
_ = x[MOVDIR64B-110]
_ = x[MOVDIRI-111]
_ = x[MOVSB_ZL-112]
_ = x[MOVU-113]
_ = x[MPX-114]
_ = x[MSRIRC-115]
_ = x[MSRLIST-116]
_ = x[MSR_PAGEFLUSH-117]
_ = x[NRIPS-118]
_ = x[NX-119]
_ = x[OSXSAVE-120]
_ = x[PCONFIG-121]
_ = x[POPCNT-122]
_ = x[PPIN-123]
_ = x[PREFETCHI-124]
_ = x[PSFD-125]
_ = x[RDPRU-126]
_ = x[RDRAND-127]
_ = x[RDSEED-128]
_ = x[RDTSCP-129]
_ = x[RRSBA_CTRL-130]
_ = x[RTM-131]
_ = x[RTM_ALWAYS_ABORT-132]
_ = x[SBPB-133]
_ = x[SERIALIZE-134]
_ = x[SEV-135]
_ = x[SEV_64BIT-136]
_ = x[SEV_ALTERNATIVE-137]
_ = x[SEV_DEBUGSWAP-138]
_ = x[SEV_ES-139]
_ = x[SEV_RESTRICTED-140]
_ = x[SEV_SNP-141]
_ = x[SGX-142]
_ = x[SGXLC-143]
_ = x[SHA-144]
_ = x[SME-145]
_ = x[SME_COHERENT-146]
_ = x[SPEC_CTRL_SSBD-147]
_ = x[SRBDS_CTRL-148]
_ = x[SRSO_MSR_FIX-149]
_ = x[SRSO_NO-150]
_ = x[SRSO_USER_KERNEL_NO-151]
_ = x[SSE-152]
_ = x[SSE2-153]
_ = x[SSE3-154]
_ = x[SSE4-155]
_ = x[SSE42-156]
_ = x[SSE4A-157]
_ = x[SSSE3-158]
_ = x[STIBP-159]
_ = x[STIBP_ALWAYSON-160]
_ = x[STOSB_SHORT-161]
_ = x[SUCCOR-162]
_ = x[SVM-163]
_ = x[SVMDA-164]
_ = x[SVMFBASID-165]
_ = x[SVML-166]
_ = x[SVMNP-167]
_ = x[SVMPF-168]
_ = x[SVMPFT-169]
_ = x[SYSCALL-170]
_ = x[SYSEE-171]
_ = x[TBM-172]
_ = x[TDX_GUEST-173]
_ = x[TLB_FLUSH_NESTED-174]
_ = x[TME-175]
_ = x[TOPEXT-176]
_ = x[TSCRATEMSR-177]
_ = x[TSXLDTRK-178]
_ = x[VAES-179]
_ = x[VMCBCLEAN-180]
_ = x[VMPL-181]
_ = x[VMSA_REGPROT-182]
_ = x[VMX-183]
_ = x[VPCLMULQDQ-184]
_ = x[VTE-185]
_ = x[WAITPKG-186]
_ = x[WBNOINVD-187]
_ = x[WRMSRNS-188]
_ = x[X87-189]
_ = x[XGETBV1-190]
_ = x[XOP-191]
_ = x[XSAVE-192]
_ = x[XSAVEC-193]
_ = x[XSAVEOPT-194]
_ = x[XSAVES-195]
_ = x[AESARM-196]
_ = x[ARMCPUID-197]
_ = x[ASIMD-198]
_ = x[ASIMDDP-199]
_ = x[ASIMDHP-200]
_ = x[ASIMDRDM-201]
_ = x[ATOMICS-202]
_ = x[CRC32-203]
_ = x[DCPOP-204]
_ = x[EVTSTRM-205]
_ = x[FCMA-206]
_ = x[FP-207]
_ = x[FPHP-208]
_ = x[GPA-209]
_ = x[JSCVT-210]
_ = x[LRCPC-211]
_ = x[PMULL-212]
_ = x[SHA1-213]
_ = x[SHA2-214]
_ = x[SHA3-215]
_ = x[SHA512-216]
_ = x[SM3-217]
_ = x[SM4-218]
_ = x[SVE-219]
_ = x[lastID-220]
_ = x[AMXTF32-10]
_ = x[AMXCOMPLEX-11]
_ = x[APX_F-12]
_ = x[AVX-13]
_ = x[AVX10-14]
_ = x[AVX10_128-15]
_ = x[AVX10_256-16]
_ = x[AVX10_512-17]
_ = x[AVX2-18]
_ = x[AVX512BF16-19]
_ = x[AVX512BITALG-20]
_ = x[AVX512BW-21]
_ = x[AVX512CD-22]
_ = x[AVX512DQ-23]
_ = x[AVX512ER-24]
_ = x[AVX512F-25]
_ = x[AVX512FP16-26]
_ = x[AVX512IFMA-27]
_ = x[AVX512PF-28]
_ = x[AVX512VBMI-29]
_ = x[AVX512VBMI2-30]
_ = x[AVX512VL-31]
_ = x[AVX512VNNI-32]
_ = x[AVX512VP2INTERSECT-33]
_ = x[AVX512VPOPCNTDQ-34]
_ = x[AVXIFMA-35]
_ = x[AVXNECONVERT-36]
_ = x[AVXSLOW-37]
_ = x[AVXVNNI-38]
_ = x[AVXVNNIINT8-39]
_ = x[AVXVNNIINT16-40]
_ = x[BHI_CTRL-41]
_ = x[BMI1-42]
_ = x[BMI2-43]
_ = x[CETIBT-44]
_ = x[CETSS-45]
_ = x[CLDEMOTE-46]
_ = x[CLMUL-47]
_ = x[CLZERO-48]
_ = x[CMOV-49]
_ = x[CMPCCXADD-50]
_ = x[CMPSB_SCADBS_SHORT-51]
_ = x[CMPXCHG8-52]
_ = x[CPBOOST-53]
_ = x[CPPC-54]
_ = x[CX16-55]
_ = x[EFER_LMSLE_UNS-56]
_ = x[ENQCMD-57]
_ = x[ERMS-58]
_ = x[F16C-59]
_ = x[FLUSH_L1D-60]
_ = x[FMA3-61]
_ = x[FMA4-62]
_ = x[FP128-63]
_ = x[FP256-64]
_ = x[FSRM-65]
_ = x[FXSR-66]
_ = x[FXSROPT-67]
_ = x[GFNI-68]
_ = x[HLE-69]
_ = x[HRESET-70]
_ = x[HTT-71]
_ = x[HWA-72]
_ = x[HYBRID_CPU-73]
_ = x[HYPERVISOR-74]
_ = x[IA32_ARCH_CAP-75]
_ = x[IA32_CORE_CAP-76]
_ = x[IBPB-77]
_ = x[IBPB_BRTYPE-78]
_ = x[IBRS-79]
_ = x[IBRS_PREFERRED-80]
_ = x[IBRS_PROVIDES_SMP-81]
_ = x[IBS-82]
_ = x[IBSBRNTRGT-83]
_ = x[IBSFETCHSAM-84]
_ = x[IBSFFV-85]
_ = x[IBSOPCNT-86]
_ = x[IBSOPCNTEXT-87]
_ = x[IBSOPSAM-88]
_ = x[IBSRDWROPCNT-89]
_ = x[IBSRIPINVALIDCHK-90]
_ = x[IBS_FETCH_CTLX-91]
_ = x[IBS_OPDATA4-92]
_ = x[IBS_OPFUSE-93]
_ = x[IBS_PREVENTHOST-94]
_ = x[IBS_ZEN4-95]
_ = x[IDPRED_CTRL-96]
_ = x[INT_WBINVD-97]
_ = x[INVLPGB-98]
_ = x[KEYLOCKER-99]
_ = x[KEYLOCKERW-100]
_ = x[LAHF-101]
_ = x[LAM-102]
_ = x[LBRVIRT-103]
_ = x[LZCNT-104]
_ = x[MCAOVERFLOW-105]
_ = x[MCDT_NO-106]
_ = x[MCOMMIT-107]
_ = x[MD_CLEAR-108]
_ = x[MMX-109]
_ = x[MMXEXT-110]
_ = x[MOVBE-111]
_ = x[MOVDIR64B-112]
_ = x[MOVDIRI-113]
_ = x[MOVSB_ZL-114]
_ = x[MOVU-115]
_ = x[MPX-116]
_ = x[MSRIRC-117]
_ = x[MSRLIST-118]
_ = x[MSR_PAGEFLUSH-119]
_ = x[NRIPS-120]
_ = x[NX-121]
_ = x[OSXSAVE-122]
_ = x[PCONFIG-123]
_ = x[POPCNT-124]
_ = x[PPIN-125]
_ = x[PREFETCHI-126]
_ = x[PSFD-127]
_ = x[RDPRU-128]
_ = x[RDRAND-129]
_ = x[RDSEED-130]
_ = x[RDTSCP-131]
_ = x[RRSBA_CTRL-132]
_ = x[RTM-133]
_ = x[RTM_ALWAYS_ABORT-134]
_ = x[SBPB-135]
_ = x[SERIALIZE-136]
_ = x[SEV-137]
_ = x[SEV_64BIT-138]
_ = x[SEV_ALTERNATIVE-139]
_ = x[SEV_DEBUGSWAP-140]
_ = x[SEV_ES-141]
_ = x[SEV_RESTRICTED-142]
_ = x[SEV_SNP-143]
_ = x[SGX-144]
_ = x[SGXLC-145]
_ = x[SHA-146]
_ = x[SME-147]
_ = x[SME_COHERENT-148]
_ = x[SPEC_CTRL_SSBD-149]
_ = x[SRBDS_CTRL-150]
_ = x[SRSO_MSR_FIX-151]
_ = x[SRSO_NO-152]
_ = x[SRSO_USER_KERNEL_NO-153]
_ = x[SSE-154]
_ = x[SSE2-155]
_ = x[SSE3-156]
_ = x[SSE4-157]
_ = x[SSE42-158]
_ = x[SSE4A-159]
_ = x[SSSE3-160]
_ = x[STIBP-161]
_ = x[STIBP_ALWAYSON-162]
_ = x[STOSB_SHORT-163]
_ = x[SUCCOR-164]
_ = x[SVM-165]
_ = x[SVMDA-166]
_ = x[SVMFBASID-167]
_ = x[SVML-168]
_ = x[SVMNP-169]
_ = x[SVMPF-170]
_ = x[SVMPFT-171]
_ = x[SYSCALL-172]
_ = x[SYSEE-173]
_ = x[TBM-174]
_ = x[TDX_GUEST-175]
_ = x[TLB_FLUSH_NESTED-176]
_ = x[TME-177]
_ = x[TOPEXT-178]
_ = x[TSCRATEMSR-179]
_ = x[TSXLDTRK-180]
_ = x[VAES-181]
_ = x[VMCBCLEAN-182]
_ = x[VMPL-183]
_ = x[VMSA_REGPROT-184]
_ = x[VMX-185]
_ = x[VPCLMULQDQ-186]
_ = x[VTE-187]
_ = x[WAITPKG-188]
_ = x[WBNOINVD-189]
_ = x[WRMSRNS-190]
_ = x[X87-191]
_ = x[XGETBV1-192]
_ = x[XOP-193]
_ = x[XSAVE-194]
_ = x[XSAVEC-195]
_ = x[XSAVEOPT-196]
_ = x[XSAVES-197]
_ = x[AESARM-198]
_ = x[ARMCPUID-199]
_ = x[ASIMD-200]
_ = x[ASIMDDP-201]
_ = x[ASIMDHP-202]
_ = x[ASIMDRDM-203]
_ = x[ATOMICS-204]
_ = x[CRC32-205]
_ = x[DCPOP-206]
_ = x[EVTSTRM-207]
_ = x[FCMA-208]
_ = x[FHM-209]
_ = x[FP-210]
_ = x[FPHP-211]
_ = x[GPA-212]
_ = x[JSCVT-213]
_ = x[LRCPC-214]
_ = x[PMULL-215]
_ = x[RNDR-216]
_ = x[TLB-217]
_ = x[TS-218]
_ = x[SHA1-219]
_ = x[SHA2-220]
_ = x[SHA3-221]
_ = x[SHA512-222]
_ = x[SM3-223]
_ = x[SM4-224]
_ = x[SVE-225]
_ = x[lastID-226]
_ = x[firstID-0]
}
const _FeatureID_name = "firstIDADXAESNIAMD3DNOWAMD3DNOWEXTAMXBF16AMXFP16AMXINT8AMXFP8AMXTILEAPX_FAVXAVX10AVX10_128AVX10_256AVX10_512AVX2AVX512BF16AVX512BITALGAVX512BWAVX512CDAVX512DQAVX512ERAVX512FAVX512FP16AVX512IFMAAVX512PFAVX512VBMIAVX512VBMI2AVX512VLAVX512VNNIAVX512VP2INTERSECTAVX512VPOPCNTDQAVXIFMAAVXNECONVERTAVXSLOWAVXVNNIAVXVNNIINT8AVXVNNIINT16BHI_CTRLBMI1BMI2CETIBTCETSSCLDEMOTECLMULCLZEROCMOVCMPCCXADDCMPSB_SCADBS_SHORTCMPXCHG8CPBOOSTCPPCCX16EFER_LMSLE_UNSENQCMDERMSF16CFLUSH_L1DFMA3FMA4FP128FP256FSRMFXSRFXSROPTGFNIHLEHRESETHTTHWAHYBRID_CPUHYPERVISORIA32_ARCH_CAPIA32_CORE_CAPIBPBIBPB_BRTYPEIBRSIBRS_PREFERREDIBRS_PROVIDES_SMPIBSIBSBRNTRGTIBSFETCHSAMIBSFFVIBSOPCNTIBSOPCNTEXTIBSOPSAMIBSRDWROPCNTIBSRIPINVALIDCHKIBS_FETCH_CTLXIBS_OPDATA4IBS_OPFUSEIBS_PREVENTHOSTIBS_ZEN4IDPRED_CTRLINT_WBINVDINVLPGBKEYLOCKERKEYLOCKERWLAHFLAMLBRVIRTLZCNTMCAOVERFLOWMCDT_NOMCOMMITMD_CLEARMMXMMXEXTMOVBEMOVDIR64BMOVDIRIMOVSB_ZLMOVUMPXMSRIRCMSRLISTMSR_PAGEFLUSHNRIPSNXOSXSAVEPCONFIGPOPCNTPPINPREFETCHIPSFDRDPRURDRANDRDSEEDRDTSCPRRSBA_CTRLRTMRTM_ALWAYS_ABORTSBPBSERIALIZESEVSEV_64BITSEV_ALTERNATIVESEV_DEBUGSWAPSEV_ESSEV_RESTRICTEDSEV_SNPSGXSGXLCSHASMESME_COHERENTSPEC_CTRL_SSBDSRBDS_CTRLSRSO_MSR_FIXSRSO_NOSRSO_USER_KERNEL_NOSSESSE2SSE3SSE4SSE42SSE4ASSSE3STIBPSTIBP_ALWAYSONSTOSB_SHORTSUCCORSVMSVMDASVMFBASIDSVMLSVMNPSVMPFSVMPFTSYSCALLSYSEETBMTDX_GUESTTLB_FLUSH_NESTEDTMETOPEXTTSCRATEMSRTSXLDTRKVAESVMCBCLEANVMPLVMSA_REGPROTVMXVPCLMULQDQVTEWAITPKGWBNOINVDWRMSRNSX87XGETBV1XOPXSAVEXSAVECXSAVEOPTXSAVESAESARMARMCPUIDASIMDASIMDDPASIMDHPASIMDRDMATOMICSCRC32DCPOPEVTSTRMFCMAFPFPHPGPAJSCVTLRCPCPMULLSHA1SHA2SHA3SHA512SM3SM4SVElastID"
const _FeatureID_name = "firstIDADXAESNIAMD3DNOWAMD3DNOWEXTAMXBF16AMXFP16AMXINT8AMXFP8AMXTILEAMXTF32AMXCOMPLEXAPX_FAVXAVX10AVX10_128AVX10_256AVX10_512AVX2AVX512BF16AVX512BITALGAVX512BWAVX512CDAVX512DQAVX512ERAVX512FAVX512FP16AVX512IFMAAVX512PFAVX512VBMIAVX512VBMI2AVX512VLAVX512VNNIAVX512VP2INTERSECTAVX512VPOPCNTDQAVXIFMAAVXNECONVERTAVXSLOWAVXVNNIAVXVNNIINT8AVXVNNIINT16BHI_CTRLBMI1BMI2CETIBTCETSSCLDEMOTECLMULCLZEROCMOVCMPCCXADDCMPSB_SCADBS_SHORTCMPXCHG8CPBOOSTCPPCCX16EFER_LMSLE_UNSENQCMDERMSF16CFLUSH_L1DFMA3FMA4FP128FP256FSRMFXSRFXSROPTGFNIHLEHRESETHTTHWAHYBRID_CPUHYPERVISORIA32_ARCH_CAPIA32_CORE_CAPIBPBIBPB_BRTYPEIBRSIBRS_PREFERREDIBRS_PROVIDES_SMPIBSIBSBRNTRGTIBSFETCHSAMIBSFFVIBSOPCNTIBSOPCNTEXTIBSOPSAMIBSRDWROPCNTIBSRIPINVALIDCHKIBS_FETCH_CTLXIBS_OPDATA4IBS_OPFUSEIBS_PREVENTHOSTIBS_ZEN4IDPRED_CTRLINT_WBINVDINVLPGBKEYLOCKERKEYLOCKERWLAHFLAMLBRVIRTLZCNTMCAOVERFLOWMCDT_NOMCOMMITMD_CLEARMMXMMXEXTMOVBEMOVDIR64BMOVDIRIMOVSB_ZLMOVUMPXMSRIRCMSRLISTMSR_PAGEFLUSHNRIPSNXOSXSAVEPCONFIGPOPCNTPPINPREFETCHIPSFDRDPRURDRANDRDSEEDRDTSCPRRSBA_CTRLRTMRTM_ALWAYS_ABORTSBPBSERIALIZESEVSEV_64BITSEV_ALTERNATIVESEV_DEBUGSWAPSEV_ESSEV_RESTRICTEDSEV_SNPSGXSGXLCSHASMESME_COHERENTSPEC_CTRL_SSBDSRBDS_CTRLSRSO_MSR_FIXSRSO_NOSRSO_USER_KERNEL_NOSSESSE2SSE3SSE4SSE42SSE4ASSSE3STIBPSTIBP_ALWAYSONSTOSB_SHORTSUCCORSVMSVMDASVMFBASIDSVMLSVMNPSVMPFSVMPFTSYSCALLSYSEETBMTDX_GUESTTLB_FLUSH_NESTEDTMETOPEXTTSCRATEMSRTSXLDTRKVAESVMCBCLEANVMPLVMSA_REGPROTVMXVPCLMULQDQVTEWAITPKGWBNOINVDWRMSRNSX87XGETBV1XOPXSAVEXSAVECXSAVEOPTXSAVESAESARMARMCPUIDASIMDASIMDDPASIMDHPASIMDRDMATOMICSCRC32DCPOPEVTSTRMFCMAFHMFPFPHPGPAJSCVTLRCPCPMULLRNDRTLBTSSHA1SHA2SHA3SHA512SM3SM4SVElastID"
var _FeatureID_index = [...]uint16{0, 7, 10, 15, 23, 34, 41, 48, 55, 61, 68, 73, 76, 81, 90, 99, 108, 112, 122, 134, 142, 150, 158, 166, 173, 183, 193, 201, 211, 222, 230, 240, 258, 273, 280, 292, 299, 306, 317, 329, 337, 341, 345, 351, 356, 364, 369, 375, 379, 388, 406, 414, 421, 425, 429, 443, 449, 453, 457, 466, 470, 474, 479, 484, 488, 492, 499, 503, 506, 512, 515, 518, 528, 538, 551, 564, 568, 579, 583, 597, 614, 617, 627, 638, 644, 652, 663, 671, 683, 699, 713, 724, 734, 749, 757, 768, 778, 785, 794, 804, 808, 811, 818, 823, 834, 841, 848, 856, 859, 865, 870, 879, 886, 894, 898, 901, 907, 914, 927, 932, 934, 941, 948, 954, 958, 967, 971, 976, 982, 988, 994, 1004, 1007, 1023, 1027, 1036, 1039, 1048, 1063, 1076, 1082, 1096, 1103, 1106, 1111, 1114, 1117, 1129, 1143, 1153, 1165, 1172, 1191, 1194, 1198, 1202, 1206, 1211, 1216, 1221, 1226, 1240, 1251, 1257, 1260, 1265, 1274, 1278, 1283, 1288, 1294, 1301, 1306, 1309, 1318, 1334, 1337, 1343, 1353, 1361, 1365, 1374, 1378, 1390, 1393, 1403, 1406, 1413, 1421, 1428, 1431, 1438, 1441, 1446, 1452, 1460, 1466, 1472, 1480, 1485, 1492, 1499, 1507, 1514, 1519, 1524, 1531, 1535, 1537, 1541, 1544, 1549, 1554, 1559, 1563, 1567, 1571, 1577, 1580, 1583, 1586, 1592}
var _FeatureID_index = [...]uint16{0, 7, 10, 15, 23, 34, 41, 48, 55, 61, 68, 75, 85, 90, 93, 98, 107, 116, 125, 129, 139, 151, 159, 167, 175, 183, 190, 200, 210, 218, 228, 239, 247, 257, 275, 290, 297, 309, 316, 323, 334, 346, 354, 358, 362, 368, 373, 381, 386, 392, 396, 405, 423, 431, 438, 442, 446, 460, 466, 470, 474, 483, 487, 491, 496, 501, 505, 509, 516, 520, 523, 529, 532, 535, 545, 555, 568, 581, 585, 596, 600, 614, 631, 634, 644, 655, 661, 669, 680, 688, 700, 716, 730, 741, 751, 766, 774, 785, 795, 802, 811, 821, 825, 828, 835, 840, 851, 858, 865, 873, 876, 882, 887, 896, 903, 911, 915, 918, 924, 931, 944, 949, 951, 958, 965, 971, 975, 984, 988, 993, 999, 1005, 1011, 1021, 1024, 1040, 1044, 1053, 1056, 1065, 1080, 1093, 1099, 1113, 1120, 1123, 1128, 1131, 1134, 1146, 1160, 1170, 1182, 1189, 1208, 1211, 1215, 1219, 1223, 1228, 1233, 1238, 1243, 1257, 1268, 1274, 1277, 1282, 1291, 1295, 1300, 1305, 1311, 1318, 1323, 1326, 1335, 1351, 1354, 1360, 1370, 1378, 1382, 1391, 1395, 1407, 1410, 1420, 1423, 1430, 1438, 1445, 1448, 1455, 1458, 1463, 1469, 1477, 1483, 1489, 1497, 1502, 1509, 1516, 1524, 1531, 1536, 1541, 1548, 1552, 1555, 1557, 1561, 1564, 1569, 1574, 1579, 1583, 1586, 1588, 1592, 1596, 1600, 1606, 1609, 1612, 1615, 1621}
func (i FeatureID) String() string {
if i < 0 || i >= FeatureID(len(_FeatureID_index)-1) {

Some files were not shown because too many files have changed in this diff Show More