Compare commits

...
Author SHA1 Message Date
Dominik Schmidt ab9a224091 Remove changelog fragment 2026-08-18 18:33:41 +02:00
Dominik Schmidt 1de86ef559 changelog: deterministic audio cover art thumbnails 2026-08-18 18:33:41 +02:00
Dominik Schmidt 0fb6877878 fix(thumbnails): pick audio cover art deterministically
Switch to the dschmidt/tag fork and select the front cover (picture type
0x03) when tagged, else the first available picture, instead of the lib's
single non-deterministic Picture().
2026-08-18 18:33:41 +02:00
Dominik Schmidt 35231b1418 feat(search): populate audio and gps-altitude facets from tika, drop the audio-only gate 2026-08-18 18:27:12 +02:00
Dominik Schmidt 15149109e2 test(search): pin the acceptance tika image to the latest 4.0.0 snapshot 2026-08-18 18:27:12 +02:00
Dominik Schmidt 2edb893ee6 refactor(search): split the tika extractor and its tests into per-facet files 2026-08-18 18:27:12 +02:00
Dominik Schmidt c7340ac004 chore(search): tighten the schema-reconcile comments 2026-08-18 18:11:42 +02:00
Dominik Schmidt 6022e8fcfd refactor(search): single-source the new-index log message 2026-08-18 18:11:41 +02:00
Dominik Schmidt b14dc31545 feat(search): log a reindex hint when a fresh search index is created 2026-08-18 18:11:41 +02:00
Dominik Schmidt dc90d2dda9 refactor(search): warn on a persisted additive change even when the reopen fails 2026-08-18 18:11:41 +02:00
Dominik Schmidt fe10ad0ead refactor(search): route schema verdict handling through a shared mapping.Reconcile 2026-08-18 18:11:41 +02:00
Dominik Schmidt 5d08f16114 refactor(search): extract opensearch.NewClient out of server startup 2026-08-18 18:11:41 +02:00
Dominik Schmidt c6f9cc72dc refactor(search): harden the index-diff helpers against unset input 2026-08-18 18:11:41 +02:00
Dominik Schmidt a74b1c58f7 refactor(search): only enforce analysis settings, tolerate operational drift 2026-08-18 18:11:41 +02:00
Dominik Schmidt edff1e93d5 refactor(search): make the breaking-schema error developer-facing 2026-08-18 18:11:41 +02:00
Dominik Schmidt c40c46aa88 fix(search): list the schema mismatch reasons on separate lines 2026-08-18 18:11:41 +02:00
Dominik Schmidt 41af1d8bb8 fix(search): name the service to stop in the schema mismatch error 2026-08-18 18:11:41 +02:00
Dominik Schmidt 7e59839a76 fix(search): address max-review findings
- the additive warnings advertise --all-spaces --force-rescan; a plain
  walk skips unchanged documents and never backfills the new fields
- Apply checks index existence first again, so a pre-provisioned index
  needs no create privilege and odd create-error shapes (string error
  bodies, cluster blocks) cannot fail a healthy startup; Create on 404
  keeps the typed already-exists swallow as the creation-race backstop
- number_of_replicas drift is not breaking, it is runtime-tunable and
  needs no rebuild
- bleve returns the classification alongside post-persist errors and
  the server warns before the error check, so the one-time additive
  warning is not lost when close or reopen fails
- a golden fixture pins the marshaled bleve mapping so a dependency
  bump that changes marshaling fails in CI instead of refusing every
  installation in the field
2026-08-18 18:11:41 +02:00
Dominik Schmidt 6d799d1439 chore(search): tighten doc comments 2026-08-18 18:07:50 +02:00
Dominik Schmidt c595a53818 chore(search): warn on additive opensearch changes and name the exact delete step
Addresses the two Copilot review comments on the PR: the additive
opensearch log now matches the bleve warning (level and re-index hint),
and the refuse message spells out how to delete the index per engine
(DELETE /<name> vs removing the bleve directory).
2026-08-18 18:07:50 +02:00
Dominik Schmidt aca8f9d2b8 chore(search): mention the impact of disabling search in the refuse message 2026-08-18 18:07:50 +02:00
Dominik Schmidt 8bfacb0823 chore(search): drop the changelog entry 2026-08-18 18:07:50 +02:00
Dominik Schmidt dfd5a47026 feat(search): check the index schema on startup and refuse breaking changes
Both engines now diff the stored/live index schema against the schema
generated from code when the service starts. A shared recursive
classifier in the mapping package is the single oracle:

- equal: start normally.
- additive (new fields without any indexed data): applied in place.
  OpenSearch gets a PUT _mapping with the full code properties, bleve
  persists the code mapping into the index (SetInternal + reopen) so
  the new fields are properly typed immediately and later startups
  classify equal. A startup warning lists the new fields because
  documents indexed before the upgrade lack them until re-indexed.
- breaking (changed definitions or analyzers, removed or renamed
  fields, or new fields that already contain data of unknown form):
  refuse to start with an error describing the rebuild procedure
  (delete the index, start, run "opencloud search index --all-spaces")
  and the OC_EXCLUDE_RUN_SERVICES=search escape hatch.

PUT _mapping is deliberately only the apply mechanism, never the
judge: its merge semantics cannot see removals or renames and it
accepts in-place updatable param changes with an ack. bleve
additionally checks idx.Fields() so previously dynamically indexed
data (which leaves no schema trace in bleve) is caught, matching by
exact name and by path prefix.

While at it: the OpenSearch startup check runs with a real,
minute-bounded context instead of context.TODO(), bleve indexes are
opened with a 5s bolt_timeout so a second process fails fast instead
of hanging on the file lock, and the reversed errors.Is arguments in
bleve.NewIndex were fixed.

https://github.com/opencloud-eu/opencloud/issues/3092
2026-08-18 18:07:50 +02:00
Dominik Schmidt a7ed42f434 test(search): re-apply opensearch backend coverage under ginkgo 2026-08-18 17:24:21 +02:00
Dominik Schmidt e5d16157bc refactor(search): make paths case-sensitive and scope searches at query level
Paths act as references (location scoping, deep links): /Foo and /foo
are distinct siblings, so path: matching must be exact. Case-insensitive
folder discovery is served by name: and its lowercase sibling. This also
matches bleve on main, where path queries have always been
case-sensitive.

Dropping the sibling removes its biggest maintenance cost: Path is the
one mutable sibling field, a move rewrites the paths of a whole subtree
and the OpenSearch move script had to rebuild Path_lowercase alongside
the base field.

With paths case-sensitive, the ref path scope moves into the query
itself: bleve as a term/prefix disjunction on the keyword Path,
OpenSearch as a term filter on its path_hierarchy tokens. The
post-filter that used to drop out-of-scope hits after the query ran is
gone; totals and paging now respect the scope instead of being computed
over the whole space, and a wrong-cased scope simply matches nothing.
2026-08-18 17:12:32 +02:00
Dominik Schmidt 51bda55501 fix(search): bind a leading NOT to the term right after it, on both backends
A leading NOT next to an operator was miscompiled: the bleve compiler left the consumed term in `next`, so `NOT x AND y` dropped `y` and produced a self-contradicting clause; the OpenSearch transpiler checked nextOp==AND before prevOp==NOT, so the negated term landed in `must` instead of `must_not`. NOT is unary and binds to the node directly after it regardless of what follows. This also fixes `mediatype:file AND <term>` (the web Files filter) at the root, so the earlier mediatype:file group workaround is dropped.
2026-08-18 17:12:32 +02:00
Dominik Schmidt f40544de04 test(search): port fieldindex, mimetype and normalize tests to ginkgo 2026-08-18 17:12:32 +02:00
Dominik Schmidt 65712716a8 test(search): make the OpenSearch testcontainer start reliably
Cold boots take well over the 5s startup timeout, and a full host disk
tripped the flood-stage create-index block mid-run; test indexes are tiny.
2026-08-18 17:12:32 +02:00
Dominik Schmidt 3affd156d6 fix(search): keep OpenSearch path queries as unanalyzed term queries
A path value with spaces went through a match_phrase query, which analyzes
the query with the path_hierarchy analyzer; the resulting "." prefix token
matches every document in the space, breaking descendant matching and the
stale-path check after a move.
2026-08-18 17:12:32 +02:00
Dominik Schmidt 4500036f33 refactor(search): anchor the OpenSearch move prefix replace to the path start
The move script rewrote Path/Path_lowercase with painless String.replace, which replaces every occurrence of the old path, not just the leading prefix. OpenCloud paths are ./-prefixed so the full old path only occurs at the start and the result is byte-identical, but startsWith + substring makes the prefix-only intent explicit and robust to any path format. Not a live bug fix, a hardening.
2026-08-18 17:12:32 +02:00
Dominik Schmidt ab6d0b56b6 fix(search): validate CaseInsensitive against the effective field type
The guard only rejected CaseInsensitive when a non-keyword/path Type was set explicitly. With no Type, isCasedType treated the field as cased, so CaseInsensitive on an inferred numeric/bool/datetime field passed validation but produced no _lowercase sibling, and the query would silently match nothing. Validate now falls back to the inferred Go type.
2026-08-18 17:12:32 +02:00
Dominik Schmidt 3fbc04d06b fix(search): keep mediatype:file atomic so it composes with other terms
mediatype:file expands to a NOT restriction. Spliced inline as `NOT MimeType:httpd/unix-directory`, the bleve compiler's NOT branch left a stale operand, so `mediatype:file AND name:x` dropped `name:x` and matched nothing (the web Files filter). It is now wrapped in a group so the negation stays atomic; verified fixing both bleve and OpenSearch.
2026-08-18 17:12:32 +02:00
Dominik Schmidt c2031654fb fix(search): nest json-tagged embedded structs instead of flattening them
resolveField marked every anonymous field embedded, so walkFields (mapping, field index, validate) and fillStruct (deserializer) flattened a json-tagged embedded struct, while conversions.To/encoding/json on the write path nests it under the tag, mapping and deserializing it at the wrong path. An anonymous field is now embedded only without a json tag name, matching encoding/json; fillStruct also recurses into a value nested struct. No current type has a tagged embedded struct, so runtime behavior is unchanged; this hardens the reflection walker.
2026-08-18 17:12:32 +02:00
Dominik Schmidt 5278fd92f3 fix(search): make mediatype categories and MIME types case-insensitive
mediatype:Folder / mediatype:IMAGE resolved to a literal MimeType search and matched nothing because Expand switched on the raw value. The value is now lowercased in the lowering pass, so categories and literal MIME types match regardless of case, consistently on both backends.
2026-08-18 17:12:32 +02:00
Dominik Schmidt 8f53b31178 test(search): cover mediatype and direct MimeType search on both backends
Adds bleve and OpenSearch coverage for category (image), literal MIME (image/svg+xml, with + and /), and raw MimeType: queries. Documents why MimeType skips the bleve escaper: it is not a bug, bleve treats / and + as literals mid-term, so a literal MIME still matches exactly while the category wildcard image/* keeps its *.
2026-08-18 17:12:32 +02:00
Dominik Schmidt b09834f98d fix(search): reject CaseInsensitive on non-keyword/path fields
CaseInsensitive routes queries to a <field>_lowercase sibling that is only generated for keyword/path fields, so marking any other type CaseInsensitive would silently match nothing. Validate now rejects it up front.
2026-08-18 17:12:32 +02:00
Dominik Schmidt ac3c2b4579 fix(search): write a consistent empty _lowercase sibling for empty arrays
The []any branch skipped the sibling for an empty array while the []string branch wrote an empty one; both now write it, matching the base field.
2026-08-18 17:12:32 +02:00
Dominik Schmidt d352ee53c5 fix(search): review fixes for path AND-term and content wildcard
bleve compiled a path restriction to a DisjunctionQuery, which mapBinary redistributes as an OR-chain, so `path:/Foo AND name:bar` matched the folder itself unconditionally. It is now a BooleanQuery (should: folder OR descendants), which mapBinary keeps atomic under an enclosing AND.

The OpenSearch full-text branch ran before the wildcard check, so `content:foo*` degraded to a phrase match and diverged from bleve; the wildcard check now comes first.

Adds the missing coverage the review flagged: path AND term, content wildcard, case-insensitive tags (the array sibling branch), and a spaced path with descendants on OpenSearch.
2026-08-18 17:12:32 +02:00
Dominik Schmidt f7087c973b fix(search): analyze OpenSearch full-text queries, stem Content like bleve
Single-term `content:` built an unanalyzed term query, so once this branch dropped the blanket query-value lowercasing, `content:Foo` missed on OpenSearch (bleve was unaffected, its query analyzes). Fielded full-text queries now use a match query. OpenSearch `Content` also gets a porter stemming analyzer (it used the default standard analyzer and never stemmed), so full-text search matches bleve on both case and stemming.
2026-08-18 17:12:32 +02:00
Dominik Schmidt 6ce3d206c3 feat(search): per-field case-insensitive search via _lowercase siblings
Keyword and path fields always index their case-preserved base and, when CaseInsensitive is set, an additional <field>_lowercase sibling used only for matching. The KQL lowering marks a restriction case-insensitive; each backend searches the sibling and lowercases the query value the same way the sibling is precomputed at index time (Go strings.ToLower on both sides, so non-ASCII stays consistent).

Search always returns the case-preserved base, so the sibling never has to be read back. In bleve it is indexed but not stored, kept out of _all, and without doc values. In OpenSearch it deliberately stays in _source: excluding it would make every update-by-query script rebuild all siblings from the document via painless toLowerCase, which lowercases differently than Go and would drift from the query side. Keeping it in _source avoids that, and a lowercased copy of a name or path is negligible disk in a cluster.

The OpenSearch move script keeps the base and its sibling in sync by swapping the moved prefix in Path_lowercase and setting Name_lowercase from Go-lowercased params, so case-insensitive search still finds a file after it moves (previously the sibling went stale). bleve re-indexes the whole document on move/delete/restore, so its siblings stay fresh for free.

This also repairs OpenSearch path search (the query value was no longer folded to lowercase, so path:<Foo> returned nothing) and makes bleve path queries match a folder and its descendants like OpenSearch's path_hierarchy. The Path base stays case-preserved so the move/delete descendant update (an exact TermQuery on Path) matches mixed-case folders.
2026-08-18 17:12:32 +02:00
Dominik Schmidt 6fae0be65d refactor(search): run the OpenSearch backend on the shared lowering pass
KQLToOpenSearchBoolQuery runs query.Normalize, then only value lowercasing stays
backend-specific; remapKey and unfoldValue are gone.
2026-08-18 17:12:32 +02:00
Dominik Schmidt 6fa56469d1 refactor(search): run the bleve backend on the shared lowering pass
The bleve Creator runs query.Normalize before compiling; the compiler consumes a
canonical AST with no field resolution or media-type special-casing.
2026-08-18 17:12:32 +02:00
Dominik Schmidt 162f6e26b8 feat(search): add shared KQL lowering pass
query.Normalize resolves field names (query.ResolveField, from the derived
index + a small alias overlay) and expands media-type restrictions
(mimetype.Expand) once, between parse and backend compilation.
2026-08-18 17:12:32 +02:00
Dominik Schmidt 2d3f44be43 feat(search): derive a case-insensitive field-name index from the resource struct
mapping.FieldNameIndex walks the struct and maps a lowercased field path to the
real field name, including nested facet sub-fields. Backend-neutral.
2026-08-18 17:12:32 +02:00
Dominik Schmidt 25450554b4 refactor(kql): move parse/validation errors into pkg/kql
The KQL parser produced its own validation errors but imported them from the
search service's query package. Move them into pkg/kql and let the search
backend consume kql.IsValidationError, so the parser stops depending on a
service package.
2026-08-18 17:12:32 +02:00
Dominik Schmidt ee500379f0 fix(search): preserve query value case for case-sensitive fields on OpenSearch
OpenSearch lowercased every KQL query value, so exact-match queries on
case-preserved keyword fields (facet values, ids) never matched their stored
token. Fold the value only for fields with a lowercasing analyzer, mirroring the
bleve backend. The field set is derived once in search.LowercaseValueFields and
shared by both backends (bleve's local buildLowercaseFields is dropped).
2026-08-18 17:12:32 +02:00
Dominik Schmidt 9dd78193c8 feat(search): version the search index by schema version
Both backends carry a shared search.SchemaVersion in the index name
(OpenSearch <base>-vN) and data path (bleve-vN). A breaking schema change
bumps the version so the service builds a fresh index instead of colliding
with the incompatible previous one; the old index is left in place.
2026-08-18 17:12:32 +02:00
Dominik Schmidt 102f2274a3 fix(search): type mtime as a date 2026-08-18 17:12:32 +02:00
Dominik Schmidt 14bcd45d4d test(search): set Mtime on opensearch folder and root fixtures
The Mtime field is mapped as an OpenSearch `date`, which rejects an
empty value with `mapper_parsing_exception: cannot parse empty date`.
The folder and root fixtures had no Mtime, so serializing them to
`"Mtime": ""` made TestEngine_Purge/purge_resource_trees fail when the
document was indexed. Give both a valid RFC3339 Mtime, matching the
file fixture.
2026-08-18 16:57:08 +02:00
Dominik Schmidt c763d96207 test(search): convert mapping package tests to ginkgo
New package, so use the repo's standard test framework.
2026-08-18 16:57:08 +02:00
Dominik Schmidt e2a2915712 test(search): convert bleve geo/mtime tests to ginkgo
The package's engine suite is ginkgo; these new tests were plain.
2026-08-18 16:57:07 +02:00
Dominik Schmidt 561a963e85 test(search): use RFC3339 Mtime in opensearch fixture
Mtime is now a date field; the fixture's Go-format string fails
OpenSearch date parsing.
2026-08-18 16:57:07 +02:00
Dominik Schmidt 19b3a96d26 feat(search): index Location as a geopoint on both backends
Add a TypeGeopoint field type. The libregraph Location facet is kept as an
object (retrieval / numeric queries) and a sibling <name>_geopoint field
carries the {lat,lon} form for geo-distance / bbox / polygon queries,
uniform across bleve and OpenSearch via the shared mapping. PrepareForIndex
splices the sibling in at write time.
2026-08-18 16:57:07 +02:00
Dominik Schmidt fb69bd525a refactor: reflection-based search mapping
Build the bleve and OpenSearch index mappings from the Go struct via
reflection (json tags + per-field overrides) instead of hand-rolled
mappings and hit deserializers. New mapping package: BleveBuildMapping,
OpenSearchBuildMapping, Deserialize[T], PrepareForIndex; field decoding is
fail-soft. Mtime is typed as a date so mtime ranges are chronological on
both backends. Route CS3 facet parsing through mapping.DeserializeStringMap.

The any-valued (bleve hit) and string-valued (CS3 metadata) deserializers
share one generic fillStruct walker with a per-value setLeaf callback.
2026-08-18 16:57:07 +02:00
dependabot[bot] 5056d4a0f4 build(deps): bump github.com/testcontainers/testcontainers-go/modules/opensearch
Bumps [github.com/testcontainers/testcontainers-go/modules/opensearch](https://github.com/testcontainers/testcontainers-go) from 0.43.0 to 0.44.0.
- [Release notes](https://github.com/testcontainers/testcontainers-go/releases)
- [Commits](https://github.com/testcontainers/testcontainers-go/compare/v0.43.0...v0.44.0)

---
updated-dependencies:
- dependency-name: github.com/testcontainers/testcontainers-go/modules/opensearch
  dependency-version: 0.44.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-18 15:51:36 +02:00
Viktor Scharf c2a01e3aad ci: run search acceptance tests against OpenSearch on opensearch PR title (#3323) 2026-08-18 12:51:24 +02:00
Andre Duffeck 8aa55eb010 Merge pull request #3331 from aduffeck/fix-opensearch-space-scope
Fix opensearch space scope
2026-08-18 12:38:42 +02:00
André Duffeck 6a9ffd6842 Switch to Ginkgo tests for readability 2026-08-18 11:26:23 +02:00
Jannik Stehle 5ad9d61fdc build(deps): bump github.com/opencloud-eu/libre-graph-api-go to 69f82a7dde55 2026-08-18 11:12:23 +02:00
André Duffeck 701276bc80 Make sure to scope updates to the index by space 2026-08-18 10:54:24 +02:00
dependabot[bot] 3445b75216 build(deps): bump go.opentelemetry.io/otel/exporters/stdout/stdouttrace
Bumps [go.opentelemetry.io/otel/exporters/stdout/stdouttrace](https://github.com/open-telemetry/opentelemetry-go) from 1.44.0 to 1.45.0.
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.44.0...v1.45.0)

---
updated-dependencies:
- dependency-name: go.opentelemetry.io/otel/exporters/stdout/stdouttrace
  dependency-version: 1.45.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-18 10:45:45 +02:00
Pascal Bleser fedfddf407 Merge pull request #3307 from fschade/mise-toml
[docs-only] feat: add mise toml
2026-08-18 10:33:33 +02:00
Sawjan Gurung 4bcf97353a test(api): fix share role update test scenario (#3322)
Signed-off-by: Saw-jan <saw.jan.grg3e@gmail.com>
2026-08-18 09:49:18 +02:00
dependabot[bot] 2fa4a0458d build(deps): bump go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp
Bumps [go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp](https://github.com/open-telemetry/opentelemetry-go-contrib) from 0.69.0 to 0.70.0.
- [Release notes](https://github.com/open-telemetry/opentelemetry-go-contrib/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go-contrib/compare/zpages/v0.69.0...zpages/v0.70.0)

---
updated-dependencies:
- dependency-name: go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp
  dependency-version: 0.70.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-18 09:43:19 +02:00
Alex a3c7b2dbb3 feat: update space template image (#3324)
* feat: update space template image

* skip test

* reduce asset size
2026-08-18 09:14:20 +02:00
opencloudeu 7130c10ef3 [tx] updated from transifex 2026-08-17 23:19:38 +00:00
Florian Schade 6077e7453c Merge pull request #3321 from fschade/bump-libre-graph-api-go
build(deps): bump github.com/opencloud-eu/libre-graph-api-go
2026-08-17 15:30:41 +02:00
Viktor Scharf 1959d79717 test: add api tests for cross-space search index mutation (#3320) 2026-08-17 15:10:34 +02:00
Florian Schade 26bd26f998 build(deps): bump github.com/opencloud-eu/libre-graph-api-go to 387da64db0b1 2026-08-17 12:29:18 +02:00
Viktor Scharf c8a1f55657 ci: run search acceptance tests against OpenSearch in nightly (#3302)
* ci: run search acceptance tests against OpenSearch in nightly

* fix

* add issue tag to failed search tests
2026-08-17 08:19:54 +02:00
opencloudeu 7243c922ef [tx] updated from transifex 2026-08-16 23:17:02 +00:00
opencloudeu 2e912d233a [tx] updated from transifex 2026-08-14 23:17:03 +00:00
Jannik Stehle 29a56da565 Merge pull request #3313 from opencloud-eu/feat/enable-rclone-crypt-app
feat(web): add rclone-crypt to default apps
2026-08-14 16:05:52 +02:00
Jannik Stehle 4e0cd4038e feat(web): add rclone-crypt to default apps
Enable the rclone-crypt app per default for the upcoming release.
2026-08-14 14:42:45 +02:00
Thomas Schweiger 1fa8950571 Merge pull request #3229 from opencloud-eu/favourite-sse-event 2026-08-14 13:00:30 +02:00
Alex AbabiiandViktor Scharf 8989106e91 fix restore file version for shared resource (#3268)
* tmp upd of web and reva version for testing purposes

* chore: bump reva and web

* upd expected failures list in acceptance test for revert file version case

* bump reva and web versions

---------

Co-authored-by: Viktor Scharf <v.scharf@opencloud.eu>
2026-08-14 10:40:59 +02:00
Thomas Schweiger 9a9443fe85 enhance: send events for adding/removing favorite items 2026-08-14 10:16:57 +02:00
Florian Schade 7fd5079973 feat: add mise toml 2026-08-14 09:32:43 +02:00
Alex b2cf7a965f fix(csp): allow blob: in style-src for EPUB reader iframe (#3300) 2026-08-13 13:16:04 +02:00
Jörn Friedrich Dreyer 8478b5daa1 allow tuning the proxies http client
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
2026-08-13 11:54:42 +02:00
Pascal Bleser 331f78eb43 feat(nats): enable the NATS monitoring HTTP endpoint in the embedded NATS server
* add configuration options to enable the NATS server HTTP monitoring
   endpoint:
   - NATS_MONITORING_ENABLED (defaults to false)
   - NATS_MONITORING_HTTP_HOST (defaults to 127.0.0.1)
   - NATS_MONITORING_HTTP_PORT (defaults to 8222)
   - NATS_MONITORING_ENABLE_TLS (defaults to false)

Fixes #3294
2026-08-13 11:46:53 +02:00
dependabot[bot] 5deb863dd8 build(deps): bump go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
Bumps [go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc](https://github.com/open-telemetry/opentelemetry-go) from 1.44.0 to 1.45.0.
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.44.0...v1.45.0)

---
updated-dependencies:
- dependency-name: go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc
  dependency-version: 1.45.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-13 11:42:47 +02:00
dependabot[bot] 1cf3ff4863 build(deps): bump github.com/rogpeppe/go-internal from 1.15.0 to 1.16.0
Bumps [github.com/rogpeppe/go-internal](https://github.com/rogpeppe/go-internal) from 1.15.0 to 1.16.0.
- [Release notes](https://github.com/rogpeppe/go-internal/releases)
- [Commits](https://github.com/rogpeppe/go-internal/compare/v1.15.0...v1.16.0)

---
updated-dependencies:
- dependency-name: github.com/rogpeppe/go-internal
  dependency-version: 1.16.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-13 11:42:08 +02:00
dependabot[bot] 9ae863ca3a build(deps): bump github.com/kovidgoyal/imaging from 1.8.22 to 1.8.23
Bumps [github.com/kovidgoyal/imaging](https://github.com/kovidgoyal/imaging) from 1.8.22 to 1.8.23.
- [Release notes](https://github.com/kovidgoyal/imaging/releases)
- [Commits](https://github.com/kovidgoyal/imaging/compare/v1.8.22...v1.8.23)

---
updated-dependencies:
- dependency-name: github.com/kovidgoyal/imaging
  dependency-version: 1.8.23
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-13 11:40:19 +02:00
Viktor Scharf 0fc2a98e6e api-test: notification settings and getting email notifications (#3281)
* api-test: notification settings and getting email notifications

* disable all email notifications
2026-08-13 11:32:12 +02:00
Jörn Friedrich Dreyer 6f5f993ada Merge pull request #3288 from fschade/feat-modernize-opa
perf(policies): reuse the compiled rego query across evaluations
2026-08-12 17:58:13 +02:00
Florian Schade 1e7cfaf92d refactor(policies): read the rego policies once at startup 2026-08-12 17:01:49 +02:00
Viktor Scharf b41d0c1040 fix(ci): stamp version into daily docker images (#3291)
* fix(ci): stamp version into daily docker images

* fix after review
2026-08-12 12:09:22 +02:00
opencloudeu 716922f76f [tx] updated from transifex 2026-08-11 23:17:55 +00:00
Florian Schade 573844ada4 Merge pull request #3286 from fschade/fix-proxy-middleware-race
Fix proxy middleware race
2026-08-11 12:40:54 +02:00
Florian Schade cd7f8f91b6 fix: oidc middleware claim race 2026-08-11 11:39:50 +02:00
opencloudeu 8504e29743 [tx] updated from transifex 2026-08-10 23:17:14 +00:00
dependabot[bot] f03429f47c build(deps): bump go.opentelemetry.io/otel/trace from 1.44.0 to 1.45.0
Bumps [go.opentelemetry.io/otel/trace](https://github.com/open-telemetry/opentelemetry-go) from 1.44.0 to 1.45.0.
- [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases)
- [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md)
- [Commits](https://github.com/open-telemetry/opentelemetry-go/compare/v1.44.0...v1.45.0)

---
updated-dependencies:
- dependency-name: go.opentelemetry.io/otel/trace
  dependency-version: 1.45.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-10 11:24:31 +02:00
Viktor Scharf 97908ac6c1 api-test: add posixfs scan and consistency CLI tests (#3263)
* api-test: add posixfs scan and consistency CLI tests

* fix after review
2026-08-10 08:50:47 +02:00
opencloudeu 3a3cba602c [tx] updated from transifex 2026-08-08 23:16:53 +00:00
Jannik Stehle 1c138efac2 Merge pull request #3259 from opencloud-eu/feat/yjs-server-url
feat(web): add yjsServerUrl config
2026-08-06 15:28:11 +02:00
Jannik Stehle 07fd041efb feat(web): add yjsServerUrl config
This config specifies a URL for a yjs server that is used for document
collaboration in web apps (e.g. tiptap editor, excalidraw, ...). It's
optional, not setting this disables this feature in Web.
2026-08-06 13:37:54 +02:00
Viktor Scharf da7849251d update rolling release template (#3242) 2026-08-06 09:29:16 +02:00
Michael Barz 466c3c8c79 Merge pull request #3252 from aduffeck/fix-favorite-flag
Fix missing favorite flag on opensearch hits
2026-08-06 09:07:57 +02:00
André Duffeck 2142894cba Fix missing favorite flag on opensearch hits 2026-08-05 18:43:13 +02:00
Viktor Scharf 76ff13b47e api-test: replace sleeps with WaitHelper poll for async state (#3239)
* api-test: replace sleeps with WaitHelper poll for async state

* php-style
2026-08-05 09:23:57 +02:00
Andre Duffeck 799f98339e Merge pull request #3235 from pbleser-oc/feat/3182-posixfs-scan-add-subtree
feat(posixfs): #3182 add basepath option in the "posixfs scan" command
2026-08-04 09:15:22 +02:00
OpenCloud Devopsandv.scharf d695d283f6 🎉 Release 7.4.0 (#3143)
* 🎉 Release 7.3.1

* 🎉 Release 7.3.1

* 🎉 Release 7.3.1

* 🎉 Release 7.3.1

* 🎉 Release 7.3.1

* 🎉 Release 7.3.1

* 🎉 Release 7.3.1

* 🎉 Release 7.3.1

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

* 🎉 Release 7.4.0

---------

Co-authored-by: v.scharf <v.scharf@opencloud.eu>
2026-08-03 20:42:51 +02:00
Viktor Scharf 553c85b7ff set introduction version 7.4.0 (#3234) 2026-08-03 20:07:23 +02:00
Pascal Bleser 6663fbeeed feat(posixfs): #3182 add basepath option in the "posixfs scan" command
* add support for specifying a set of resources when running the
   posixfs scan command scanning, or a singular file to scan, as opposed

 * refactors the resource walking function implemented in
   https://github.com/opencloud-eu/opencloud/pull/3220 in order to
   reuse it for the posixfs scan command

 * implements https://github.com/opencloud-eu/opencloud/issues/3182

 * add --halt-on-error flag

 * collect errors and fail command when more than one error occured
2026-08-03 20:04:39 +02:00
Viktor Scharf 19e44f9b64 [full-ci] chore: bump web to v7.3.0 (#3223)
* chore: bump web to v7.3.0

* Update WEB_COMMITID in .woodpecker.env
2026-08-03 19:58:05 +02:00
Andre Duffeck c93f50dc37 Merge pull request #3233 from aduffeck/extend-posixfs-consistency-check
Do not check ignored paths
2026-08-03 17:50:35 +02:00
Viktor Scharf bb4cd1ebf5 chore: reva bump -2.48.0 (#3230) 2026-08-03 17:43:51 +02:00
dependabot[bot] e12966a4fd build(deps): bump github.com/open-policy-agent/opa from 1.18.2 to 1.19.0
Bumps [github.com/open-policy-agent/opa](https://github.com/open-policy-agent/opa) from 1.18.2 to 1.19.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.18.2...v1.19.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-03 17:00:51 +02:00
André Duffeck b350b355c0 Do not check ignored paths 2026-08-03 16:29:30 +02:00
dependabot[bot] 9df3881128 build(deps): bump google.golang.org/grpc from 1.82.0 to 1.83.0
Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.82.0 to 1.83.0.
- [Release notes](https://github.com/grpc/grpc-go/releases)
- [Commits](https://github.com/grpc/grpc-go/compare/v1.82.0...v1.83.0)

---
updated-dependencies:
- dependency-name: google.golang.org/grpc
  dependency-version: 1.83.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-03 16:15:46 +02:00
Andre Duffeck 557adfc327 Merge pull request #3220 from aduffeck/extend-posixfs-consistency-check
Extend posixfs consistency check
2026-08-03 14:04:10 +02:00
André Duffeck 97ad525d5b Infer the indexes path from the config instead of calculating it 2026-08-03 13:24:23 +02:00
Ralf Haferkamp 0fd02c5ecf chore(idp): bump dependencies 2026-08-03 13:20:03 +02:00
Viktor Scharf 27a77567dd chore(skills): add skill for bumping reva (#3224)
* chore(skills): add skill for bumping reva

* chore(skills): derive OpenCloud version from open release PR

* chore: exclude .agents from codacy analysis
2026-08-03 13:18:43 +02:00
dependabot[bot] 57a615d6ce build(deps): bump github.com/nats-io/nats-server/v2
Bumps [github.com/nats-io/nats-server/v2](https://github.com/nats-io/nats-server) from 2.14.3 to 2.14.4.
- [Release notes](https://github.com/nats-io/nats-server/releases)
- [Changelog](https://github.com/nats-io/nats-server/blob/main/RELEASES.md)
- [Commits](https://github.com/nats-io/nats-server/compare/v2.14.3...v2.14.4)

---
updated-dependencies:
- dependency-name: github.com/nats-io/nats-server/v2
  dependency-version: 2.14.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-03 13:17:14 +02:00
André Duffeck deb3247b99 Move consistency check logic into a checker struct
This makes it possible to get rid of the globals without passing
multiple state vars around.
2026-08-03 12:17:19 +02:00
dependabot[bot] b9adb507f8 build(deps): bump github.com/go-ldap/ldap/v3 from 3.4.13 to 3.4.14
Bumps [github.com/go-ldap/ldap/v3](https://github.com/go-ldap/ldap) from 3.4.13 to 3.4.14.
- [Release notes](https://github.com/go-ldap/ldap/releases)
- [Commits](https://github.com/go-ldap/ldap/compare/v3.4.13...v3.4.14)

---
updated-dependencies:
- dependency-name: github.com/go-ldap/ldap/v3
  dependency-version: 3.4.14
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-03 12:16:16 +02:00
André Duffeck c6fba8543f Improve wording 2026-08-03 11:55:14 +02:00
dependabot[bot] 7c2cb14a80 build(deps): bump github.com/prometheus/client_golang
Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.23.2 to 1.24.1.
- [Release notes](https://github.com/prometheus/client_golang/releases)
- [Changelog](https://github.com/prometheus/client_golang/blob/v1.24.1/CHANGELOG.md)
- [Commits](https://github.com/prometheus/client_golang/compare/v1.23.2...v1.24.1)

---
updated-dependencies:
- dependency-name: github.com/prometheus/client_golang
  dependency-version: 1.24.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-03 11:04:15 +02:00
André Duffeck b125f0681f Fix typos 2026-08-03 11:03:45 +02:00
André Duffeck 20d16c5275 Allow for providing multiple paths to check 2026-08-03 10:58:53 +02:00
dependabot[bot] 639e3657cd build(deps): bump github.com/gabriel-vasile/mimetype
Bumps [github.com/gabriel-vasile/mimetype](https://github.com/gabriel-vasile/mimetype) from 1.4.13 to 1.4.15.
- [Release notes](https://github.com/gabriel-vasile/mimetype/releases)
- [Commits](https://github.com/gabriel-vasile/mimetype/compare/v1.4.13...v1.4.15)

---
updated-dependencies:
- dependency-name: github.com/gabriel-vasile/mimetype
  dependency-version: 1.4.15
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-03 10:44:05 +02:00
André Duffeck 559b10e90a Check if the given path is part of the storage 2026-08-03 09:49:10 +02:00
dependabot[bot] e63f1d542a build(deps): bump golang.org/x/net from 0.56.0 to 0.57.0
Bumps [golang.org/x/net](https://github.com/golang/net) from 0.56.0 to 0.57.0.
- [Commits](https://github.com/golang/net/compare/v0.56.0...v0.57.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-03 09:26:21 +02:00
dependabot[bot] 51089765d0 build(deps): bump github.com/beevik/etree from 1.6.0 to 1.7.0
Bumps [github.com/beevik/etree](https://github.com/beevik/etree) from 1.6.0 to 1.7.0.
- [Release notes](https://github.com/beevik/etree/releases)
- [Changelog](https://github.com/beevik/etree/blob/main/RELEASE_NOTES.md)
- [Commits](https://github.com/beevik/etree/compare/v1.6.0...v1.7.0)

---
updated-dependencies:
- dependency-name: github.com/beevik/etree
  dependency-version: 1.7.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-03 09:25:47 +02:00
André Duffeck 54cced7c56 Streamline logging in the commands 2026-08-03 08:58:19 +02:00
André Duffeck 3d546693c6 Allow for checking specific spaces and files as well 2026-08-03 08:55:49 +02:00
André Duffeck 40ced9997e Also check blobsize and checksums (when --fix-checkums is set) 2026-08-03 08:55:10 +02:00
André Duffeck 3bd188122e Simplify output, remove spinner lib 2026-08-03 08:55:10 +02:00
opencloudeu 9b5849f470 [tx] updated from transifex 2026-07-31 23:16:44 +00:00
Andre Duffeck 942cca8eef Merge pull request #3191 from pbleser-oc/feat/#3182-posixfs-scan-subtree
feat(posixfs): #3182 add basepath option in the "posixfs scan" command
2026-07-31 16:39:48 +02:00
Dominik Schmidt a9f39b85d5 Merge pull request #3140 from opencloud-eu/fix/service-startup-logging
fix(runtime): log service startup errors instead of printing them beside the log
2026-07-31 16:37:19 +02:00
Andre Duffeck 15fc44be94 Merge pull request #3213 from aduffeck/improve-reindex-command
Improve reindex command
2026-07-31 16:34:54 +02:00
André Duffeck 2eb1fe069c Add a --concurrency flag to the index command
It controls the number of spaces that are indexed in parallel. The max
concurrency configured in the server is still considered.
2026-07-31 16:07:18 +02:00
André Duffeck a82b6223aa Remove the SilenceUsage flag again
It will be obsolete once #3140 has been merged
2026-07-31 15:55:36 +02:00
Pascal Bleser 433dea41e8 feat(posixfs): #3182 add basepath option in the "posixfs scan" command
* add support for specifying a basepath using -p when running the
   posixfs scan command, to indicate a directory under which to start
   scanning, or a singular file to scan, as opposed to scanning from the
   storage root directory as is the default behaviour

 * implements https://github.com/opencloud-eu/opencloud/issues/3182
2026-07-31 15:06:50 +02:00
André Duffeck e26a009fc1 Improve "opencloud search index" command
The command no longer times out after 10 minutes when the processing
hasn't been finished yet. Instead it shows progress and logs successful
and failed spaces. The process can also be aborted using ctrl+c.

Example output:

```
$ bin/opencloud search index --all-spaces --insecure --force-rescan
[1/602] indexed space a9033d65-6c13-4556-b923-f321ab33a9ca$eb6a8a0e-2e62-4b40-bce9-360063236676!eb6a8a0e-2e62-4b40-bce9-360063236676 in 5.501190908s
[2/602] indexed space a9033d65-6c13-4556-b923-f321ab33a9ca$34b7c565-da3b-4f53-8559-825e87db4011!34b7c565-da3b-4f53-8559-825e87db4011 in 5.935075697s
[3/602] indexed space a9033d65-6c13-4556-b923-f321ab33a9ca$e08c6026-24f6-4a9e-a805-ed335b34b8da!e08c6026-24f6-4a9e-a805-ed335b34b8da in 6.016350958s
^Caborted, indexing has been stopped
```

Fixes #2592
2026-07-31 14:50:09 +02:00
André Duffeck 49a81c9c1f Cleanup .bingo 2026-07-31 14:50:09 +02:00
Andre Duffeck 7e8179a704 Merge pull request #3207 from aduffeck/concurrent-reindex
Reindex spaces concurrently
2026-07-31 14:49:58 +02:00
André Duffeck d50d8d8900 Rename max concurrency option 2026-07-31 12:04:44 +02:00
André Duffeck 243514ec17 Do not abort reindexing all spaces if one of the spaces fails 2026-07-30 15:34:57 +02:00
André Duffeck be75d8fe95 Reindex spaces concurrently
This speeds up reindexing all spaces which happend sequentially space
after space until now. The level of concurrency can be configured using
the SEARCH_REINDEX_CONCURRENCY env var (3 by default).
2026-07-30 15:25:13 +02:00
Dominik Schmidt bb8cefa33b Merge pull request #3189 from opencloud-eu/feat/announcement-banner
feat: add announcement banner
2026-07-30 10:44:17 +02:00
Viktor Scharf 0a44bbae9e api-test: mark group last-manager removal scenario as flaky (#3194) 2026-07-30 09:50:05 +05:45
opencloudeu fb387a16b6 [tx] updated from transifex 2026-07-29 23:16:50 +00:00
Ralf Haferkamp e358cb6e6e fix(posixfs scan): Setup logger for scan command
Setup a logger for the FS. The nats kv clients for the caches need one
to be able to log NAT connection issues.

Fixes: #3184
2026-07-29 14:29:19 +02:00
Dominik Schmidt 341ebdf6cc refactor: mark the announcement config as output-only (yaml:"-")
The announcement is runtime-managed and injected into config.json; it is not a
static yaml config option. Exclude it from yaml (yaml:"-") so it is not
presented as a configurable knob, keeping the json tag only for the config.json
output.
2026-07-29 12:03:57 +02:00
Dominik Schmidt 6d2d6c38ec fix: fail fast when the announcement store is unreachable
Replace reva's cache.NewNatsKeyValue (which retries with backoff and can hang
the web service startup) with a direct nats.Connect + jetstream setup like the
graph service, so an unreachable or misconfigured store surfaces as a clear
startup error instead of a hang.
2026-07-29 11:53:58 +02:00
Dominik Schmidt d27b7ef40a refactor: drop static config for the announcement, runtime store only
A statically configured announcement is not supported: it cannot be removed via
the runtime API and disappears from the running session once the admin settings
load (they read the store, not config.json). Make the store the single source
of truth, config.json always reflects it and a statically configured
options.announcement is ignored.
2026-07-29 11:52:09 +02:00
Dominik Schmidt 27bdda265f refactor: back the announcement store with plain NATS JetStream
Replace the go-micro store with a NATS JetStream key-value bucket, created via
reva's cache.NewNatsKeyValue, so the web service no longer depends on go-micro
stores. The store methods now take a context, threaded through the config.json
render path and the management handlers. Tests use a mockery mock of
jetstream.KeyValue.
2026-07-29 10:22:43 +02:00
Dominik Schmidt 7d59a83c18 feat: log announcement handler errors with the request id
Add a logger to the announcement service and log server-side errors before
returning a 5xx, tagged with the request id so they correlate with the
request log line from the logging middleware.
2026-07-29 10:08:47 +02:00
Dominik Schmidt 9d472290f2 fix: return 413 when the announcement body exceeds the size cap
Distinguish the http.MaxBytesReader limit from a malformed body: an
oversized payload now returns 413 Request Entity Too Large instead of a
generic 400.
2026-07-29 08:46:46 +02:00
Dominik Schmidt e29d961be3 refactor: rename Announcement.Write to Announcement.ReadWrite
The permission gates reading the full announcement state (including
disabled ones) as well as writing it, so name it ReadWrite to match the
other management permissions (Accounts.ReadWrite, Settings.ReadWrite, ...)
and use the READWRITE operation.
2026-07-29 08:40:29 +02:00
Dominik Schmidt 809d32c4d8 fix: keep a static announcement as fallback when the store is empty
Make the store authoritative only once it manages an announcement: an
enabled record is exposed, a disabled record clears any static config, and
an empty store falls back to a statically configured
web.config.options.announcement. This matches the review request and stops
a static announcement from being silently dropped.
2026-07-29 08:29:58 +02:00
Dominik Schmidt 046f46ce8d fix: make the runtime store authoritative for the announcement
Always reflect the stored announcement in config.json: expose it while live
and clear it otherwise. A disabled announcement now clears the config output
instead of falling back to a statically configured one, which removes the
precedence ambiguity raised in review.
2026-07-29 08:18:56 +02:00
Dominik Schmidt 51dd107767 feat: add announcement banner 2026-07-29 00:39:59 +02:00
Viktor Scharf d9e406ca99 rerun flaky tests (#3183) 2026-07-28 13:44:28 +02:00
Viktor Scharf a2bdbc8b56 api-test: fix removeAccessToDrive.feature:145 (#3179)
* api-test: fix removeAccessToDrive.feature:145

* fix after review
2026-07-28 13:19:26 +02:00
Viktor Scharf 743899055a delete qa report (#3178) 2026-07-28 09:29:44 +02:00
opencloudeu f6ffd125c9 [tx] updated from transifex 2026-07-27 23:16:42 +00:00
Viktor Scharf f3693ef112 api-test: cover additional unified roles in acceptance tests (#3169) 2026-07-27 09:12:38 +02:00
opencloudeu a87163fb14 [tx] updated from transifex 2026-07-25 23:16:48 +00:00
Thomas Schweiger 2649fa0aab Merge pull request #3155 from opencloud-eu/clean-up-auth-app-docu
maint: clean-up auth-app documentation
2026-07-24 21:31:41 +02:00
opencloudeu 12cec14b56 [tx] updated from transifex 2026-07-22 23:16:36 +00:00
Viktor Scharf 44ae3a8ab5 ci: sync tests/README.md to docs (#3164) 2026-07-22 14:27:50 +02:00
Viktor Scharf a3a271aad5 test(apiAuthApp): fix flaky token pattern (#3163) 2026-07-22 17:39:01 +05:45
Florian Schadeandv.scharf 9041ee8df9 feat: add space viewer with versions role (#2961)
* feat: add space viewer with versions role

* fix after review

---------

Co-authored-by: v.scharf <v.scharf@opencloud.eu>
2026-07-22 07:05:51 +02:00
opencloudeu 052636ff0f [tx] updated from transifex 2026-07-21 23:16:43 +00:00
Ralf Haferkamp c8805265e2 chore: don't log non-error message at error level
When walking the tree for creating the search index, ignore "not found"
errors. Search indexing happens asynchronously so the underlying space,
file or folder might just not exist anymore when the indexing starts.
2026-07-21 11:40:44 +02:00
Thomas Schweiger a28ddc8285 maint: clean-up auth-app documentation 2026-07-20 10:37:57 +02:00
opencloudeu 0245a2197b [tx] updated from transifex 2026-07-19 23:16:36 +00:00
Michael Stingl bf3b5c5e1f test(apiArchiver): the single-resource archive is named after the resource (#3080)
An archive download of a single folder was always named "download.zip" until the
handler resolved the resource name for the Content-Disposition header
(https://github.com/opencloud-eu/reva/pull/661). Add a scenario asserting the
archive of a folder carries a Content-Disposition filename of the folder,
reusing the archiver download step and the header-regex assertion.

Verified red->green on posix and decomposed: red on an opencloud built on a reva
with the change reverted (the archive is "download.zip"), green on the shipped
reva.
2026-07-17 16:37:36 +02:00
Michael Stinglandv.scharf 76ffc82bba test(coreApiWebdavUploadTUS): assert etag and permissions on the finalizing TUS chunk (#3078)
* test(coreApiWebdavUploadTUS): assert etag and permissions on the finalizing TUS chunk

The chunked TUS finalize returns OC-ETag, ETag and OC-Perm since
https://github.com/opencloud-eu/reva/pull/718, so a client no longer
needs a follow-up PROPFIND for the new etag and permissions. Add a
scenario asserting these headers on the finalizing chunk, reusing
existing step definitions (the etag is a dynamic quoted hash, hence the
header-regex assertion).

Verified locally red->green: red on stock (headers absent), green on an
opencloud built on a reva carrying that change, on posix and decomposed.

https://github.com/opencloud-eu/opencloud/issues/2409

* test(coreApiWebdavUploadTUS): assert exact OC-Perm and tighten etag regex

---------

Co-authored-by: v.scharf <v.scharf@opencloud.eu>
2026-07-17 14:40:37 +02:00
Michael Stingl 3893be6ed1 test(coreApiWebdavOperations): download a file with a literal "%" via its oc:downloadURL (#3079)
A file whose name contains a literal "%" 404s on download because the
server-built oc:downloadURL did not percent-encode the path (#2852, fixed in
reva by https://github.com/opencloud-eu/reva/pull/653). Add a scenario mirroring
the web client download flow: read the oc:downloadURL from PROPFIND and GET it
as-is (the signature in the URL authenticates it), asserting 200 and the content.

The new step "user X downloads the P file via its oc:downloadURL" lives in
WebDavPropertiesContext; a regex annotation avoids the ":" in oc:downloadURL
colliding with the turnip :placeholder syntax.

Verified red->green on posix and decomposed: red on an opencloud built on a reva
with the fix reverted (the download 404s), green on the shipped reva.

https://github.com/opencloud-eu/opencloud/issues/2852
2026-07-17 14:20:00 +02:00
Viktor Scharf a82aeef2eb add header to release pr. remove 📦️ Dependencies from release description (#3144) 2026-07-17 08:07:28 +02:00
Viktor Scharf e13b86950a fix(ci): replace deprecated runs_on. Removed skipCheckStep() (#3145)
* fix(ci): replace deprecated runs_on

* drop skipCheckStep()

* fix
2026-07-17 08:06:35 +02:00
Alex 2f9d9c582c add version to apps config (#3139) 2026-07-16 11:28:45 +02:00
Jannik Stehle d731cb4c0f Merge pull request #3137 from opencloud-eu/refactor/remove-color-palette-from-theme
refactor(web): remove colorPalette from theme
2026-07-16 06:29:50 +02:00
Dominik Schmidt fec92d2f22 fix(runtime): keep the usage block for flag errors only 2026-07-15 19:01:03 +02:00
Dominik Schmidt 00dd4f1b7f fix(runtime): log service startup errors instead of printing them beside the log 2026-07-15 18:32:04 +02:00
Jannik Stehle e7f850c2aa refactor(web): remove colorPalette from theme
With the recently added new file type icons in Web, the colorPalette
option in the theme.json becomes obsolete. Hence remove it.

Also see https://github.com/opencloud-eu/web/pull/2892
2026-07-15 08:56:37 +02:00
OpenCloud Devopsandv.scharf 85e63ca252 🎉 Release 7.3.0 (#2890)
* 🎉 Release 6.2.1

* 🎉 Release 6.2.1

* 🎉 Release 6.3.0

* 🎉 Release 6.3.0

* 🎉 Release 6.3.0

* 🎉 Release 6.3.0

* 🎉 Release 6.3.0

* 🎉 Release 6.3.0

* 🎉 Release 6.3.0

* 🎉 Release 6.3.0

* 🎉 Release 7.0.0

* add release 7.2.0 to changelog

* add release 7.3.0 to changelog

---------

Co-authored-by: v.scharf <v.scharf@opencloud.eu>
2026-07-14 18:52:14 +02:00
Viktor Scharf 5accb6056b set 7.3.0 version placeholder (#3132) 2026-07-14 18:12:24 +02:00
Elias Schneider 4734c57f2b fix(proxy): honor access token cache ttl 2026-07-14 17:49:40 +02:00
dependabot[bot] fcde95750b build(deps): bump golang.org/x/image from 0.43.0 to 0.44.0
Bumps [golang.org/x/image](https://github.com/golang/image) from 0.43.0 to 0.44.0.
- [Commits](https://github.com/golang/image/compare/v0.43.0...v0.44.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-14 16:38:06 +02:00
dependabot[bot] eab58b8190 build(deps): bump golang.org/x/text from 0.39.0 to 0.40.0
Bumps [golang.org/x/text](https://github.com/golang/text) from 0.39.0 to 0.40.0.
- [Release notes](https://github.com/golang/text/releases)
- [Commits](https://github.com/golang/text/compare/v0.39.0...v0.40.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-14 16:37:38 +02:00
Jörn Friedrich Dreyer 48e40a385c update collaboration readme
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
2026-07-14 16:29:57 +02:00
Viktor Scharf 4d511a3a42 [full-ci] chore: reva bump -2.47.0 (#3127) 2026-07-14 13:15:54 +02:00
Viktor Scharf a53eb44083 steps refactoring (#3100) 2026-07-14 09:32:35 +02:00
Benedikt Kulmann ea1a1dd5e2 Merge pull request #3121 from opencloud-eu/chore/bump-web-v7.2.0
[full-ci] chore: bump web to v7.2.0
2026-07-13 12:30:10 +02:00
v.scharf ff5bcdee3f add rclone to web-config 2026-07-13 11:56:15 +02:00
v.scharf 559706696a adjust e2e tests in CI 2026-07-13 11:19:51 +02:00
Benedikt Kulmann 02aea2e65e chore: bump web to v7.2.0 2026-07-13 10:29:16 +02:00
Ralf Haferkamp 8c3ef60da1 chore(idp): bump form-data and xmldom
To address issues raised in the security dashboard. Also ran `pnpm
dedupe` for cleanup
2026-07-10 14:46:32 +02:00
dependabot[bot] b5b6a4ee26 build(deps): bump golang.org/x/term from 0.44.0 to 0.45.0
Bumps [golang.org/x/term](https://github.com/golang/term) from 0.44.0 to 0.45.0.
- [Commits](https://github.com/golang/term/compare/v0.44.0...v0.45.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-10 13:11:45 +02:00
dependabot[bot] e992f952d3 build(deps): bump github.com/coreos/go-oidc/v3 from 3.19.0 to 3.20.0
Bumps [github.com/coreos/go-oidc/v3](https://github.com/coreos/go-oidc) from 3.19.0 to 3.20.0.
- [Release notes](https://github.com/coreos/go-oidc/releases)
- [Commits](https://github.com/coreos/go-oidc/compare/v3.19.0...v3.20.0)

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

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-10 13:11:02 +02:00
Jörn Friedrich Dreyer e5105ab33f Merge pull request #3097 from opencloud-eu/update-idp-i18n
chore(idp): update i18n, document workflow
2026-07-10 08:38:34 +02:00
opencloudeu 44c51e88ca [tx] updated from transifex 2026-07-09 23:16:27 +00:00
Jörn Friedrich Dreyer bb028a569f chore(idp): update i18n, document workflow
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
2026-07-09 14:48:34 +02:00
1240 changed files with 100519 additions and 27056 deletions

No files matched your search

+153
View File
@@ -0,0 +1,153 @@
---
name: bumping-reva
description: Use when the user asks to bump, update, or upgrade the OpenCloud reva dependency to a specific version (e.g. "reva bump to 2.48.0", "bump reva to v2.48.0"). Covers editing go.mod, re-vendoring, bumping the OpenCloud LatestTag, the single commit, and opening the PR against main.
---
# Bumping Reva
## Overview
Bumping reva updates the pinned [opencloud-eu/reva](https://github.com/opencloud-eu/reva) dependency (`github.com/opencloud-eu/reva/v2`) to a tagged release, re-vendors the module graph, and bumps the OpenCloud dev version. It touches `go.mod`, `go.sum`, `vendor/**` and `pkg/version/version.go`, lands as one commit, and ships as a PR whose body is the reva changelog for that version.
Template PR: https://github.com/opencloud-eu/opencloud/pull/3127
## Prerequisites
- **The reva release must already be tagged.** A reva release is cut by merging its release PR (title `🎉 Release X.Y.Z`, branch `next-release/main`). The **user merges that PR themselves** — this skill starts *after* the tag `vX.Y.Z` exists. Verify the tag before doing anything (step 1); if it's missing, stop and ask the user to merge the reva release PR first.
- **`gh` (GitHub CLI), authenticated** — tag lookup and PR creation go through `gh api` / `gh pr`. Verify with `gh auth status`; if it fails, ask the user to run `gh auth login` (suggest `! gh auth login` so it runs in-session).
- `gh` needs the system keyring, so run all `gh` commands with the sandbox disabled.
- **Go toolchain + network** — `go get` / `go mod tidy` / `go mod vendor` hit the Go module proxy. Run them with the sandbox disabled (network access).
- `git` and `base64` (decoding the changelog) — standard on macOS/Linux.
## Inputs
- `REVA_VERSION` — the new reva tag, always normalized to a leading `v` (e.g. `v2.48.0`). If the user didn't give it, ask (or take the latest reva release tag).
- `OC_VERSION` — the OpenCloud target for `LatestTag`, **without** the `+dev` suffix (e.g. `7.4.0`). **Do not ask or guess** — derive it from the open OpenCloud release PR (step 3). It can be a new major (e.g. `8.0.0`) when release-please picked up a breaking change.
## What changes
| File | What |
| ------------------------ | ------------------------------------------------------------------- |
| `go.mod` | `github.com/opencloud-eu/reva/v2``REVA_VERSION` (+ indirect deps pulled by `go mod tidy`) |
| `go.sum` | updated by `go get` / `go mod tidy` |
| `vendor/**` | re-vendored by `go mod vendor` (incl. `vendor/modules.txt`) |
| `pkg/version/version.go` | `LatestTag = "<OC_VERSION>+dev"` |
## Procedure
### 1. Verify the reva tag exists
```bash
gh api repos/opencloud-eu/reva/commits/$REVA_VERSION --jq '.sha'
```
- Success (a sha) → the release is tagged, continue.
- `422`/`404` → the tag does not exist yet. The reva release PR (`🎉 Release X.Y.Z`) is probably not merged. **Stop** and tell the user to merge it first. Helpful checks:
```bash
gh api repos/opencloud-eu/reva/releases/latest --jq '.tag_name' # current latest tag
gh pr list --repo opencloud-eu/reva --search '🎉 Release in:title' --state open --json number,title
```
### 2. Bump the dependency and re-vendor
```bash
go get github.com/opencloud-eu/reva/v2@$REVA_VERSION
go mod tidy
go mod vendor
```
(Sandbox disabled — these need network.) Notes:
- Right after a fresh tag the module proxy can lag; if `go get` reports the version as unknown, retry, or use `GOPROXY=direct go get github.com/opencloud-eu/reva/v2@$REVA_VERSION`.
- `go mod tidy` will also bump indirect dependencies that reva pulled in — that is expected (the template PR did the same).
### 3. Bump the OpenCloud dev version
`OC_VERSION` is the version of the **open OpenCloud release PR** — the release-please PR from branch `next-release/main`, titled `🎉 Release X.Y.Z` (e.g. #3143). Derive it, don't ask:
```bash
gh pr list --repo opencloud-eu/opencloud --head next-release/main --state open \
--json title --jq '.[0].title' | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1
```
This is the next release target and tracks breaking changes — it may be a new major (e.g. `8.0.0`), not just a minor bump. If no such PR is open, stop and ask the user.
Edit `pkg/version/version.go`:
```go
LatestTag = "<OC_VERSION>+dev" // e.g. "7.4.0+dev"
```
### 4. Fetch the reva changelog for the PR body
```bash
gh api "repos/opencloud-eu/reva/contents/CHANGELOG.md?ref=$REVA_VERSION" --jq '.content' | base64 -d
```
Take **only the section for this version** and trim it exactly like the web bump: start at the first content heading (`### 🐛 Bug Fixes` / `### 📈 Enhancement` / `### 💥 Breaking changes`), drop the `# Changelog` title, the `## [x.y.z] - date` header and the `### ❤️ Thanks to all contributors!` block, and stop before the next `## [...]` version header.
Then **prepend two summary bullets** so the final PR body is:
```
- bump opencloud version to <OC_VERSION>
- reva bump <REVA_VERSION without the leading v>
### 🐛 Bug Fixes
...trimmed reva changelog...
```
Write this to a file for `--body-file` (e.g. in the scratchpad).
### 5. Confirm before committing
The `vendor/` diff is huge — do **not** dump it. Show the user:
```bash
git diff go.mod pkg/version/version.go # the meaningful edits
git diff --stat | tail -1 # vendor churn summary
```
Confirm the reva line in `go.mod` is exactly `github.com/opencloud-eu/reva/v2 REVA_VERSION`, show the target branch (`main`), and the PR body. **Do not commit until the user approves.**
### 6. Commit, push, open PR
- Create a branch (do not commit on `main`), e.g. `reva-bump-2.48.0`.
- Stage everything the bump touched: `git add go.mod go.sum vendor pkg/version/version.go`.
- One commit, conventional-commits format, **empty body**:
```
chore: reva bump -2.48.0
```
- PR base: **`main`** (reva bumps always target main).
- PR title: `[full-ci] chore: reva bump -2.48.0` (the commit message prefixed with `[full-ci] `).
- PR body: the file from step 4.
- Add the label `Type:Maintenance`.
```bash
gh pr create --base main \
--title "[full-ci] chore: reva bump -$REVA_VERSION_NO_V" \
--label "Type:Maintenance" \
--body-file <body-file>
```
(`gh` commands need the sandbox disabled — they require the system keyring.)
## Quick reference
```bash
REVA_VERSION=v2.48.0
gh api repos/opencloud-eu/reva/commits/$REVA_VERSION --jq '.sha' # verify tag exists
OC_VERSION=$(gh pr list --repo opencloud-eu/opencloud --head next-release/main --state open \
--json title --jq '.[0].title' | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -1) # from open release PR
go get github.com/opencloud-eu/reva/v2@$REVA_VERSION && go mod tidy && go mod vendor # bump + re-vendor
# edit pkg/version/version.go -> LatestTag = "$OC_VERSION+dev"
gh api "repos/opencloud-eu/reva/contents/CHANGELOG.md?ref=$REVA_VERSION" --jq '.content' | base64 -d # changelog
```
## Common mistakes
- Running the bump before the reva release PR is merged — the tag won't exist and `go get` will fail. Verify the tag first (step 1).
- Forgetting to re-run `go mod vendor` after `go mod tidy`, leaving `vendor/` out of sync with `go.mod`.
- Asking for or hardcoding `OC_VERSION` — always derive it from the open `next-release/main` release PR (step 3); it can even be a new major after a breaking change.
- Reading the changelog from reva `main` instead of the tag (`?ref=$REVA_VERSION`). Always pin to the tag.
- Missing the `[full-ci] ` prefix in the PR title, the `Type:Maintenance` label, or the two summary bullets at the top of the body.
- Dumping the full `vendor/` diff at the confirmation step instead of `go.mod` + `version.go` + a `--stat` summary.
- Committing before the user confirms the diff.
+2
View File
@@ -1,6 +1,7 @@
---
exclude_paths:
- '.github/**'
- '.agents/**'
- 'CHANGELOG.md'
- '**/CHANGELOG.md'
- 'changelog/**'
@@ -15,6 +16,7 @@ exclude_paths:
- 'idp/src/**'
- 'devtools/**'
- 'deployments/**'
- "release-config.ts"
- 'tests/acceptance/expected-failures-*.md'
- 'tests/acceptance/bootstrap/**'
- 'tests/acceptance/TestHelpers/**'
+5 -3
View File
@@ -2,6 +2,8 @@
[Release Template](https://github.com/opencloud-eu/opencloud/blob/main/.github/rolling_release_template.md)
## Prerequisites
* [ ] replace `%%NEXT%%` with the release version
* [ ] web release
* [ ] bump web version
* [ ] squash and merge the web release PR
@@ -14,17 +16,17 @@
## QA Phase
* [ ] bump `opencloud_commitid` in web and run all working tests in CI
* [ ] compatibility test
* [ ] n8n integration QA
* [ ] confirmatory testing, if needed
* [ ] squash and merge Release PR
## Collected bugs
## After QA Phase
* [ ] replace `%%NEXT%%` wuth the release version
* [ ] squash and merge Release PR
* [ ] publish release notes to the docs
* [ ] add migration guide to changelog with prefix `**ACTION REQUIRED:**`, if needed.
* [ ] add release notes from web and reva to opencloud changelog
* [ ] n8n integration - update new opencloud version
* [ ] docker-compose - update new opencloud version
* [ ] update the public matrix channel topic
* [ ] update https://update.opencloud.eu/server.json
* [ ] update the version on demo.opencloud.eu
+2 -2
View File
@@ -40,8 +40,8 @@ vendor-php
suite-logs
tests/acceptance/filesForUpload/filesWithVirus/
# QA activity reports
tests/qa-activity-report/reports/
# Generated docs page (published to the server-testing-docs branch by CI)
tests/.docs-dist/
# drone CI is in .drone.star, do not let someone accidentally commit a local .drone.yml
.drone.yml
+5
View File
@@ -0,0 +1,5 @@
{
"recommendations": [
"alexkrechik.cucumberautocomplete"
]
}
+16
View File
@@ -0,0 +1,16 @@
{
"cucumberautocomplete.steps": [
"tests/acceptance/bootstrap/*.php"
],
"cucumberautocomplete.syncfeatures": "tests/acceptance/features/**/*.feature",
"cucumberautocomplete.strictGherkinCompletion": false,
"cucumberautocomplete.strictGherkinValidation": false,
"cucumberautocomplete.customParameters": [
{ "parameter": ":string", "value": "\"([^\"]*)\"" },
{ "parameter": "'/\\^(.*)\\$/'", "value": "'^$1$$'", "isRegex": true, "flags": "g" },
{ "parameter": "\\$\\w+", "value": "(.*)", "isRegex": true, "flags": "g" },
{ "parameter": "(?<!\\?):[a-zA-Z_][a-zA-Z0-9_]*", "value": "\"([^\"]*)\"", "isRegex": true, "flags": "g" }
],
"cucumberautocomplete.gherkinDefinitionPart": "(Given|When|Then|But)\\(",
"cucumberautocomplete.pureTextSteps": false
}
+1 -1
View File
@@ -1,3 +1,3 @@
# The test runner source for UI tests
WEB_COMMITID=47a1cfb1dbda4479b88e831d089bfa54b1f4bb8d
WEB_COMMITID=52b3c79f772feae23b7e77058c89c4151087502e
WEB_BRANCH=main
+283 -155
View File
@@ -202,12 +202,14 @@ config = {
"apiSearch1",
],
"skip": False,
"nightlyOpenSearch": True,
},
"search2": {
"suites": [
"apiSearch2",
],
"skip": False,
"nightlyOpenSearch": True,
},
"sharingNg": {
"suites": [
@@ -271,6 +273,7 @@ config = {
],
"skip": False,
"tikaNeeded": True,
"nightlyOpenSearch": True,
},
"ocm": {
"suites": [
@@ -375,30 +378,32 @@ config = {
"1": {
"skip": False,
"suites": [
"journeys",
"smoke",
"journeys/",
"smoke/",
],
},
"2": {
"skip": False,
"suites": [
"admin-settings",
"spaces",
"admin-settings/",
"spaces/",
"rclone-crypt/",
],
},
"3": {
"skip": False,
"suites": [
"shares",
"search",
"shares/",
"search/",
],
"tikaNeeded": True,
},
"4": {
"skip": False,
"suites": [
"user-settings",
#"fileaction",
# skip user-settings due to failing pagination test. see https://github.com/opencloud-eu/opencloud/pull/3324
#"user-settings/",
"fileaction/",
"embed",
],
},
@@ -407,12 +412,12 @@ config = {
"testSuites": {
"skip": False,
"suites": [
"smoke",
"shares",
"search",
"journeys",
#"file-action",
"spaces",
"smoke/",
"shares/",
"search/",
"journeys/",
"file-action/",
"spaces/",
],
"tikaNeeded": True,
},
@@ -489,13 +494,14 @@ def prefixStepCommands(pipeline, commands = [], skip_steps = []):
if "commands" in step.keys() and step["name"] not in skip_steps:
step["commands"] = commands + step["commands"]
def pipelineDependsOn(pipeline, dependant_pipelines):
def pipelineDependsOn(pipeline, dependant_pipelines, optional = False):
if type(pipeline) == "list":
pipeline = pipeline[0]
depends = getPipelineNames(dependant_pipelines, optional = optional)
if "depends_on" in pipeline.keys():
pipeline["depends_on"] = pipeline["depends_on"] + getPipelineNames(dependant_pipelines)
pipeline["depends_on"] = pipeline["depends_on"] + depends
else:
pipeline["depends_on"] = getPipelineNames(dependant_pipelines)
pipeline["depends_on"] = depends
return pipeline
def pipelinesDependsOn(pipelines, dependant_pipelines):
@@ -505,18 +511,13 @@ def pipelinesDependsOn(pipelines, dependant_pipelines):
return pipes
def getPipelineNames(pipelines = []):
"""getPipelineNames returns names of pipelines as a string array
Args:
pipelines: array of woodpecker pipelines
Returns:
names of the given pipelines as string array
"""
def getPipelineNames(pipelines = [], optional = False):
names = []
for pipeline in pipelines:
names.append(pipeline["name"])
if optional:
names.append({"name": pipeline["name"], "optional": True})
else:
names.append(pipeline["name"])
return names
def main(ctx):
@@ -569,6 +570,7 @@ def main(ctx):
pipelineDependsOn(
purgeBuildArtifactCache(ctx),
testPipelines(ctx),
optional = True,
),
)
@@ -576,6 +578,7 @@ def main(ctx):
pipelineDependsOn(
purgeBrowserCache(ctx),
testPipelines(ctx),
optional = True,
),
)
@@ -583,6 +586,7 @@ def main(ctx):
pipelineDependsOn(
purgeTracingCache(ctx),
testPipelines(ctx),
optional = True,
),
)
@@ -590,6 +594,7 @@ def main(ctx):
pipelineDependsOn(
purgeOpencloudWebBuildCache(ctx),
testPipelines(ctx),
optional = True,
),
)
@@ -597,6 +602,7 @@ def main(ctx):
pipelineDependsOn(
purgeGoBinCache(ctx),
testPipelines(ctx),
optional = True,
),
)
@@ -604,10 +610,11 @@ def main(ctx):
pipelineDependsOn(
purgePipelineInfoCache(),
testPipelines(ctx),
optional = True,
),
)
pipelines = test_pipelines + build_release_pipelines + genDocsPr(ctx) + notifyMatrixCheckSteps(ctx, getPipelineNames(testPipelines(ctx)))
pipelines = test_pipelines + build_release_pipelines + genDocsPr(ctx) + serverTestingDocs(ctx) + notifyMatrixCheckSteps(ctx, getPipelineNames(testPipelines(ctx), optional = True))
pipelineSanityChecks(pipelines)
return savePipelineNumber(ctx) + pipelines
@@ -648,7 +655,6 @@ def evaluateWorkflowStep():
}]
def cachePipeline(ctx, name, steps):
steps = skipCheckStep(ctx, "base") + steps
pipeline = {
"name": "cache-%s" % name,
"steps": steps,
@@ -658,13 +664,14 @@ def cachePipeline(ctx, name, steps):
"branch": ["main", "stable-*"],
},
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "base"),
},
},
],
}
prefixStepCommands(pipeline, [
". ./.woodpecker.env",
'[ "$SKIP_WORKFLOW" = "true" ] && exit 0',
])
return pipeline
def buildWebCache(ctx):
@@ -713,8 +720,7 @@ def testPipelines(ctx):
def getGoBinForTesting(ctx):
pipeline = {
"name": "get-go-bin-cache",
"steps": skipCheckStep(ctx, "base") +
checkGoBinCache() +
"steps": checkGoBinCache() +
cacheGoBin(),
"when": [
event["tag"],
@@ -723,14 +729,15 @@ def getGoBinForTesting(ctx):
"event": ["push", "manual"],
"branch": ["main", "stable-*"],
},
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "unit-tests"),
},
},
],
"workspace": workspace,
}
prefixStepCommands(pipeline, [
". ./.woodpecker.env",
'[ "$SKIP_WORKFLOW" = "true" ] && exit 0',
])
return [pipeline]
def checkGoBinCache():
@@ -803,7 +810,6 @@ def restoreGoBinCache():
]
def testOpencloud(ctx):
#steps = skipCheckStep(ctx, "unit-tests") + evaluateWorkflowStep() + restoreGoBinCache() + makeGoGenerate("") + [
steps = evaluateWorkflowStep() + restoreGoBinCache() + makeGoGenerate("") + [
{
"name": "golangci-lint",
@@ -815,30 +821,7 @@ def testOpencloud(ctx):
],
"environment": CI_HTTP_PROXY_ENV,
},
{
"name": "open-search",
"image": OPEN_SEARCH,
"detach": True,
"environment": {
"discovery.type": "single-node",
"DISABLE_INSTALL_DEMO_CONFIG": True,
"DISABLE_SECURITY_PLUGIN": True,
},
"entrypoint": ["/usr/share/opensearch/opensearch-docker-entrypoint.sh", "opensearch"],
},
{
"name": "wait-for-open-search",
"image": OC_CI_ALPINE,
"commands": [
"bash -c '" +
"until curl -sS \"http://open-search:9200/_cat/health?h=status\" | grep \"green\\|yellow\"; do\n" +
" echo \"Waiting for http://open-search:9200 to be healthy...\"\n" +
" sleep 5\n" +
"done\n" +
"echo \"http://open-search:9200 healthy...\"\n" +
"'",
],
},
] + waitForOpenSearch() + [
{
"name": "test",
"image": OC_CI_GOLANG,
@@ -870,10 +853,16 @@ def testOpencloud(ctx):
pipeline = {
"name": "test-lint-unit",
"steps": steps,
"services": openSearchService(),
"when": [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "unit-tests"),
},
},
],
"depends_on": getPipelineNames(getGoBinForTesting(ctx)),
"workspace": workspace,
@@ -887,7 +876,7 @@ def testOpencloud(ctx):
return [pipeline]
def scanOpencloud(ctx):
steps = skipCheckStep(ctx, "base") + restoreGoBinCache() + makeGoGenerate("") + [
steps = restoreGoBinCache() + makeGoGenerate("") + [
{
"name": "govulncheck",
"image": OC_CI_GOLANG,
@@ -898,22 +887,22 @@ def scanOpencloud(ctx):
},
]
pipeline = {
return {
"name": "go-vulnerability-scanning",
"steps": steps,
"when": [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "acceptance-tests"),
},
},
],
"depends_on": getPipelineNames(getGoBinForTesting(ctx)),
"workspace": workspace,
}
prefixStepCommands(pipeline, [
". ./.woodpecker.env",
'[ "$SKIP_WORKFLOW" = "true" ] && exit 0',
])
return [pipeline]
def buildOpencloudBinaryForTesting(ctx):
pipeline = {
@@ -970,7 +959,12 @@ def checkTestSuitesInExpectedFailures(ctx):
"when": [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "acceptance-tests"),
},
},
],
}]
@@ -990,7 +984,12 @@ def checkGherkinLint(ctx):
"when": [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "lint"),
},
},
],
}]
@@ -1054,7 +1053,12 @@ def codestyle(ctx):
"when": [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "lint"),
},
},
],
}
@@ -1065,8 +1069,7 @@ def codestyle(ctx):
def cs3ApiTests(ctx, storage):
pipeline = {
"name": "test-cs3-API-%s" % storage,
"steps": skipCheckStep(ctx, "acceptance-tests") +
evaluateWorkflowStep() +
"steps": evaluateWorkflowStep() +
restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBinPath"]) +
opencloudServer(storage, deploy_type = "cs3api_validator") +
[
@@ -1085,7 +1088,12 @@ def cs3ApiTests(ctx, storage):
"when": [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "acceptance-tests"),
},
},
],
}
prefixStepCommands(pipeline, [
@@ -1169,8 +1177,7 @@ def wopiValidatorTests(ctx, storage, wopiServerType):
pipeline = {
"name": "test-wopi-validator-%s-%s" % (wopiServerType, storage),
"services": fakeOffice(),
"steps": skipCheckStep(ctx, "acceptance-tests") +
evaluateWorkflowStep() +
"steps": evaluateWorkflowStep() +
restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBinPath"]) +
waitForServices("fake-office", ["fakeoffice:8080"]) +
opencloudServer(storage, deploy_type = "wopi_validator", extra_server_environment = extra_server_environment) +
@@ -1201,7 +1208,12 @@ def wopiValidatorTests(ctx, storage, wopiServerType):
"when": [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "acceptance-tests"),
},
},
],
}
prefixStepCommands(pipeline, [
@@ -1254,14 +1266,31 @@ def build_api_test_workflow_matrix(ctx, storage, suite_cfg, default_cfg):
matrix = {
"withRemotePhp": m["withRemotePhp"],
"enableWatchFs": m["enableWatchFs"],
"openSearch": False,
}
if override_with_remote_php != None:
matrix["withRemotePhp"] = override_with_remote_php
if override_enable_watch_fs != None:
matrix["enableWatchFs"] = override_enable_watch_fs
if matrix not in workflow_metrices and matrix in matrices:
base = {
"withRemotePhp": matrix["withRemotePhp"],
"enableWatchFs": matrix["enableWatchFs"],
}
if matrix not in workflow_metrices and base in matrices:
workflow_metrices.append(matrix)
# Add an OpenSearch search-engine variant for nightly running search tests,
# or on demand when "opensearch" is specified in the PR title
run_open_search = ctx.build.event == "cron" or "opensearch" in ctx.build.title.lower()
if run_open_search and storage == "posix" and suite_cfg.get("nightlyOpenSearch", False):
os_matrix = {
"withRemotePhp": False,
"enableWatchFs": False,
"openSearch": True,
}
if os_matrix not in workflow_metrices:
workflow_metrices.append(os_matrix)
return workflow_metrices
def localApiTestPipeline(ctx):
@@ -1282,6 +1311,7 @@ def localApiTestPipeline(ctx):
"withRemotePhp": False,
"enableWatchFs": False,
"ldapNeeded": False,
"nightlyOpenSearch": False,
}
if "localApiTests" in config:
@@ -1307,6 +1337,7 @@ def localApiTestPipeline(ctx):
for m in matrices:
run_with_remote_php = m["withRemotePhp"]
run_with_watch_fs = m["enableWatchFs"]
run_with_open_search = m["openSearch"]
pipeline_name = "test-API"
if name.startswith("cli"):
@@ -1317,11 +1348,19 @@ def localApiTestPipeline(ctx):
pipeline_name += "-withRemotePhp"
if run_with_watch_fs:
pipeline_name += "-watchfs"
if run_with_open_search:
pipeline_name += "-opensearch"
server_environment = dict(params["extraServerEnvironment"])
if run_with_open_search:
server_environment["SEARCH_ENGINE_TYPE"] = "open-search"
server_environment["SEARCH_ENGINE_OPEN_SEARCH_CLIENT_ADDRESSES"] = "http://open-search:9200"
pipeline = {
"name": pipeline_name,
"steps": skipCheckStep(ctx, "acceptance-tests") + evaluateWorkflowStep() + restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBinPath"]) +
"steps": evaluateWorkflowStep() + restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBinPath"]) +
(tikaService() if params["tikaNeeded"] else []) +
(waitForOpenSearch() if run_with_open_search else []) +
(waitForWebOffices(["https://collabora:9980", "https://onlyoffice", "http://fakeoffice:8080"]) if params["collaborationServiceNeeded"] else []) +
(waitForClamavService() if params["antivirusNeeded"] else []) +
(waitForEmailService() if params["emailNeeded"] else []) +
@@ -1329,7 +1368,7 @@ def localApiTestPipeline(ctx):
(waitForLdapService() if params["ldapNeeded"] else []) +
opencloudServer(
storage,
extra_server_environment = params["extraServerEnvironment"],
extra_server_environment = server_environment,
with_wrapper = True,
tika_enabled = params["tikaNeeded"],
watch_fs_enabled = run_with_watch_fs,
@@ -1341,12 +1380,18 @@ def localApiTestPipeline(ctx):
logRequests(),
"services": (emailService() if params["emailNeeded"] else []) +
(clamavService() if params["antivirusNeeded"] else []) +
(openSearchService() if run_with_open_search else []) +
((fakeOffice() + collaboraService() + onlyofficeService()) if params["collaborationServiceNeeded"] else []),
"depends_on": getPipelineNames(buildOpencloudBinaryForTesting(ctx)),
"when": [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "acceptance-tests"),
},
},
],
}
prefixStepCommands(pipeline, [
@@ -1441,8 +1486,7 @@ def coreApiTestPipeline(ctx):
pipeline = {
"name": pipeline_name,
"steps": skipCheckStep(ctx, "acceptance-tests") +
evaluateWorkflowStep() +
"steps": evaluateWorkflowStep() +
restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBinPath"]) +
opencloudServer(
storage,
@@ -1461,7 +1505,12 @@ def coreApiTestPipeline(ctx):
"when": [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "acceptance-tests"),
},
},
],
}
prefixStepCommands(pipeline, [
@@ -1520,7 +1569,12 @@ def e2eTestPipeline(ctx):
e2e_trigger = [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "e2e-tests"),
},
},
{
"event": "tag",
"ref": "refs/tags/**",
@@ -1546,15 +1600,16 @@ def e2eTestPipeline(ctx):
if "[decomposed]" in ctx.build.title.lower():
params["storages"] = ["decomposed"]
e2e_args = "--suites %s" % ",".join(params["suites"]) if params["suites"] else ""
e2e_args = " ".join(params["suites"]) if params["suites"] else ""
if "with-tracing" in ctx.build.title.lower():
params["reportTracing"] = True
for storage in params["storages"]:
for watch_fs_enabled in params["enableWatchFs"]:
pipeline_name = "test-e2e-%s-%s%s" % (name, storage, "-watchfs" if watch_fs_enabled else "")
steps = \
skipCheckStep(ctx, "e2e-tests") + \
evaluateWorkflowStep() + \
restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBin"]) + \
restoreWebCache() + \
@@ -1572,24 +1627,23 @@ def e2eTestPipeline(ctx):
"image": OC_CI_NODEJS,
"environment": {
"OC_BASE_URL": OC_DOMAIN,
"HEADLESS": True,
"RETRY": "1",
"WEB_UI_CONFIG_FILE": "%s/%s" % (dirs["base"], dirs["opencloudConfig"]),
"LOCAL_UPLOAD_DIR": "/uploads",
"PLAYWRIGHT_BROWSERS_PATH": "%s/%s" % (dirs["base"], ".playwright"),
"BROWSER": "chromium",
"REPORT_TRACING": params["reportTracing"],
"SLOW_MO": "300",
},
"commands": [
"cd %s/tests/e2e" % dirs["web"],
"bash run-e2e.sh %s" % e2e_args,
"pnpm playwright install chromium",
"pnpm bddgen",
"pnpm playwright test %s --project=chromium" % e2e_args,
],
}] + \
uploadTracingResult(ctx)
uploadTestArtifacts(pipeline_name)
pipeline = {
"name": "test-e2e-%s-%s%s" % (name, storage, "-watchfs" if watch_fs_enabled else ""),
"name": pipeline_name,
"steps": steps,
"depends_on": getPipelineNames(buildOpencloudBinaryForTesting(ctx) + buildWebCache(ctx)),
"when": e2e_trigger,
@@ -1608,7 +1662,6 @@ def multiServiceE2ePipeline(ctx):
defaults = {
"skip": False,
"suites": [],
"xsuites": [],
"tikaNeeded": False,
"reportTracing": False,
"enableWatchFs": [False],
@@ -1618,7 +1671,12 @@ def multiServiceE2ePipeline(ctx):
e2e_trigger = [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "e2e-tests"),
},
},
]
if "skip-e2e" in ctx.build.title.lower():
@@ -1692,13 +1750,7 @@ def multiServiceE2ePipeline(ctx):
if "[decomposed]" in ctx.build.title.lower():
params["storages"] = ["decomposed"]
e2e_args = ""
if params["suites"]:
e2e_args = "--suites %s" % ",".join(params["suites"])
# suites to skip
if params["xsuites"]:
e2e_args += " --xsuites %s" % ",".join(params["xsuites"])
e2e_args = " ".join(params["suites"]) if params["suites"] else ""
if "with-tracing" in ctx.build.title.lower():
params["reportTracing"] = True
@@ -1708,8 +1760,9 @@ def multiServiceE2ePipeline(ctx):
if watch_fs_enabled:
extra_server_environment["STORAGE_USERS_POSIX_WATCH_FS"] = True
pipeline_name = "test-e2e-multi-service%s" % ("-watchfs" if watch_fs_enabled else "")
steps = \
skipCheckStep(ctx, "e2e-tests") + \
evaluateWorkflowStep() + \
restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBin"]) + \
restoreWebCache() + \
@@ -1723,21 +1776,20 @@ def multiServiceE2ePipeline(ctx):
"image": OC_CI_NODEJS,
"environment": {
"OC_BASE_URL": OC_DOMAIN,
"HEADLESS": True,
"RETRY": "1",
"REPORT_TRACING": params["reportTracing"],
"PLAYWRIGHT_BROWSERS_PATH": "%s/%s" % (dirs["base"], ".playwright"),
"BROWSER": "chromium",
},
"commands": [
"cd %s/tests/e2e" % dirs["web"],
"bash run-e2e.sh %s" % e2e_args,
"pnpm playwright install chromium",
"pnpm bddgen",
"pnpm playwright test %s --project=chromium" % e2e_args,
],
}] + \
uploadTracingResult(ctx)
uploadTestArtifacts(pipeline_name)
pipeline = {
"name": "test-e2e-multi-service%s" % ("-watchfs" if watch_fs_enabled else ""),
"name": pipeline_name,
"steps": steps,
"depends_on": getPipelineNames(buildOpencloudBinaryForTesting(ctx) + buildWebCache(ctx)),
"when": e2e_trigger,
@@ -1749,24 +1801,20 @@ def multiServiceE2ePipeline(ctx):
pipelines.append(pipeline)
return pipelines
def uploadTracingResult(ctx):
status = ["failure"]
if "with-tracing" in ctx.build.title.lower():
status = ["failure", "success"]
def uploadTestArtifacts(pipeline_name):
return [{
"name": "upload-tracing-result",
"name": "upload-test-artifacts",
"image": MINIO_MC,
"environment": MINIO_MC_ENV,
"commands": [
"microdnf install -y zip",
"mc alias set s3 $MC_HOST $AWS_ACCESS_KEY_ID $AWS_SECRET_ACCESS_KEY",
"mc cp -a %s/reports/e2e/playwright/tracing/* s3/$PUBLIC_BUCKET/web/tracing/$CI_REPO_NAME/$CI_PIPELINE_NUMBER/" % dirs["web"],
"cd %s/reports/e2e/playwright/tracing/" % dirs["web"],
'echo "To see the trace, please open the following link in the console"',
'for f in *.zip; do echo "npx playwright show-trace $MC_HOST/$PUBLIC_BUCKET/web/tracing/$CI_REPO_NAME/$CI_PIPELINE_NUMBER/$f \n"; done',
"cd %s/tests/e2e/playwright-report && zip -r /tmp/playwright-report.zip ." % dirs["web"],
"mc cp /tmp/playwright-report.zip s3/$PUBLIC_BUCKET/web/artifacts/$CI_REPO_NAME/$CI_PIPELINE_NUMBER/%s/playwright-report.zip" % pipeline_name,
'printf "=== HTML Report ===\ncurl -O $MC_HOST/$PUBLIC_BUCKET/web/artifacts/$CI_REPO_NAME/$CI_PIPELINE_NUMBER/%s/playwright-report.zip && npx playwright show-report playwright-report.zip\n"' % pipeline_name,
],
"when": {
"status": status,
"status": ["failure", "success"],
},
}]
@@ -1868,6 +1916,9 @@ def dockerRelease(ctx, repo, build_type):
"EDITION": "stable" if build_type == "production" else "rolling",
}
if ctx.build.event != "tag":
build_args["STRING"] = ctx.build.commit[:8]
# if no additional tag is given, the build-plugin adds latest
hard_tag = "daily"
if ctx.build.event == "tag":
@@ -2305,11 +2356,56 @@ def genDocsPr(ctx):
],
}]
def serverTestingDocs(ctx):
return [{
"name": "server-testing-docs",
"steps": [
{
"name": "build",
"image": OC_CI_NODEJS,
"commands": [
"node tests/scripts/generate-docs.mjs",
# add dummy woodpecker config to disable CI on push to the docs branch
"printf 'def main(ctx):\n return [{\n \"name\":\"dummy-pipeline\",\n" +
" \"steps\":[{\"name\":\"dummy-step\",\"image\":\"alpine:latest\"}],\n" +
" \"when\":[{\"branch\":[\"main\"]}],\n }]\n' > tests/.docs-dist/.woodpecker.star",
],
},
{
"name": "publish",
"image": "plugins/gh-pages:1",
"settings": {
"username": {
"from_secret": "github_username",
},
"password": {
"from_secret": "github_token",
},
"pages_directory": "tests/.docs-dist/",
"copy_contents": True,
"target_branch": "server-testing-docs",
"delete": True,
},
"when": [
{
"event": ["push"],
"branch": "${CI_REPO_DEFAULT_BRANCH}",
},
],
},
],
"when": [
{
"event": ["push", "pull_request"],
"path": "tests/README.md",
},
],
}]
def notifyMatrixCheckSteps(ctx, depends_on):
result = [{
"name": "all-checks-finished",
"skip_clone": True,
"runs_on": ["success", "failure"],
"depends_on": depends_on,
"steps": [
{
@@ -2348,9 +2444,9 @@ def notifyMatrixCheckSteps(ctx, depends_on):
},
],
"when": [
event["cron"],
event["base"],
event["pull_request"],
dict(event["cron"], status = ["success", "failure"]),
dict(event["base"], status = ["success", "failure"]),
dict(event["pull_request"], status = ["success", "failure"]),
],
}]
@@ -2573,14 +2669,18 @@ def skipIfUnchanged(ctx, type):
return []
base = [
".agents/**",
".claude/**",
".github/**",
".vscode/**",
"docs/**",
"deployments/**",
".codacy.yml",
"CHANGELOG.md",
"CONTRIBUTING.md",
"LICENSE",
"README.md",
"release-config.ts",
]
unit = [
"**/*_test.go",
@@ -2680,7 +2780,12 @@ def checkStarlark(ctx):
"when": [
event["cron"],
event["base"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "base"),
},
},
],
}]
@@ -2720,11 +2825,10 @@ def purgeCache(name, flush_path, flush_age):
"name": name,
"skip_clone": True,
"when": [
event["cron"],
event["base"],
event["pull_request"],
dict(event["cron"], status = ["success", "failure"]),
dict(event["base"], status = ["success", "failure"]),
dict(event["pull_request"], status = ["success", "failure"]),
],
"runs_on": ["success", "failure"],
"steps": [
{
"name": "purge",
@@ -2807,8 +2911,9 @@ def pipelineSanityChecks(pipelines):
for pipeline in pipelines:
if "depends_on" in pipeline.keys():
for depends in pipeline["depends_on"]:
if not depends in possible_depends:
print("Error: depends_on %s for pipeline %s is not defined" % (depends, pipeline["name"]))
depends_name = depends["name"] if type(depends) == "dict" else depends
if not depends_name in possible_depends:
print("Error: depends_on %s for pipeline %s is not defined" % (depends_name, pipeline["name"]))
# check for non declared volumes
# for pipeline in pipelines:
@@ -2854,8 +2959,7 @@ def litmus(ctx, storage):
pipeline = {
"name": "test-litmus",
"steps": skipCheckStep(ctx, "litmus") +
evaluateWorkflowStep() +
"steps": evaluateWorkflowStep() +
restoreBuildArtifactCache(ctx, dirs["opencloudBinArtifact"], dirs["opencloudBinPath"]) +
opencloudServer(storage) +
setupForLitmus() +
@@ -2930,7 +3034,12 @@ def litmus(ctx, storage):
"when": [
event["cron"],
event["base"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "litmus"),
},
},
],
}
@@ -3034,7 +3143,12 @@ def cacheBrowsers(ctx):
e2e_trigger = [
event["base"],
event["cron"],
event["pull_request"],
{
"event": "pull_request",
"path": {
"exclude": skipIfUnchanged(ctx, "e2e-tests"),
},
},
{
"event": "tag",
"ref": "refs/tags/**",
@@ -3332,6 +3446,33 @@ def tikaService():
],
}]
def openSearchService():
return [{
"name": "open-search",
"image": OPEN_SEARCH,
"environment": {
"discovery.type": "single-node",
"DISABLE_INSTALL_DEMO_CONFIG": True,
"DISABLE_SECURITY_PLUGIN": True,
},
"entrypoint": ["/usr/share/opensearch/opensearch-docker-entrypoint.sh", "opensearch"],
}]
def waitForOpenSearch():
return [{
"name": "wait-for-open-search",
"image": OC_CI_ALPINE,
"commands": [
"bash -c '" +
"until curl -sS \"http://open-search:9200/_cat/health?h=status\" | grep \"green\\|yellow\"; do\n" +
" echo \"Waiting for http://open-search:9200 to be healthy...\"\n" +
" sleep 5\n" +
"done\n" +
"echo \"http://open-search:9200 healthy...\"\n" +
"'",
],
}]
def logRequests():
return [{
"name": "api-test-failure-logs",
@@ -3431,16 +3572,3 @@ def waitForWebOffices(services = []):
"commands": commands,
},
]
def skipCheckStep(ctx, type):
if ("full-ci" in ctx.build.title.lower() or ctx.build.event == "tag" or ctx.build.event == "cron"):
return []
return [{
"name": "skip-check",
"image": OC_CI_NODEJS_ALPINE,
"commands": [
"npm install minimatch",
"node tests/config/woodpecker/skip_if_unchanged.js %s" % type,
],
}]
+127
View File
@@ -1,5 +1,132 @@
# Changelog
## [7.4.0](https://github.com/opencloud-eu/opencloud/releases/tag/v7.4.0) - 2026-08-03
### ❤️ Thanks to all contributors! ❤️
@AlexAndBear, @JammingBen, @aduffeck, @dschmidt, @fschade, @michaelstingl, @pbleser-oc, @rhafer, @schweigisito, @v-scharf
### 📈 Enhancement
- Do not check ignored paths [[#3233](https://github.com/opencloud-eu/opencloud/pull/3233)]
- Extend posixfs consistency check [[#3220](https://github.com/opencloud-eu/opencloud/pull/3220)]
- Improve reindex command [[#3213](https://github.com/opencloud-eu/opencloud/pull/3213)]
- Reindex spaces concurrently [[#3207](https://github.com/opencloud-eu/opencloud/pull/3207)]
- feat: add announcement banner [[#3189](https://github.com/opencloud-eu/opencloud/pull/3189)]
- feat: add space viewer with versions role [[#2961](https://github.com/opencloud-eu/opencloud/pull/2961)]
### 🐛 Bug Fixes
- fix(runtime): log service startup errors instead of printing them beside the log [[#3140](https://github.com/opencloud-eu/opencloud/pull/3140)]
- fix(posixfs scan): Setup logger for scan command [[#3185](https://github.com/opencloud-eu/opencloud/pull/3185)]
### ✅ Tests
- api-test: mark group last-manager removal scenario as flaky [[#3194](https://github.com/opencloud-eu/opencloud/pull/3194)]
- rerun flaky tests [[#3183](https://github.com/opencloud-eu/opencloud/pull/3183)]
- api-test: fix removeAccessToDrive.feature:145 [[#3179](https://github.com/opencloud-eu/opencloud/pull/3179)]
- api-test: cover additional unified roles in acceptance tests [[#3169](https://github.com/opencloud-eu/opencloud/pull/3169)]
- test(apiAuthApp): fix flaky token pattern [[#3163](https://github.com/opencloud-eu/opencloud/pull/3163)]
- test(apiArchiver): the single-resource archive is named after the resource [[#3080](https://github.com/opencloud-eu/opencloud/pull/3080)]
- test(coreApiWebdavUploadTUS): assert etag and permissions on the finalizing TUS chunk [[#3078](https://github.com/opencloud-eu/opencloud/pull/3078)]
- test(coreApiWebdavOperations): download a file with a literal "%" via its oc:downloadURL [[#3079](https://github.com/opencloud-eu/opencloud/pull/3079)]
### 📚 Documentation
- maint: clean-up auth-app documentation [[#3155](https://github.com/opencloud-eu/opencloud/pull/3155)]
- ci: sync tests/README.md to docs [[#3164](https://github.com/opencloud-eu/opencloud/pull/3164)]
### 📦️ Dependencies
- [full-ci] chore: bump web to v7.3.0 [[#3223](https://github.com/opencloud-eu/opencloud/pull/3223)]
- build(deps): bump github.com/open-policy-agent/opa from 1.18.2 to 1.19.0 [[#3231](https://github.com/opencloud-eu/opencloud/pull/3231)]
- build(deps): bump google.golang.org/grpc from 1.82.0 to 1.83.0 [[#3232](https://github.com/opencloud-eu/opencloud/pull/3232)]
- chore(idp): bump dependencies [[#3226](https://github.com/opencloud-eu/opencloud/pull/3226)]
- build(deps): bump github.com/nats-io/nats-server/v2 from 2.14.3 to 2.14.4 [[#3221](https://github.com/opencloud-eu/opencloud/pull/3221)]
- build(deps): bump github.com/go-ldap/ldap/v3 from 3.4.13 to 3.4.14 [[#3222](https://github.com/opencloud-eu/opencloud/pull/3222)]
- build(deps): bump github.com/prometheus/client_golang from 1.23.2 to 1.24.1 [[#3218](https://github.com/opencloud-eu/opencloud/pull/3218)]
- build(deps): bump github.com/gabriel-vasile/mimetype from 1.4.13 to 1.4.15 [[#3217](https://github.com/opencloud-eu/opencloud/pull/3217)]
- build(deps): bump golang.org/x/net from 0.56.0 to 0.57.0 [[#3136](https://github.com/opencloud-eu/opencloud/pull/3136)]
- build(deps): bump github.com/beevik/etree from 1.6.0 to 1.7.0 [[#3134](https://github.com/opencloud-eu/opencloud/pull/3134)]
## [7.3.0](https://github.com/opencloud-eu/opencloud/releases/tag/v7.3.0) - 2026-07-14
### 🐛 Bug Fixes
- fix(proxy): honor access token cache ttl [[#3056](https://github.com/opencloud-eu/opencloud/pull/3056)]
- chore(idp): update axios [[#3094](https://github.com/opencloud-eu/opencloud/pull/3094)]
- fix: make the collaboration service events optional [[#3001](https://github.com/opencloud-eu/opencloud/pull/3001)]
- Revert "fix: disallow thumbnails for tiff and jpeg2000 images" [[#2973](https://github.com/opencloud-eu/opencloud/pull/2973)]
- bump reva [[#2950](https://github.com/opencloud-eu/opencloud/pull/2950)]
- change error level for trashing items interaction with search [[#2951](https://github.com/opencloud-eu/opencloud/pull/2951)]
- fix: Send SSE events for SpaceEnabled/Disabled to affected users [[#2871](https://github.com/opencloud-eu/opencloud/pull/2871)]
### 📚 Documentation
- update collaboration readme [[#3076](https://github.com/opencloud-eu/opencloud/pull/3076)]
- fix: fix typo in proxy service documentation [[#3089](https://github.com/opencloud-eu/opencloud/pull/3089)]
- roling release template [[#2972](https://github.com/opencloud-eu/opencloud/pull/2972)]
- enhance: fix typos in webfinger service description [[#2958](https://github.com/opencloud-eu/opencloud/pull/2958)]
### ✅ Tests
- [full-ci] gherkin steps refactoring. cleaning code [[#3100](https://github.com/opencloud-eu/opencloud/pull/3100)]
- [decomposed] more cli command tests [[#3087](https://github.com/opencloud-eu/opencloud/pull/3087)]
- test(apiSpaces): a space admin can delete a space with no manager [[#3040](https://github.com/opencloud-eu/opencloud/pull/3040)]
- Update tests for opencloud-eu/reva#655 [[#2889](https://github.com/opencloud-eu/opencloud/pull/2889)]
- api-test: deleting space [[#2970](https://github.com/opencloud-eu/opencloud/pull/2970)]
### 📈 Enhancement
- feat: add disableSponsorLink web config option [[#3093](https://github.com/opencloud-eu/opencloud/pull/3093)]
- feat(graph): add MS Graph colon-syntax path lookup middleware [[#2688](https://github.com/opencloud-eu/opencloud/pull/2688)]
- feat: adjust theme chrome colors and logos [[#2599](https://github.com/opencloud-eu/opencloud/pull/2599)]
- add tls support for all nats connections [[#2063](https://github.com/opencloud-eu/opencloud/pull/2063)]
- feat: add more roles [[#2928](https://github.com/opencloud-eu/opencloud/pull/2928)]
- next to main [[#2924](https://github.com/opencloud-eu/opencloud/pull/2924)]
- feat: add core apps env variable to override the default core apps [[#2930](https://github.com/opencloud-eu/opencloud/pull/2930)]
### 📦️ Dependencies
- build(deps): bump golang.org/x/image from 0.43.0 to 0.44.0 [[#3112](https://github.com/opencloud-eu/opencloud/pull/3112)]
- build(deps): bump golang.org/x/text from 0.39.0 to 0.40.0 [[#3101](https://github.com/opencloud-eu/opencloud/pull/3101)]
- [full-ci] chore: bump web to v7.2.0 [[#3121](https://github.com/opencloud-eu/opencloud/pull/3121)]
- build(deps): bump golang.org/x/term from 0.44.0 to 0.45.0 [[#3103](https://github.com/opencloud-eu/opencloud/pull/3103)]
- build(deps): bump github.com/coreos/go-oidc/v3 from 3.19.0 to 3.20.0 [[#3102](https://github.com/opencloud-eu/opencloud/pull/3102)]
- build(deps): bump golang.org/x/text from 0.38.0 to 0.39.0 [[#3085](https://github.com/opencloud-eu/opencloud/pull/3085)]
- build(deps): bump github.com/go-chi/chi/v5 from 5.3.0 to 5.3.1 [[#3073](https://github.com/opencloud-eu/opencloud/pull/3073)]
- build(deps): bump github.com/nats-io/nats-server/v2 from 2.14.2 to 2.14.3 [[#3063](https://github.com/opencloud-eu/opencloud/pull/3063)]
- build(deps): bump github.com/gookit/config/v2 from 2.2.8 to 2.2.9 [[#3075](https://github.com/opencloud-eu/opencloud/pull/3075)]
- build(deps): bump github.com/open-policy-agent/opa from 1.18.1 to 1.18.2 [[#3061](https://github.com/opencloud-eu/opencloud/pull/3061)]
- build(deps): bump github.com/kovidgoyal/imaging from 1.8.21 to 1.8.22 [[#3060](https://github.com/opencloud-eu/opencloud/pull/3060)]
- build(deps): bump github.com/libregraph/lico from 0.66.0 to 0.67.0 [[#3028](https://github.com/opencloud-eu/opencloud/pull/3028)]
- chore: bump web to v7.2.0-beta.3 [[#2953](https://github.com/opencloud-eu/opencloud/pull/2953)]
- chore: bump reva to latest main [[#2943](https://github.com/opencloud-eu/opencloud/pull/2943)]
## [7.2.0](https://github.com/opencloud-eu/opencloud/releases/tag/v7.2.0) - 2026-06-24
### ❤️ Thanks to all contributors! ❤️
@Heiko-Pohl, @JammingBen, @ScharfViktor, @aduffeck, @butonic, @dragonchaser, @kulmann, @rhafer
### 🐛 Bug Fixes
- [stable-7.2] Backport fixes from main [[#2999](https://github.com/opencloud-eu/opencloud/pull/2999)]
- fix(idp): aarch64 build [[#2906](https://github.com/opencloud-eu/opencloud/pull/2906)]
- use ldap instead of ldaps internally [[#2880](https://github.com/opencloud-eu/opencloud/pull/2880)]
### 📚 Documentation
- Rename role_name from "guest" to "user-light" [[#2912](https://github.com/opencloud-eu/opencloud/pull/2912)]
### 📦️ Dependencies
- [full-ci] chore: bump web to v7.1.2 [[#3012](https://github.com/opencloud-eu/opencloud/pull/3012)]
- [full-ci] chore: bump web to v7.1.1 [[#2998](https://github.com/opencloud-eu/opencloud/pull/2998)]
- bump reva to latest main [[#2922](https://github.com/opencloud-eu/opencloud/pull/2922)]
- build(deps-dev): bump webpack-manifest-plugin from 5.0.0 to 6.0.1 in /services/idp [[#2884](https://github.com/opencloud-eu/opencloud/pull/2884)]
- build(deps): bump axios from 1.16.0 to 1.16.1 in /services/idp [[#2883](https://github.com/opencloud-eu/opencloud/pull/2883)]
## [7.1.0](https://github.com/opencloud-eu/opencloud/releases/tag/v7.1.0) - 2026-06-02
### ❤️ Thanks to all contributors! ❤️
+5 -7
View File
@@ -107,6 +107,7 @@ help:
@echo -e "${GREEN}Tools for linting gherkin feature files:\n${RESET}"
@echo -e "\tmake test-gherkin-lint\t\t${BLUE}run lint checks on Gherkin feature files${RESET}"
@echo -e "\tmake test-gherkin-lint-fix\t${BLUE}apply lint fixes to gherkin feature files${RESET}"
@echo -e "\tmake find-unused-steps\t\t${BLUE}list Behat step definitions unused by any .feature file${RESET}"
@echo
.PHONY: clean-tests
@@ -228,6 +229,10 @@ test-gherkin-lint:
test-gherkin-lint-fix:
gherlint --fix tests/acceptance/features -c tests/acceptance/config/.gherlintrc.json
.PHONY: find-unused-steps
find-unused-steps: vendor-bin/behat/vendor
tests/acceptance/scripts/find-unused-steps.sh
.PHONY: bingo-update
bingo-update: $(BINGO)
$(BINGO) get -l -v -t 20
@@ -341,10 +346,3 @@ vendor-bin/php_codesniffer/vendor: vendor/bamarni/composer-bin-plugin vendor-bin
vendor-bin/php_codesniffer/composer.lock: vendor-bin/php_codesniffer/composer.json
@echo php_codesniffer composer.lock is not up to date.
.PHONY: generate-qa-activity-report
generate-qa-activity-report: node_modules
@if [ -z "${MONTH}" ] || [ -z "${YEAR}" ]; then \
echo "Please set the MONTH and YEAR environment variables. Usage: make generate-qa-activity-report MONTH=<month> YEAR=<year>"; \
exit 1; \
fi
go run tests/qa-activity-report/generate-qa-activity-report.go --month ${MONTH} --year ${YEAR}
@@ -45,3 +45,4 @@ directives:
style-src:
- '''self'''
- '''unsafe-inline'''
- 'blob:'
@@ -42,3 +42,4 @@ directives:
style-src:
- '''self'''
- '''unsafe-inline'''
- 'blob:'
+74 -75
View File
@@ -10,20 +10,20 @@ require (
github.com/MicahParks/keyfunc/v2 v2.1.0
github.com/Nerzal/gocloak/v13 v13.9.0
github.com/bbalet/stopwords v1.0.0
github.com/beevik/etree v1.6.0
github.com/beevik/etree v1.7.0
github.com/blevesearch/bleve/v2 v2.6.0
github.com/cenkalti/backoff v2.2.1+incompatible
github.com/coreos/go-oidc/v3 v3.19.0
github.com/coreos/go-oidc/v3 v3.20.0
github.com/cs3org/go-cs3apis v0.0.0-20260424072047-8d9ef7076ae9
github.com/davidbyttow/govips/v2 v2.18.0
github.com/dhowden/tag v0.0.0-20240417053706-3d75831295e8
github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e
github.com/gabriel-vasile/mimetype v1.4.13
github.com/gabriel-vasile/mimetype v1.4.15
github.com/ggwhite/go-masker v1.1.0
github.com/go-chi/chi/v5 v5.3.1
github.com/go-chi/render v1.0.3
github.com/go-jose/go-jose/v3 v3.0.5
github.com/go-ldap/ldap/v3 v3.4.13
github.com/go-ldap/ldap/v3 v3.4.14
github.com/go-ldap/ldif v0.0.0-20200320164324-fd88d9b715b3
github.com/go-micro/plugins/v4/client/grpc v1.2.1
github.com/go-micro/plugins/v4/logger/zerolog v1.2.0
@@ -49,32 +49,33 @@ require (
github.com/jellydator/ttlcache/v3 v3.4.1
github.com/jinzhu/now v1.1.5
github.com/justinas/alice v1.2.0
github.com/kovidgoyal/imaging v1.8.22
github.com/kovidgoyal/imaging v1.8.23
github.com/leonelquinteros/gotext v1.7.3-0.20260422134830-b012b4ccae69
github.com/libregraph/idm v0.5.0
github.com/libregraph/lico v0.67.0
github.com/mna/pigeon v1.3.0
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
github.com/nats-io/nats-server/v2 v2.14.3
github.com/nats-io/nats-server/v2 v2.14.4
github.com/nats-io/nats.go v1.52.0
github.com/olekukonko/tablewriter v1.1.4
github.com/onsi/ginkgo v1.16.5
github.com/onsi/ginkgo/v2 v2.32.0
github.com/onsi/gomega v1.42.1
github.com/open-policy-agent/opa v1.18.2
github.com/open-policy-agent/opa v1.19.0
github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d
github.com/opencloud-eu/reva/v2 v2.46.4-0.20260625152426-8cff2a7032ec
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260818063016-69f82a7dde55
github.com/opencloud-eu/reva/v2 v2.48.1-0.20260811071808-9bf68d2ccd96
github.com/opensearch-project/opensearch-go/v4 v4.6.0
github.com/orcaman/concurrent-map v1.0.0
github.com/pkg/errors v0.9.1
github.com/pkg/xattr v0.4.12
github.com/prometheus/client_golang v1.23.2
github.com/prometheus/client_golang v1.24.1
github.com/r3labs/sse/v2 v2.10.0
github.com/riandyrn/otelchi v0.12.3
github.com/rogpeppe/go-internal v1.15.0
github.com/rogpeppe/go-internal v1.16.0
github.com/rs/cors v1.11.1
github.com/rs/zerolog v1.35.1
github.com/shamaton/msgpack/v2 v2.4.1
github.com/sirupsen/logrus v1.9.4
github.com/spf13/afero v1.15.0
github.com/spf13/cobra v1.10.2
@@ -82,9 +83,8 @@ require (
github.com/spf13/viper v1.21.0
github.com/stretchr/testify v1.11.1
github.com/test-go/testify v1.1.4
github.com/testcontainers/testcontainers-go v0.43.0
github.com/testcontainers/testcontainers-go/modules/opensearch v0.43.0
github.com/theckman/yacspin v0.13.12
github.com/testcontainers/testcontainers-go v0.44.0
github.com/testcontainers/testcontainers-go/modules/opensearch v0.44.0
github.com/thejerf/suture/v4 v4.0.6
github.com/tidwall/gjson v1.19.0
github.com/tidwall/sjson v1.2.5
@@ -95,23 +95,23 @@ require (
go-micro.dev/v4 v4.11.0
go.etcd.io/bbolt v1.5.0
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.69.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.70.0
go.opentelemetry.io/contrib/zpages v0.69.0
go.opentelemetry.io/otel v1.44.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.44.0
go.opentelemetry.io/otel/sdk v1.44.0
go.opentelemetry.io/otel/trace v1.44.0
golang.org/x/crypto v0.53.0
go.opentelemetry.io/otel v1.45.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.45.0
go.opentelemetry.io/otel/sdk v1.45.0
go.opentelemetry.io/otel/trace v1.45.0
golang.org/x/crypto v0.54.0
golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f
golang.org/x/image v0.43.0
golang.org/x/net v0.56.0
golang.org/x/image v0.44.0
golang.org/x/net v0.57.0
golang.org/x/oauth2 v0.36.0
golang.org/x/sync v0.21.0
golang.org/x/term v0.44.0
golang.org/x/text v0.39.0
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa
google.golang.org/grpc v1.82.0
golang.org/x/sync v0.22.0
golang.org/x/term v0.45.0
golang.org/x/text v0.40.0
google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d
google.golang.org/grpc v1.83.0
google.golang.org/protobuf v1.36.11
gopkg.in/yaml.v2 v2.4.0
gopkg.in/yaml.v3 v3.0.1
@@ -126,7 +126,7 @@ require (
github.com/Azure/go-ntlmssp v0.1.1 // indirect
github.com/BurntSushi/toml v1.6.0 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
github.com/Masterminds/semver/v3 v3.4.0 // indirect
github.com/Masterminds/semver/v3 v3.5.0 // indirect
github.com/Masterminds/sprig v2.22.0+incompatible // indirect
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/ProtonMail/go-crypto v1.1.6 // indirect
@@ -135,7 +135,7 @@ require (
github.com/ajg/form v1.5.1 // indirect
github.com/alexedwards/argon2id v1.0.0 // indirect
github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964 // indirect
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op // indirect
github.com/antithesishq/antithesis-sdk-go v0.7.2 // indirect
github.com/armon/go-radix v1.0.0 // indirect
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
github.com/beorn7/perks v1.0.1 // indirect
@@ -166,8 +166,8 @@ require (
github.com/ceph/go-ceph v0.40.0 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/cevaris/ordered_map v0.0.0-20190319150403-3adeae072e73 // indirect
github.com/clipperhouse/displaywidth v0.10.0 // indirect
github.com/clipperhouse/uax29/v2 v2.6.0 // indirect
github.com/clipperhouse/displaywidth v0.11.0 // indirect
github.com/clipperhouse/uax29/v2 v2.7.0 // indirect
github.com/cloudflare/circl v1.6.3 // indirect
github.com/containerd/errdefs v1.0.0 // indirect
github.com/containerd/errdefs/pkg v0.3.0 // indirect
@@ -189,34 +189,33 @@ require (
github.com/dgryski/go-farm v0.0.0-20240924180020-3414d57e47da // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/dlclark/regexp2 v1.4.0 // indirect
github.com/docker/go-connections v0.6.0 // indirect
github.com/dlclark/regexp2 v1.12.0 // indirect
github.com/docker/go-connections v0.7.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/ebitengine/purego v0.10.0 // indirect
github.com/ebitengine/purego v0.10.1 // indirect
github.com/egirna/icap v0.0.0-20181108071049-d5ee18bd70bc // indirect
github.com/emirpasic/gods v1.18.1 // indirect
github.com/emvi/iso-639-1 v1.1.1 // indirect
github.com/evanphx/json-patch/v5 v5.5.0 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fatih/color v1.19.0 // indirect
github.com/felixge/httpsnoop v1.1.0 // indirect
github.com/fsnotify/fsnotify v1.10.1 // indirect
github.com/gdexlab/go-render v1.0.1 // indirect
github.com/go-acme/lego/v4 v4.4.0 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.8 // indirect
github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
github.com/go-git/go-billy/v5 v5.9.0 // indirect
github.com/go-git/go-git/v5 v5.19.1 // indirect
github.com/go-ini/ini v1.67.0 // indirect
github.com/go-git/go-git/v5 v5.19.2 // indirect
github.com/go-jose/go-jose/v4 v4.1.4 // indirect
github.com/go-kit/log v0.2.1 // indirect
github.com/go-logfmt/logfmt v0.5.1 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/logr v1.4.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-micro/plugins/v4/events/natsjs v1.2.2 // indirect
github.com/go-micro/plugins/v4/store/nats-js v1.2.1 // indirect
github.com/go-micro/plugins/v4/store/redis v1.2.1 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-redis/redis/v8 v8.11.5 // indirect
@@ -256,7 +255,7 @@ require (
github.com/json-iterator/go v1.1.12 // indirect
github.com/juliangruber/go-intersect v1.1.0 // indirect
github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/klauspost/compress v1.18.6 // indirect
github.com/klauspost/compress v1.19.1 // indirect
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
github.com/klauspost/crc32 v1.3.0 // indirect
github.com/kovidgoyal/go-parallel v1.1.1 // indirect
@@ -272,13 +271,13 @@ require (
github.com/libregraph/oidc-go v1.1.0 // indirect
github.com/longsleep/go-metrics v1.0.0 // indirect
github.com/longsleep/rndm v1.2.0 // indirect
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 // indirect
github.com/lufia/plan9stats v0.0.0-20260330125221-c963978e514e // indirect
github.com/magiconair/properties v1.8.10 // indirect
github.com/mattermost/xml-roundtrip-validator v0.1.0 // indirect
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.19 // indirect
github.com/mattn/go-sqlite3 v1.14.42 // indirect
github.com/mattn/go-colorable v0.1.15 // indirect
github.com/mattn/go-isatty v0.0.22 // indirect
github.com/mattn/go-runewidth v0.0.24 // indirect
github.com/mattn/go-sqlite3 v1.14.49 // 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.68 // indirect
@@ -286,15 +285,15 @@ require (
github.com/minio/crc64nvme v1.1.1 // indirect
github.com/minio/highwayhash v1.0.4 // indirect
github.com/minio/md5-simd v1.1.2 // indirect
github.com/minio/minio-go/v7 v7.1.0 // indirect
github.com/minio/minio-go/v7 v7.2.1 // indirect
github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/go-archive v0.2.0 // indirect
github.com/moby/moby/api v1.54.2 // indirect
github.com/moby/moby/client v0.4.0 // indirect
github.com/moby/moby/api v1.55.0 // indirect
github.com/moby/moby/client v0.5.0 // indirect
github.com/moby/patternmatcher v0.6.1 // indirect
github.com/moby/sys/sequential v0.6.0 // indirect
github.com/moby/sys/sequential v0.7.0 // indirect
github.com/moby/sys/user v0.4.0 // indirect
github.com/moby/sys/userns v0.1.0 // indirect
github.com/moby/term v0.5.2 // indirect
@@ -317,17 +316,17 @@ require (
github.com/pablodz/inotifywaitgo v0.0.12 // indirect
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 // indirect
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
github.com/pelletier/go-toml/v2 v2.3.1 // indirect
github.com/philhofer/fwd v1.2.0 // indirect
github.com/pierrec/lz4/v4 v4.1.15 // indirect
github.com/pierrec/lz4/v4 v4.1.26 // indirect
github.com/pjbgf/sha1cd v0.6.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 // indirect
github.com/pquerna/cachecontrol v0.2.0 // indirect
github.com/prometheus/alertmanager v0.31.1 // indirect
github.com/prometheus/alertmanager v0.33.1 // indirect
github.com/prometheus/client_model v0.6.2 // indirect
github.com/prometheus/common v0.67.5 // indirect
github.com/prometheus/procfs v0.20.1 // indirect
github.com/prometheus/common v0.70.1 // indirect
github.com/prometheus/procfs v0.21.1 // indirect
github.com/prometheus/statsd_exporter v0.22.8 // indirect
github.com/rcrowley/go-metrics v0.0.0-20250401214520-65e299d6c5c9 // indirect
github.com/rs/xid v1.6.0 // indirect
@@ -339,16 +338,13 @@ require (
github.com/samber/slog-common v0.21.0 // indirect
github.com/samber/slog-zerolog/v2 v2.9.2 // indirect
github.com/segmentio/asm v1.2.1 // indirect
github.com/segmentio/kafka-go v0.4.50 // indirect
github.com/segmentio/kafka-go v0.4.51 // indirect
github.com/segmentio/ksuid v1.0.4 // indirect
github.com/sercand/kuberesolver/v5 v5.1.1 // indirect
github.com/sergi/go-diff v1.4.0 // indirect
github.com/sethvargo/go-diceware v0.5.0 // indirect
github.com/sethvargo/go-password v0.3.1 // indirect
github.com/shamaton/msgpack/v2 v2.4.1 // indirect
github.com/shirou/gopsutil/v4 v4.26.5 // indirect
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c // indirect
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92 // indirect
github.com/sethvargo/go-diceware v0.6.0 // indirect
github.com/sethvargo/go-password v0.4.0 // indirect
github.com/shirou/gopsutil/v4 v4.26.6 // indirect
github.com/skeema/knownhosts v1.3.1 // indirect
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
github.com/spacewander/go-suffix-tree v0.0.0-20191010040751-0865e368c784 // indirect
@@ -360,13 +356,13 @@ require (
github.com/tidwall/match v1.1.1 // indirect
github.com/tidwall/pretty v1.2.1 // indirect
github.com/tinylib/msgp v1.6.1 // indirect
github.com/tklauser/go-sysconf v0.3.16 // indirect
github.com/tklauser/numcpus v0.11.0 // indirect
github.com/tklauser/go-sysconf v0.4.0 // indirect
github.com/tklauser/numcpus v0.12.0 // indirect
github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208 // indirect
github.com/trustelem/zxcvbn v1.0.1 // indirect
github.com/urfave/cli/v2 v2.27.7 // indirect
github.com/valyala/fastjson v1.6.10 // indirect
github.com/vektah/gqlparser/v2 v2.5.34 // indirect
github.com/vektah/gqlparser/v2 v2.5.36 // indirect
github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect
github.com/wk8/go-ordered-map v1.0.0 // indirect
github.com/xanzy/ssh-agent v0.3.3 // indirect
@@ -376,25 +372,26 @@ require (
github.com/yashtewari/glob-intersection v0.2.0 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
github.com/zeebo/xxh3 v1.1.0 // indirect
go.etcd.io/etcd/api/v3 v3.6.11 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.6.11 // indirect
go.etcd.io/etcd/client/v3 v3.6.11 // indirect
go.etcd.io/etcd/api/v3 v3.6.13 // indirect
go.etcd.io/etcd/client/pkg/v3 v3.6.13 // indirect
go.etcd.io/etcd/client/v3 v3.6.13 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 // indirect
go.opentelemetry.io/otel/metric v1.44.0 // indirect
go.opentelemetry.io/proto/otlp v1.10.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0 // indirect
go.opentelemetry.io/otel/metric v1.45.0 // indirect
go.opentelemetry.io/proto/otlp v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
go.yaml.in/yaml/v2 v2.4.4 // indirect
go.yaml.in/yaml/v3 v3.0.4 // indirect
golang.org/x/mod v0.37.0 // indirect
golang.org/x/sys v0.46.0 // indirect
golang.org/x/sys v0.47.0 // indirect
golang.org/x/time v0.15.0 // indirect
golang.org/x/tools v0.47.0 // indirect
google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d // indirect
gopkg.in/cenkalti/backoff.v1 v1.1.0 // indirect
gopkg.in/ini.v1 v1.67.3 // indirect
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
sigs.k8s.io/yaml v1.6.0 // indirect
@@ -411,3 +408,5 @@ replace go-micro.dev/v4 => github.com/butonic/go-micro/v4 v4.11.1-0.202411151126
exclude github.com/mattn/go-sqlite3 v2.0.3+incompatible
replace github.com/go-micro/plugins/v4/store/nats-js-kv => github.com/opencloud-eu/go-micro-plugins/v4/store/nats-js-kv v0.0.0-20250512152754-23325793059a
replace github.com/dhowden/tag => github.com/dschmidt/tag v0.0.0-20260730135516-8eb6fc4a6973
+153 -158
View File
@@ -76,8 +76,8 @@ github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJ
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/Masterminds/semver/v3 v3.5.0 h1:kQceYJfbupGfZOKZQg0kou0DgAKhzDg2NZPAwZ/2OOE=
github.com/Masterminds/semver/v3 v3.5.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
github.com/MicahParks/keyfunc/v2 v2.1.0 h1:6ZXKb9Rp6qp1bDbJefnG7cTH8yMN1IC/4nf+GVjO99k=
@@ -115,8 +115,8 @@ github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964 h1:I9YN9WMo3SUh7p/
github.com/amoghe/go-crypt v0.0.0-20220222110647-20eada5f5964/go.mod h1:eFiR01PwTcpbzXtdMces7zxg6utvFM5puiWHpWB8D/k=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op h1:Z/MZK75wC/NSrkgqeNIa7jexam9uWzhLmFTSCPI/kn0=
github.com/antithesishq/antithesis-sdk-go v0.7.0-default-no-op/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
github.com/antithesishq/antithesis-sdk-go v0.7.2 h1:oEEedg1Xgi8drRjqB0f9tfjhLoInE0IYZfZ6zAhQUbY=
github.com/antithesishq/antithesis-sdk-go v0.7.2/go.mod h1:FQyySiasQQM8735Ddel3MRojmy4dA1IqCeyJ5jmPMbI=
github.com/apache/thrift v0.12.0/go.mod h1:cp2SuWMxlEZw2r+iP2GNCdIi4C1qmUzdZFSVb+bacwQ=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0 h1:jfIu9sQUG6Ig+0+Ap1h4unLjW6YQJpKZVmUzxsD4E/Q=
github.com/arbovm/levenshtein v0.0.0-20160628152529-48b4e1c0c4d0/go.mod h1:t2tdKJDJF9BV14lnkjHmOQgcvEKgtqs5a1N3LNdJhGE=
@@ -132,8 +132,8 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:W
github.com/aws/aws-sdk-go v1.37.27/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
github.com/bbalet/stopwords v1.0.0 h1:0TnGycCtY0zZi4ltKoOGRFIlZHv0WqpoIGUsObjztfo=
github.com/bbalet/stopwords v1.0.0/go.mod h1:sAWrQoDMfqARGIn4s6dp7OW7ISrshUD8IP2q3KoqPjc=
github.com/beevik/etree v1.6.0 h1:u8Kwy8pp9D9XeITj2Z0XtA5qqZEmtJtuXZRQi+j03eE=
github.com/beevik/etree v1.6.0/go.mod h1:bh4zJxiIr62SOf9pRzN7UUYaEDa9HEKafK25+sLc0Gc=
github.com/beevik/etree v1.7.0 h1:xjBk9O4p4x7D1YajePjfLzdaFC4/uYUENA7P0pv6gXA=
github.com/beevik/etree v1.7.0/go.mod h1:bh4zJxiIr62SOf9pRzN7UUYaEDa9HEKafK25+sLc0Gc=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20160804104726-4c0e84591b9a/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
@@ -195,8 +195,6 @@ github.com/bufbuild/protocompile v0.14.1 h1:iA73zAf/fyljNjQKwYzUHD6AD4R8KMasmwa/
github.com/bufbuild/protocompile v0.14.1/go.mod h1:ppVdAIhbr2H8asPk6k4pY7t9zB1OU5DoEw9xY/FUi1c=
github.com/butonic/go-micro/v4 v4.11.1-0.20241115112658-b5d4de5ed9b3 h1:h8Z0hBv5tg/uZMKu8V47+DKWYVQg0lYP8lXDQq7uRpE=
github.com/butonic/go-micro/v4 v4.11.1-0.20241115112658-b5d4de5ed9b3/go.mod h1:eE/tD53n3KbVrzrWxKLxdkGw45Fg1qaNLWjpJMvIUF4=
github.com/bytecodealliance/wasmtime-go/v44 v44.0.0 h1:WRZXnLPIer/TWs5aYPaMlmVcOlzmR6Ur6wjLRIQOhTQ=
github.com/bytecodealliance/wasmtime-go/v44 v44.0.0/go.mod h1:GP93piU+39CoFVCQ5xfHrPOUtL0APlMnkbblJ2d3YY0=
github.com/c-bata/go-prompt v0.2.5/go.mod h1:vFnjEGDIIA/Lib7giyE4E9c50Lvl8j0S+7FVlAwDAVw=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
@@ -220,10 +218,10 @@ github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWR
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/clipperhouse/displaywidth v0.10.0 h1:GhBG8WuerxjFQQYeuZAeVTuyxuX+UraiZGD4HJQ3Y8g=
github.com/clipperhouse/displaywidth v0.10.0/go.mod h1:XqJajYsaiEwkxOj4bowCTMcT1SgvHo9flfF3jQasdbs=
github.com/clipperhouse/uax29/v2 v2.6.0 h1:z0cDbUV+aPASdFb2/ndFnS9ts/WNXgTNNGFoKXuhpos=
github.com/clipperhouse/uax29/v2 v2.6.0/go.mod h1:Wn1g7MK6OoeDT0vL+Q0SQLDz/KpfsVRgg6W7ihQeh4g=
github.com/clipperhouse/displaywidth v0.11.0 h1:lBc6kY44VFw+TDx4I8opi/EtL9m20WSEFgwIwO+UVM8=
github.com/clipperhouse/displaywidth v0.11.0/go.mod h1:bkrFNkf81G8HyVqmKGxsPufD3JhNl3dSqnGhOoSD/o0=
github.com/clipperhouse/uax29/v2 v2.7.0 h1:+gs4oBZ2gPfVrKPthwbMzWZDaAFPGYK72F0NJv2v7Vk=
github.com/clipperhouse/uax29/v2 v2.7.0/go.mod h1:EFJ2TJMRUaplDxHKj1qAEhCtQPW2tJSwu5BF98AuoVM=
github.com/cloudflare/circl v1.6.3 h1:9GPOhQGF9MCYUeXyMYlqTR6a5gTrgR/fBLXvUgtVcg8=
github.com/cloudflare/circl v1.6.3/go.mod h1:2eXP6Qfat4O/Yhh8BznvKnJ+uzEoTQ6jVKJRn81BiS4=
github.com/cloudflare/cloudflare-go v0.14.0/go.mod h1:EnwdgGMaFOruiPZRFSgn+TsQ3hQ7C/YWzIGLeu5c304=
@@ -238,8 +236,8 @@ github.com/containerd/platforms v1.0.0-rc.2 h1:0SPgaNZPVWGEi4grZdV8VRYQn78y+nm6a
github.com/containerd/platforms v1.0.0-rc.2/go.mod h1:J71L7B+aiM5SdIEqmd9wp6THLVRzJGXfNuWCZCllLA4=
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.19.0 h1:F/xyOi3x1UnG1U27YVnM1N6bHiL1K2upi6U/0qr8r+I=
github.com/coreos/go-oidc/v3 v3.19.0/go.mod h1:DYCf24+ncYi+XkIH97GY1+dqoRlbaSI26KVTCI9SrY4=
github.com/coreos/go-oidc/v3 v3.20.0 h1:EtE0WIBHk03N+DqGkY4+UONzzZHk7amKt6IyNd7OsZE=
github.com/coreos/go-oidc/v3 v3.20.0/go.mod h1:DYCf24+ncYi+XkIH97GY1+dqoRlbaSI26KVTCI9SrY4=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
github.com/coreos/go-semver v0.3.1 h1:yi21YpKnrx1gt5R+la8n5WgS0kCrsPp33dmEyHReZr4=
github.com/coreos/go-semver v0.3.1/go.mod h1:irMmmIw/7yzSRPWryHsK7EYSg09caPQL03VsM8rvUec=
@@ -281,8 +279,8 @@ github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.1/go.mod h1:ZXNYxsqcloTdSy/rNShjY
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.9.2 h1:Wb5qw8gElqwV1a8msHTeQKova9b1V10heFKMIiPd80E=
github.com/dgraph-io/badger/v4 v4.9.2/go.mod h1:nJjaJTUOSsQEBhsq209FmwCvMJzEA3e74RjZw6V2pQI=
github.com/dgraph-io/badger/v4 v4.9.4 h1:bcw+waCpzRZ2nmcSPbnPvDVhiEsn98TKmvnAhK7r7LM=
github.com/dgraph-io/badger/v4 v4.9.4/go.mod h1:nJjaJTUOSsQEBhsq209FmwCvMJzEA3e74RjZw6V2pQI=
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.2.0 h1:bkY3XzJcXoMuELV8F+vS8kzNgicwQFAaGINAEJdWGOM=
@@ -295,19 +293,19 @@ github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cu
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54 h1:SG7nF6SRlWhcT7cNTs5R6Hk4V2lcmLz2NsG2VnInyNo=
github.com/dgryski/trifles v0.0.0-20230903005119-f50d829f2e54/go.mod h1:if7Fbed8SFyPtHLHbg49SI7NAdJiC5WIA09pe59rfAA=
github.com/dhowden/tag v0.0.0-20240417053706-3d75831295e8 h1:OtSeLS5y0Uy01jaKK4mA/WVIYtpzVm63vLVAPzJXigg=
github.com/dhowden/tag v0.0.0-20240417053706-3d75831295e8/go.mod h1:apkPC/CR3s48O2D7Y++n1XWEpgPNNCjXYga3PPbJe2E=
github.com/dimchansky/utfbom v1.1.0/go.mod h1:rO41eb7gLfo8SF1jd9F8HplJm1Fewwi4mQvIirEdv+8=
github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/dlclark/regexp2 v1.4.0 h1:F1rxgk7p4uKjwIQxBs9oAXe5CqrXlCduYEJvrF4u93E=
github.com/dlclark/regexp2 v1.4.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
github.com/dlclark/regexp2 v1.12.0 h1:0j4c5qQmnC6XOWNjP3PIXURXN2gWx76rd3KvgdPkCz8=
github.com/dlclark/regexp2 v1.12.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8=
github.com/dnaeon/go-vcr v1.0.1/go.mod h1:aBB1+wY4s93YsC3HHjMBMrwTj2R9FHDzUr9KyGc8n1E=
github.com/dnsimple/dnsimple-go v0.63.0/go.mod h1:O5TJ0/U6r7AfT8niYNlmohpLbCSG+c71tQlGr9SeGrg=
github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94=
github.com/docker/go-connections v0.6.0/go.mod h1:AahvXYshr6JgfUJGdDCs2b5EZG/vmaMAntpSFH5BFKE=
github.com/docker/go-connections v0.7.0 h1:6SsRfJddP22WMrCkj19x9WKjEDTB+ahsdiGYf0mN39c=
github.com/docker/go-connections v0.7.0/go.mod h1:no1qkHdjq7kLMGUXYAduOhYPSJxxvgWBh7ogVvptn3Q=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/dschmidt/tag v0.0.0-20260730135516-8eb6fc4a6973 h1:XnAwTTbblPJI6OVkRwqVA2MGjre29B/+wsi16lQfJ+E=
github.com/dschmidt/tag v0.0.0-20260730135516-8eb6fc4a6973/go.mod h1:apkPC/CR3s48O2D7Y++n1XWEpgPNNCjXYga3PPbJe2E=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e h1:rcHHSQqzCgvlwP0I/fQ8rQMn/MpHE5gWSLdtpxtP6KQ=
@@ -315,8 +313,8 @@ github.com/dutchcoders/go-clamd v0.0.0-20170520113014-b970184f4d9e/go.mod h1:Byz
github.com/eapache/go-resiliency v1.1.0/go.mod h1:kFI+JgMyC7bLPUVY133qvEBtVayf5mFgVsvEsIPBvNs=
github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU=
github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I=
github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU=
github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/ebitengine/purego v0.10.1 h1:dewVBCBT2GaMu1SrNTYxQhgQBethzfhiwvZiLGP/qyY=
github.com/ebitengine/purego v0.10.1/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/egirna/icap v0.0.0-20181108071049-d5ee18bd70bc h1:6IxmRbXV8WXVkcYcTzkU219A3UZeNMX/e6X2sve1wXA=
github.com/egirna/icap v0.0.0-20181108071049-d5ee18bd70bc/go.mod h1:FdVN2WHg7zOHhJ7kZQdDorfFhIfqZaHttjAzDDvAXHE=
github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o=
@@ -334,12 +332,12 @@ github.com/evanphx/json-patch/v5 v5.5.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2Vvl
github.com/exoscale/egoscale v0.46.0/go.mod h1:mpEXBpROAa/2i5GC0r33rfxG+TxSEka11g1PIXt9+zc=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w=
github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE=
github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg=
github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
github.com/felixge/httpsnoop v1.1.0 h1:3YtUj32ZZkqZtt3sZZsClsymw/QDuVfpNhoA31zeORc=
github.com/felixge/httpsnoop v1.1.0/go.mod h1:Zqxgdd+1Rkcz8euOqdr7lqgCRJztwr5hp9vDSi5UZCE=
github.com/fortytw2/leaktest v1.3.0 h1:u8491cBMTQ8ft8aeV+adlcytMZylmA5nnwwkRZjI8vw=
github.com/fortytw2/leaktest v1.3.0/go.mod h1:jDsjWgpAGjm2CA7WthBh/CdZYEPF31XHquHwclZch5g=
github.com/foxcpp/go-mockdns v1.2.0 h1:omK3OrHRD1IWJz1FuFBCFquhXslXoF17OvBS6JPzZF0=
@@ -350,8 +348,8 @@ github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMo
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx59Ho=
github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo=
github.com/gabriel-vasile/mimetype v1.4.13 h1:46nXokslUBsAJE/wMsp5gtO500a4F3Nkz9Ufpk2AcUM=
github.com/gabriel-vasile/mimetype v1.4.13/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
github.com/gabriel-vasile/mimetype v1.4.15 h1:05iP/CYtZ/w455R/KZM6rZ5ieAdh99UPtd+d3YzLmaI=
github.com/gabriel-vasile/mimetype v1.4.15/go.mod h1:azpTcoLcDZRNgFou5j+APrqQx9HqVPWa6ijYQIIVswQ=
github.com/gdexlab/go-render v1.0.1 h1:rxqB3vo5s4n1kF0ySmoNeSPRYkEsyHgln4jFIQY7v0U=
github.com/gdexlab/go-render v1.0.1/go.mod h1:wRi5nW2qfjiGj4mPukH4UV0IknS1cHD4VgFTmJX5JzM=
github.com/getkin/kin-openapi v0.13.0/go.mod h1:WGRs2ZMM1Q8LR1QBEwUxC6RJEfaBcD0s+pcEVXFuAjw=
@@ -370,8 +368,8 @@ github.com/go-acme/lego/v4 v4.4.0 h1:uHhU5LpOYQOdp3aDU+XY2bajseu8fuExphTL1Ss6/Fc
github.com/go-acme/lego/v4 v4.4.0/go.mod h1:l3+tFUFZb590dWcqhWZegynUthtaHJbG2fevUpoOOE0=
github.com/go-asn1-ber/asn1-ber v1.3.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-asn1-ber/asn1-ber v1.4.1/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 h1:BP4M0CvQ4S3TGls2FvczZtj5Re/2ZzkV9VwqPHH/3Bo=
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-asn1-ber/asn1-ber v1.5.8 h1:H9AZkK22UOmfX8J84ubyaZxKJZ3FMHVwn8swoMML7iQ=
github.com/go-asn1-ber/asn1-ber v1.5.8/go.mod h1:hEBeB/ic+5LoWskz+yKT7vGhhPYkProFKoKdwZRWMe0=
github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
github.com/go-chi/chi/v5 v5.3.1 h1:3j4HZLGZQ3JpMCrPJF/Jl3mYJfWLKBfNJ6quurUGCf8=
github.com/go-chi/chi/v5 v5.3.1/go.mod h1:R+tYY2hNuVUUjxoPtqUdgBqevM9s9njzkTLutVsOCto=
@@ -385,13 +383,11 @@ github.com/go-git/go-billy/v5 v5.9.0 h1:jItGXszUDRtR/AlferWPTMN4j38BQ88XnXKbilmm
github.com/go-git/go-billy/v5 v5.9.0/go.mod h1:jCnQMLj9eUgGU7+ludSTYoZL/GGmii14RxKFj7ROgHw=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399 h1:eMje31YglSBqCdIqdhKBW8lokaMrL3uTkpGYlE2OOT4=
github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20231010084843-55a94097c399/go.mod h1:1OCfN199q1Jm3HZlxleg+Dw/mwps2Wbk9frAWm+4FII=
github.com/go-git/go-git/v5 v5.19.1 h1:nX27AnaU43/K5bKktKwgBmR9lawoYVe1Ckg0rgzzN00=
github.com/go-git/go-git/v5 v5.19.1/go.mod h1:Pb1v0c7/g8aGQJwx9Us09W85yGoyvSwuhEGMH7zjDKQ=
github.com/go-git/go-git/v5 v5.19.2 h1:wkfn7vOlUBu8ivAWKBWisTiwJK4jYHzTF8Ndv1LyGqY=
github.com/go-git/go-git/v5 v5.19.2/go.mod h1:QqCBE1EFN5ddFmrliLQ3/ntRCUjZU3EJuwuB/jWEHjk=
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
github.com/go-ini/ini v1.67.0 h1:z6ZrTEZqSWOTyH2FlglNbNgARyHG8oLW9gMELqKr06A=
github.com/go-ini/ini v1.67.0/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8=
github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
github.com/go-jose/go-jose/v3 v3.0.5 h1:BLLJWbC4nMZOfuPVxoZIxeYsn6Nl2r1fITaJ78UQlVQ=
github.com/go-jose/go-jose/v3 v3.0.5/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ=
@@ -404,8 +400,8 @@ github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBj
github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU=
github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0=
github.com/go-ldap/ldap/v3 v3.1.7/go.mod h1:5Zun81jBTabRaI8lzN7E1JjyEl1g6zI6u9pd8luAK4Q=
github.com/go-ldap/ldap/v3 v3.4.13 h1:+x1nG9h+MZN7h/lUi5Q3UZ0fJ1GyDQYbPvbuH38baDQ=
github.com/go-ldap/ldap/v3 v3.4.13/go.mod h1:LxsGZV6vbaK0sIvYfsv47rfh4ca0JXokCoKjZxsszv0=
github.com/go-ldap/ldap/v3 v3.4.14 h1:D6PYdEgsaVzsXyr6w/yDC06Ria4uUhWm+Rb+er8lfAs=
github.com/go-ldap/ldap/v3 v3.4.14/go.mod h1:S4eJUMUNjDkE0ZJtIZdybwyb03sGGLW6gxXT1Hs8VKA=
github.com/go-ldap/ldif v0.0.0-20200320164324-fd88d9b715b3 h1:sfz1YppV05y4sYaW7kXZtrocU/+vimnIWt4cxAYh7+o=
github.com/go-ldap/ldif v0.0.0-20200320164324-fd88d9b715b3/go.mod h1:ZXFhGda43Z2TVbfGZefXyMJzsDHhCh0go3bZUcwTx7o=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
@@ -414,8 +410,8 @@ github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG
github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA=
github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8=
github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-micro/plugins/v4/client/grpc v1.2.1 h1:7xAwZRCO6mdUtBHsYIQs1/eCTdhCrnjF70GB+AVd6L0=
@@ -440,8 +436,9 @@ github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus v1.2.0 h1:UWBUYtMXC
github.com/go-micro/plugins/v4/wrapper/monitoring/prometheus v1.2.0/go.mod h1:8BYxs/wEE4ZJayHZQffw4A8s9rcPumyoNms0hYoNocM=
github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry v1.2.0 h1:e2hgtWMNqJ3DmbMt9ZxzmH/BkVAw9Xg23l6CHrXQfKw=
github.com/go-micro/plugins/v4/wrapper/trace/opentelemetry v1.2.0/go.mod h1:BBqL7ckGNb7rFfk3vU2Yj/CILVsz/WF19CkAyveQl8A=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
@@ -551,7 +548,6 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
@@ -717,8 +713,8 @@ github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.18.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao=
github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/klauspost/compress v1.19.1 h1:VsB4HPswih7mmZ8WleSFQ75c/Ui1M4trX5oAsJnhSlk=
github.com/klauspost/compress v1.19.1/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ=
github.com/klauspost/cpuid/v2 v2.0.1/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y=
github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0=
@@ -734,8 +730,8 @@ github.com/kovidgoyal/go-parallel v1.1.1 h1:1OzpNjtrUkBPq3UaqrnvOoB2F9RttSt811ui
github.com/kovidgoyal/go-parallel v1.1.1/go.mod h1:BJNIbe6+hxyFWv7n6oEDPj3PA5qSw5OCtf0hcVxWJiw=
github.com/kovidgoyal/go-shm v1.0.0 h1:HJEel9D1F9YhULvClEHJLawoRSj/1u/EDV7MJbBPgQo=
github.com/kovidgoyal/go-shm v1.0.0/go.mod h1:Yzb80Xf9L3kaoB2RGok9hHwMIt7Oif61kT6t3+VnZds=
github.com/kovidgoyal/imaging v1.8.22 h1:CtpoRXQpS79xxJsKu8+LUJJE/0i4FLquJZy0QH+QNlM=
github.com/kovidgoyal/imaging v1.8.22/go.mod h1:y8wo4JTv4D+skbtQf6fHg8nA1qtagvCcn8J2Nu5k2Jg=
github.com/kovidgoyal/imaging v1.8.23 h1:4WsboyQ/E8tic2kX49P93Rvscg33SPsCwTBG5EZZF54=
github.com/kovidgoyal/imaging v1.8.23/go.mod h1:k3Iot3H0v2rSWXIxQISfT3e9wIryqzAHLHCuhG7z9lM=
github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
@@ -785,8 +781,8 @@ github.com/longsleep/go-metrics v1.0.0 h1:o2A6Dbu4MhLpZuL444WFoZzM7X7igewrj2Mouw
github.com/longsleep/go-metrics v1.0.0/go.mod h1:w6QO1LBkVla70FZrrF6XcB0YN+jTEYugjkn3+6RYTSM=
github.com/longsleep/rndm v1.2.0 h1:wPl+kIMyIUTUFW5+2b327DmM1Rlj+gmexsiyOTB7rzM=
github.com/longsleep/rndm v1.2.0/go.mod h1:5qyvM6CXNteKgz6djqqwZOP4+KcPsewrfKyLWd1dCFY=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0 h1:6E+4a0GO5zZEnZ81pIr0yLvtUWk2if982qA3F3QD6H4=
github.com/lufia/plan9stats v0.0.0-20211012122336-39d0f177ccd0/go.mod h1:zJYVVT2jmtg6P3p1VtQj7WsuWi/y4VnjVBn7F8KPB3I=
github.com/lufia/plan9stats v0.0.0-20260330125221-c963978e514e h1:Q6MvJtQK/iRcRtzAscm/zF23XxJlbECiGPyRicsX+Ak=
github.com/lufia/plan9stats v0.0.0-20260330125221-c963978e514e/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=
github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60=
github.com/magiconair/properties v1.8.10 h1:s31yESBquKXCV9a/ScB3ESkOjUYYv+X0rg8SYxI99mE=
@@ -803,23 +799,23 @@ github.com/mattn/go-colorable v0.1.7/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-colorable v0.1.15 h1:+u9SLTRGnXv73cEsnsmoZBom+dMU88B2M0aDcWy0/jY=
github.com/mattn/go-colorable v0.1.15/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8=
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-isatty v0.0.22 h1:j8l17JJ9i6VGPUFUYoTUKPSgKe/83EYU2zBC7YNKMw4=
github.com/mattn/go-isatty v0.0.22/go.mod h1:ZXfXG4SQHsB/w3ZeOYbR0PrPwLy+n6xiMrJlRFqopa4=
github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-runewidth v0.0.19 h1:v++JhqYnZuu5jSKrk9RbgF5v4CGUjqRfBm05byFGLdw=
github.com/mattn/go-runewidth v0.0.19/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
github.com/mattn/go-sqlite3 v1.14.42 h1:MigqEP4ZmHw3aIdIT7T+9TLa90Z6smwcthx+Azv4Cgo=
github.com/mattn/go-sqlite3 v1.14.42/go.mod h1:pjEuOr8IwzLJP2MfGeTb0A35jauH+C2kbHKBr7yXKVQ=
github.com/mattn/go-runewidth v0.0.24 h1:cpokDiIn0MGnhdHwuWnJBITySJ20QyNGnY2kR/ay2DU=
github.com/mattn/go-runewidth v0.0.24/go.mod h1:XBkDxAl56ILZc9knddidhrOlY5R/pDhgLpndooCuJAs=
github.com/mattn/go-sqlite3 v1.14.49 h1:B8jBHC3xhxZgxztrgruTuLucebnULQnx4W7cF7SAE9w=
github.com/mattn/go-sqlite3 v1.14.49/go.mod h1:6JTjA44L93a0QCyJef5YvlPoKXntQPjzWv5gtm9sB6w=
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=
@@ -841,8 +837,8 @@ github.com/minio/highwayhash v1.0.4 h1:asJizugGgchQod2ja9NJlGOWq4s7KsAWr5XUc9Clg
github.com/minio/highwayhash v1.0.4/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.1.0 h1:QEt5IStDpxgGjEdtOgpiZ5QhmSl3ax7qy61vi2SwHO8=
github.com/minio/minio-go/v7 v7.1.0/go.mod h1:Dm7WS1AgLmBa0NcQD6SeJnJf+K/EUW3GR7Ks6olB3OA=
github.com/minio/minio-go/v7 v7.2.1 h1:PfBfwvKB/MmqyN8Vb1G9voWisaM9OrLv+WwOvMwS9Dw=
github.com/minio/minio-go/v7 v7.2.1/go.mod h1:EU9hENAStx/xXduNdrGO5e4X5vk19NtgB+RIPjZO8o0=
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=
@@ -863,14 +859,14 @@ github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3N
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
github.com/moby/go-archive v0.2.0 h1:zg5QDUM2mi0JIM9fdQZWC7U8+2ZfixfTYoHL7rWUcP8=
github.com/moby/go-archive v0.2.0/go.mod h1:mNeivT14o8xU+5q1YnNrkQVpK+dnNe/K6fHqnTg4qPU=
github.com/moby/moby/api v1.54.2 h1:wiat9QAhnDQjA7wk1kh/TqHz2I1uUA7M7t9SAl/JNXg=
github.com/moby/moby/api v1.54.2/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs=
github.com/moby/moby/client v0.4.0 h1:S+2XegzHQrrvTCvF6s5HFzcrywWQmuVnhOXe2kiWjIw=
github.com/moby/moby/client v0.4.0/go.mod h1:QWPbvWchQbxBNdaLSpoKpCdf5E+WxFAgNHogCWDoa7g=
github.com/moby/moby/api v1.55.0 h1:2/sexvQyqIWS8pRSCFddBfpW2qE7vR7FCL+vN8pxwMc=
github.com/moby/moby/api v1.55.0/go.mod h1:+RQ6wluLwtYaTd1WnPLykIDPekkuyD/ROWQClE83pzs=
github.com/moby/moby/client v0.5.0 h1:5XhyPk2fuOWf6RlSFa3MkIIgDZkF25xToXW8Q/BH7cc=
github.com/moby/moby/client v0.5.0/go.mod h1:rcVpF8ncl9vo5gaIBdol6CnbEtSj1uxMvEV/UrykF/s=
github.com/moby/patternmatcher v0.6.1 h1:qlhtafmr6kgMIJjKJMDmMWq7WLkKIo23hsrpR3x084U=
github.com/moby/patternmatcher v0.6.1/go.mod h1:hDPoyOpDY7OrrMDLaYoY3hf52gNCR/YOUYxkhApJIxc=
github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7zgvCU=
github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko=
github.com/moby/sys/sequential v0.7.0 h1:ASQNGNROJSuOO6LL6bPHbKvuZu6NU8P4ldPWk31zj/8=
github.com/moby/sys/sequential v0.7.0/go.mod h1:NfSTAp6V3fw4tmkD62PEcOKeZKquXT8VKCkf7aVR79o=
github.com/moby/sys/user v0.4.0 h1:jhcMKit7SA80hivmFJcbB1vqmw//wU61Zdui2eQXuMs=
github.com/moby/sys/user v0.4.0/go.mod h1:bG+tYYYJgaMtRKgEmuueC0hJEAZWwtIbZTB+85uoHjs=
github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g=
@@ -896,8 +892,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRW
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04/go.mod h1:5sN+Lt1CaY4wsPvgQH/jsuJi4XO2ssZbdsIizr4CVC8=
github.com/nats-io/jwt/v2 v2.8.2 h1:XXRgB60MSTnqsRwejQurVDs/hcv2dkt+86GjI+I/bMc=
github.com/nats-io/jwt/v2 v2.8.2/go.mod h1:Ag/56sq9OblL4JgdYufDd16Egb17Kr/8WwwuO/forVc=
github.com/nats-io/nats-server/v2 v2.14.3 h1:+xjydPt7rkit67G+04TN0mcO2n+8nveZE7tK/PPV53A=
github.com/nats-io/nats-server/v2 v2.14.3/go.mod h1:5IlCtBzfwyzQzPMjmoJ9W2/LKmnJRtNyuOs/OT+NHDY=
github.com/nats-io/nats-server/v2 v2.14.4 h1:efgjZ8cdExAKRuqSg8UPJFprb+l7NlBtSDPhDlw3rO4=
github.com/nats-io/nats-server/v2 v2.14.4/go.mod h1:BltdpOYestjbtQSnVO2zGHdg5SGBZjt+GYTgB9LZq/I=
github.com/nats-io/nats.go v1.52.0 h1:n3avV4VBsCgsdwh71TppsTwtv+QdPs7ntSKM8qJLGsc=
github.com/nats-io/nats.go v1.52.0/go.mod h1:26HypzazeOkyO3/mqd1zZd53STJN0EjCYF9Uy2ZOBno=
github.com/nats-io/nkeys v0.4.16 h1:rd5oAuLOb8mnAycB0xleuEBNS1pVVnN0fv/FF34Eypg=
@@ -938,16 +934,16 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
github.com/onsi/gomega v1.42.1 h1:iN1rCUX+44NZ1Dc97MPoeFYbFR0vh8zxoxMFwKdyZ6I=
github.com/onsi/gomega v1.42.1/go.mod h1:REff/hsDsodHoKlWsP2mAPhu1+5/6hVYNf9rIEBpeSg=
github.com/open-policy-agent/opa v1.18.2 h1:VBiLJpioTuk7XTW1JoQi4ILo+FVxD2/8uD8iP9/OcxY=
github.com/open-policy-agent/opa v1.18.2/go.mod h1:9GY+hER4ZEXtxPlMjftVbqJJY9xLtCD3Q0oufRCfAKo=
github.com/open-policy-agent/opa v1.19.0 h1:+j2OCsjMezZEML2T1lI9giJdGJS/PL1XFKgkHPGIhpo=
github.com/open-policy-agent/opa v1.19.0/go.mod h1:pb6Y6klyf7X7X8uXNDflruA9dQC2gMqWROXI5w/kvv0=
github.com/opencloud-eu/go-micro-plugins/v4/store/nats-js-kv v0.0.0-20250512152754-23325793059a h1:Sakl76blJAaM6NxylVkgSzktjo2dS504iDotEFJsh3M=
github.com/opencloud-eu/go-micro-plugins/v4/store/nats-js-kv v0.0.0-20250512152754-23325793059a/go.mod h1:pjcozWijkNPbEtX5SIQaxEW/h8VAVZYTLx+70bmB3LY=
github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89 h1:W1ms+lP5lUUIzjRGDg93WrQfZJZCaV1ZP3KeyXi8bzY=
github.com/opencloud-eu/icap-client v0.0.0-20250930132611-28a2afe62d89/go.mod h1:vigJkNss1N2QEceCuNw/ullDehncuJNFB6mEnzfq9UI=
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d h1:JcqGDiyrcaQwVyV861TUyQgO7uEmsjkhfm7aQd84dOw=
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260310090739-853d972b282d/go.mod h1:pzatilMEHZFT3qV7C/X3MqOa3NlRQuYhlRhZTL+hN6Q=
github.com/opencloud-eu/reva/v2 v2.46.4-0.20260625152426-8cff2a7032ec h1:kL9P87cVpe8GKvo5vzLpJstpiVXFvkZn2+Dco53nfuM=
github.com/opencloud-eu/reva/v2 v2.46.4-0.20260625152426-8cff2a7032ec/go.mod h1:l4CG5u8tdWZj6IyavXO9xDdnNTV85oaFudGwEDPvsnk=
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260818063016-69f82a7dde55 h1:dzYZ5iA6i0QoFUap9l6sZ4Ts2HXiXVfsOoiRYToYgm8=
github.com/opencloud-eu/libre-graph-api-go v1.0.8-0.20260818063016-69f82a7dde55/go.mod h1:lTM8JeGblNpoMySTW7Lui2+c5TTLI95mwxtdUIHHrhU=
github.com/opencloud-eu/reva/v2 v2.48.1-0.20260811071808-9bf68d2ccd96 h1:2yPjf1jhrhEkrHsX8s6gAQVogBmNY6ZTtPNOtLfc1p8=
github.com/opencloud-eu/reva/v2 v2.48.1-0.20260811071808-9bf68d2ccd96/go.mod h1:+2IJFVwi3yBEBfw0T+jgY7M9LBSPv7ecPYDiG3/bWYg=
github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4 h1:l2oB/RctH+t8r7QBj5p8thfEHCM/jF35aAY3WQ3hADI=
github.com/opencloud-eu/secure v0.0.0-20260312082735-b6f5cb2244e4/go.mod h1:BmF5hyM6tXczk3MpQkFf1hpKSRqCyhqcbiQtiAF7+40=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
@@ -975,15 +971,15 @@ github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58 h1:onHthvaw9LFnH4t2D
github.com/pbnjay/memory v0.0.0-20210728143218-7b4eea64cf58/go.mod h1:DXv8WO4yhMYhSNPKjeNKa5WY9YCIEBRbNzFFPJbWO6Y=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
github.com/pelletier/go-toml v1.8.1/go.mod h1:T2/BmBdy8dvIRq1a/8aqjN41wvWlN4lrapLU/GW4pbc=
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/pelletier/go-toml/v2 v2.3.1 h1:MYEvvGnQjeNkRF1qUuGolNtNExTDwct51yp7olPtrEc=
github.com/pelletier/go-toml/v2 v2.3.1/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5 h1:Ii+DKncOVM8Cu1Hc+ETb5K+23HdAMvESYE3ZJ5b5cMI=
github.com/phayes/freeport v0.0.0-20220201140144-74d24b5ae9f5/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE=
github.com/philhofer/fwd v1.2.0 h1:e6DnBTl7vGY+Gz322/ASL4Gyp1FspeMvx1RNDoToZuM=
github.com/philhofer/fwd v1.2.0/go.mod h1:RqIHx9QI14HlwKwm98g9Re5prTQ6LdeRQn+gXJFxsJM=
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0=
github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4=
github.com/pierrec/lz4/v4 v4.1.26 h1:GrpZw1gZttORinvzBdXPUXATeqlJjqUG/D87TKMnhjY=
github.com/pierrec/lz4/v4 v4.1.26/go.mod h1:EoQMVJgeeEOMsCqCzqFm2O0cJvljX2nGZjcRIPL34O4=
github.com/pierrec/xxHash v0.1.5 h1:n/jBpwTHiER4xYvK3/CdPVnLDPchj8eTJFFLUb4QHBo=
github.com/pierrec/xxHash v0.1.5/go.mod h1:w2waW5Zoa/Wc4Yqe0wgrIYAGKqRMf7czn2HNKXmuL+I=
github.com/pjbgf/sha1cd v0.6.0 h1:3WJ8Wz8gvDz29quX1OcEmkAlUg9diU4GxJHqs0/XiwU=
@@ -1005,8 +1001,8 @@ github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:Om
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/prometheus/alertmanager v0.31.1 h1:eAmIC42lzbWslHkMt693T36qdxfyZULswiHr681YS3Q=
github.com/prometheus/alertmanager v0.31.1/go.mod h1:zWPQwhbLt2ybee8rL921UONeQ59Oncash+m/hGP17tU=
github.com/prometheus/alertmanager v0.33.1 h1:PJHGvTdb8Q0ZEpJnWff120WxB2kxIScLa707AaIudTo=
github.com/prometheus/alertmanager v0.33.1/go.mod h1:V06Uc8EZ5X5wLOJRGhtXx+EE2LgrinFIADbKWMVm1RY=
github.com/prometheus/client_golang v0.8.0/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v0.9.3-0.20190127221311-3c4408c8b829/go.mod h1:p2iRAGwDERtqlqzRXnrOVns+ignqQo//hLXqYxZYVNs=
@@ -1018,8 +1014,8 @@ github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqr
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ=
github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o=
github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg=
github.com/prometheus/client_golang v1.24.1 h1:JnJkREXzWxUdCuPFpIWZiPispT9xVV59uiuyR2bPlnU=
github.com/prometheus/client_golang v1.24.1/go.mod h1:F+oSRECHg4sse5ucfYpYDeIv/hu68Zo0uoHKetWnzcE=
github.com/prometheus/client_model v0.0.0-20170216185247-6f3806018612/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190115171406-56726106282f/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
@@ -1039,8 +1035,8 @@ github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA=
github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4=
github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw=
github.com/prometheus/common v0.70.1 h1:1HvjP4D5oL3t8RsPlwxA9onvvStjtIHYE5XuuwOi/PY=
github.com/prometheus/common v0.70.1/go.mod h1:VdFUQDMZK3VLkurFUVhia6uys/0suUp86TJz5qbJRhc=
github.com/prometheus/procfs v0.0.0-20170703101242-e645f4e5aaa8/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190117184657-bf6a532e95b1/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
@@ -1051,8 +1047,8 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4=
github.com/prometheus/procfs v0.20.1 h1:XwbrGOIplXW/AU3YhIhLODXMJYyC1isLFfYCsTEycfc=
github.com/prometheus/procfs v0.20.1/go.mod h1:o9EMBZGRyvDrSPH1RqdxhojkuXstoe4UlK79eF5TGGo=
github.com/prometheus/procfs v0.21.1 h1:GljZCt+zSTS+NZq88cyQ1LjZ+RCHp3uVuabBWA5+OJI=
github.com/prometheus/procfs v0.21.1/go.mod h1:aB55Cww9pdSJVHk0hUf0inxWyyjPogFIjmHKYgMKmtY=
github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI=
github.com/prometheus/statsd_exporter v0.22.8 h1:Qo2D9ZzaQG+id9i5NYNGmbf1aa/KxKbB9aKfMS+Yib0=
github.com/prometheus/statsd_exporter v0.22.8/go.mod h1:/DzwbTEaFTE0Ojz5PqcSk6+PFHOPWGxdXVr6yC8eFOM=
@@ -1067,8 +1063,8 @@ github.com/riandyrn/otelchi v0.12.3 h1:KW9gA+97d6mExk8vbh0FRwb2biUvpyYlc8YuxP1Oa
github.com/riandyrn/otelchi v0.12.3/go.mod h1:weZZeUJURvtCcbWsdb7Y6F8KFZGedJlSrgUjq9VirV8=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.15.0 h1:D0RCU5rMAp+SpgkiNdrjfJ+LX4J1M32V2NeCY7EJ6hc=
github.com/rogpeppe/go-internal v1.15.0/go.mod h1:DrUVZyrJU+txYW5/1kwtXQSMFio52ZOxX7yM1VHvnxs=
github.com/rogpeppe/go-internal v1.16.0 h1:O9DK+vNMDVGLr2BeZqmpLeMjiMNkuXfcqntWbZV6S5g=
github.com/rogpeppe/go-internal v1.16.0/go.mod h1:DrUVZyrJU+txYW5/1kwtXQSMFio52ZOxX7yM1VHvnxs=
github.com/rs/cors v1.11.1 h1:eU3gRzXLRK57F5rKMGMZURNdIG4EoAmX8k94r9wXWHA=
github.com/rs/cors v1.11.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU=
github.com/rs/xid v1.6.0 h1:fV591PaemRlL6JfRxGDEPl69wICngIQ3shQtzfy2gxU=
@@ -1096,29 +1092,25 @@ github.com/scaleway/scaleway-sdk-go v1.0.0-beta.7.0.20210127161313-bd30bebeac4f/
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
github.com/segmentio/asm v1.2.1 h1:DTNbBqs57ioxAD4PrArqftgypG4/qNpXoJx8TVXxPR0=
github.com/segmentio/asm v1.2.1/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
github.com/segmentio/kafka-go v0.4.50 h1:mcyC3tT5WeyWzrFbd6O374t+hmcu1NKt2Pu1L3QaXmc=
github.com/segmentio/kafka-go v0.4.50/go.mod h1:Y1gn60kzLEEaW28YshXyk2+VCUKbJ3Qr6DrnT3i4+9E=
github.com/segmentio/kafka-go v0.4.51 h1:JgDPPG75tC1rWIS2Me6MwcvXJ6f49UQ4HjAOef71Hno=
github.com/segmentio/kafka-go v0.4.51/go.mod h1:Y1gn60kzLEEaW28YshXyk2+VCUKbJ3Qr6DrnT3i4+9E=
github.com/segmentio/ksuid v1.0.4 h1:sBo2BdShXjmcugAMwjugoGUdUV0pcxY5mW4xKRn3v4c=
github.com/segmentio/ksuid v1.0.4/go.mod h1:/XUiZBD3kVx5SmUOl55voK5yeAbBNNIed+2O73XgrPE=
github.com/sercand/kuberesolver/v5 v5.1.1 h1:CYH+d67G0sGBj7q5wLK61yzqJJ8gLLC8aeprPTHb6yY=
github.com/sercand/kuberesolver/v5 v5.1.1/go.mod h1:Fs1KbKhVRnB2aDWN12NjKCB+RgYMWZJ294T3BtmVCpQ=
github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw=
github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4=
github.com/sethvargo/go-diceware v0.5.0 h1:exrQ7GpaBo00GqRVM1N8ChXSsi3oS7tjQiIehsD+yR0=
github.com/sethvargo/go-diceware v0.5.0/go.mod h1:Lg1SyPS7yQO6BBgTN5r4f2MUDkqGfLWsOjHPY0kA8iw=
github.com/sethvargo/go-password v0.3.1 h1:WqrLTjo7X6AcVYfC6R7GtSyuUQR9hGyAj/f1PYQZCJU=
github.com/sethvargo/go-password v0.3.1/go.mod h1:rXofC1zT54N7R8K/h1WDUdkf9BOx5OptoxrMBcrXzvs=
github.com/sethvargo/go-diceware v0.6.0 h1:B3nhMhbBP7KwtTQ7hHRIOmv5FqeD8bJs77RFrV24iWk=
github.com/sethvargo/go-diceware v0.6.0/go.mod h1:lHmdB0xuWaJ06KCraW6bztRT+71Dp+lsXQvborhhsBc=
github.com/sethvargo/go-password v0.4.0 h1:eSidVKQw5C7CmTDAtH3RipBTSjdU1ZRxQaynD2GWLVU=
github.com/sethvargo/go-password v0.4.0/go.mod h1:PO3nYHwUpcHPR0F9woy7a4abZPvzRuqJr0GaeIYTm3k=
github.com/shamaton/msgpack/v2 v2.4.1 h1:JtJ141QoQ3NqgPDsjq2v9VXlaON8SiQOwEaoNLEK/MQ=
github.com/shamaton/msgpack/v2 v2.4.1/go.mod h1:6khjYnkx73f7VQU7wjcFS9DFjs+59naVWJv1TB7qdOI=
github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI=
github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shirou/gopsutil/v4 v4.26.5 h1:RPcBXkpz7kOj9PqGFQOlBPZHsyaPvPVQc098y9RmCNM=
github.com/shirou/gopsutil/v4 v4.26.5/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ=
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c h1:aqg5Vm5dwtvL+YgDpBcK1ITf3o96N/K7/wsRXQnUTEs=
github.com/shurcooL/httpfs v0.0.0-20230704072500-f1e31cf0ba5c/go.mod h1:owqhoLW1qZoYLZzLnBw+QkPP9WZnjlSWihhxAJC1+/M=
github.com/shirou/gopsutil/v4 v4.26.6 h1:Mzr/npDtQC/xpeEuQKHZt8Zo9CmPvhTj8nkR8w5TLDs=
github.com/shirou/gopsutil/v4 v4.26.6/go.mod h1:LZ6ewCSkBqUpvSOf+LsTGnRinC6iaNUNMGBtDkJBaLQ=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92 h1:OfRzdxCzDhp+rsKWXuOO2I/quKMJ/+TQwVbIP/gltZg=
github.com/shurcooL/vfsgen v0.0.0-20230704071429-0000e147ea92/go.mod h1:7/OT02F6S6I7v6WXb+IjhMuZEYfH/RJ5RwEWnEo5BMg=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88=
@@ -1167,6 +1159,7 @@ github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
github.com/stretchr/objx v0.3.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4=
github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
@@ -1179,6 +1172,7 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc=
@@ -1189,14 +1183,14 @@ github.com/tchap/go-patricia/v2 v2.3.3 h1:xfNEsODumaEcCcY3gI0hYPZ/PcpVv5ju6RMAhg
github.com/tchap/go-patricia/v2 v2.3.3/go.mod h1:VZRHKAb53DLaG+nA9EaYYiaEx6YztwDlLElMsnSHD4k=
github.com/test-go/testify v1.1.4 h1:Tf9lntrKUMHiXQ07qBScBTSA0dhYQlu83hswqelv1iE=
github.com/test-go/testify v1.1.4/go.mod h1:rH7cfJo/47vWGdi4GPj16x3/t1xGOj2YxzmNQzk2ghU=
github.com/testcontainers/testcontainers-go v0.43.0 h1:oEQx5MW2DGd9z3AeEQfB2lPM0eLs7ztyaGRu75bFo5A=
github.com/testcontainers/testcontainers-go v0.43.0/go.mod h1:+VxkT2NQnKOZPKi6praMuMKYHYyOGXr0XSBSlSMCzFo=
github.com/testcontainers/testcontainers-go/modules/opensearch v0.43.0 h1:a1ipjF7d/VxPX1dgVPIk4F+t6YkgMbE2OtBuRQCHJt8=
github.com/testcontainers/testcontainers-go/modules/opensearch v0.43.0/go.mod h1:OWSeUDiGMUy30iMsAltIJIo9uh/CleLv6KyxjYOsgR8=
github.com/testcontainers/testcontainers-go v0.44.0 h1:/Fwh6HY1mIikhnm9e7HwoxGycx0lzRAE0f5VQpjFxzI=
github.com/testcontainers/testcontainers-go v0.44.0/go.mod h1:IcnwQrYTO86xHXu5bvMaBH7ATlbS3Qn1M1QWW3c66rE=
github.com/testcontainers/testcontainers-go/modules/opensearch v0.44.0 h1:iuBDo8U8Nwt0z+bxEmU+c7jS9hw81nPL9uGkkFOcXTo=
github.com/testcontainers/testcontainers-go/modules/opensearch v0.44.0/go.mod h1:8Qw29ffsCPzhomxqoeGhpj3J3Lbsrv0FsOUWeOjTl+I=
github.com/tetratelabs/wazero v1.12.0 h1:DuWcpNu/FzgEXgGBDp8J1Spc+CWOvvtvVyjKlaZopYU=
github.com/tetratelabs/wazero v1.12.0/go.mod h1:LvKtzl2RqO4gyF27BiXU+nKAjcV8f38U+kP/q2vgxh0=
github.com/thanhpk/randstr v1.0.6 h1:psAOktJFD4vV9NEVb3qkhRSMvYh4ORRaj1+w/hn4B+o=
github.com/thanhpk/randstr v1.0.6/go.mod h1:M/H2P1eNLZzlDwAzpkkkUvoyNNMbzRGhESZuEQk3r0U=
github.com/theckman/yacspin v0.13.12 h1:CdZ57+n0U6JMuh2xqjnjRq5Haj6v1ner2djtLQRzJr4=
github.com/theckman/yacspin v0.13.12/go.mod h1:Rd2+oG2LmQi5f3zC3yeZAOl245z8QOvrH4OPOJNZxLg=
github.com/thejerf/suture/v4 v4.0.6 h1:QsuCEsCqb03xF9tPAsWAj8QOAJBgQI1c0VqJNaingg8=
github.com/thejerf/suture/v4 v4.0.6/go.mod h1:gu9Y4dXNUWFrByqRt30Rm9/UZ0wzRSt9AJS6xu/ZGxU=
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
@@ -1211,10 +1205,10 @@ github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
github.com/tinylib/msgp v1.6.1 h1:ESRv8eL3u+DNHUoSAAQRE50Hm162zqAnBoGv9PzScPY=
github.com/tinylib/msgp v1.6.1/go.mod h1:RSp0LW9oSxFut3KzESt5Voq4GVWyS+PSulT77roAqEA=
github.com/tklauser/go-sysconf v0.3.16 h1:frioLaCQSsF5Cy1jgRBrzr6t502KIIwQ0MArYICU0nA=
github.com/tklauser/go-sysconf v0.3.16/go.mod h1:/qNL9xxDhc7tx3HSRsLWNnuzbVfh3e7gh/BmM179nYI=
github.com/tklauser/numcpus v0.11.0 h1:nSTwhKH5e1dMNsCdVBukSZrURJRoHbSEQjdEbY+9RXw=
github.com/tklauser/numcpus v0.11.0/go.mod h1:z+LwcLq54uWZTX0u/bGobaV34u6V7KNlTZejzM6/3MQ=
github.com/tklauser/go-sysconf v0.4.0 h1:7H0uAN+7RkwWRaxhYXDLqa5V3LPrJeV8wmD9dRUgPQU=
github.com/tklauser/go-sysconf v0.4.0/go.mod h1:8mTNWyog7H+MpKijp4VmKJAd2bbYQ2zuUwkYRbUArPI=
github.com/tklauser/numcpus v0.12.0 h1:NR85qdvHA9pFse3x3weVZ0r0ST8R6l5RHbZrlRaqob4=
github.com/tklauser/numcpus v0.12.0/go.mod h1:ABHeXzJnr/qqwguhClkZKT1/8VABcYrsyUiUGobwWJg=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208 h1:PM5hJF7HVfNWmCjMdEfbuOBNXSVF2cMFGgQTPdKCbwM=
github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208/go.mod h1:BzWtXXrXzZUvMacR0oF/fbDDgUPO8L36tDMmRAf14ns=
@@ -1233,8 +1227,8 @@ github.com/valyala/fastjson v1.6.10 h1:/yjJg8jaVQdYR3arGxPE2X5z89xrlhS0eGXdv+ADT
github.com/valyala/fastjson v1.6.10/go.mod h1:e6FubmQouUNP73jtMLmcbxS6ydWIpOfhz34TSfO3JaE=
github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/valyala/fasttemplate v1.1.0/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8=
github.com/vektah/gqlparser/v2 v2.5.34 h1:MEea5P0qhdcqfBL45ghKE+qr9laidVHTMHjav5h7ckk=
github.com/vektah/gqlparser/v2 v2.5.34/go.mod h1:mFdHLGCio7OGX1fby9ZjTW6FN+qxgmbnBcRIeeScE5s=
github.com/vektah/gqlparser/v2 v2.5.36 h1:CN9mKVHgMkc+XftdOWIhb4HEL8wKSYkFAqhf8booa7s=
github.com/vektah/gqlparser/v2 v2.5.36/go.mod h1:cAJ9qwVgPaUkWv6Gn8vn0mqOE0Ui5Pn56wNy5396XWo=
github.com/vinyldns/go-vinyldns v0.0.0-20200917153823-148a5f6b8f14/go.mod h1:RWc47jtnVuQv6+lY3c768WtXCas/Xi+U5UFc5xULmYg=
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
@@ -1280,12 +1274,12 @@ github.com/zeebo/xxh3 v1.1.0/go.mod h1:IisAie1LELR4xhVinxWS5+zf1lA4p0MW4T+w+W07F
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.etcd.io/bbolt v1.5.0 h1:S7GAl7Fxv12yohbwFfIbQCGDWbQbtDGPET4P/bD4lxU=
go.etcd.io/bbolt v1.5.0/go.mod h1:mkltfYE5aUHQxUct9N9V+Kp7aSjFqjgrhcXIS70Lrdk=
go.etcd.io/etcd/api/v3 v3.6.11 h1:XFGTgrJ8nak3kB4NgMG8t7NT+lEeuuvKQAqUHKVgkWQ=
go.etcd.io/etcd/api/v3 v3.6.11/go.mod h1:HYfTh0jyh+uFgp6gMbxJteIDYY97yMuYz85Rnw6Gy9o=
go.etcd.io/etcd/client/pkg/v3 v3.6.11 h1:e41mp315Yn3QMGPmEzCyLsMINgJXTY/dX8kM++1csxU=
go.etcd.io/etcd/client/pkg/v3 v3.6.11/go.mod h1:DysuMe/inqRyC/1tjRR6hReH/VV9Lufs27YKSKBWWJg=
go.etcd.io/etcd/client/v3 v3.6.11 h1:LAByD96VmmeuairkvdAcE0RZnrmGz/q3ceeWePo9bwc=
go.etcd.io/etcd/client/v3 v3.6.11/go.mod h1:vOTDMCo+fGPEClJqcFEFSqZ+8e7WKV7AyqJjX//HR2w=
go.etcd.io/etcd/api/v3 v3.6.13 h1:AvHPZv15LYEe7tZDyFglv7xnbiuF6GMZpZqKpIzXTt0=
go.etcd.io/etcd/api/v3 v3.6.13/go.mod h1:X9+3gaKwzjlOxzo6TZ2u3b7HcHBcAL+Ph7EBPjI/VWk=
go.etcd.io/etcd/client/pkg/v3 v3.6.13 h1:7QeMOisYByx8dBA7/CKcwCaPWfjb5C0xpmrIov/8WyY=
go.etcd.io/etcd/client/pkg/v3 v3.6.13/go.mod h1:Dn2zUBOCu/6xYcd6iAjB7LgoY16OTQjDZfWHLwvuQj4=
go.etcd.io/etcd/client/v3 v3.6.13 h1:0E+9ZYGpMsi9KlOJVoCdONh9PUDawKDTy5mSNY8wOEI=
go.etcd.io/etcd/client/v3 v3.6.13/go.mod h1:rtVI3vwobljb8xlTGcp1Yhz7hBIuBWULXwB848kqJGw=
go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
@@ -1300,28 +1294,28 @@ go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.69.0 h1:2yEATaop1/a1I4psnSLgWVPLWwCzkqWakgJy7xTDVy0=
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.69.0/go.mod h1:D7J12YRapIekYyPWgGPlA/23pRmpSEZC5xJC/TTLI9U=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0 h1:8tvICD4vSTOOsNrsI4Ljf6C+6UKvpTEH5XY3JMoyPoo=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0/go.mod h1:z9+yiacE0IHRqM4qFfkbt/JYlmYXgss8GY/jXoNuPJI=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.70.0 h1:LMuyCAyfalSjDyjdC65nK6N0zoTT63+E/u95X0JovZI=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.70.0/go.mod h1:085m8qbm4hgc8rZWGDEa4vmyyo2c3nPxUslYUKUIU04=
go.opentelemetry.io/contrib/zpages v0.69.0 h1:YQC1PumJq6lUGQNrLW14ID9a0dXSBcbC/aC6VRSIARU=
go.opentelemetry.io/contrib/zpages v0.69.0/go.mod h1:FGvUcMGN5atRzUIgUsqOi+MiMvlQsfbuYATBHPP4cGs=
go.opentelemetry.io/otel v1.44.0 h1:JjwHmHpA4iZ3wBxluu2fbbE7j4kqlE8jXyAyPXH7HqU=
go.opentelemetry.io/otel v1.44.0/go.mod h1:BMgjTHL9WPRlRjL2oZCBTL4whCGtXch2H4BhOPIAyYc=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 h1:4YsVu3B8+3qtWYYrsUYgn0OG78pN0rnNPRGX4SbokQI=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0/go.mod h1:+wnlSn0mD1ADVMe3v9Z/WIaiz6q6gL2J/ejaAmdmv80=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0 h1:qazEJlUOQzhCpzQpFETGby7EdqjI1wsd0W+6Gg1SCTU=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.44.0/go.mod h1:fOD2Yefuxixkx3ahVNf0O/PERb6r4OlbxfATVnYvzCo=
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.44.0 h1:bl2S7Ubua0Nms+D/gAmznQTd4dxxMA93aKbcpKqiTCs=
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.44.0/go.mod h1:L0hRV50XdVIODHUfWEqGRCXQvj2rV82STVo12FMFBU0=
go.opentelemetry.io/otel/metric v1.44.0 h1:1w0gILTcHdr3YI+ixLyjemwrVnsMURbTZFrSYCdDdmc=
go.opentelemetry.io/otel/metric v1.44.0/go.mod h1:8O7hanEPBNgEMmybD3s2VBKcgWOCsA6tzHBPODAiquo=
go.opentelemetry.io/otel/sdk v1.44.0 h1:nHYwb9lK+fJPU/dnT6s7W7Z8itMWyqrnVfbheVYrZ58=
go.opentelemetry.io/otel/sdk v1.44.0/go.mod h1:Osuydd3Se74nqjAKxid74N5eC+jfEqfTegHRnq58oK0=
go.opentelemetry.io/otel/sdk/metric v1.44.0 h1:3LlKgI+VjbVsjNRFZJZAJ30WjXC5VkNRks6si09iEfI=
go.opentelemetry.io/otel/sdk/metric v1.44.0/go.mod h1:5B5pMARnXxKhltooO4xUuCBorl65a4EpnTalObqOigA=
go.opentelemetry.io/otel/trace v1.44.0 h1:jxF5CsGYCe74MCRx2X4g7WsY/VBKRqqpNvXlX/6gtIk=
go.opentelemetry.io/otel/trace v1.44.0/go.mod h1:oLl1jrMQAVo6v3GAggN+1VH9VIz9iUSvW53sW1Q8PIE=
go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpuCSL2g=
go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk=
go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU=
go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0 h1:QRefszxJmfPdjXUUm3j6iDzY03mTPXMjqErFqQ67vUg=
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.45.0/go.mod h1:Tiz03lTBVBrm7eWZBOidzEaYaJa8tjwGUGv6d8mlTyk=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0 h1:fG5MCxGz8+2VtrN/WgqSpJFctVz24gpxj8CxkKmc8Ww=
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc v1.45.0/go.mod h1:BmAYTn+3ysbRe+IU2msxmf5Rx3g6DHvex+tWI3LdhYI=
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.45.0 h1:lsA/S1bxgdbyFGkTj+3meEdJ6ADVU7QoFstV6MXgE68=
go.opentelemetry.io/otel/exporters/stdout/stdouttrace v1.45.0/go.mod h1:L7u+MirGoB1bjeLH66+xDykF4RC8C3RN7lIFpBiewUo=
go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M=
go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s=
go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw=
go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA=
go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o=
go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA=
go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag=
go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc=
go.opentelemetry.io/proto/otlp v1.11.0 h1:5rrYs0Ykyj50sdU/JU0x8etU+LubXWb+gED6TbEdMIk=
go.opentelemetry.io/proto/otlp v1.11.0/go.mod h1:SmVizdCOAm3XBtG1g1NnOdhW6jtddT72hLMhv8VwA8E=
go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
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=
@@ -1360,8 +1354,8 @@ golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
golang.org/x/crypto v0.53.0 h1:QZ4Muo8THX6CizN2vPPd5fBGHyogrdK9fG4wLPFUsto=
golang.org/x/crypto v0.53.0/go.mod h1:DNLU434OwVakk9PzuwV8w62mAJpRJL3vsgcfp4Qnsio=
golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw=
golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@@ -1376,8 +1370,8 @@ golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJk
golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80=
golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js=
golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.43.0 h1:FLxcP4ec2350nTfOC8ysKtqYSIFbk/QGjw1ZHNP4tsY=
golang.org/x/image v0.43.0/go.mod h1:rrpelvGFt+kLPAjPM4HeWPgrl0FtafueU//e5N0qk/Q=
golang.org/x/image v0.44.0 h1:+tDekMZED9+LrtB3G5xzRggpVh9CARjZqROla3R3R+I=
golang.org/x/image v0.44.0/go.mod h1:V8K3KE9KKKE+pLpQDOeN18w9oacNSvy1tDOirTu4xtY=
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -1451,8 +1445,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
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.56.0 h1:Rw8j/hFzGvJUZwNBXnAtf5sVDVt+65SK2C7IxCxZt5o=
golang.org/x/net v0.56.0/go.mod h1:D3Ku6r+V6JROoZK144D2XfMHFcMq/0zSfLelVTCFKec=
golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE=
golang.org/x/net v0.57.0/go.mod h1:KpXc8iv+r3XplLAG/f7Jsf9RPszJzdR0f58q9vGOuEU=
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=
@@ -1476,8 +1470,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM=
golang.org/x/sync v0.21.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sync v0.22.0 h1:SZjpbeLmrCk4xhRSZFNZW5gFUeCeFgjekvI/+gfScek=
golang.org/x/sync v0.22.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
golang.org/x/sys v0.0.0-20180622082034-63fc586f45fe/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -1551,6 +1545,7 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -1558,8 +1553,8 @@ golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.18.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.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
golang.org/x/sys v0.47.0 h1:o7XGOvZQCADBQQ4Y7VNq2dRWQR7JmOUW8Kxx4ZsNgWs=
golang.org/x/sys v0.47.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
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=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@@ -1568,8 +1563,8 @@ golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
golang.org/x/term v0.44.0 h1:0rLvDRCtNj0gZkyIXhCyOb2OAzEhLVqc4B+hrsBhrmc=
golang.org/x/term v0.44.0/go.mod h1:7ze4MdzUzLXpSAoFP1H0bOI9aXDqveSvatT5vKcFh2Y=
golang.org/x/term v0.45.0 h1:NwWyBmoJCbfTHpxrWoZ9C6/VxOf7ic219I8xZZFdrf0=
golang.org/x/term v0.45.0/go.mod h1:9aqxs0blBcrm/n0L9QW0aRVD+ktan8ssZromtqJC43w=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -1582,8 +1577,8 @@ golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/text v0.39.0 h1:UbZz4pLOvn600D6Oh6GGEI6VAmndrEBLv8/6BEXzyus=
golang.org/x/text v0.39.0/go.mod h1:3UwRclnC2g0TU9x8PZiyfOajCd1zaUNHF9cvqcQZ+ZM=
golang.org/x/text v0.40.0 h1:Ub2Z6/xjgF1WrYQz2nuITOEegKFtiIy+rieRJ5lHZKs=
golang.org/x/text v0.40.0/go.mod h1:hpnzDAfGV753zIKo+wk3u1bVKCGPbrnF7+7LBF/UHVY=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -1646,8 +1641,6 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.47.0 h1:7Kn5x/d1svx/PzryTsqeoZN4TZwqeH5pGWjefhLi/1Q=
golang.org/x/tools v0.47.0/go.mod h1:dFHnyTvFWY212G+h7ZY4Vsp/K3U4/7W9TyVaAul8uCA=
golang.org/x/tools/godoc v0.1.0-deprecated h1:o+aZ1BOj6Hsx/GBdJO/s815sqftjSnrZZwyYTHODvtk=
golang.org/x/tools/godoc v0.1.0-deprecated/go.mod h1:qM63CriJ961IHWmnWa9CjZnBndniPt4a3CK0PVB9bIg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -1709,10 +1702,10 @@ google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7 h1:XzmzkmB14QhVhgnawEVsOn6OFsnpyxNPRY9QV01dNB0=
google.golang.org/genproto v0.0.0-20260319201613-d00831a3d3e7/go.mod h1:L43LFes82YgSonw6iTXTxXUX1OlULt4AQtkik4ULL/I=
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa h1:Kjn0N0tCrDgiAFW+lGO4JZ3ck44CehvJQMAwj9QF0G8=
google.golang.org/genproto/googleapis/api v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:q4lMZS6kskjT5HvCPrnnypcDPVJqT/f4nfxmkE7gryY=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa h1:mZHHdPZl0dbGHCflZgAq/Q468DWVFcU2whhB2KAo8fk=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d h1:FarXi840EJWSHYTN3ERkADbPWjl307+FGrA22KAVjjc=
google.golang.org/genproto/googleapis/api v0.0.0-20260803160001-6ac0973c030d/go.mod h1:K/+WGbmBY7aNW1HDw1fJnKYo10i0DkAX6pows00dLig=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d h1:IL4hdHzcUv2l/gcg98/Rj3FbtE6axwqslOW8SW0C+S0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20260803160001-6ac0973c030d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8=
google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.19.1/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
@@ -1728,8 +1721,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.82.0 h1:vguDnZUPjE26w09A63VoxZPnvPjB5Riyc0mkXPFmAIU=
google.golang.org/grpc v1.82.0/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA=
google.golang.org/grpc v1.83.0 h1:JeNZEKJFbQxArAMl+hiytHauacDNqJUllNfmIMmpqnQ=
google.golang.org/grpc v1.83.0/go.mod h1:kDyl6SKsiHKt0uylY5gtn5cEjkrIOhQOGDgIc4JGwzQ=
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=
@@ -1764,6 +1757,8 @@ gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.51.1/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.57.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.67.3 h1:iM9Lhz5MRSGhHVGGwCuzG9KO8PoirCXj/m/qTmOJJQw=
gopkg.in/ini.v1 v1.67.3/go.mod h1:x/cyOwCgZqOkJoDIJ3c1KNHMo10+nLGAhh+kn3Zizss=
gopkg.in/ns1/ns1-go.v2 v2.4.4/go.mod h1:GMnKY+ZuoJ+lVLL+78uSTjwTz2jMazq6AfGKQOYhsPk=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/square/go-jose.v2 v2.5.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
+133
View File
@@ -0,0 +1,133 @@
[tools]
go = "1.25"
node = "24"
pnpm = "11.1.3"
"go:github.com/go-delve/delve/cmd/dlv" = "1.27.0"
"aqua:nats-io/natscli" = "0.4.0"
[tasks.build]
description = "build"
run = "make -C opencloud build"
[tasks."build:debug"]
description = "build with debug symbols"
run = "make -C opencloud build-debug"
[tasks."docker:build"]
description = "docker image opencloudeu/opencloud:dev"
run = "make -C opencloud dev-docker"
[tasks."docker:build:multiarch"]
description = "docker image for amd64 + arm64"
depends = ["gen"]
run = "make -C opencloud dev-docker-multiarch"
[tasks."docker:build:debug"]
description = "docker image with delve"
run = "make -C opencloud debug-docker"
[tasks.serve]
description = "start the server"
depends = ["build"]
run = "opencloud/bin/opencloud server"
[tasks."serve:init"]
description = "create the local config"
depends = ["build"]
run = "opencloud/bin/opencloud init"
[tasks."serve:debug"]
description = "start the server under delve"
depends = ["build:debug"]
run = "dlv exec opencloud/bin/opencloud-debug -- server"
[tasks.test]
description = "go test"
run = "go test -tags disable_crypt ./..."
[tasks."test:changed"]
description = "go test, changed packages"
run = """
base=$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null || echo origin/main)
files=$(git diff --name-only --diff-filter=ACM $(git merge-base "$base" HEAD) -- '*.go' | grep -v vendor/ || true)
[ -n "$files" ] || exit 0
go test -tags disable_crypt $(echo "$files" | xargs -n1 dirname | sort -u | sed 's|^|./|')
"""
[tasks."test:race"]
description = "go test + race"
run = "go test -race -tags disable_crypt ./..."
[tasks."test:coverage"]
description = "go test + coverage"
run = ["make test", "make go-coverage"]
[tasks.check]
description = "all checks"
depends = ["check:fmt", "check:lint", "check:vendor", "check:env-vars", "test"]
[tasks."check:fmt"]
description = "gofmt"
run = """
base=$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null || echo origin/main)
files=$(git diff --name-only --diff-filter=ACM $(git merge-base "$base" HEAD) -- '*.go' | grep -v vendor/ || true)
[ -n "$files" ] || exit 0
out=$(gofmt -s -l $files)
[ -z "$out" ] || { echo "$out"; exit 1; }
"""
[tasks."check:lint"]
description = "golangci-lint"
run = """
set -e
base=$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null || echo origin/main)
gobin=$(go env GOBIN)
[ -n "$gobin" ] || gobin="$(go env GOPATH)/bin"
bin="$gobin/golangci-lint-$(awk '/golangci-lint v/ {print $3}' .bingo/golangci-lint.mod)"
[ -x "$bin" ] || make -s golangci-lint >/dev/null
exec "$bin" run --modules-download-mode vendor --timeout 15m0s --new-from-merge-base "$base"
"""
[tasks."check:vendor"]
description = "vendor matches go.mod"
run = "GOWORK=off go list -mod=vendor ./... >/dev/null"
[tasks."check:env-vars"]
description = "env var annotations"
run = "make check-env-var-annotations"
[tasks.fix]
description = "gofmt + lint fixes"
run = [{ task = "fix:fmt" }, { task = "fix:lint" }]
[tasks."fix:fmt"]
description = "gofmt -w"
run = """
base=$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null || echo origin/main)
files=$(git diff --name-only --diff-filter=ACM $(git merge-base "$base" HEAD) -- '*.go' | grep -v vendor/ || true)
[ -z "$files" ] || gofmt -s -w $files
"""
[tasks."fix:lint"]
description = "golangci-lint --fix"
run = "make golangci-lint-fix"
[tasks."pre:commit"]
description = "before commit"
run = [{ task = "fix:fmt" }, { task = "check:lint" }, { task = "test:changed" }]
[tasks."pre:push"]
description = "before push"
run = [{ task = "tidy" }, { task = "fix:fmt" }, { task = "check" }]
[tasks.gen]
description = "assets & mocks"
run = "make generate"
[tasks."gen:protobuf"]
description = "protobuf"
run = "make protobuf"
[tasks.tidy]
description = "tidy + vendor"
run = ["GOWORK=off go mod tidy", "GOWORK=off go mod vendor"]
+4 -1
View File
@@ -11,7 +11,10 @@ RUN --mount=type=bind,target=/build,rw \
--mount=type=cache,target=/go/pkg/mod \
--mount=type=cache,target=/root/.cache \
GOOS="${TARGETOS:-linux}" GOARCH="${TARGETARCH:-amd64}" ; \
make -C ${SRCDIR:-.}/opencloud release-linux-docker-${TARGETARCH} ENABLE_VIPS=true DIST=/dist
make -C ${SRCDIR:-.}/opencloud release-linux-docker-${TARGETARCH} \
ENABLE_VIPS=true DIST=/dist \
VERSION="${VERSION}" EDITION="${EDITION}" \
${STRING:+STRING="${STRING}"}
FROM alpine:3.24
ARG VERSION
+273 -446
View File
@@ -1,17 +1,16 @@
package command
import (
"bufio"
"fmt"
"os"
"path/filepath"
"strings"
"time"
"github.com/opencloud-eu/opencloud/opencloud/pkg/register"
"github.com/opencloud-eu/opencloud/pkg/config"
"github.com/opencloud-eu/opencloud/pkg/config/configlog"
"github.com/opencloud-eu/opencloud/pkg/config/parser"
"github.com/opencloud-eu/opencloud/pkg/x/path/filepathx"
storageUsersParser "github.com/opencloud-eu/opencloud/services/storage-users/pkg/config/parser"
"github.com/opencloud-eu/opencloud/services/storage-users/pkg/event"
"github.com/opencloud-eu/opencloud/services/storage-users/pkg/revaconfig"
@@ -19,27 +18,10 @@ import (
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/ignore"
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/options"
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/registry"
"github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/prefixes"
"github.com/pkg/xattr"
"github.com/rs/zerolog"
"github.com/spf13/cobra"
"github.com/theckman/yacspin"
"github.com/vmihailenco/msgpack/v5"
)
// Define the names of the extended attributes we are working with.
const (
parentIDAttrName = "user.oc.parentid"
idAttrName = "user.oc.id"
nameAttrName = "user.oc.name"
spaceIDAttrName = "user.oc.space.id"
ownerIDAttrName = "user.oc.owner.id"
)
var (
spinner *yacspin.Spinner
restartRequired = false
ignorer *ignore.Ignorer
)
type IDCacher interface {
@@ -73,11 +55,23 @@ func init() {
// scanCmd performs a posixfs id cache warmup scan
func scanCmd(ocCfg *config.Config) *cobra.Command {
cmd := &cobra.Command{
Use: "scan",
scanCmd := &cobra.Command{
Use: "scan [path ...]",
Short: "Perform a filesystem scan and update the ID and filemetadata cache",
PreRunE: func(cmd *cobra.Command, args []string) error {
Long: `Perform a filesystem scan and update the ID and filemetadata cache.
You can specify one or more paths to limit the scope of the scan.
If no path is provided, the whole storage is checked, starting at the storage root directory.
The provided arguments determines the scope of the check:
- a storage root: the whole storage (all personal and project spaces) is scanned
- a space root: only that space is scanned
- a file or directory: only that single resource is scanned (and its children, if it is a directory)
Any specified file or directory must be underneath the storage root directory and if that is not the case,
the command is aborted with an error before performing any scanning.`,
Args: cobra.ArbitraryArgs,
PreRunE: func(cmd *cobra.Command, args []string) error {
if err := parser.ParseConfig(ocCfg, true); err != nil {
return configlog.ReturnError(err)
}
@@ -94,448 +88,281 @@ func scanCmd(ocCfg *config.Config) *cobra.Command {
os.Exit(1)
}
// We want to initialize the driver but disable scanfs on boot, so we can trigger it manually afterwards
drivers := revaconfig.StorageProviderDrivers(cfg)
drivers["posix"] = revaconfig.Posix(cfg, false, false)
var fsStream events.Stream
var err error
fsStream, err = event.NewStream(cfg)
haltOnError, err := cmd.Flags().GetBool("halt-on-error")
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to create event stream for posix driver: %v\n", err)
os.Exit(1)
}
f, ok := registry.NewFuncs["posix"]
if !ok {
fmt.Fprintf(os.Stderr, "posix driver not found in registry\n")
os.Exit(1)
}
fs, err := f(drivers["posix"].(map[string]any), fsStream, nil)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to initialize filesystem driver '%s': %v\n", cfg.Driver, err)
return err
}
cacher, ok := fs.(IDCacher)
if !ok {
fmt.Fprintf(os.Stderr, "The posix driver does not expose WarmupIDCache.\n")
os.Exit(1)
storageRoot := cfg.Drivers.Posix.Root
paths := []string{storageRoot}
if len(args) > 0 {
paths = []string{}
for _, v := range args {
path := v
if !filepath.IsAbs(path) {
if v, err := filepath.Abs(path); err != nil {
fmt.Fprintf(os.Stderr, "Failed to make the specified path %q absolute: %v\n", v, err)
os.Exit(1)
} else {
path = v
}
}
// not ensuring whether the path is under the storage root here, will be done when iterating over them
path = filepath.Clean(path)
paths = append(paths, path)
}
}
fmt.Println("Starting posixfs scan...")
err = cacher.WarmupIDCache(cfg.Drivers.Posix.Root, true, false)
if err != nil {
fmt.Fprintf(os.Stderr, "Scan failed: %v\n", err)
return err
var scan func(path string) error = nil
{
// We want to initialize the driver but disable scanfs on boot, so we can trigger it manually afterwards
drivers := revaconfig.StorageProviderDrivers(cfg)
drivers["posix"] = revaconfig.Posix(cfg, false, false)
var fsStream events.Stream
var err error
fsStream, err = event.NewStream(cfg)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to create event stream for posix driver: %v\n", err)
os.Exit(1)
}
log := logger("posixfs")
f, ok := registry.NewFuncs["posix"]
if !ok {
fmt.Fprintf(os.Stderr, "posix driver not found in registry\n")
os.Exit(1)
}
fs, err := f(drivers["posix"].(map[string]any), fsStream, &log)
if err != nil {
fmt.Fprintf(os.Stderr, "Failed to initialize filesystem driver '%s': %v\n", cfg.Driver, err)
return err
}
cacher, ok := fs.(IDCacher)
if !ok {
fmt.Fprintf(os.Stderr, "The posix driver does not expose WarmupIDCache.\n")
os.Exit(1)
}
scan = func(path string) error {
err := cacher.WarmupIDCache(path, true, false)
if err != nil {
logFailure("Error scanning path '%s': %v", path, err)
}
return err
}
}
fmt.Println("Scan completed successfully.")
return nil
errors := processPosixFsResources(paths, !haltOnError,
func(path string) error {
fmt.Println("Scanning personal spaces...")
return scan(path)
},
func(path string) error {
fmt.Println("Scanning project spaces...")
return scan(path)
},
func(path string) error {
fmt.Printf("Scanning space '%s'...\n", path)
return scan(path)
},
func(path string) error {
fmt.Printf("Scanning '%s'...\n", path)
return scan(path)
},
)
if len(errors) == 0 {
fmt.Println("Scan completed successfully.")
return nil
} else {
plural := "s"
if len(errors) == 1 {
plural = ""
}
verb := "completed"
if haltOnError {
verb = "aborted"
}
return fmt.Errorf("scan %s with %d error%s", verb, len(errors), plural)
}
},
}
return cmd
scanCmd.Flags().BoolP("halt-on-error", "E", false, "Halt at once when an error occurs when processing one of the paths (default behaviour is to keep going and attempt to process all paths).")
return scanCmd
}
// consistencyCmd returns a command to check the consistency of the posixfs storage.
func consistencyCmd(cfg *config.Config) *cobra.Command {
func consistencyCmd(ocCfg *config.Config) *cobra.Command {
consCmd := &cobra.Command{
Use: "consistency",
Short: "check the consistency of the posixfs storage",
Use: "consistency [path ...]",
Short: "Check the consistency of the posixfs storage",
Long: `Check the consistency of the posixfs storage.
You can specify one or more paths to limit the scope of the check.
If no path is provided, the whole storage is checked.
The provided arguments determines the scope of the check:
- a storage root: the whole storage (all personal and project spaces) is checked
- a space root: only that space is checked
- a file or directory: only that single entity is checked (and its children, if it is a directory)`,
Args: cobra.ArbitraryArgs,
PreRunE: func(cmd *cobra.Command, args []string) error {
if err := parser.ParseConfig(ocCfg, true); err != nil {
return configlog.ReturnError(err)
}
// Parse storage users config
ocCfg.StorageUsers.Commons = ocCfg.Commons
return configlog.ReturnFatal(storageUsersParser.ParseConfig(ocCfg.StorageUsers))
},
RunE: func(cmd *cobra.Command, args []string) error {
return checkPosixfsConsistency(cmd, cfg)
cfg := ocCfg.StorageUsers
if len(args) == 0 {
args = []string{cfg.Drivers.Posix.Root}
}
log := logger("posixfs")
recalculateChecksums, err := cmd.Flags().GetBool("fix-checksums")
if err != nil {
return err
}
drivers := revaconfig.StorageProviderDrivers(cfg)
drivers["posix"] = revaconfig.Posix(cfg, false, false)
opts, err := options.New(drivers["posix"].(map[string]any))
if err != nil {
return err
}
ignorer := ignore.NewIgnorer(opts, &log)
checker := &consistencyChecker{
cfg: cfg,
ignorer: ignorer,
recalculateChecksums: recalculateChecksums,
}
return checker.Check(args)
},
}
consCmd.Flags().StringP("root", "r", "", "Path to the root directory of the posixfs storage")
_ = consCmd.MarkFlagRequired("root")
consCmd.Flags().Bool("fix-checksums", false, "Recalculate and fix the file checksums. This reads every file and can be slow on large storages.")
return consCmd
}
// checkPosixfsConsistency checks the consistency of the posixfs storage.
func checkPosixfsConsistency(cmd *cobra.Command, cfg *config.Config) error {
rootPath, _ := cmd.Flags().GetString("root")
indexesPath := filepath.Join(rootPath, "indexes")
opt, _ := options.New(map[string]interface{}{
"root": rootPath,
})
log := zerolog.Nop()
ignorer = ignore.NewIgnorer(opt, &log)
_, err := os.Stat(indexesPath)
if err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("consistency check failed: '%s' is not a posixfs root", rootPath)
}
return fmt.Errorf("error accessing '%s': %w", indexesPath, err)
}
spinnerCfg := yacspin.Config{
Frequency: 100 * time.Millisecond,
CharSet: yacspin.CharSets[11],
StopCharacter: "✓",
StopColors: []string{"fgGreen"},
StopFailCharacter: "✗",
StopFailColors: []string{"fgRed"},
}
spinner, err = yacspin.New(spinnerCfg)
err = spinner.Start()
if err != nil {
return fmt.Errorf("error creating spinner: %w", err)
}
checkSpaces(filepath.Join(rootPath, "users"))
spinner.Suffix(" Personal spaces check ")
spinner.StopMessage("completed\n")
spinner.Stop()
checkSpaces(filepath.Join(rootPath, "projects"))
spinner.Suffix(" Project spaces check ")
spinner.StopMessage("completed")
spinner.Stop()
if restartRequired {
fmt.Println("\n\n ⚠️ Please restart your openCloud instance to apply changes.")
}
return nil
}
func checkSpaces(basePath string) {
dirEntries, err := os.ReadDir(basePath)
if err != nil {
spinner.Message(fmt.Sprintf("Error reading spaces directory '%s'\n", basePath))
spinner.StopFail()
return
}
for _, entry := range dirEntries {
if entry.IsDir() {
fullPath := filepath.Join(basePath, entry.Name())
checkSpace(fullPath)
}
}
}
func checkSpace(spacePath string) {
spinner.Message("")
spinner.Suffix(fmt.Sprintf(" Checking space '%s'", spacePath))
info, err := os.Stat(spacePath)
if err != nil {
logFailure("Error accessing path '%s': %v", spacePath, err)
return
}
if !info.IsDir() {
logFailure("Error: The provided path '%s' is not a directory\n", spacePath)
return
}
spaceID, err := xattr.Get(spacePath, spaceIDAttrName)
if err != nil || len(spaceID) == 0 {
logFailure("Error: The directory '%s' does not seem to be a space root, it's missing the '%s' attribute\n", spacePath, spaceIDAttrName)
return
}
checkSpaceID(spacePath)
checkNodeIDs(spacePath)
}
func checkSpaceID(spacePath string) {
spinner.Message(" - checking space ID uniqueness")
entries, uniqueIDs, oldestEntry, err := gatherAttributes(spacePath)
if err != nil {
logFailure("Failed to gather attributes: %v", err)
return
}
if len(entries) == 0 {
return
}
if len(uniqueIDs) > 1 {
spinner.Pause()
fmt.Println("\n ⚠ Multiple space IDs found:")
for id := range uniqueIDs {
fmt.Printf(" - %s\n", id)
}
fmt.Printf("\n ⏳ Oldest entry is '%s' (modified on %s).\n",
filepath.Base(oldestEntry.Path), oldestEntry.ModTime.Format(time.RFC1123))
targetID := oldestEntry.ParentID
fmt.Printf(" ✅ Proposed target Parent ID: %s\n", targetID)
fmt.Printf("\n Do you want to unify all parent IDs to '%s'? This will modify %d entries, the directory, and the user index. (y/N): ", targetID, len(entries))
reader := bufio.NewReader(os.Stdin)
input, _ := reader.ReadString('\n')
input = strings.TrimSpace(strings.ToLower(input))
if input != "y" {
spinner.Unpause()
logFailure("Operation cancelled by user.")
return
}
restartRequired = true
obsoleteIDs := []string{}
for id := range uniqueIDs {
if id != targetID {
obsoleteIDs = append(obsoleteIDs, id)
}
}
fixSpaceID(spacePath, obsoleteIDs, targetID, entries)
spinner.Unpause()
}
}
func walkNodes(dir string, parentID string) int {
fixes := 0
entries, err := os.ReadDir(dir)
if err != nil {
logFailure("Error reading directory '%s': %v", dir, err)
return 0
}
for _, entry := range entries {
fullPath := filepath.Join(dir, entry.Name())
if ignorer.IsIgnored(fullPath) {
continue
}
// Check if the parent ID attribute matches the expected parent ID, if not, fix it.
actualParentID, err := xattr.Get(fullPath, parentIDAttrName)
if err != nil || string(actualParentID) != parentID {
err = xattr.Set(fullPath, parentIDAttrName, []byte(parentID))
if err != nil {
logFailure("Failed to fix parent ID for '%s': %v", fullPath, err)
} else {
spinner.Pause()
fmt.Printf(" + Fixed parent ID for '%s'", fullPath)
spinner.Unpause()
fixes++
restartRequired = true
}
}
// Check that the name attribute matches the actual name of the file/directory, if not, fix it.
nameAttr, err := xattr.Get(fullPath, nameAttrName)
if err != nil || string(nameAttr) != entry.Name() {
err = xattr.Set(fullPath, nameAttrName, []byte(entry.Name()))
if err != nil {
logFailure("Failed to fix name attribute for '%s': %v", fullPath, err)
} else {
spinner.Pause()
fmt.Printf(" + Fixed name attribute for '%s'", fullPath)
spinner.Unpause()
fixes++
restartRequired = true
}
}
if entry.IsDir() {
nodeID, err := xattr.Get(fullPath, idAttrName)
if err != nil || len(nodeID) == 0 {
logFailure("Directory '%s' missing '%s', skipping its children", fullPath, idAttrName)
continue
}
walkNodes(fullPath, string(nodeID))
}
}
return fixes
}
func checkNodeIDs(spacePath string) {
spinner.Message(" - checking nodes")
rootID, err := xattr.Get(spacePath, idAttrName)
if err != nil || len(rootID) == 0 {
logFailure("Space root '%s' missing '%s' attribute", spacePath, idAttrName)
return
}
fixes := walkNodes(spacePath, string(rootID))
if fixes > 0 {
spinner.Pause()
fmt.Printf("\n ✓ Fixed %d incorrect node attributes in %s\n", fixes, filepath.Base(spacePath))
spinner.Unpause()
}
}
func fixSpaceID(spacePath string, obsoleteIDs []string, targetID string, entries []EntryInfo) {
// Set all parentid attributes to the proper space ID
err := setAllParentIDAttributes(entries, targetID)
if err != nil {
logFailure("an error occurred during file attribute update: %v", err)
return
}
// Update space ID itself
fmt.Printf(" Updating directory '%s' with attribute '%s' -> %s\n", filepath.Base(spacePath), idAttrName, targetID)
err = xattr.Set(spacePath, idAttrName, []byte(targetID))
if err != nil {
logFailure("Failed to set attribute on directory '%s': %v", spacePath, err)
return
}
err = xattr.Set(spacePath, spaceIDAttrName, []byte(targetID))
if err != nil {
logFailure("Failed to set attribute on directory '%s': %v", spacePath, err)
return
}
// update the index
err = updateOwnerIndexFile(spacePath, obsoleteIDs)
if err != nil {
logFailure("Could not update the owner index file: %v", err)
}
}
func gatherAttributes(path string) ([]EntryInfo, map[string]struct{}, EntryInfo, error) {
dirEntries, err := os.ReadDir(path)
if err != nil {
return nil, nil, EntryInfo{}, fmt.Errorf("failed to read directory: %w", err)
}
var allEntries []EntryInfo
uniqueIDs := make(map[string]struct{})
var oldestEntry EntryInfo
oldestTime := time.Now().Add(100 * 365 * 24 * time.Hour) // Set to a future date to find the oldest entry
for _, entry := range dirEntries {
fullPath := filepath.Join(path, entry.Name())
if ignorer.IsIgnored(fullPath) {
continue
}
info, err := os.Stat(fullPath)
if err != nil {
fmt.Printf(" - Warning: could not stat %s: %v\n", entry.Name(), err)
continue
}
parentID, err := xattr.Get(fullPath, parentIDAttrName)
if err != nil {
continue // Skip if attribute doesn't exist or can't be read
}
entryInfo := EntryInfo{
Path: fullPath,
ModTime: info.ModTime(),
ParentID: string(parentID),
}
allEntries = append(allEntries, entryInfo)
uniqueIDs[string(parentID)] = struct{}{}
if entryInfo.ModTime.Before(oldestTime) {
oldestTime = entryInfo.ModTime
oldestEntry = entryInfo
}
}
return allEntries, uniqueIDs, oldestEntry, nil
}
func setAllParentIDAttributes(entries []EntryInfo, targetID string) error {
fmt.Printf(" Setting all parent IDs to '%s':\n", targetID)
for _, entry := range entries {
if entry.ParentID == targetID {
fmt.Printf(" - Skipping '%s' (already has target ID).\n", filepath.Base(entry.Path))
continue
}
fmt.Printf(" - Removing all attributes from '%s'. It will be re-assimilated\n", filepath.Base(entry.Path))
filepath.WalkDir(entry.Path, func(path string, d os.DirEntry, err error) error {
if err != nil {
return fmt.Errorf("error walking path '%s': %w", path, err)
}
// Remove all attributes from the file.
if err := removeAttributes(path); err != nil {
fmt.Printf("failed to remove attributes from '%s': %v", path, err)
}
return nil
})
}
return nil
}
// updateOwnerIndexFile handles the logic of reading, modifying, and writing the MessagePack index file.
func updateOwnerIndexFile(basePath string, obsoleteIDs []string) error {
fmt.Printf(" Rewriting index file '%s'\n", basePath)
ownerID, err := xattr.Get(basePath, ownerIDAttrName)
if err != nil {
return fmt.Errorf("could not get owner ID from oldest entry '%s' to find index: %w", basePath, err)
}
indexPath := filepath.Join(basePath, "../../indexes/by-user-id", string(ownerID)+".mpk")
indexPath = filepath.Clean(indexPath)
// Read the MessagePack file
fileData, err := os.ReadFile(indexPath)
if err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("index file does not exist, skipping update")
}
return fmt.Errorf("could not read index file: %w", err)
}
var indexMap map[string]string
if err := msgpack.Unmarshal(fileData, &indexMap); err != nil {
return fmt.Errorf("failed to parse MessagePack index file (is it corrupt?): %w", err)
}
// Remove obsolete IDs from the map
itemsRemoved := 0
for _, id := range obsoleteIDs {
if _, exists := indexMap[id]; exists {
fmt.Printf(" - Removing obsolete ID '%s' from index.\n", id)
delete(indexMap, id)
itemsRemoved++
} else {
fmt.Printf(" - Obsolete ID '%s' not found in index\n", id)
}
}
if itemsRemoved == 0 {
return nil
}
// Write the data back to the file
updatedData, err := msgpack.Marshal(&indexMap)
if err != nil {
return fmt.Errorf("failed to marshal updated index map: %w", err)
}
if err := os.WriteFile(indexPath, updatedData, 0644); err != nil {
return fmt.Errorf("failed to write updated index file: %w", err)
}
fmt.Printf(" ✓ Successfully removed %d item(s) and saved index file.\n", itemsRemoved)
return nil
}
func removeAttributes(path string) error {
attrNames, err := xattr.List(path)
if err != nil {
return fmt.Errorf("failed to list attributes for '%s': %w", path, err)
}
for _, attrName := range attrNames {
if err := xattr.Remove(path, attrName); err != nil {
return fmt.Errorf("failed to remove attribute '%s' from '%s': %w", attrName, path, err)
}
}
return nil
}
func logFailure(message string, args ...any) {
spinner.StopFailMessage(fmt.Sprintf("\n"+message, args...))
spinner.StopFail()
spinner.Start()
fmt.Fprintf(os.Stderr, message+"\n", args...)
}
// findStorageRoot walks up the directory tree starting at path until it finds a
// directory that contains an "indexes" subdirectory which marks the root of a
// posixfs storage. A user directory inside a space might also be named "indexes",
// so to disambiguate we require that the "indexes" directory is an internal
// directory: the storage's own indexes directory is skipped during assimilation
// and therefore never receives a node ID attribute, whereas a regular user
// directory would have one.
func findStorageRoot(path string) (string, error) {
current := path
for {
indexesPath := filepath.Join(current, "indexes")
if info, err := os.Stat(indexesPath); err == nil && info.IsDir() {
if id, err := xattr.Get(indexesPath, prefixes.IDAttr); err != nil || len(id) == 0 {
return current, nil
}
}
parent := filepath.Dir(current)
if parent == current {
return "", fmt.Errorf("'%s' does not appear to be inside a posixfs storage (no 'indexes' directory found)", path)
}
current = parent
}
}
// isSpaceRoot reports whether the given path is a space root, which is
// identified by the presence of the space ID attribute.
func isSpaceRoot(path string) bool {
spaceID, err := xattr.Get(path, prefixes.SpaceIDAttr)
return err == nil && len(spaceID) > 0
}
// iterates over a list of paths and processes them all, using the appropriate function
// depending on the type of resource
//
// note that whenever an error occurs, it collects that error and continues processing
// subsequent paths, and then returns a slice of errors at the end (or an empty slice
// if no errors occured)
func processPosixFsResources(paths []string,
keepGoing bool,
personalSpaceDir func(string) error,
projectSpaceDir func(string) error,
spaceRoot func(string) error,
entity func(string) error,
) []error {
// no need to guard this with a mutex for now, since the implementation is not parallelized
errors := []error{}
for _, path := range paths {
rootPath, err := findStorageRoot(path)
if err != nil {
errors = append(errors, err)
logFailure("error: %s", err)
if keepGoing {
continue
} else {
return errors
}
}
path = filepath.Clean(path)
if _, err := os.Stat(path); err != nil {
errors = append(errors, err)
logFailure("error accessing '%s': %w", path, err)
if keepGoing {
continue
} else {
return errors
}
}
contained, _ := filepathx.IsSameOrContainedBy(rootPath, path)
switch {
case path == rootPath:
if err := personalSpaceDir(filepath.Join(path, "users")); err != nil {
errors = append(errors, err)
if !keepGoing {
return errors
}
}
if err := projectSpaceDir(filepath.Join(path, "projects")); err != nil {
errors = append(errors, err)
if !keepGoing {
return errors
}
}
case isSpaceRoot(path):
if err := spaceRoot(path); err != nil {
errors = append(errors, err)
if !keepGoing {
return errors
}
}
case contained:
if err := entity(path); err != nil {
errors = append(errors, err)
if !keepGoing {
return errors
}
}
default:
err := fmt.Errorf("error: the provided path '%s' is neither a space root nor contained by the storage root '%s'", path, rootPath)
errors = append(errors, err)
logFailure(err.Error())
if !keepGoing {
return errors
}
}
}
return errors
}
@@ -0,0 +1,489 @@
// Copyright 2026 OpenCloud GmbH <mail@opencloud.eu>
// SPDX-License-Identifier: Apache-2.0
package command
import (
"bufio"
"bytes"
"context"
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"time"
storageUsersConfig "github.com/opencloud-eu/opencloud/services/storage-users/pkg/config"
"github.com/opencloud-eu/reva/v2/pkg/storage/fs/posix/ignore"
"github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/metadata/prefixes"
"github.com/opencloud-eu/reva/v2/pkg/storage/pkg/decomposedfs/node"
"github.com/pkg/xattr"
"github.com/shamaton/msgpack/v2"
)
type consistencyChecker struct {
cfg *storageUsersConfig.Config
ignorer *ignore.Ignorer
recalculateChecksums bool
restartRequired bool
}
// checkPosixfsConsistency checks the consistency of the posixfs storage. The
// given path determines the scope of the check: the whole storage, a single
// space or a single entity within a space.
func (c *consistencyChecker) Check(paths []string) error {
_ = processPosixFsResources(paths, true,
func(path string) error {
fmt.Println("Checking personal spaces...")
c.checkSpaces(path)
return nil
},
func(path string) error {
fmt.Println("Checking project spaces...")
c.checkSpaces(path)
return nil
},
func(path string) error {
fmt.Printf("Checking space '%s'...\n", path)
c.checkSpace(path)
return nil
},
func(path string) error {
if c.ignorer.IsIgnored(path) {
return nil
}
fmt.Printf("Checking '%s'...\n", path)
c.checkEntity(path)
return nil
},
)
if c.restartRequired {
fmt.Println("\n\n ⚠️ Please restart your openCloud instance to apply changes.")
}
return nil
}
func (c *consistencyChecker) checkSpaces(basePath string) {
dirEntries, err := os.ReadDir(basePath)
if err != nil {
logFailure("Error reading spaces directory '%s': %v", basePath, err)
return
}
for _, entry := range dirEntries {
if entry.IsDir() {
fullPath := filepath.Join(basePath, entry.Name())
c.checkSpace(fullPath)
}
}
}
func (c *consistencyChecker) checkSpace(spacePath string) {
info, err := os.Stat(spacePath)
if err != nil {
logFailure("Error accessing path '%s': %v", spacePath, err)
return
}
if !info.IsDir() {
logFailure("Error: The provided path '%s' is not a directory\n", spacePath)
return
}
spaceID, err := xattr.Get(spacePath, prefixes.SpaceIDAttr)
if err != nil || len(spaceID) == 0 {
logFailure("Error: The directory '%s' does not seem to be a space root, it's missing the '%s' attribute\n", spacePath, prefixes.SpaceIDAttr)
return
}
c.checkSpaceID(spacePath)
c.checkNodes(spacePath)
}
func (c *consistencyChecker) checkSpaceID(spacePath string) {
entries, uniqueIDs, oldestEntry, err := c.gatherAttributes(spacePath)
if err != nil {
logFailure("Failed to gather attributes: %v", err)
return
}
if len(entries) == 0 {
return
}
if len(uniqueIDs) > 1 {
fmt.Println("\n ⚠ Multiple space IDs found:")
for id := range uniqueIDs {
fmt.Printf(" - %s\n", id)
}
fmt.Printf("\n ⏳ Oldest entry is '%s' (modified on %s).\n",
filepath.Base(oldestEntry.Path), oldestEntry.ModTime.Format(time.RFC1123))
targetID := oldestEntry.ParentID
fmt.Printf(" ✅ Proposed target Parent ID: %s\n", targetID)
fmt.Printf("\n Do you want to unify all parent IDs to '%s'? This will modify %d entries, the directory, and the user index. (y/N): ", targetID, len(entries))
reader := bufio.NewReader(os.Stdin)
input, _ := reader.ReadString('\n')
input = strings.TrimSpace(strings.ToLower(input))
if input != "y" {
logFailure("Operation cancelled by user.")
return
}
c.restartRequired = true
obsoleteIDs := []string{}
for id := range uniqueIDs {
if id != targetID {
obsoleteIDs = append(obsoleteIDs, id)
}
}
c.fixSpaceID(spacePath, obsoleteIDs, targetID, entries)
}
}
func (c *consistencyChecker) walkNodes(dir string, parentID string) int {
fixes := 0
entries, err := os.ReadDir(dir)
if err != nil {
logFailure("Error reading directory '%s': %v", dir, err)
return 0
}
for _, entry := range entries {
fullPath := filepath.Join(dir, entry.Name())
if c.ignorer.IsIgnored(fullPath) {
continue
}
fixes += c.checkNodeAttributes(fullPath, entry.Name(), parentID, entry.IsDir())
if entry.IsDir() {
nodeID, err := xattr.Get(fullPath, prefixes.IDAttr)
if err != nil || len(nodeID) == 0 {
logFailure("Directory '%s' missing '%s', skipping its children", fullPath, prefixes.IDAttr)
continue
}
fixes += c.walkNodes(fullPath, string(nodeID))
}
}
return fixes
}
// checkNodeAttributes checks and fixes the parent ID and name attributes of a
// single node. For files it additionally checks the blobsize and, when
// requested, the checksums. It returns the number of fixes applied.
func (c *consistencyChecker) checkNodeAttributes(path, name, parentID string, isDir bool) int {
fixes := 0
// Check if the parent ID attribute matches the expected parent ID, if not, fix it.
actualParentID, err := xattr.Get(path, prefixes.ParentidAttr)
if err != nil || string(actualParentID) != parentID {
if err := xattr.Set(path, prefixes.ParentidAttr, []byte(parentID)); err != nil {
logFailure("Failed to fix parent ID for '%s': %v", path, err)
} else {
fmt.Printf(" + Fixed parent ID for '%s'\n", path)
fixes++
c.restartRequired = true
}
}
// Check that the name attribute matches the actual name of the file/directory, if not, fix it.
nameAttr, err := xattr.Get(path, prefixes.NameAttr)
if err != nil || string(nameAttr) != name {
if err := xattr.Set(path, prefixes.NameAttr, []byte(name)); err != nil {
logFailure("Failed to fix name attribute for '%s': %v", path, err)
} else {
fmt.Printf(" + Fixed name attribute for '%s'\n", path)
fixes++
c.restartRequired = true
}
}
if !isDir {
fixes += c.checkBlobsize(path)
if c.recalculateChecksums {
fixes += c.fixChecksums(path)
}
}
return fixes
}
// checkEntity checks a single file or directory within a space, including its own
// parent ID, name and (for files) blobsize/checksums. If the entity is a directory
// its children are checked recursively.
func (c *consistencyChecker) checkEntity(path string) {
info, err := os.Stat(path)
if err != nil {
logFailure("Error accessing path '%s': %v", path, err)
return
}
// The expected parent ID is the ID attribute of the containing directory.
parentDir := filepath.Dir(path)
parentID, err := xattr.Get(parentDir, prefixes.IDAttr)
if err != nil || len(parentID) == 0 {
logFailure("Parent directory '%s' is missing the '%s' attribute", parentDir, prefixes.IDAttr)
return
}
fixes := c.checkNodeAttributes(path, info.Name(), string(parentID), info.IsDir())
if info.IsDir() {
nodeID, err := xattr.Get(path, prefixes.IDAttr)
if err != nil || len(nodeID) == 0 {
logFailure("Directory '%s' missing '%s' attribute", path, prefixes.IDAttr)
} else {
fixes += c.walkNodes(path, string(nodeID))
}
}
if fixes > 0 {
fmt.Printf(" ✓ Fixed %d incorrect node attributes for %s\n", fixes, filepath.Base(path))
}
}
// checkBlobsize verifies that the stored blobsize attribute matches the actual
// file size and fixes it if it doesn't. It returns the number of fixes applied.
func (c *consistencyChecker) checkBlobsize(path string) int {
info, err := os.Stat(path)
if err != nil {
logFailure("Error accessing file '%s': %v", path, err)
return 0
}
expectedSize := strconv.FormatInt(info.Size(), 10)
blobsize, err := xattr.Get(path, prefixes.BlobsizeAttr)
if err == nil && string(blobsize) == expectedSize {
return 0
}
if err := xattr.Set(path, prefixes.BlobsizeAttr, []byte(expectedSize)); err != nil {
logFailure("Failed to fix blobsize for '%s': %v", path, err)
return 0
}
fmt.Printf(" + Fixed blobsize for '%s'\n", path)
c.restartRequired = true
return 1
}
// fixChecksums recalculates the sha1, md5 and adler32 checksums of the file and
// updates the stored attributes if they differ. It returns the number of fixes applied.
func (c *consistencyChecker) fixChecksums(path string) int {
sha1h, md5h, adler32h, err := node.CalculateChecksums(context.Background(), path)
if err != nil {
logFailure("Failed to calculate checksums for '%s': %v", path, err)
return 0
}
checksums := map[string][]byte{
prefixes.ChecksumPrefix + "sha1": sha1h.Sum(nil),
prefixes.ChecksumPrefix + "md5": md5h.Sum(nil),
prefixes.ChecksumPrefix + "adler32": adler32h.Sum(nil),
}
fixes := 0
for attrName, sum := range checksums {
current, err := xattr.Get(path, attrName)
if err == nil && bytes.Equal(current, sum) {
continue
}
if err := xattr.Set(path, attrName, sum); err != nil {
logFailure("Failed to fix checksum '%s' for '%s': %v", attrName, path, err)
continue
}
fmt.Printf(" + Fixed checksum '%s' for '%s'\n", attrName, path)
c.restartRequired = true
fixes++
}
return fixes
}
func (c *consistencyChecker) checkNodes(spacePath string) {
rootID, err := xattr.Get(spacePath, prefixes.IDAttr)
if err != nil || len(rootID) == 0 {
logFailure("Space root '%s' missing '%s' attribute", spacePath, prefixes.IDAttr)
return
}
fixes := c.walkNodes(spacePath, string(rootID))
if fixes > 0 {
fmt.Printf(" ✓ Fixed %d incorrect node attributes in %s\n", fixes, filepath.Base(spacePath))
}
}
// fixSpaceID updates the parentid attributes of all entries in a space to a new target ID,
// updates the space's own ID attributes, and removes obsolete IDs from the user index file.
func (c *consistencyChecker) fixSpaceID(spacePath string, obsoleteIDs []string, targetID string, entries []EntryInfo) {
// Set all parentid attributes to the proper space ID
err := setAllParentIDAttributes(entries, targetID)
if err != nil {
logFailure("an error occurred during file attribute update: %v", err)
return
}
// Update space ID itself
fmt.Printf(" Updating directory '%s' with attribute '%s' -> %s\n", filepath.Base(spacePath), prefixes.IDAttr, targetID)
err = xattr.Set(spacePath, prefixes.IDAttr, []byte(targetID))
if err != nil {
logFailure("Failed to set attribute on directory '%s': %v", spacePath, err)
return
}
err = xattr.Set(spacePath, prefixes.SpaceIDAttr, []byte(targetID))
if err != nil {
logFailure("Failed to set attribute on directory '%s': %v", spacePath, err)
return
}
// update the index
err = c.updateOwnerIndexFile(spacePath, obsoleteIDs)
if err != nil {
logFailure("Could not update the owner index file: %v", err)
}
}
func (c *consistencyChecker) gatherAttributes(path string) ([]EntryInfo, map[string]struct{}, EntryInfo, error) {
dirEntries, err := os.ReadDir(path)
if err != nil {
return nil, nil, EntryInfo{}, fmt.Errorf("failed to read directory: %w", err)
}
var allEntries []EntryInfo
uniqueIDs := make(map[string]struct{})
var oldestEntry EntryInfo
oldestTime := time.Now().Add(100 * 365 * 24 * time.Hour) // Set to a future date to find the oldest entry
for _, entry := range dirEntries {
fullPath := filepath.Join(path, entry.Name())
if c.ignorer.IsIgnored(fullPath) {
continue
}
info, err := os.Stat(fullPath)
if err != nil {
fmt.Printf(" - Warning: could not stat %s: %v\n", entry.Name(), err)
continue
}
parentID, err := xattr.Get(fullPath, prefixes.ParentidAttr)
if err != nil {
continue // Skip if attribute doesn't exist or can't be read
}
entryInfo := EntryInfo{
Path: fullPath,
ModTime: info.ModTime(),
ParentID: string(parentID),
}
allEntries = append(allEntries, entryInfo)
uniqueIDs[string(parentID)] = struct{}{}
if entryInfo.ModTime.Before(oldestTime) {
oldestTime = entryInfo.ModTime
oldestEntry = entryInfo
}
}
return allEntries, uniqueIDs, oldestEntry, nil
}
func setAllParentIDAttributes(entries []EntryInfo, targetID string) error {
fmt.Printf(" Setting all parent IDs to '%s':\n", targetID)
for _, entry := range entries {
if entry.ParentID == targetID {
fmt.Printf(" - Skipping '%s' (already has target ID).\n", filepath.Base(entry.Path))
continue
}
fmt.Printf(" - Removing all attributes from '%s'. It will be re-assimilated\n", filepath.Base(entry.Path))
filepath.WalkDir(entry.Path, func(path string, d os.DirEntry, err error) error {
if err != nil {
return fmt.Errorf("error walking path '%s': %w", path, err)
}
// Remove all attributes from the file.
if err := removeAttributes(path); err != nil {
fmt.Printf("failed to remove attributes from '%s': %v", path, err)
}
return nil
})
}
return nil
}
// updateOwnerIndexFile handles the logic of reading, modifying, and writing the MessagePack index file.
func (c *consistencyChecker) updateOwnerIndexFile(basePath string, obsoleteIDs []string) error {
fmt.Printf(" Rewriting index file '%s'\n", basePath)
ownerID, err := xattr.Get(basePath, prefixes.OwnerIDAttr)
if err != nil {
return fmt.Errorf("could not get owner ID from oldest entry '%s' to find index: %w", basePath, err)
}
indexPath := filepath.Join(c.cfg.Drivers.Posix.Root, "indexes", "by-user-id", string(ownerID)+".mpk")
indexPath = filepath.Clean(indexPath)
// Read the MessagePack file
fileData, err := os.ReadFile(indexPath)
if err != nil {
if os.IsNotExist(err) {
return fmt.Errorf("index file does not exist, skipping update")
}
return fmt.Errorf("could not read index file: %w", err)
}
var indexMap map[string]string
if err := msgpack.Unmarshal(fileData, &indexMap); err != nil {
return fmt.Errorf("failed to parse MessagePack index file (is it corrupt?): %w", err)
}
// Remove obsolete IDs from the map
itemsRemoved := 0
for _, id := range obsoleteIDs {
if _, exists := indexMap[id]; exists {
fmt.Printf(" - Removing obsolete ID '%s' from index.\n", id)
delete(indexMap, id)
itemsRemoved++
} else {
fmt.Printf(" - Obsolete ID '%s' not found in index\n", id)
}
}
if itemsRemoved == 0 {
return nil
}
// Write the data back to the file
updatedData, err := msgpack.Marshal(&indexMap)
if err != nil {
return fmt.Errorf("failed to marshal updated index map: %w", err)
}
if err := os.WriteFile(indexPath, updatedData, 0644); err != nil {
return fmt.Errorf("failed to write updated index file: %w", err)
}
fmt.Printf(" ✓ Successfully removed %d item(s) and saved index file.\n", itemsRemoved)
return nil
}
func removeAttributes(path string) error {
attrNames, err := xattr.List(path)
if err != nil {
return fmt.Errorf("failed to list attributes for '%s': %w", path, err)
}
for _, attrName := range attrNames {
if err := xattr.Remove(path, attrName); err != nil {
return fmt.Errorf("failed to remove attribute '%s' from '%s': %w", attrName, path, err)
}
}
return nil
}
+12 -2
View File
@@ -6,11 +6,13 @@ import (
"os/signal"
"syscall"
"github.com/rs/zerolog"
"github.com/spf13/cobra"
"github.com/opencloud-eu/opencloud/opencloud/pkg/register"
"github.com/opencloud-eu/opencloud/pkg/clihelper"
"github.com/opencloud-eu/opencloud/pkg/config"
"github.com/spf13/cobra"
oclog "github.com/opencloud-eu/opencloud/pkg/log"
)
// Execute is the entry point for the opencloud command.
@@ -38,3 +40,11 @@ func Execute() error {
ctx, _ := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT, syscall.SIGHUP)
return app.ExecuteContext(ctx)
}
func logger(name string) zerolog.Logger {
return oclog.NewLogger(
oclog.Name(name),
oclog.Level("info"),
oclog.Pretty(true),
oclog.Color(true)).Logger
}
+2 -12
View File
@@ -9,7 +9,6 @@ import (
"github.com/opencloud-eu/opencloud/pkg/config"
"github.com/opencloud-eu/opencloud/pkg/config/configlog"
"github.com/opencloud-eu/opencloud/pkg/config/parser"
oclog "github.com/opencloud-eu/opencloud/pkg/log"
mregistry "github.com/opencloud-eu/opencloud/pkg/registry"
sharing "github.com/opencloud-eu/opencloud/services/sharing/pkg/config"
sharingparser "github.com/opencloud-eu/opencloud/services/sharing/pkg/config/parser"
@@ -85,7 +84,7 @@ func cleanup(_ *cobra.Command, cfg *config.Config) error {
return configlog.ReturnError(errors.New("cleanup is only implemented for the jsoncs3 share manager"))
}
l := logger()
l := logger("migrate")
zerolog.SetGlobalLevel(zerolog.InfoLevel)
@@ -94,7 +93,7 @@ func cleanup(_ *cobra.Command, cfg *config.Config) error {
if !ok {
return configlog.ReturnError(errors.New("Unknown share manager type '" + driver + "'"))
}
mgr, err := f(rcfg[driver].(map[string]any), l)
mgr, err := f(rcfg[driver].(map[string]any), &l)
if err != nil {
return configlog.ReturnError(err)
}
@@ -167,12 +166,3 @@ func revaShareConfig(cfg *sharing.Config) map[string]any {
},
}
}
func logger() *zerolog.Logger {
log := oclog.NewLogger(
oclog.Name("migrate"),
oclog.Level("info"),
oclog.Pretty(true),
oclog.Color(true)).Logger
return &log
}
+10 -3
View File
@@ -389,9 +389,16 @@ func Start(ctx context.Context, o ...Option) error {
if ev.Restarting {
l = s.Log.Error()
}
l.Str("event", e.String()).Str("service", ev.ServiceName).Str("supervisor", ev.SupervisorName).
Bool("restarting", ev.Restarting).Float64("failures", ev.CurrentFailures).Float64("threshold", ev.FailureThreshold).
Interface("error", ev.Err).Msg("service terminated")
l = l.Str("event", e.String()).Str("service", ev.ServiceName).Str("supervisor", ev.SupervisorName).
Bool("restarting", ev.Restarting).Float64("failures", ev.CurrentFailures).Float64("threshold", ev.FailureThreshold)
// ev.Err is an interface{}: marshaling an error yields {} because
// its fields are unexported, so the message has to go through Err
if err, ok := ev.Err.(error); ok {
l = l.Err(err)
} else {
l = l.Interface("error", ev.Err)
}
l.Msg("service terminated")
case suture.EventBackoff:
s.Log.Warn().Str("event", e.String()).Str("supervisor", ev.SupervisorName).Msg("service backoff")
case suture.EventResume:
+1
View File
@@ -86,5 +86,6 @@
<property name="lineLimit" value="120" />
<property name="absoluteLineLimit" value="120" />
</properties>
<exclude-pattern>*/tests/acceptance/bootstrap/*</exclude-pattern>
</rule>
</ruleset>
+3
View File
@@ -43,6 +43,9 @@ type StringNode struct {
*Base
Key string
Value string
// CaseInsensitive marks a case-insensitive restriction; set by the search
// lowering pass, a backend routes it to the field's lowercased form.
CaseInsensitive bool
}
// BooleanNode represents a bool value
+12
View File
@@ -14,5 +14,17 @@ func DefaultApp(app *cobra.Command) *cobra.Command {
// version info
app.Version = fmt.Sprintf("%s (%s <%s>) (%s)", version.String, "OpenCloud GmbH", "support@opencloud.eu", version.Compiled())
// cobra would print the error on top of what main() already prints
app.SilenceErrors = true
// keep the usage block for flag parse errors, drop it once RunE runs.
// Traversing runs the hook even below a subcommand that brings its own,
// e.g. every service below ServiceCommand.
cobra.EnableTraverseRunHooks = true
app.PersistentPreRunE = func(cmd *cobra.Command, _ []string) error {
cmd.SilenceUsage = true
return nil
}
return app
}
+2 -3
View File
@@ -6,7 +6,6 @@ import (
"github.com/jinzhu/now"
"github.com/opencloud-eu/opencloud/pkg/ast"
"github.com/opencloud-eu/opencloud/services/search/pkg/query"
)
func toNode[T ast.Node](in any) (T, error) {
@@ -84,7 +83,7 @@ func toTimeRange(in any) (*time.Time, *time.Time, error) {
value, err := toString(in)
if err != nil {
return &from, &to, &query.UnsupportedTimeRangeError{}
return &from, &to, &UnsupportedTimeRangeError{}
}
c := &now.Config{
@@ -131,7 +130,7 @@ func toTimeRange(in any) (*time.Time, *time.Time, error) {
}
if from.IsZero() || to.IsZero() {
return nil, nil, &query.UnsupportedTimeRangeError{}
return nil, nil, &UnsupportedTimeRangeError{}
}
return &from, &to, nil
+10 -11
View File
@@ -9,7 +9,6 @@ import (
"github.com/opencloud-eu/opencloud/pkg/ast"
"github.com/opencloud-eu/opencloud/pkg/ast/test"
"github.com/opencloud-eu/opencloud/pkg/kql"
"github.com/opencloud-eu/opencloud/services/search/pkg/query"
tAssert "github.com/stretchr/testify/assert"
)
@@ -34,13 +33,13 @@ func TestParse_Spec(t *testing.T) {
},
{
name: `AND`,
error: query.StartsWithBinaryOperatorError{
error: kql.StartsWithBinaryOperatorError{
Node: &ast.OperatorNode{Value: kql.BoolAND},
},
},
{
name: `AND cat AND dog`,
error: query.StartsWithBinaryOperatorError{
error: kql.StartsWithBinaryOperatorError{
Node: &ast.OperatorNode{Value: kql.BoolAND},
},
},
@@ -80,13 +79,13 @@ func TestParse_Spec(t *testing.T) {
},
{
name: `OR`,
error: query.StartsWithBinaryOperatorError{
error: kql.StartsWithBinaryOperatorError{
Node: &ast.OperatorNode{Value: kql.BoolOR},
},
},
{
name: `OR cat AND dog`,
error: query.StartsWithBinaryOperatorError{
error: kql.StartsWithBinaryOperatorError{
Node: &ast.OperatorNode{Value: kql.BoolOR},
},
},
@@ -860,37 +859,37 @@ func TestParse_Errors(t *testing.T) {
tests := []testCase{
{
query: "animal:(mammal:cat mammal:dog reptile:turtle)",
error: query.NamedGroupInvalidNodesError{
error: kql.NamedGroupInvalidNodesError{
Node: &ast.StringNode{Key: "mammal", Value: "cat"},
},
},
{
query: "animal:(cat mammal:dog turtle)",
error: query.NamedGroupInvalidNodesError{
error: kql.NamedGroupInvalidNodesError{
Node: &ast.StringNode{Key: "mammal", Value: "dog"},
},
},
{
query: "animal:(AND cat)",
error: query.StartsWithBinaryOperatorError{
error: kql.StartsWithBinaryOperatorError{
Node: &ast.OperatorNode{Value: kql.BoolAND},
},
},
{
query: "animal:(OR cat)",
error: query.StartsWithBinaryOperatorError{
error: kql.StartsWithBinaryOperatorError{
Node: &ast.OperatorNode{Value: kql.BoolOR},
},
},
{
query: "(AND cat)",
error: query.StartsWithBinaryOperatorError{
error: kql.StartsWithBinaryOperatorError{
Node: &ast.OperatorNode{Value: kql.BoolAND},
},
},
{
query: "(OR cat)",
error: query.StartsWithBinaryOperatorError{
error: kql.StartsWithBinaryOperatorError{
Node: &ast.OperatorNode{Value: kql.BoolOR},
},
},
@@ -1,4 +1,4 @@
package query
package kql
import (
"fmt"
@@ -38,6 +38,8 @@ func (e UnsupportedTimeRangeError) Error() string {
return fmt.Sprintf("unable to convert '%v' to a time range", e.Value)
}
// IsValidationError reports whether err is one of the KQL parse/validation
// errors produced by this package.
func IsValidationError(err error) bool {
switch err.(type) {
case *StartsWithBinaryOperatorError, *NamedGroupInvalidNodesError, *UnsupportedTimeRangeError:
+1 -2
View File
@@ -5,7 +5,6 @@ import (
"github.com/opencloud-eu/opencloud/pkg/ast"
"github.com/opencloud-eu/opencloud/pkg/kql"
"github.com/opencloud-eu/opencloud/services/search/pkg/query"
tAssert "github.com/stretchr/testify/assert"
)
@@ -22,7 +21,7 @@ func TestNewAST(t *testing.T) {
{
name: "error",
givenQuery: kql.BoolAND,
expectedError: query.StartsWithBinaryOperatorError{
expectedError: kql.StartsWithBinaryOperatorError{
Node: &ast.OperatorNode{Value: kql.BoolAND},
},
},
+3 -4
View File
@@ -2,7 +2,6 @@ package kql
import (
"github.com/opencloud-eu/opencloud/pkg/ast"
"github.com/opencloud-eu/opencloud/services/search/pkg/query"
)
func validateAst(a *ast.Ast) error {
@@ -10,7 +9,7 @@ func validateAst(a *ast.Ast) error {
case *ast.OperatorNode:
switch node.Value {
case BoolAND, BoolOR:
return &query.StartsWithBinaryOperatorError{Node: node}
return &StartsWithBinaryOperatorError{Node: node}
}
}
return nil
@@ -21,14 +20,14 @@ func validateGroupNode(n *ast.GroupNode) error {
case *ast.OperatorNode:
switch node.Value {
case BoolAND, BoolOR:
return &query.StartsWithBinaryOperatorError{Node: node}
return &StartsWithBinaryOperatorError{Node: node}
}
}
if n.Key != "" {
for _, node := range n.Nodes {
if ast.NodeKey(node) != "" {
return &query.NamedGroupInvalidNodesError{Node: node}
return &NamedGroupInvalidNodesError{Node: node}
}
}
}
+3 -3
View File
@@ -56,9 +56,9 @@ type Cache struct {
DisablePersistence bool `yaml:"disable_persistence" env:"OC_CACHE_DISABLE_PERSISTENCE" desc:"Disables persistence of the cache. Only applies when store type 'nats-js-kv' is configured. Defaults to false." introductionVersion:"1.0.0"`
AuthUsername string `yaml:"auth_username" env:"OC_CACHE_AUTH_USERNAME" desc:"The username to use for authentication. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
AuthPassword string `yaml:"auth_password" env:"OC_CACHE_AUTH_PASSWORD" desc:"The password to use for authentication. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
EnableTLS bool `yaml:"enable_tls" env:"OC_CACHE_ENABLE_TLS" desc:"Enable TLS for the connection to file metadata cache." introductionVersion:"%%NEXT%%"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_CACHE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"%%NEXT%%"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_CACHE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided OC_CACHE_TLS_INSECURE will be seen as false." introductionVersion:"%%NEXT%%"`
EnableTLS bool `yaml:"enable_tls" env:"OC_CACHE_ENABLE_TLS" desc:"Enable TLS for the connection to file metadata cache." introductionVersion:"7.3.0"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_CACHE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"7.3.0"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_CACHE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided OC_CACHE_TLS_INSECURE will be seen as false." introductionVersion:"7.3.0"`
}
// Commons holds configuration that are common to all extensions. Each extension can then decide whether
+1 -1
View File
@@ -34,7 +34,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 = "7.1.0+dev"
LatestTag = "7.4.0+dev"
// Date indicates the build date.
// This has been removed, it looks like you can only replace static strings with recent go versions
+26
View File
@@ -1,7 +1,9 @@
package filepathx
import (
"fmt"
"path/filepath"
"strings"
)
// JailJoin joins any number of path elements into a single path,
@@ -10,3 +12,27 @@ import (
func JailJoin(jail string, elem ...string) string {
return filepath.Join(jail, filepath.Join(append([]string{"/"}, elem...)...))
}
// Determines whether the file or directory 'child' is same as or underneath the directory 'parent'.
//
// Note that 'parent' is expected to be a directory.
func IsSameOrContainedBy(parent string, child string) (bool, error) {
absParent, err := filepath.Abs(parent)
if err != nil {
return false, fmt.Errorf("failed to make parent directory absolute: %q: %w", parent, err)
}
absChild, err := filepath.Abs(child)
if err != nil {
return false, fmt.Errorf("failed to make child file/directory absolute: %q: %w", child, err)
}
rel, err := filepath.Rel(absParent, absChild)
if err != nil {
return false, fmt.Errorf("failed to determine the relative path between the parent directory %q and the child file/directory: %q: %w", absParent, absChild, err)
}
if rel == ".." || strings.HasPrefix(rel, ".."+string(filepath.Separator)) {
return false, nil
}
return true, nil
}
+23
View File
@@ -1,9 +1,12 @@
package filepathx_test
import (
"fmt"
"strings"
"testing"
"github.com/opencloud-eu/opencloud/pkg/x/path/filepathx"
"github.com/stretchr/testify/require"
)
func TestJailJoin(t *testing.T) {
@@ -61,3 +64,23 @@ func TestJailJoin(t *testing.T) {
})
}
}
func TestIsSameOrContainedBy(t *testing.T) {
for _, tt := range []struct {
parent string
child string
expected bool
}{
{"foo", "foo", true},
{"/foo", "/foo", true},
{"foo", "foo/bar", true},
{"foo", "bar", false},
} {
t.Run(fmt.Sprintf("%s: %s vs %s", t.Name(), strings.ReplaceAll(tt.parent, "/", "."), strings.ReplaceAll(tt.child, "/", ".")), func(t *testing.T) {
require := require.New(t)
b, err := filepathx.IsSameOrContainedBy(tt.parent, tt.child)
require.NoError(err)
require.Equal(tt.expected, b)
})
}
}
@@ -627,13 +627,13 @@ type Bundle struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // @gotags: yaml:"id"
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // @gotags: yaml:"name"
Type Bundle_Type `protobuf:"varint,3,opt,name=type,proto3,enum=opencloud.messages.settings.v0.Bundle_Type" json:"type,omitempty"` // @gotags: yaml:"type"
Extension string `protobuf:"bytes,4,opt,name=extension,proto3" json:"extension,omitempty"` // @gotags: yaml:"extension"
DisplayName string `protobuf:"bytes,5,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` // @gotags: yaml:"display_name"
Settings []*Setting `protobuf:"bytes,6,rep,name=settings,proto3" json:"settings,omitempty"` // @gotags: yaml:"settings"
Resource *Resource `protobuf:"bytes,7,opt,name=resource,proto3" json:"resource,omitempty"` // @gotags: yaml:"resource"
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"` // @gotags: yaml:"id"
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` // @gotags: yaml:"name"
Type Bundle_Type `protobuf:"varint,3,opt,name=type,proto3,enum=opencloud.messages.settings.v0.Bundle_Type" json:"type,omitempty" yaml:"type"` // @gotags: yaml:"type"
Extension string `protobuf:"bytes,4,opt,name=extension,proto3" json:"extension,omitempty" yaml:"extension"` // @gotags: yaml:"extension"
DisplayName string `protobuf:"bytes,5,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty" yaml:"display_name"` // @gotags: yaml:"display_name"
Settings []*Setting `protobuf:"bytes,6,rep,name=settings,proto3" json:"settings,omitempty" yaml:"settings"` // @gotags: yaml:"settings"
Resource *Resource `protobuf:"bytes,7,opt,name=resource,proto3" json:"resource,omitempty" yaml:"resource"` // @gotags: yaml:"resource"
}
func (x *Bundle) Reset() {
@@ -722,10 +722,10 @@ type Setting struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // @gotags: yaml:"id"
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` // @gotags: yaml:"name"
DisplayName string `protobuf:"bytes,3,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty"` // @gotags: yaml:"display_name"
Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty"` // @gotags: yaml:"description"
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"` // @gotags: yaml:"id"
Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty" yaml:"name"` // @gotags: yaml:"name"
DisplayName string `protobuf:"bytes,3,opt,name=display_name,json=displayName,proto3" json:"display_name,omitempty" yaml:"display_name"` // @gotags: yaml:"display_name"
Description string `protobuf:"bytes,4,opt,name=description,proto3" json:"description,omitempty" yaml:"description"` // @gotags: yaml:"description"
// Types that are assignable to Value:
//
// *Setting_IntValue
@@ -736,7 +736,7 @@ type Setting struct {
// *Setting_PermissionValue
// *Setting_MultiChoiceCollectionValue
Value isSetting_Value `protobuf_oneof:"value"`
Resource *Resource `protobuf:"bytes,11,opt,name=resource,proto3" json:"resource,omitempty"` // @gotags: yaml:"resource"
Resource *Resource `protobuf:"bytes,11,opt,name=resource,proto3" json:"resource,omitempty" yaml:"resource"` // @gotags: yaml:"resource"
}
func (x *Setting) Reset() {
@@ -867,31 +867,31 @@ type isSetting_Value interface {
}
type Setting_IntValue struct {
IntValue *Int `protobuf:"bytes,5,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value"
IntValue *Int `protobuf:"bytes,5,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value"
}
type Setting_StringValue struct {
StringValue *String `protobuf:"bytes,6,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value"
StringValue *String `protobuf:"bytes,6,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value"
}
type Setting_BoolValue struct {
BoolValue *Bool `protobuf:"bytes,7,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value"
BoolValue *Bool `protobuf:"bytes,7,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value"
}
type Setting_SingleChoiceValue struct {
SingleChoiceValue *SingleChoiceList `protobuf:"bytes,8,opt,name=single_choice_value,json=singleChoiceValue,proto3,oneof"` // @gotags: yaml:"single_choice_value"
SingleChoiceValue *SingleChoiceList `protobuf:"bytes,8,opt,name=single_choice_value,json=singleChoiceValue,proto3,oneof" yaml:"single_choice_value"` // @gotags: yaml:"single_choice_value"
}
type Setting_MultiChoiceValue struct {
MultiChoiceValue *MultiChoiceList `protobuf:"bytes,9,opt,name=multi_choice_value,json=multiChoiceValue,proto3,oneof"` // @gotags: yaml:"multi_choice_value"
MultiChoiceValue *MultiChoiceList `protobuf:"bytes,9,opt,name=multi_choice_value,json=multiChoiceValue,proto3,oneof" yaml:"multi_choice_value"` // @gotags: yaml:"multi_choice_value"
}
type Setting_PermissionValue struct {
PermissionValue *Permission `protobuf:"bytes,10,opt,name=permission_value,json=permissionValue,proto3,oneof"` // @gotags: yaml:"permission_value"
PermissionValue *Permission `protobuf:"bytes,10,opt,name=permission_value,json=permissionValue,proto3,oneof" yaml:"permission_value"` // @gotags: yaml:"permission_value"
}
type Setting_MultiChoiceCollectionValue struct {
MultiChoiceCollectionValue *MultiChoiceCollection `protobuf:"bytes,12,opt,name=multi_choice_collection_value,json=multiChoiceCollectionValue,proto3,oneof"` // @gotags: yaml:"multi_choice_collection_value"
MultiChoiceCollectionValue *MultiChoiceCollection `protobuf:"bytes,12,opt,name=multi_choice_collection_value,json=multiChoiceCollectionValue,proto3,oneof" yaml:"multi_choice_collection_value"` // @gotags: yaml:"multi_choice_collection_value"
}
func (*Setting_IntValue) isSetting_Value() {}
@@ -913,11 +913,11 @@ type Int struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Default int64 `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty"` // @gotags: yaml:"default"
Min int64 `protobuf:"varint,2,opt,name=min,proto3" json:"min,omitempty"` // @gotags: yaml:"min"
Max int64 `protobuf:"varint,3,opt,name=max,proto3" json:"max,omitempty"` // @gotags: yaml:"max"
Step int64 `protobuf:"varint,4,opt,name=step,proto3" json:"step,omitempty"` // @gotags: yaml:"step"
Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty"` // @gotags: yaml:"placeholder"
Default int64 `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty" yaml:"default"` // @gotags: yaml:"default"
Min int64 `protobuf:"varint,2,opt,name=min,proto3" json:"min,omitempty" yaml:"min"` // @gotags: yaml:"min"
Max int64 `protobuf:"varint,3,opt,name=max,proto3" json:"max,omitempty" yaml:"max"` // @gotags: yaml:"max"
Step int64 `protobuf:"varint,4,opt,name=step,proto3" json:"step,omitempty" yaml:"step"` // @gotags: yaml:"step"
Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty" yaml:"placeholder"` // @gotags: yaml:"placeholder"
}
func (x *Int) Reset() {
@@ -992,11 +992,11 @@ type String struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Default string `protobuf:"bytes,1,opt,name=default,proto3" json:"default,omitempty"` // @gotags: yaml:"default"
Required bool `protobuf:"varint,2,opt,name=required,proto3" json:"required,omitempty"` // @gotags: yaml:"required"
MinLength int32 `protobuf:"varint,3,opt,name=min_length,json=minLength,proto3" json:"min_length,omitempty"` // @gotags: yaml:"min_length"
MaxLength int32 `protobuf:"varint,4,opt,name=max_length,json=maxLength,proto3" json:"max_length,omitempty"` // @gotags: yaml:"max_length"
Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty"` // @gotags: yaml:"placeholder"
Default string `protobuf:"bytes,1,opt,name=default,proto3" json:"default,omitempty" yaml:"default"` // @gotags: yaml:"default"
Required bool `protobuf:"varint,2,opt,name=required,proto3" json:"required,omitempty" yaml:"required"` // @gotags: yaml:"required"
MinLength int32 `protobuf:"varint,3,opt,name=min_length,json=minLength,proto3" json:"min_length,omitempty" yaml:"min_length"` // @gotags: yaml:"min_length"
MaxLength int32 `protobuf:"varint,4,opt,name=max_length,json=maxLength,proto3" json:"max_length,omitempty" yaml:"max_length"` // @gotags: yaml:"max_length"
Placeholder string `protobuf:"bytes,5,opt,name=placeholder,proto3" json:"placeholder,omitempty" yaml:"placeholder"` // @gotags: yaml:"placeholder"
}
func (x *String) Reset() {
@@ -1071,8 +1071,8 @@ type Bool struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Default bool `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty"` // @gotags: yaml:"default"
Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty"` // @gotags: yaml:"label"
Default bool `protobuf:"varint,1,opt,name=default,proto3" json:"default,omitempty" yaml:"default"` // @gotags: yaml:"default"
Label string `protobuf:"bytes,2,opt,name=label,proto3" json:"label,omitempty" yaml:"label"` // @gotags: yaml:"label"
}
func (x *Bool) Reset() {
@@ -1126,7 +1126,7 @@ type SingleChoiceList struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty"` // @gotags: yaml:"options"
Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty" yaml:"options"` // @gotags: yaml:"options"
}
func (x *SingleChoiceList) Reset() {
@@ -1173,7 +1173,7 @@ type MultiChoiceList struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty"` // @gotags: yaml:"options"
Options []*ListOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty" yaml:"options"` // @gotags: yaml:"options"
}
func (x *MultiChoiceList) Reset() {
@@ -1220,9 +1220,9 @@ type ListOption struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Value *ListOptionValue `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` // @gotags: yaml:"value"
Default bool `protobuf:"varint,2,opt,name=default,proto3" json:"default,omitempty"` // @gotags: yaml:"default"
DisplayValue string `protobuf:"bytes,3,opt,name=display_value,json=displayValue,proto3" json:"display_value,omitempty"` // @gotags: yaml:"display_value"
Value *ListOptionValue `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty" yaml:"value"` // @gotags: yaml:"value"
Default bool `protobuf:"varint,2,opt,name=default,proto3" json:"default,omitempty" yaml:"default"` // @gotags: yaml:"default"
DisplayValue string `protobuf:"bytes,3,opt,name=display_value,json=displayValue,proto3" json:"display_value,omitempty" yaml:"display_value"` // @gotags: yaml:"display_value"
}
func (x *ListOption) Reset() {
@@ -1283,7 +1283,7 @@ type MultiChoiceCollection struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Options []*MultiChoiceCollectionOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty"` // @gotags: yaml:"options"
Options []*MultiChoiceCollectionOption `protobuf:"bytes,1,rep,name=options,proto3" json:"options,omitempty" yaml:"options"` // @gotags: yaml:"options"
}
func (x *MultiChoiceCollection) Reset() {
@@ -1330,10 +1330,10 @@ type MultiChoiceCollectionOption struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Value *MultiChoiceCollectionOptionValue `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"` // @gotags: yaml:"value"
Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty"` // @gotags: yaml:"key"
Attribute string `protobuf:"bytes,3,opt,name=attribute,proto3" json:"attribute,omitempty"` // @gotags: yaml:"attribute"
DisplayValue string `protobuf:"bytes,4,opt,name=display_value,json=displayValue,proto3" json:"display_value,omitempty"` // @gotags: yaml:"display_value"
Value *MultiChoiceCollectionOptionValue `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty" yaml:"value"` // @gotags: yaml:"value"
Key string `protobuf:"bytes,2,opt,name=key,proto3" json:"key,omitempty" yaml:"key"` // @gotags: yaml:"key"
Attribute string `protobuf:"bytes,3,opt,name=attribute,proto3" json:"attribute,omitempty" yaml:"attribute"` // @gotags: yaml:"attribute"
DisplayValue string `protobuf:"bytes,4,opt,name=display_value,json=displayValue,proto3" json:"display_value,omitempty" yaml:"display_value"` // @gotags: yaml:"display_value"
}
func (x *MultiChoiceCollectionOption) Reset() {
@@ -1474,15 +1474,15 @@ type isMultiChoiceCollectionOptionValue_Option interface {
}
type MultiChoiceCollectionOptionValue_IntValue struct {
IntValue *Int `protobuf:"bytes,1,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value"
IntValue *Int `protobuf:"bytes,1,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value"
}
type MultiChoiceCollectionOptionValue_StringValue struct {
StringValue *String `protobuf:"bytes,2,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value"
StringValue *String `protobuf:"bytes,2,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value"
}
type MultiChoiceCollectionOptionValue_BoolValue struct {
BoolValue *Bool `protobuf:"bytes,3,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value"
BoolValue *Bool `protobuf:"bytes,3,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value"
}
func (*MultiChoiceCollectionOptionValue_IntValue) isMultiChoiceCollectionOptionValue_Option() {}
@@ -1496,8 +1496,8 @@ type Permission struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Operation Permission_Operation `protobuf:"varint,1,opt,name=operation,proto3,enum=opencloud.messages.settings.v0.Permission_Operation" json:"operation,omitempty"` // @gotags: yaml:"operation"
Constraint Permission_Constraint `protobuf:"varint,2,opt,name=constraint,proto3,enum=opencloud.messages.settings.v0.Permission_Constraint" json:"constraint,omitempty"` // @gotags: yaml:"constraint"
Operation Permission_Operation `protobuf:"varint,1,opt,name=operation,proto3,enum=opencloud.messages.settings.v0.Permission_Operation" json:"operation,omitempty" yaml:"operation"` // @gotags: yaml:"operation"
Constraint Permission_Constraint `protobuf:"varint,2,opt,name=constraint,proto3,enum=opencloud.messages.settings.v0.Permission_Constraint" json:"constraint,omitempty" yaml:"constraint"` // @gotags: yaml:"constraint"
}
func (x *Permission) Reset() {
@@ -1552,12 +1552,12 @@ type Value struct {
unknownFields protoimpl.UnknownFields
// id is the id of the Value. It is generated on saving it.
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"` // @gotags: yaml:"id"
BundleId string `protobuf:"bytes,2,opt,name=bundle_id,json=bundleId,proto3" json:"bundle_id,omitempty"` // @gotags: yaml:"bundle_id"
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty" yaml:"id"` // @gotags: yaml:"id"
BundleId string `protobuf:"bytes,2,opt,name=bundle_id,json=bundleId,proto3" json:"bundle_id,omitempty" yaml:"bundle_id"` // @gotags: yaml:"bundle_id"
// setting_id is the id of the setting from within its bundle.
SettingId string `protobuf:"bytes,3,opt,name=setting_id,json=settingId,proto3" json:"setting_id,omitempty"` // @gotags: yaml:"setting_id"
AccountUuid string `protobuf:"bytes,4,opt,name=account_uuid,json=accountUuid,proto3" json:"account_uuid,omitempty"` // @gotags: yaml:"account_uuid"
Resource *Resource `protobuf:"bytes,5,opt,name=resource,proto3" json:"resource,omitempty"` // @gotags: yaml:"resource"
SettingId string `protobuf:"bytes,3,opt,name=setting_id,json=settingId,proto3" json:"setting_id,omitempty" yaml:"setting_id"` // @gotags: yaml:"setting_id"
AccountUuid string `protobuf:"bytes,4,opt,name=account_uuid,json=accountUuid,proto3" json:"account_uuid,omitempty" yaml:"account_uuid"` // @gotags: yaml:"account_uuid"
Resource *Resource `protobuf:"bytes,5,opt,name=resource,proto3" json:"resource,omitempty" yaml:"resource"` // @gotags: yaml:"resource"
// Types that are assignable to Value:
//
// *Value_BoolValue
@@ -1682,23 +1682,23 @@ type isValue_Value interface {
}
type Value_BoolValue struct {
BoolValue bool `protobuf:"varint,6,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value"
BoolValue bool `protobuf:"varint,6,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value"
}
type Value_IntValue struct {
IntValue int64 `protobuf:"varint,7,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value"
IntValue int64 `protobuf:"varint,7,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value"
}
type Value_StringValue struct {
StringValue string `protobuf:"bytes,8,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value"
StringValue string `protobuf:"bytes,8,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value"
}
type Value_ListValue struct {
ListValue *ListValue `protobuf:"bytes,9,opt,name=list_value,json=listValue,proto3,oneof"` // @gotags: yaml:"list_value"
ListValue *ListValue `protobuf:"bytes,9,opt,name=list_value,json=listValue,proto3,oneof" yaml:"list_value"` // @gotags: yaml:"list_value"
}
type Value_CollectionValue struct {
CollectionValue *CollectionValue `protobuf:"bytes,10,opt,name=collection_value,json=collectionValue,proto3,oneof"` // @gotags: yaml:"collection_value"
CollectionValue *CollectionValue `protobuf:"bytes,10,opt,name=collection_value,json=collectionValue,proto3,oneof" yaml:"collection_value"` // @gotags: yaml:"collection_value"
}
func (*Value_BoolValue) isValue_Value() {}
@@ -1716,7 +1716,7 @@ type ListValue struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Values []*ListOptionValue `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` // @gotags: yaml:"values"
Values []*ListOptionValue `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty" yaml:"values"` // @gotags: yaml:"values"
}
func (x *ListValue) Reset() {
@@ -1836,15 +1836,15 @@ type isListOptionValue_Option interface {
}
type ListOptionValue_StringValue struct {
StringValue string `protobuf:"bytes,1,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value"
StringValue string `protobuf:"bytes,1,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value"
}
type ListOptionValue_IntValue struct {
IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value"
IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value"
}
type ListOptionValue_BoolValue struct {
BoolValue bool `protobuf:"varint,3,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value"
BoolValue bool `protobuf:"varint,3,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value"
}
func (*ListOptionValue_StringValue) isListOptionValue_Option() {}
@@ -1858,7 +1858,7 @@ type CollectionValue struct {
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Values []*CollectionOption `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty"` // @gotags: yaml:"values"
Values []*CollectionOption `protobuf:"bytes,1,rep,name=values,proto3" json:"values,omitempty" yaml:"values"` // @gotags: yaml:"values"
}
func (x *CollectionValue) Reset() {
@@ -1906,7 +1906,7 @@ type CollectionOption struct {
unknownFields protoimpl.UnknownFields
// required
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty"` // @gotags: yaml:"key"
Key string `protobuf:"bytes,1,opt,name=key,proto3" json:"key,omitempty" yaml:"key"` // @gotags: yaml:"key"
// Types that are assignable to Option:
//
// *CollectionOption_IntValue
@@ -1987,15 +1987,15 @@ type isCollectionOption_Option interface {
}
type CollectionOption_IntValue struct {
IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof"` // @gotags: yaml:"int_value"
IntValue int64 `protobuf:"varint,2,opt,name=int_value,json=intValue,proto3,oneof" yaml:"int_value"` // @gotags: yaml:"int_value"
}
type CollectionOption_StringValue struct {
StringValue string `protobuf:"bytes,3,opt,name=string_value,json=stringValue,proto3,oneof"` // @gotags: yaml:"string_value"
StringValue string `protobuf:"bytes,3,opt,name=string_value,json=stringValue,proto3,oneof" yaml:"string_value"` // @gotags: yaml:"string_value"
}
type CollectionOption_BoolValue struct {
BoolValue bool `protobuf:"varint,4,opt,name=bool_value,json=boolValue,proto3,oneof"` // @gotags: yaml:"bool_value"
BoolValue bool `protobuf:"varint,4,opt,name=bool_value,json=boolValue,proto3,oneof" yaml:"bool_value"` // @gotags: yaml:"bool_value"
}
func (*CollectionOption_IntValue) isCollectionOption_Option() {}
@@ -40,7 +40,7 @@ func (_m *SearchProviderService) EXPECT() *SearchProviderService_Expecter {
}
// IndexSpace provides a mock function for the type SearchProviderService
func (_mock *SearchProviderService) IndexSpace(ctx context.Context, in *v0.IndexSpaceRequest, opts ...client.CallOption) (*v0.IndexSpaceResponse, error) {
func (_mock *SearchProviderService) IndexSpace(ctx context.Context, in *v0.IndexSpaceRequest, opts ...client.CallOption) (v0.SearchProvider_IndexSpaceService, error) {
var tmpRet mock.Arguments
if len(opts) > 0 {
tmpRet = _mock.Called(ctx, in, opts)
@@ -53,16 +53,16 @@ func (_mock *SearchProviderService) IndexSpace(ctx context.Context, in *v0.Index
panic("no return value specified for IndexSpace")
}
var r0 *v0.IndexSpaceResponse
var r0 v0.SearchProvider_IndexSpaceService
var r1 error
if returnFunc, ok := ret.Get(0).(func(context.Context, *v0.IndexSpaceRequest, ...client.CallOption) (*v0.IndexSpaceResponse, error)); ok {
if returnFunc, ok := ret.Get(0).(func(context.Context, *v0.IndexSpaceRequest, ...client.CallOption) (v0.SearchProvider_IndexSpaceService, error)); ok {
return returnFunc(ctx, in, opts...)
}
if returnFunc, ok := ret.Get(0).(func(context.Context, *v0.IndexSpaceRequest, ...client.CallOption) *v0.IndexSpaceResponse); ok {
if returnFunc, ok := ret.Get(0).(func(context.Context, *v0.IndexSpaceRequest, ...client.CallOption) v0.SearchProvider_IndexSpaceService); ok {
r0 = returnFunc(ctx, in, opts...)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*v0.IndexSpaceResponse)
r0 = ret.Get(0).(v0.SearchProvider_IndexSpaceService)
}
}
if returnFunc, ok := ret.Get(1).(func(context.Context, *v0.IndexSpaceRequest, ...client.CallOption) error); ok {
@@ -112,12 +112,12 @@ func (_c *SearchProviderService_IndexSpace_Call) Run(run func(ctx context.Contex
return _c
}
func (_c *SearchProviderService_IndexSpace_Call) Return(indexSpaceResponse *v0.IndexSpaceResponse, err error) *SearchProviderService_IndexSpace_Call {
_c.Call.Return(indexSpaceResponse, err)
func (_c *SearchProviderService_IndexSpace_Call) Return(searchProvider_IndexSpaceService v0.SearchProvider_IndexSpaceService, err error) *SearchProviderService_IndexSpace_Call {
_c.Call.Return(searchProvider_IndexSpaceService, err)
return _c
}
func (_c *SearchProviderService_IndexSpace_Call) RunAndReturn(run func(ctx context.Context, in *v0.IndexSpaceRequest, opts ...client.CallOption) (*v0.IndexSpaceResponse, error)) *SearchProviderService_IndexSpace_Call {
func (_c *SearchProviderService_IndexSpace_Call) RunAndReturn(run func(ctx context.Context, in *v0.IndexSpaceRequest, opts ...client.CallOption) (v0.SearchProvider_IndexSpaceService, error)) *SearchProviderService_IndexSpace_Call {
_c.Call.Return(run)
return _c
}
@@ -12,6 +12,7 @@ import (
_ "google.golang.org/genproto/googleapis/api/annotations"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
durationpb "google.golang.org/protobuf/types/known/durationpb"
_ "google.golang.org/protobuf/types/known/fieldmaskpb"
reflect "reflect"
sync "sync"
@@ -310,6 +311,7 @@ type IndexSpaceRequest struct {
SpaceId string `protobuf:"bytes,1,opt,name=space_id,json=spaceId,proto3" json:"space_id,omitempty"`
UserId string `protobuf:"bytes,2,opt,name=user_id,json=userId,proto3" json:"user_id,omitempty"`
ForceReindex bool `protobuf:"varint,3,opt,name=force_reindex,json=forceReindex,proto3" json:"force_reindex,omitempty"`
Concurrency int32 `protobuf:"varint,4,opt,name=concurrency,proto3" json:"concurrency,omitempty"`
}
func (x *IndexSpaceRequest) Reset() {
@@ -365,10 +367,28 @@ func (x *IndexSpaceRequest) GetForceReindex() bool {
return false
}
func (x *IndexSpaceRequest) GetConcurrency() int32 {
if x != nil {
return x.Concurrency
}
return 0
}
type IndexSpaceResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
// The id of the space that has just been indexed.
SpaceId string `protobuf:"bytes,1,opt,name=space_id,json=spaceId,proto3" json:"space_id,omitempty"`
// The duration it took to index this space.
SpaceDuration *durationpb.Duration `protobuf:"bytes,2,opt,name=space_duration,json=spaceDuration,proto3" json:"space_duration,omitempty"`
// The number of spaces that have been indexed so far.
IndexedSpaces int64 `protobuf:"varint,3,opt,name=indexed_spaces,json=indexedSpaces,proto3" json:"indexed_spaces,omitempty"`
// The total number of spaces that are being indexed.
TotalSpaces int64 `protobuf:"varint,4,opt,name=total_spaces,json=totalSpaces,proto3" json:"total_spaces,omitempty"`
// Contains an error message in case indexing this particular space failed.
Error string `protobuf:"bytes,5,opt,name=error,proto3" json:"error,omitempty"`
}
func (x *IndexSpaceResponse) Reset() {
@@ -403,6 +423,41 @@ func (*IndexSpaceResponse) Descriptor() ([]byte, []int) {
return file_opencloud_services_search_v0_search_proto_rawDescGZIP(), []int{5}
}
func (x *IndexSpaceResponse) GetSpaceId() string {
if x != nil {
return x.SpaceId
}
return ""
}
func (x *IndexSpaceResponse) GetSpaceDuration() *durationpb.Duration {
if x != nil {
return x.SpaceDuration
}
return nil
}
func (x *IndexSpaceResponse) GetIndexedSpaces() int64 {
if x != nil {
return x.IndexedSpaces
}
return 0
}
func (x *IndexSpaceResponse) GetTotalSpaces() int64 {
if x != nil {
return x.TotalSpaces
}
return 0
}
func (x *IndexSpaceResponse) GetError() string {
if x != nil {
return x.Error
}
return ""
}
var File_opencloud_services_search_v0_search_proto protoreflect.FileDescriptor
var file_opencloud_services_search_v0_search_proto_rawDesc = []byte{
@@ -422,6 +477,8 @@ var file_opencloud_services_search_v0_search_proto_rawDesc = []byte{
0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x1a, 0x20, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x62, 0x75, 0x66, 0x2f, 0x66, 0x69, 0x65, 0x6c, 0x64, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e,
0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xae, 0x01, 0x0a, 0x0d, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x21, 0x0a, 0x09, 0x70, 0x61, 0x67, 0x65, 0x5f,
0x73, 0x69, 0x7a, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x01,
@@ -465,68 +522,83 @@ var file_opencloud_services_search_v0_search_proto_rawDesc = []byte{
0x74, 0x50, 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x23, 0x0a, 0x0d, 0x74, 0x6f,
0x74, 0x61, 0x6c, 0x5f, 0x6d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28,
0x05, 0x52, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x65, 0x73, 0x22,
0x6c, 0x0a, 0x11, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64,
0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12,
0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09,
0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x6f, 0x72, 0x63,
0x65, 0x5f, 0x72, 0x65, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52,
0x0c, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x22, 0x14, 0x0a,
0x12, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x32, 0xb1, 0x02, 0x0a, 0x0e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x72,
0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x85, 0x01, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63,
0x68, 0x12, 0x2b, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65,
0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30,
0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c,
0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x53, 0x65,
0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3,
0xe4, 0x93, 0x02, 0x1a, 0x3a, 0x01, 0x2a, 0x22, 0x15, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x30,
0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x96,
0x01, 0x0a, 0x0a, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x70, 0x61, 0x63, 0x65, 0x12, 0x2f, 0x2e,
0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x49, 0x6e, 0x64,
0x65, 0x78, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30,
0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69,
0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x49, 0x6e,
0x64, 0x65, 0x78, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x3a, 0x01, 0x2a, 0x22, 0x1a, 0x2f, 0x61, 0x70,
0x69, 0x2f, 0x76, 0x30, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x69, 0x6e, 0x64, 0x65,
0x78, 0x2d, 0x73, 0x70, 0x61, 0x63, 0x65, 0x32, 0xa7, 0x01, 0x0a, 0x0d, 0x49, 0x6e, 0x64, 0x65,
0x78, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x95, 0x01, 0x0a, 0x06, 0x53, 0x65,
0x61, 0x72, 0x63, 0x68, 0x12, 0x30, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
0x94, 0x01, 0x0a, 0x11, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69,
0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64,
0x12, 0x17, 0x0a, 0x07, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28,
0x09, 0x52, 0x06, 0x75, 0x73, 0x65, 0x72, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x66, 0x6f, 0x72,
0x63, 0x65, 0x5f, 0x72, 0x65, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08,
0x52, 0x0c, 0x66, 0x6f, 0x72, 0x63, 0x65, 0x52, 0x65, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x26,
0x0a, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x18, 0x04, 0x20,
0x01, 0x28, 0x05, 0x42, 0x04, 0xe2, 0x41, 0x01, 0x01, 0x52, 0x0b, 0x63, 0x6f, 0x6e, 0x63, 0x75,
0x72, 0x72, 0x65, 0x6e, 0x63, 0x79, 0x22, 0xd1, 0x01, 0x0a, 0x12, 0x49, 0x6e, 0x64, 0x65, 0x78,
0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x19, 0x0a,
0x08, 0x73, 0x70, 0x61, 0x63, 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52,
0x07, 0x73, 0x70, 0x61, 0x63, 0x65, 0x49, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x73, 0x70, 0x61, 0x63,
0x65, 0x5f, 0x64, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x73, 0x70, 0x61,
0x63, 0x65, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x25, 0x0a, 0x0e, 0x69, 0x6e,
0x64, 0x65, 0x78, 0x65, 0x64, 0x5f, 0x73, 0x70, 0x61, 0x63, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01,
0x28, 0x03, 0x52, 0x0d, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x65, 0x64, 0x53, 0x70, 0x61, 0x63, 0x65,
0x73, 0x12, 0x21, 0x0a, 0x0c, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x5f, 0x73, 0x70, 0x61, 0x63, 0x65,
0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0b, 0x74, 0x6f, 0x74, 0x61, 0x6c, 0x53, 0x70,
0x61, 0x63, 0x65, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x05, 0x20,
0x01, 0x28, 0x09, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x32, 0xb3, 0x02, 0x0a, 0x0e, 0x53,
0x65, 0x61, 0x72, 0x63, 0x68, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64, 0x65, 0x72, 0x12, 0x85, 0x01,
0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x2b, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63,
0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65,
0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2c, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75,
0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63,
0x68, 0x2e, 0x76, 0x30, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x6e, 0x73, 0x65, 0x22, 0x20, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1a, 0x3a, 0x01, 0x2a, 0x22, 0x15,
0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x30, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x73,
0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x98, 0x01, 0x0a, 0x0a, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53,
0x70, 0x61, 0x63, 0x65, 0x12, 0x2f, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68,
0x2e, 0x76, 0x30, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52,
0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x31, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f,
0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72,
0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x49, 0x6e, 0x64, 0x65,
0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02,
0x20, 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x30, 0x2f, 0x73, 0x65,
0x61, 0x72, 0x63, 0x68, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63,
0x68, 0x42, 0xf2, 0x02, 0x5a, 0x4a, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2d, 0x65, 0x75, 0x2f, 0x6f, 0x70,
0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x67, 0x65, 0x6e,
0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x73,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x76, 0x30,
0x92, 0x41, 0xa2, 0x02, 0x12, 0xb7, 0x01, 0x0a, 0x10, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x6c, 0x6f,
0x75, 0x64, 0x20, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x22, 0x51, 0x0a, 0x0e, 0x4f, 0x70, 0x65,
0x6e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x20, 0x47, 0x6d, 0x62, 0x48, 0x12, 0x29, 0x68, 0x74, 0x74,
0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2d, 0x65, 0x75, 0x2f, 0x6f, 0x70, 0x65,
0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x1a, 0x14, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x40,
0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x65, 0x75, 0x2a, 0x49, 0x0a, 0x0a,
0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2d, 0x32, 0x2e, 0x30, 0x12, 0x3b, 0x68, 0x74, 0x74, 0x70,
0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f,
0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2d, 0x65, 0x75, 0x2f, 0x6f, 0x70, 0x65, 0x6e,
0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x62, 0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2f,
0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45, 0x32, 0x05, 0x31, 0x2e, 0x30, 0x2e, 0x30, 0x2a, 0x02,
0x01, 0x02, 0x32, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f,
0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x10, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x72, 0x3e, 0x0a, 0x10, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f,
0x70, 0x65, 0x72, 0x20, 0x4d, 0x61, 0x6e, 0x75, 0x61, 0x6c, 0x12, 0x2a, 0x68, 0x74, 0x74, 0x70,
0x73, 0x3a, 0x2f, 0x2f, 0x64, 0x6f, 0x63, 0x73, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f,
0x75, 0x64, 0x2e, 0x65, 0x75, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x73,
0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
0x2e, 0x76, 0x30, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52, 0x65,
0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x30, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75,
0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63,
0x68, 0x2e, 0x76, 0x30, 0x2e, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x53, 0x70, 0x61, 0x63, 0x65, 0x52,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x25, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x1f, 0x3a,
0x01, 0x2a, 0x22, 0x1a, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x76, 0x30, 0x2f, 0x73, 0x65, 0x61, 0x72,
0x63, 0x68, 0x2f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2d, 0x73, 0x70, 0x61, 0x63, 0x65, 0x30, 0x01,
0x32, 0xa7, 0x01, 0x0a, 0x0d, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x50, 0x72, 0x6f, 0x76, 0x69, 0x64,
0x65, 0x72, 0x12, 0x95, 0x01, 0x0a, 0x06, 0x53, 0x65, 0x61, 0x72, 0x63, 0x68, 0x12, 0x30, 0x2e,
0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63,
0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x53, 0x65, 0x61,
0x72, 0x63, 0x68, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x31, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x73, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x73, 0x2e, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2e, 0x76, 0x30, 0x2e, 0x53,
0x65, 0x61, 0x72, 0x63, 0x68, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e,
0x73, 0x65, 0x22, 0x26, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x20, 0x3a, 0x01, 0x2a, 0x22, 0x1b, 0x2f,
0x61, 0x70, 0x69, 0x2f, 0x76, 0x30, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x69, 0x6e,
0x64, 0x65, 0x78, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x42, 0xf2, 0x02, 0x5a, 0x4a, 0x67,
0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c,
0x6f, 0x75, 0x64, 0x2d, 0x65, 0x75, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64,
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x67, 0x65, 0x6e, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x6f, 0x70,
0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2f,
0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x76, 0x30, 0x92, 0x41, 0xa2, 0x02, 0x12, 0xb7, 0x01,
0x0a, 0x10, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x20, 0x73, 0x65, 0x61, 0x72,
0x63, 0x68, 0x22, 0x51, 0x0a, 0x0e, 0x4f, 0x70, 0x65, 0x6e, 0x43, 0x6c, 0x6f, 0x75, 0x64, 0x20,
0x47, 0x6d, 0x62, 0x48, 0x12, 0x29, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69,
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f,
0x75, 0x64, 0x2d, 0x65, 0x75, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x1a,
0x14, 0x73, 0x75, 0x70, 0x70, 0x6f, 0x72, 0x74, 0x40, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f,
0x75, 0x64, 0x2e, 0x65, 0x75, 0x2a, 0x49, 0x0a, 0x0a, 0x41, 0x70, 0x61, 0x63, 0x68, 0x65, 0x2d,
0x32, 0x2e, 0x30, 0x12, 0x3b, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x67, 0x69, 0x74,
0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75,
0x64, 0x2d, 0x65, 0x75, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2f, 0x62,
0x6c, 0x6f, 0x62, 0x2f, 0x6d, 0x61, 0x69, 0x6e, 0x2f, 0x4c, 0x49, 0x43, 0x45, 0x4e, 0x53, 0x45,
0x32, 0x05, 0x31, 0x2e, 0x30, 0x2e, 0x30, 0x2a, 0x02, 0x01, 0x02, 0x32, 0x10, 0x61, 0x70, 0x70,
0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x3a, 0x10, 0x61,
0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x6a, 0x73, 0x6f, 0x6e, 0x72,
0x3e, 0x0a, 0x10, 0x44, 0x65, 0x76, 0x65, 0x6c, 0x6f, 0x70, 0x65, 0x72, 0x20, 0x4d, 0x61, 0x6e,
0x75, 0x61, 0x6c, 0x12, 0x2a, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x64, 0x6f, 0x63,
0x73, 0x2e, 0x6f, 0x70, 0x65, 0x6e, 0x63, 0x6c, 0x6f, 0x75, 0x64, 0x2e, 0x65, 0x75, 0x2f, 0x73,
0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x73, 0x2f, 0x73, 0x65, 0x61, 0x72, 0x63, 0x68, 0x2f, 0x62,
0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
}
var (
@@ -551,23 +623,25 @@ var file_opencloud_services_search_v0_search_proto_goTypes = []interface{}{
(*IndexSpaceResponse)(nil), // 5: opencloud.services.search.v0.IndexSpaceResponse
(*v0.Reference)(nil), // 6: opencloud.messages.search.v0.Reference
(*v0.Match)(nil), // 7: opencloud.messages.search.v0.Match
(*durationpb.Duration)(nil), // 8: google.protobuf.Duration
}
var file_opencloud_services_search_v0_search_proto_depIdxs = []int32{
6, // 0: opencloud.services.search.v0.SearchRequest.ref:type_name -> opencloud.messages.search.v0.Reference
7, // 1: opencloud.services.search.v0.SearchResponse.matches:type_name -> opencloud.messages.search.v0.Match
6, // 2: opencloud.services.search.v0.SearchIndexRequest.ref:type_name -> opencloud.messages.search.v0.Reference
7, // 3: opencloud.services.search.v0.SearchIndexResponse.matches:type_name -> opencloud.messages.search.v0.Match
0, // 4: opencloud.services.search.v0.SearchProvider.Search:input_type -> opencloud.services.search.v0.SearchRequest
4, // 5: opencloud.services.search.v0.SearchProvider.IndexSpace:input_type -> opencloud.services.search.v0.IndexSpaceRequest
2, // 6: opencloud.services.search.v0.IndexProvider.Search:input_type -> opencloud.services.search.v0.SearchIndexRequest
1, // 7: opencloud.services.search.v0.SearchProvider.Search:output_type -> opencloud.services.search.v0.SearchResponse
5, // 8: opencloud.services.search.v0.SearchProvider.IndexSpace:output_type -> opencloud.services.search.v0.IndexSpaceResponse
3, // 9: opencloud.services.search.v0.IndexProvider.Search:output_type -> opencloud.services.search.v0.SearchIndexResponse
7, // [7:10] is the sub-list for method output_type
4, // [4:7] is the sub-list for method input_type
4, // [4:4] is the sub-list for extension type_name
4, // [4:4] is the sub-list for extension extendee
0, // [0:4] is the sub-list for field type_name
8, // 4: opencloud.services.search.v0.IndexSpaceResponse.space_duration:type_name -> google.protobuf.Duration
0, // 5: opencloud.services.search.v0.SearchProvider.Search:input_type -> opencloud.services.search.v0.SearchRequest
4, // 6: opencloud.services.search.v0.SearchProvider.IndexSpace:input_type -> opencloud.services.search.v0.IndexSpaceRequest
2, // 7: opencloud.services.search.v0.IndexProvider.Search:input_type -> opencloud.services.search.v0.SearchIndexRequest
1, // 8: opencloud.services.search.v0.SearchProvider.Search:output_type -> opencloud.services.search.v0.SearchResponse
5, // 9: opencloud.services.search.v0.SearchProvider.IndexSpace:output_type -> opencloud.services.search.v0.IndexSpaceResponse
3, // 10: opencloud.services.search.v0.IndexProvider.Search:output_type -> opencloud.services.search.v0.SearchIndexResponse
8, // [8:11] is the sub-list for method output_type
5, // [5:8] is the sub-list for method input_type
5, // [5:5] is the sub-list for extension type_name
5, // [5:5] is the sub-list for extension extendee
0, // [0:5] is the sub-list for field type_name
}
func init() { file_opencloud_services_search_v0_search_proto_init() }
@@ -9,6 +9,7 @@ import (
_ "github.com/opencloud-eu/opencloud/protogen/gen/opencloud/messages/search/v0"
_ "google.golang.org/genproto/googleapis/api/annotations"
proto "google.golang.org/protobuf/proto"
_ "google.golang.org/protobuf/types/known/durationpb"
_ "google.golang.org/protobuf/types/known/fieldmaskpb"
math "math"
)
@@ -45,6 +46,7 @@ func NewSearchProviderEndpoints() []*api.Endpoint {
Name: "SearchProvider.IndexSpace",
Path: []string{"/api/v0/search/index-space"},
Method: []string{"POST"},
Stream: true,
Handler: "rpc",
},
}
@@ -54,7 +56,9 @@ func NewSearchProviderEndpoints() []*api.Endpoint {
type SearchProviderService interface {
Search(ctx context.Context, in *SearchRequest, opts ...client.CallOption) (*SearchResponse, error)
IndexSpace(ctx context.Context, in *IndexSpaceRequest, opts ...client.CallOption) (*IndexSpaceResponse, error)
// IndexSpace (re)indexes one or all spaces. The response is streamed, sending
// progress information after each space has been indexed.
IndexSpace(ctx context.Context, in *IndexSpaceRequest, opts ...client.CallOption) (SearchProvider_IndexSpaceService, error)
}
type searchProviderService struct {
@@ -79,27 +83,73 @@ func (c *searchProviderService) Search(ctx context.Context, in *SearchRequest, o
return out, nil
}
func (c *searchProviderService) IndexSpace(ctx context.Context, in *IndexSpaceRequest, opts ...client.CallOption) (*IndexSpaceResponse, error) {
req := c.c.NewRequest(c.name, "SearchProvider.IndexSpace", in)
out := new(IndexSpaceResponse)
err := c.c.Call(ctx, req, out, opts...)
func (c *searchProviderService) IndexSpace(ctx context.Context, in *IndexSpaceRequest, opts ...client.CallOption) (SearchProvider_IndexSpaceService, error) {
req := c.c.NewRequest(c.name, "SearchProvider.IndexSpace", &IndexSpaceRequest{})
stream, err := c.c.Stream(ctx, req, opts...)
if err != nil {
return nil, err
}
return out, nil
if err := stream.Send(in); err != nil {
return nil, err
}
return &searchProviderServiceIndexSpace{stream}, nil
}
type SearchProvider_IndexSpaceService interface {
Context() context.Context
SendMsg(interface{}) error
RecvMsg(interface{}) error
CloseSend() error
Close() error
Recv() (*IndexSpaceResponse, error)
}
type searchProviderServiceIndexSpace struct {
stream client.Stream
}
func (x *searchProviderServiceIndexSpace) CloseSend() error {
return x.stream.CloseSend()
}
func (x *searchProviderServiceIndexSpace) Close() error {
return x.stream.Close()
}
func (x *searchProviderServiceIndexSpace) Context() context.Context {
return x.stream.Context()
}
func (x *searchProviderServiceIndexSpace) SendMsg(m interface{}) error {
return x.stream.Send(m)
}
func (x *searchProviderServiceIndexSpace) RecvMsg(m interface{}) error {
return x.stream.Recv(m)
}
func (x *searchProviderServiceIndexSpace) Recv() (*IndexSpaceResponse, error) {
m := new(IndexSpaceResponse)
err := x.stream.Recv(m)
if err != nil {
return nil, err
}
return m, nil
}
// Server API for SearchProvider service
type SearchProviderHandler interface {
Search(context.Context, *SearchRequest, *SearchResponse) error
IndexSpace(context.Context, *IndexSpaceRequest, *IndexSpaceResponse) error
// IndexSpace (re)indexes one or all spaces. The response is streamed, sending
// progress information after each space has been indexed.
IndexSpace(context.Context, *IndexSpaceRequest, SearchProvider_IndexSpaceStream) error
}
func RegisterSearchProviderHandler(s server.Server, hdlr SearchProviderHandler, opts ...server.HandlerOption) error {
type searchProvider interface {
Search(ctx context.Context, in *SearchRequest, out *SearchResponse) error
IndexSpace(ctx context.Context, in *IndexSpaceRequest, out *IndexSpaceResponse) error
IndexSpace(ctx context.Context, stream server.Stream) error
}
type SearchProvider struct {
searchProvider
@@ -115,6 +165,7 @@ func RegisterSearchProviderHandler(s server.Server, hdlr SearchProviderHandler,
Name: "SearchProvider.IndexSpace",
Path: []string{"/api/v0/search/index-space"},
Method: []string{"POST"},
Stream: true,
Handler: "rpc",
}))
return s.Handle(s.NewHandler(&SearchProvider{h}, opts...))
@@ -128,8 +179,44 @@ func (h *searchProviderHandler) Search(ctx context.Context, in *SearchRequest, o
return h.SearchProviderHandler.Search(ctx, in, out)
}
func (h *searchProviderHandler) IndexSpace(ctx context.Context, in *IndexSpaceRequest, out *IndexSpaceResponse) error {
return h.SearchProviderHandler.IndexSpace(ctx, in, out)
func (h *searchProviderHandler) IndexSpace(ctx context.Context, stream server.Stream) error {
m := new(IndexSpaceRequest)
if err := stream.Recv(m); err != nil {
return err
}
return h.SearchProviderHandler.IndexSpace(ctx, m, &searchProviderIndexSpaceStream{stream})
}
type SearchProvider_IndexSpaceStream interface {
Context() context.Context
SendMsg(interface{}) error
RecvMsg(interface{}) error
Close() error
Send(*IndexSpaceResponse) error
}
type searchProviderIndexSpaceStream struct {
stream server.Stream
}
func (x *searchProviderIndexSpaceStream) Close() error {
return x.stream.Close()
}
func (x *searchProviderIndexSpaceStream) Context() context.Context {
return x.stream.Context()
}
func (x *searchProviderIndexSpaceStream) SendMsg(m interface{}) error {
return x.stream.Send(m)
}
func (x *searchProviderIndexSpaceStream) RecvMsg(m interface{}) error {
return x.stream.Recv(m)
}
func (x *searchProviderIndexSpaceStream) Send(m *IndexSpaceResponse) error {
return x.stream.Send(m)
}
// Api Endpoints for IndexProvider service
@@ -1,346 +0,0 @@
// Code generated by protoc-gen-microweb. DO NOT EDIT.
// source: v0.proto
package v0
import (
"bytes"
"encoding/json"
"net/http"
"github.com/go-chi/chi/v5"
"github.com/go-chi/render"
"github.com/golang/protobuf/jsonpb"
merrors "go-micro.dev/v4/errors"
)
type webSearchProviderHandler struct {
r chi.Router
h SearchProviderHandler
}
func (h *webSearchProviderHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.r.ServeHTTP(w, r)
}
func (h *webSearchProviderHandler) Search(w http.ResponseWriter, r *http.Request) {
req := &SearchRequest{}
resp := &SearchResponse{}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusPreconditionFailed)
return
}
if err := h.h.Search(
r.Context(),
req,
resp,
); err != nil {
if merr, ok := merrors.As(err); ok && merr.Code == http.StatusNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusBadRequest)
}
return
}
render.Status(r, http.StatusCreated)
render.JSON(w, r, resp)
}
func (h *webSearchProviderHandler) IndexSpace(w http.ResponseWriter, r *http.Request) {
req := &IndexSpaceRequest{}
resp := &IndexSpaceResponse{}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusPreconditionFailed)
return
}
if err := h.h.IndexSpace(
r.Context(),
req,
resp,
); err != nil {
if merr, ok := merrors.As(err); ok && merr.Code == http.StatusNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusBadRequest)
}
return
}
render.Status(r, http.StatusCreated)
render.JSON(w, r, resp)
}
func RegisterSearchProviderWeb(r chi.Router, i SearchProviderHandler, middlewares ...func(http.Handler) http.Handler) {
handler := &webSearchProviderHandler{
r: r,
h: i,
}
r.MethodFunc("POST", "/api/v0/search/search", handler.Search)
r.MethodFunc("POST", "/api/v0/search/index-space", handler.IndexSpace)
}
type webIndexProviderHandler struct {
r chi.Router
h IndexProviderHandler
}
func (h *webIndexProviderHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
h.r.ServeHTTP(w, r)
}
func (h *webIndexProviderHandler) Search(w http.ResponseWriter, r *http.Request) {
req := &SearchIndexRequest{}
resp := &SearchIndexResponse{}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), http.StatusPreconditionFailed)
return
}
if err := h.h.Search(
r.Context(),
req,
resp,
); err != nil {
if merr, ok := merrors.As(err); ok && merr.Code == http.StatusNotFound {
http.Error(w, err.Error(), http.StatusNotFound)
} else {
http.Error(w, err.Error(), http.StatusBadRequest)
}
return
}
render.Status(r, http.StatusCreated)
render.JSON(w, r, resp)
}
func RegisterIndexProviderWeb(r chi.Router, i IndexProviderHandler, middlewares ...func(http.Handler) http.Handler) {
handler := &webIndexProviderHandler{
r: r,
h: i,
}
r.MethodFunc("POST", "/api/v0/search/index/search", handler.Search)
}
// SearchRequestJSONMarshaler describes the default jsonpb.Marshaler used by all
// instances of SearchRequest. This struct is safe to replace or modify but
// should not be done so concurrently.
var SearchRequestJSONMarshaler = new(jsonpb.Marshaler)
// MarshalJSON satisfies the encoding/json Marshaler interface. This method
// uses the more correct jsonpb package to correctly marshal the message.
func (m *SearchRequest) MarshalJSON() ([]byte, error) {
if m == nil {
return json.Marshal(nil)
}
buf := &bytes.Buffer{}
if err := SearchRequestJSONMarshaler.Marshal(buf, m); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
var _ json.Marshaler = (*SearchRequest)(nil)
// SearchRequestJSONUnmarshaler describes the default jsonpb.Unmarshaler used by all
// instances of SearchRequest. This struct is safe to replace or modify but
// should not be done so concurrently.
var SearchRequestJSONUnmarshaler = new(jsonpb.Unmarshaler)
// UnmarshalJSON satisfies the encoding/json Unmarshaler interface. This method
// uses the more correct jsonpb package to correctly unmarshal the message.
func (m *SearchRequest) UnmarshalJSON(b []byte) error {
return SearchRequestJSONUnmarshaler.Unmarshal(bytes.NewReader(b), m)
}
var _ json.Unmarshaler = (*SearchRequest)(nil)
// SearchResponseJSONMarshaler describes the default jsonpb.Marshaler used by all
// instances of SearchResponse. This struct is safe to replace or modify but
// should not be done so concurrently.
var SearchResponseJSONMarshaler = new(jsonpb.Marshaler)
// MarshalJSON satisfies the encoding/json Marshaler interface. This method
// uses the more correct jsonpb package to correctly marshal the message.
func (m *SearchResponse) MarshalJSON() ([]byte, error) {
if m == nil {
return json.Marshal(nil)
}
buf := &bytes.Buffer{}
if err := SearchResponseJSONMarshaler.Marshal(buf, m); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
var _ json.Marshaler = (*SearchResponse)(nil)
// SearchResponseJSONUnmarshaler describes the default jsonpb.Unmarshaler used by all
// instances of SearchResponse. This struct is safe to replace or modify but
// should not be done so concurrently.
var SearchResponseJSONUnmarshaler = new(jsonpb.Unmarshaler)
// UnmarshalJSON satisfies the encoding/json Unmarshaler interface. This method
// uses the more correct jsonpb package to correctly unmarshal the message.
func (m *SearchResponse) UnmarshalJSON(b []byte) error {
return SearchResponseJSONUnmarshaler.Unmarshal(bytes.NewReader(b), m)
}
var _ json.Unmarshaler = (*SearchResponse)(nil)
// SearchIndexRequestJSONMarshaler describes the default jsonpb.Marshaler used by all
// instances of SearchIndexRequest. This struct is safe to replace or modify but
// should not be done so concurrently.
var SearchIndexRequestJSONMarshaler = new(jsonpb.Marshaler)
// MarshalJSON satisfies the encoding/json Marshaler interface. This method
// uses the more correct jsonpb package to correctly marshal the message.
func (m *SearchIndexRequest) MarshalJSON() ([]byte, error) {
if m == nil {
return json.Marshal(nil)
}
buf := &bytes.Buffer{}
if err := SearchIndexRequestJSONMarshaler.Marshal(buf, m); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
var _ json.Marshaler = (*SearchIndexRequest)(nil)
// SearchIndexRequestJSONUnmarshaler describes the default jsonpb.Unmarshaler used by all
// instances of SearchIndexRequest. This struct is safe to replace or modify but
// should not be done so concurrently.
var SearchIndexRequestJSONUnmarshaler = new(jsonpb.Unmarshaler)
// UnmarshalJSON satisfies the encoding/json Unmarshaler interface. This method
// uses the more correct jsonpb package to correctly unmarshal the message.
func (m *SearchIndexRequest) UnmarshalJSON(b []byte) error {
return SearchIndexRequestJSONUnmarshaler.Unmarshal(bytes.NewReader(b), m)
}
var _ json.Unmarshaler = (*SearchIndexRequest)(nil)
// SearchIndexResponseJSONMarshaler describes the default jsonpb.Marshaler used by all
// instances of SearchIndexResponse. This struct is safe to replace or modify but
// should not be done so concurrently.
var SearchIndexResponseJSONMarshaler = new(jsonpb.Marshaler)
// MarshalJSON satisfies the encoding/json Marshaler interface. This method
// uses the more correct jsonpb package to correctly marshal the message.
func (m *SearchIndexResponse) MarshalJSON() ([]byte, error) {
if m == nil {
return json.Marshal(nil)
}
buf := &bytes.Buffer{}
if err := SearchIndexResponseJSONMarshaler.Marshal(buf, m); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
var _ json.Marshaler = (*SearchIndexResponse)(nil)
// SearchIndexResponseJSONUnmarshaler describes the default jsonpb.Unmarshaler used by all
// instances of SearchIndexResponse. This struct is safe to replace or modify but
// should not be done so concurrently.
var SearchIndexResponseJSONUnmarshaler = new(jsonpb.Unmarshaler)
// UnmarshalJSON satisfies the encoding/json Unmarshaler interface. This method
// uses the more correct jsonpb package to correctly unmarshal the message.
func (m *SearchIndexResponse) UnmarshalJSON(b []byte) error {
return SearchIndexResponseJSONUnmarshaler.Unmarshal(bytes.NewReader(b), m)
}
var _ json.Unmarshaler = (*SearchIndexResponse)(nil)
// IndexSpaceRequestJSONMarshaler describes the default jsonpb.Marshaler used by all
// instances of IndexSpaceRequest. This struct is safe to replace or modify but
// should not be done so concurrently.
var IndexSpaceRequestJSONMarshaler = new(jsonpb.Marshaler)
// MarshalJSON satisfies the encoding/json Marshaler interface. This method
// uses the more correct jsonpb package to correctly marshal the message.
func (m *IndexSpaceRequest) MarshalJSON() ([]byte, error) {
if m == nil {
return json.Marshal(nil)
}
buf := &bytes.Buffer{}
if err := IndexSpaceRequestJSONMarshaler.Marshal(buf, m); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
var _ json.Marshaler = (*IndexSpaceRequest)(nil)
// IndexSpaceRequestJSONUnmarshaler describes the default jsonpb.Unmarshaler used by all
// instances of IndexSpaceRequest. This struct is safe to replace or modify but
// should not be done so concurrently.
var IndexSpaceRequestJSONUnmarshaler = new(jsonpb.Unmarshaler)
// UnmarshalJSON satisfies the encoding/json Unmarshaler interface. This method
// uses the more correct jsonpb package to correctly unmarshal the message.
func (m *IndexSpaceRequest) UnmarshalJSON(b []byte) error {
return IndexSpaceRequestJSONUnmarshaler.Unmarshal(bytes.NewReader(b), m)
}
var _ json.Unmarshaler = (*IndexSpaceRequest)(nil)
// IndexSpaceResponseJSONMarshaler describes the default jsonpb.Marshaler used by all
// instances of IndexSpaceResponse. This struct is safe to replace or modify but
// should not be done so concurrently.
var IndexSpaceResponseJSONMarshaler = new(jsonpb.Marshaler)
// MarshalJSON satisfies the encoding/json Marshaler interface. This method
// uses the more correct jsonpb package to correctly marshal the message.
func (m *IndexSpaceResponse) MarshalJSON() ([]byte, error) {
if m == nil {
return json.Marshal(nil)
}
buf := &bytes.Buffer{}
if err := IndexSpaceResponseJSONMarshaler.Marshal(buf, m); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
var _ json.Marshaler = (*IndexSpaceResponse)(nil)
// IndexSpaceResponseJSONUnmarshaler describes the default jsonpb.Unmarshaler used by all
// instances of IndexSpaceResponse. This struct is safe to replace or modify but
// should not be done so concurrently.
var IndexSpaceResponseJSONUnmarshaler = new(jsonpb.Unmarshaler)
// UnmarshalJSON satisfies the encoding/json Unmarshaler interface. This method
// uses the more correct jsonpb package to correctly unmarshal the message.
func (m *IndexSpaceResponse) UnmarshalJSON(b []byte) error {
return IndexSpaceResponseJSONUnmarshaler.Unmarshal(bytes.NewReader(b), m)
}
var _ json.Unmarshaler = (*IndexSpaceResponse)(nil)
@@ -34,12 +34,22 @@
"paths": {
"/api/v0/search/index-space": {
"post": {
"summary": "IndexSpace (re)indexes one or all spaces. The response is streamed, sending\nprogress information after each space has been indexed.",
"operationId": "SearchProvider_IndexSpace",
"responses": {
"200": {
"description": "A successful response.",
"description": "A successful response.(streaming responses)",
"schema": {
"$ref": "#/definitions/v0IndexSpaceResponse"
"type": "object",
"properties": {
"result": {
"$ref": "#/definitions/v0IndexSpaceResponse"
},
"error": {
"$ref": "#/definitions/rpcStatus"
}
},
"title": "Stream result of v0IndexSpaceResponse"
}
},
"default": {
@@ -332,11 +342,39 @@
},
"forceReindex": {
"type": "boolean"
},
"concurrency": {
"type": "integer",
"format": "int32"
}
}
},
"v0IndexSpaceResponse": {
"type": "object"
"type": "object",
"properties": {
"spaceId": {
"type": "string",
"description": "The id of the space that has just been indexed."
},
"spaceDuration": {
"type": "string",
"description": "The duration it took to index this space."
},
"indexedSpaces": {
"type": "string",
"format": "int64",
"description": "The number of spaces that have been indexed so far."
},
"totalSpaces": {
"type": "string",
"format": "int64",
"description": "The total number of spaces that are being indexed."
},
"error": {
"type": "string",
"description": "Contains an error message in case indexing this particular space failed."
}
}
},
"v0Match": {
"type": "object",
@@ -28,7 +28,9 @@ const (
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type SearchProviderClient interface {
Search(ctx context.Context, in *SearchRequest, opts ...grpc.CallOption) (*SearchResponse, error)
IndexSpace(ctx context.Context, in *IndexSpaceRequest, opts ...grpc.CallOption) (*IndexSpaceResponse, error)
// IndexSpace (re)indexes one or all spaces. The response is streamed, sending
// progress information after each space has been indexed.
IndexSpace(ctx context.Context, in *IndexSpaceRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[IndexSpaceResponse], error)
}
type searchProviderClient struct {
@@ -49,22 +51,33 @@ func (c *searchProviderClient) Search(ctx context.Context, in *SearchRequest, op
return out, nil
}
func (c *searchProviderClient) IndexSpace(ctx context.Context, in *IndexSpaceRequest, opts ...grpc.CallOption) (*IndexSpaceResponse, error) {
func (c *searchProviderClient) IndexSpace(ctx context.Context, in *IndexSpaceRequest, opts ...grpc.CallOption) (grpc.ServerStreamingClient[IndexSpaceResponse], error) {
cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...)
out := new(IndexSpaceResponse)
err := c.cc.Invoke(ctx, SearchProvider_IndexSpace_FullMethodName, in, out, cOpts...)
stream, err := c.cc.NewStream(ctx, &SearchProvider_ServiceDesc.Streams[0], SearchProvider_IndexSpace_FullMethodName, cOpts...)
if err != nil {
return nil, err
}
return out, nil
x := &grpc.GenericClientStream[IndexSpaceRequest, IndexSpaceResponse]{ClientStream: stream}
if err := x.ClientStream.SendMsg(in); err != nil {
return nil, err
}
if err := x.ClientStream.CloseSend(); err != nil {
return nil, err
}
return x, nil
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type SearchProvider_IndexSpaceClient = grpc.ServerStreamingClient[IndexSpaceResponse]
// SearchProviderServer is the server API for SearchProvider service.
// All implementations must embed UnimplementedSearchProviderServer
// for forward compatibility.
type SearchProviderServer interface {
Search(context.Context, *SearchRequest) (*SearchResponse, error)
IndexSpace(context.Context, *IndexSpaceRequest) (*IndexSpaceResponse, error)
// IndexSpace (re)indexes one or all spaces. The response is streamed, sending
// progress information after each space has been indexed.
IndexSpace(*IndexSpaceRequest, grpc.ServerStreamingServer[IndexSpaceResponse]) error
mustEmbedUnimplementedSearchProviderServer()
}
@@ -78,8 +91,8 @@ type UnimplementedSearchProviderServer struct{}
func (UnimplementedSearchProviderServer) Search(context.Context, *SearchRequest) (*SearchResponse, error) {
return nil, status.Error(codes.Unimplemented, "method Search not implemented")
}
func (UnimplementedSearchProviderServer) IndexSpace(context.Context, *IndexSpaceRequest) (*IndexSpaceResponse, error) {
return nil, status.Error(codes.Unimplemented, "method IndexSpace not implemented")
func (UnimplementedSearchProviderServer) IndexSpace(*IndexSpaceRequest, grpc.ServerStreamingServer[IndexSpaceResponse]) error {
return status.Error(codes.Unimplemented, "method IndexSpace not implemented")
}
func (UnimplementedSearchProviderServer) mustEmbedUnimplementedSearchProviderServer() {}
func (UnimplementedSearchProviderServer) testEmbeddedByValue() {}
@@ -120,24 +133,17 @@ func _SearchProvider_Search_Handler(srv interface{}, ctx context.Context, dec fu
return interceptor(ctx, in, info, handler)
}
func _SearchProvider_IndexSpace_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(IndexSpaceRequest)
if err := dec(in); err != nil {
return nil, err
func _SearchProvider_IndexSpace_Handler(srv interface{}, stream grpc.ServerStream) error {
m := new(IndexSpaceRequest)
if err := stream.RecvMsg(m); err != nil {
return err
}
if interceptor == nil {
return srv.(SearchProviderServer).IndexSpace(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: SearchProvider_IndexSpace_FullMethodName,
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(SearchProviderServer).IndexSpace(ctx, req.(*IndexSpaceRequest))
}
return interceptor(ctx, in, info, handler)
return srv.(SearchProviderServer).IndexSpace(m, &grpc.GenericServerStream[IndexSpaceRequest, IndexSpaceResponse]{ServerStream: stream})
}
// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name.
type SearchProvider_IndexSpaceServer = grpc.ServerStreamingServer[IndexSpaceResponse]
// SearchProvider_ServiceDesc is the grpc.ServiceDesc for SearchProvider service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
@@ -149,12 +155,14 @@ var SearchProvider_ServiceDesc = grpc.ServiceDesc{
MethodName: "Search",
Handler: _SearchProvider_Search_Handler,
},
},
Streams: []grpc.StreamDesc{
{
MethodName: "IndexSpace",
Handler: _SearchProvider_IndexSpace_Handler,
StreamName: "IndexSpace",
Handler: _SearchProvider_IndexSpace_Handler,
ServerStreams: true,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "opencloud/services/search/v0/search.proto",
}
+3 -1
View File
@@ -31,7 +31,9 @@ plugins:
opencloud.services.eventhistory.v0;\
opencloud.messages.eventhistory.v0;\
opencloud.services.policies.v0;\
opencloud.messages.policies.v0"
opencloud.messages.policies.v0;\
opencloud.services.search.v0;\
opencloud.messages.search.v0"
- name: openapiv2
path: ../../.bingo/protoc-gen-openapiv2
@@ -9,6 +9,7 @@ import "protoc-gen-openapiv2/options/annotations.proto";
import "google/api/field_behavior.proto";
import "google/api/annotations.proto";
import "google/protobuf/field_mask.proto";
import "google/protobuf/duration.proto";
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
info: {
@@ -41,7 +42,9 @@ service SearchProvider {
body: "*"
};
};
rpc IndexSpace(IndexSpaceRequest) returns (IndexSpaceResponse) {
// IndexSpace (re)indexes one or all spaces. The response is streamed, sending
// progress information after each space has been indexed.
rpc IndexSpace(IndexSpaceRequest) returns (stream IndexSpaceResponse) {
option (google.api.http) = {
post: "/api/v0/search/index-space",
body: "*"
@@ -105,7 +108,18 @@ message IndexSpaceRequest {
string space_id = 1;
string user_id = 2;
bool force_reindex = 3;
int32 concurrency = 4 [(google.api.field_behavior) = OPTIONAL];
}
message IndexSpaceResponse {
// The id of the space that has just been indexed.
string space_id = 1;
// The duration it took to index this space.
google.protobuf.Duration space_duration = 2;
// The number of spaces that have been indexed so far.
int64 indexed_spaces = 3;
// The total number of spaces that are being indexed.
int64 total_spaces = 4;
// Contains an error message in case indexing this particular space failed.
string error = 5;
}
+32
View File
@@ -73,6 +73,38 @@ export default {
const latestTag = tags.pop() || "v0.0.0";
return compareVersions(latestTag, nextVersion) === -1;
},
getReleaseDescription: async ({ nextVersion }) => {
const note =
"> [!IMPORTANT]\n" +
"> This is a rolling release. Learn here about the [release types and lifecycle](https://docs.opencloud.eu/docs/admin/resources/lifecycle#release-types).\n\n";
// Exclude the "📦️ Dependencies" section from the release description
const section = removeChangelogSubsection(
await getChangelogSection(nextVersion),
"📦️ Dependencies"
);
return `${note}${section}`;
},
};
// helper functions
const getChangelogSection = async (nextVersion: string) => {
const { promises: fs } = await import("fs");
const changelog = await fs.readFile("CHANGELOG.md", "utf-8").catch(() => "");
const section = changelog
.split(/\n(?=## \[)/)
.find((s) => s.startsWith(`## [${nextVersion}]`));
return section?.trim() ?? "";
};
const removeChangelogSubsection = (section: string, heading: string) => {
return section
.split(/\n(?=### )/)
.filter((s) => !s.startsWith(`### ${heading}`))
.join("\n")
.trim();
};
const parseVersion = (tag: string) => {
+3 -3
View File
@@ -56,9 +56,9 @@ type Store struct {
TTL time.Duration `yaml:"ttl" env:"OC_PERSISTENT_STORE_TTL;ACTIVITYLOG_STORE_TTL" desc:"Time to live for events in the store. See the Environment Variable Types description for more details." introductionVersion:"1.0.0"`
AuthUsername string `yaml:"username" env:"OC_PERSISTENT_STORE_AUTH_USERNAME;ACTIVITYLOG_STORE_AUTH_USERNAME" desc:"The username to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
AuthPassword string `yaml:"password" env:"OC_PERSISTENT_STORE_AUTH_PASSWORD;ACTIVITYLOG_STORE_AUTH_PASSWORD" desc:"The password to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
EnableTLS bool `yaml:"enable_tls" env:"OC_PERSISTENT_STORE_ENABLE_TLS;ACTIVITYLOG_STORE_ENABLE_TLS" desc:"Enable TLS for the connection to the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"%%NEXT%%"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_PERSISTENT_STORE_TLS_INSECURE;ACTIVITYLOG_STORE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"%%NEXT%%"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_PERSISTENT_STORE_TLS_ROOT_CA_CERTIFICATE;ACTIVITYLOG_STORE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided ACTIVITYLOG_STORE_TLS_INSECURE will be seen as false." introductionVersion:"%%NEXT%%"`
EnableTLS bool `yaml:"enable_tls" env:"OC_PERSISTENT_STORE_ENABLE_TLS;ACTIVITYLOG_STORE_ENABLE_TLS" desc:"Enable TLS for the connection to the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"7.3.0"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_PERSISTENT_STORE_TLS_INSECURE;ACTIVITYLOG_STORE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"7.3.0"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_PERSISTENT_STORE_TLS_ROOT_CA_CERTIFICATE;ACTIVITYLOG_STORE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided ACTIVITYLOG_STORE_TLS_INSECURE will be seen as false." introductionVersion:"7.3.0"`
}
// ServiceAccount is the configuration for the used service account
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-08-08 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Ivan Fustero, 2025\n"
"Language-Team: Catalan (https://app.transifex.com/opencloud-eu/teams/204053/ca/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-08-08 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Jörn Friedrich Dreyer <jfd@butonic.de>, 2025\n"
"Language-Team: German (https://app.transifex.com/opencloud-eu/teams/204053/de/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-08-08 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Efstathios Iosifidis <eiosifidis@gmail.com>, 2026\n"
"Language-Team: Greek (https://app.transifex.com/opencloud-eu/teams/204053/el/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-08-08 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Elías Martín, 2025\n"
"Language-Team: Spanish (https://app.transifex.com/opencloud-eu/teams/204053/es/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-08-08 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n"
"Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-08-08 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: eric_G <junk.eg@free.fr>, 2025\n"
"Language-Team: French (https://app.transifex.com/opencloud-eu/teams/204053/fr/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-08-08 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: mitibor, 2026\n"
"Language-Team: Hungarian (https://app.transifex.com/opencloud-eu/teams/204053/hu/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-08-08 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Simone Broglia, 2025\n"
"Language-Team: Italian (https://app.transifex.com/opencloud-eu/teams/204053/it/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-08-08 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: iikaka88, 2025\n"
"Language-Team: Japanese (https://app.transifex.com/opencloud-eu/teams/204053/ja/)\n"
@@ -12,7 +12,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-08-08 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: 4580f07cef35810b72f8a1e8fd521c9a_6684a19 <07c3e3571dc5eebd81f2c3a10488f503_1171750>, 2025\n"
"Language-Team: Korean (https://app.transifex.com/opencloud-eu/teams/204053/ko/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-08-08 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: BoneNI, 2026\n"
"Language-Team: Lao (https://app.transifex.com/opencloud-eu/teams/204053/lo/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-08-08 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Stephan Paternotte <stephan@paternottes.net>, 2025\n"
"Language-Team: Dutch (https://app.transifex.com/opencloud-eu/teams/204053/nl/)\n"
@@ -13,7 +13,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-08-08 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Matt, 2026\n"
"Language-Team: Polish (https://app.transifex.com/opencloud-eu/teams/204053/pl/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-08-08 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Mário Machado, 2025\n"
"Language-Team: Portuguese (https://app.transifex.com/opencloud-eu/teams/204053/pt/)\n"
@@ -12,7 +12,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-08-08 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Lulufox, 2025\n"
"Language-Team: Russian (https://app.transifex.com/opencloud-eu/teams/204053/ru/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-08-08 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Daniel Nylander <po@danielnylander.se>, 2025\n"
"Language-Team: Swedish (https://app.transifex.com/opencloud-eu/teams/204053/sv/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-08-08 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Quan Tran, 2025\n"
"Language-Team: Vietnamese (https://app.transifex.com/opencloud-eu/teams/204053/vi/)\n"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-06-29 23:15+0000\n"
"POT-Creation-Date: 2026-08-08 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: YQS Yang, 2025\n"
"Language-Team: Chinese (https://app.transifex.com/opencloud-eu/teams/204053/zh/)\n"
+33 -15
View File
@@ -11,7 +11,7 @@ PROXY_ENABLE_APP_AUTH=false # mandatory, disables app authentication. In ca
## App Tokens
App Tokens are password specifically generated to be used by 3rd party applications
App Tokens are passwords specifically generated to be used by 3rd party applications
for authentication when accessing the OpenCloud API endpoints. To
be able to use an app token, one must first create a token. There are different
options of creating a token.
@@ -32,16 +32,22 @@ in the `graph` service for allowing the management of App Tokens.
The `auth-app` service provides an API to create (POST), list (GET) and delete (DELETE) tokens at the `/auth-app/tokens` endpoint.
* **Create a token**\
* **Create a token**
The POST request requires:
* A `expiry` key/value pair in the form of `expiry=<number><h|m|s>`\
Example: `expiry=72h`
An `expiry` key/value pair in the form of `expiry=<number><h|m|s>`
Example: `expiry=72h`
```bash
curl --request POST 'https://<your host:9200>/auth-app/tokens?expiry={value}' \
--header 'accept: application/json'
```
Example output:
```
```bash
{
"token": "3s2K7816M4vuSpd5",
"expiration_date": "2024-08-08T13:42:42.796888022+02:00",
@@ -53,18 +59,20 @@ The `auth-app` service provides an API to create (POST), list (GET) and delete (
Note, that this is the only time the app token will be returned in cleartext. To use the token
please copy it from the response.
* **List tokens**\
* **List tokens**
```bash
curl --request GET 'https://<your host:9200>/auth-app/tokens' \
--header 'accept: application/json'
```
Note that the `token` value in the response to the "List Tokens` request is not the actual
Note that the `token` value in the response to the "List Tokens" request is not the actual
app token, but the UUID of the token. So this value cannot be used for authenticating
with the token.
Example output:
```
```bash
[
{
"token": "155f402e-1c5c-411c-92d4-92f3b612cd99"
@@ -81,10 +89,14 @@ The `auth-app` service provides an API to create (POST), list (GET) and delete (
]
```
* **Delete a token**\
* **Delete a token**
The DELETE request requires:
* A `token` key/value pair in the form of `token=<token_issued>`. The value needs to be the hashed value as returned by the `List Tokens` respone.\
A `token` key/value pair in the form of `token=<token_issued>`. The value needs to be the hashed value as returned by the `List Tokens` respone.
Example: `token=8c606bdb-e22e-4094-9304-732fd4702bc9`
```bash
curl --request DELETE 'https://<your host:9200>/auth-app/tokens?token={value}' \
--header 'accept: application/json'
@@ -101,16 +113,22 @@ reasons.
To impersonate, the respective requests from the CLI commands above extend with
the following parameters, where you can use one or the other:
* The `userID` in the form of: `userID={value}`\
Example:\
* The `userID` in the form of: `userID={value}`
Example:
`userID=4c510ada- ... -42cdf82c3d51`
* The `userName` in the form of: `userName={value}`\
Example:\
* The `userName` in the form of: `userName={value}`
Example:
`userName=alan`
Example:\
Example:
A final create request would then look like:
```bash
curl --request POST 'https://<your host:9200>/auth-app/tokens?expiry={value}&userName={value}' \
--header 'accept: application/json'
+2
View File
@@ -48,6 +48,8 @@ var _registeredEvents = []events.Unmarshaller{
events.LinkUpdated{},
events.LinkRemoved{},
events.BackchannelLogout{},
events.LabelAdded{},
events.LabelRemoved{},
}
// Server is the entrypoint for the server command.
+27
View File
@@ -132,6 +132,11 @@ func (cl *ClientlogService) processEvent(event events.Event) {
users, data, err = processShareEvent(ctx, ref, gwc, event.InitiatorID, uid, gid)
}
labelEv := func(typ string, ref *provider.Reference, uid *user.UserId) {
evType = typ
users, data, err = processLabelEvent(ctx, ref, gwc, event.InitiatorID, uid)
}
spaceEv := func(typ string, id *provider.StorageSpaceId, uids []string) {
evType = typ
users, data, err = processSpaceEvent(ctx, id, gwc, event.InitiatorID, uids)
@@ -166,6 +171,10 @@ func (cl *ClientlogService) processEvent(event events.Event) {
fileEv("file-unlocked", e.Ref)
case events.FileTouched:
fileEv("file-touched", e.Ref)
case events.LabelAdded:
labelEv("item-favorite-added", e.Ref, e.UserID)
case events.LabelRemoved:
labelEv("item-favorite-removed", e.Ref, e.UserID)
case events.SpaceCreated:
spaceEv("space-created", e.ID, []string{e.Executant.GetOpaqueId()})
case events.SpaceDisabled:
@@ -255,6 +264,24 @@ func processFileEvent(ctx context.Context, ref *provider.Reference, gwc gateway.
return users, data, err
}
// process label (e.g. favorite) related events, notifying only the user the label belongs to
func processLabelEvent(ctx context.Context, ref *provider.Reference, gwc gateway.GatewayAPIClient, initiatorid string, uid *user.UserId) ([]string, FileEvent, error) {
info, err := utils.GetResource(ctx, ref, gwc)
if err != nil {
return nil, FileEvent{}, err
}
data := FileEvent{
ParentItemID: storagespace.FormatResourceID(info.GetParentId()),
ItemID: storagespace.FormatResourceID(info.GetId()),
SpaceID: storagespace.FormatStorageID(info.GetSpace().GetRoot().GetStorageId(), info.GetSpace().GetRoot().GetSpaceId()),
InitiatorID: initiatorid,
Etag: info.GetEtag(),
}
return []string{uid.GetOpaqueId()}, data, nil
}
// process share related events
func processShareEvent(ctx context.Context, ref *provider.Reference, gwc gateway.GatewayAPIClient, initiatorid string, shareeID *user.UserId, shareeGroupID *group.GroupId) ([]string, FileEvent, error) {
users, data, err := processFileEvent(ctx, ref, gwc, initiatorid)
+2 -3
View File
@@ -2,7 +2,7 @@
The collaboration service connects opencloud with document servers such as Collabora, ONLYOFFICE or Microsoft using the WOPI protocol.
Since this service requires an external document server, it won't start by default when using `opencloud server`. You must start it manually with the `opencloud collaboration server` command.
Since this service requires an external document server, it is not enabled by default. You need to add it to `OC_RUN_SERVICES`, `OC_ADD_RUN_SERVICES` or start it in a separate process with the `opencloud collaboration server` command.
Because the collaboration service needs to be started manually, the following prerequisite applies: On collaboration service startup, particular environment variables are required to be populated. If environment variables have a default like the `MICRO_REGISTRY_ADDRESS`, the default will be used, if not set otherwise. Use for all others the instance values as defined. If these environment variables are not provided or misconfigured, the collaboration service will not start up.
@@ -14,9 +14,8 @@ Required environment variables:
## Requirements
The collaboration service requires the target document server (ONLYOFFICE, Collabora, etc.) to be up and running. Additionally, some OpenCloud services are also required to be running in order to register the GRPC service for the `open in app` action in the webUI. The following internal and external services need to be available:
The collaboration periodically checks the target document server (ONLYOFFICE, Collabora, etc.) to update the available edit options. Additionally, some OpenCloud services are required to be running in order to register the GRPC service for the `open in app` action in the webUI. The following internal and external services need to be available:
* External document server.
* The gateway service.
* The app-registry service.
+1 -1
View File
@@ -29,5 +29,5 @@ type Config struct {
Context context.Context `yaml:"-"`
MachineAuthAPIKey string `yaml:"machine_auth_api_key" env:"OC_MACHINE_AUTH_API_KEY;COLLABORATION_MACHINE_AUTH_API_KEY" desc:"The machine auth API key used to validate internal requests necessary to access resources from other services." introductionVersion:"%%NEXT%%"`
MachineAuthAPIKey string `yaml:"machine_auth_api_key" env:"OC_MACHINE_AUTH_API_KEY;COLLABORATION_MACHINE_AUTH_API_KEY" desc:"The machine auth API key used to validate internal requests necessary to access resources from other services." introductionVersion:"7.3.0"`
}
+7 -7
View File
@@ -2,11 +2,11 @@ package config
// Events combines the configuration options for the event bus.
type Events struct {
Endpoint string `yaml:"endpoint" env:"OC_EVENTS_ENDPOINT;COLLABORATION_EVENTS_ENDPOINT" desc:"The address of the event system. The event system is the message queuing service. It is used as message broker for the microservice architecture." introductionVersion:"%%NEXT%%"`
Cluster string `yaml:"cluster" env:"OC_EVENTS_CLUSTER;COLLABORATION_EVENTS_CLUSTER" desc:"The clusterID of the event system. The event system is the message queuing service. It is used as message broker for the microservice architecture. Mandatory when using NATS as event system." introductionVersion:"%%NEXT%%"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_EVENTS_TLS_INSECURE;COLLABORATION_EVENTS_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"%%NEXT%%"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_EVENTS_TLS_ROOT_CA_CERTIFICATE;COLLABORATION_EVENTS_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided COLLABORATION_EVENTS_TLS_INSECURE will be seen as false." introductionVersion:"%%NEXT%%"`
EnableTLS bool `yaml:"enable_tls" env:"OC_EVENTS_ENABLE_TLS;COLLABORATION_EVENTS_ENABLE_TLS" desc:"Enable TLS for the connection to the events broker. The events broker is the OpenCloud service which receives and delivers events between the services." introductionVersion:"%%NEXT%%"`
AuthUsername string `yaml:"username" env:"OC_EVENTS_AUTH_USERNAME;COLLABORATION_EVENTS_AUTH_USERNAME" desc:"The username to authenticate with the events broker. The events broker is the OpenCloud service which receives and delivers events between the services." introductionVersion:"%%NEXT%%"`
AuthPassword string `yaml:"password" env:"OC_EVENTS_AUTH_PASSWORD;COLLABORATION_EVENTS_AUTH_PASSWORD" desc:"The password to authenticate with the events broker. The events broker is the OpenCloud service which receives and delivers events between the services." introductionVersion:"%%NEXT%%"`
Endpoint string `yaml:"endpoint" env:"OC_EVENTS_ENDPOINT;COLLABORATION_EVENTS_ENDPOINT" desc:"The address of the event system. The event system is the message queuing service. It is used as message broker for the microservice architecture." introductionVersion:"7.3.0"`
Cluster string `yaml:"cluster" env:"OC_EVENTS_CLUSTER;COLLABORATION_EVENTS_CLUSTER" desc:"The clusterID of the event system. The event system is the message queuing service. It is used as message broker for the microservice architecture. Mandatory when using NATS as event system." introductionVersion:"7.3.0"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_EVENTS_TLS_INSECURE;COLLABORATION_EVENTS_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"7.3.0"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_EVENTS_TLS_ROOT_CA_CERTIFICATE;COLLABORATION_EVENTS_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided COLLABORATION_EVENTS_TLS_INSECURE will be seen as false." introductionVersion:"7.3.0"`
EnableTLS bool `yaml:"enable_tls" env:"OC_EVENTS_ENABLE_TLS;COLLABORATION_EVENTS_ENABLE_TLS" desc:"Enable TLS for the connection to the events broker. The events broker is the OpenCloud service which receives and delivers events between the services." introductionVersion:"7.3.0"`
AuthUsername string `yaml:"username" env:"OC_EVENTS_AUTH_USERNAME;COLLABORATION_EVENTS_AUTH_USERNAME" desc:"The username to authenticate with the events broker. The events broker is the OpenCloud service which receives and delivers events between the services." introductionVersion:"7.3.0"`
AuthPassword string `yaml:"password" env:"OC_EVENTS_AUTH_PASSWORD;COLLABORATION_EVENTS_AUTH_PASSWORD" desc:"The password to authenticate with the events broker. The events broker is the OpenCloud service which receives and delivers events between the services." introductionVersion:"7.3.0"`
}
+2 -2
View File
@@ -1,6 +1,6 @@
package config
type Font struct {
AssetPath string `yaml:"asset_path" env:"COLLABORATION_FONT_ASSET_PATH" desc:"Serve fonts from a path on the filesystem instead of the builtin assets. If not defined, the root directory derives from $OC_BASE_DATA_PATH/collaboration/fonts" introductionVersion:"%%NEXT%%"`
PreviewText string `yaml:"preview_text" env:"COLLABORATION_FONT_PREVIEW_TEXT" desc:"The text that will be displayed in the font preview." introductionVersion:"%%NEXT%%"`
AssetPath string `yaml:"asset_path" env:"COLLABORATION_FONT_ASSET_PATH" desc:"Serve fonts from a path on the filesystem instead of the builtin assets. If not defined, the root directory derives from $OC_BASE_DATA_PATH/collaboration/fonts" introductionVersion:"7.3.0"`
PreviewText string `yaml:"preview_text" env:"COLLABORATION_FONT_PREVIEW_TEXT" desc:"The text that will be displayed in the font preview." introductionVersion:"7.3.0"`
}
+3 -3
View File
@@ -11,7 +11,7 @@ type Store struct {
TTL time.Duration `yaml:"ttl" env:"OC_PERSISTENT_STORE_TTL;COLLABORATION_STORE_TTL" desc:"Time to live for events in the store. Defaults to '30m' (30 minutes). See the Environment Variable Types description for more details." introductionVersion:"1.0.0"`
AuthUsername string `yaml:"username" env:"OC_PERSISTENT_STORE_AUTH_USERNAME;COLLABORATION_STORE_AUTH_USERNAME" desc:"The username to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
AuthPassword string `yaml:"password" env:"OC_PERSISTENT_STORE_AUTH_PASSWORD;COLLABORATION_STORE_AUTH_PASSWORD" desc:"The password to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
EnableTLS bool `yaml:"enable_tls" env:"OC_PERSISTENT_STORE_ENABLE_TLS;COLLABORATION_STORE_ENABLE_TLS" desc:"Enable TLS for the connection to the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"%%NEXT%%"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_PERSISTENT_STORE_TLS_INSECURE;COLLABORATION_STORE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"%%NEXT%%"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_PERSISTENT_STORE_TLS_ROOT_CA_CERTIFICATE;COLLABORATION_STORE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided COLLABORATION_STORE_TLS_INSECURE will be seen as false." introductionVersion:"%%NEXT%%"`
EnableTLS bool `yaml:"enable_tls" env:"OC_PERSISTENT_STORE_ENABLE_TLS;COLLABORATION_STORE_ENABLE_TLS" desc:"Enable TLS for the connection to the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"7.3.0"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_PERSISTENT_STORE_TLS_INSECURE;COLLABORATION_STORE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"7.3.0"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_PERSISTENT_STORE_TLS_ROOT_CA_CERTIFICATE;COLLABORATION_STORE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided COLLABORATION_STORE_TLS_INSECURE will be seen as false." introductionVersion:"7.3.0"`
}
@@ -27,17 +27,18 @@ import (
typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
"github.com/golang/protobuf/proto"
"github.com/google/uuid"
"github.com/opencloud-eu/opencloud/services/collaboration/pkg/config"
"github.com/opencloud-eu/opencloud/services/collaboration/pkg/connector/fileinfo"
"github.com/opencloud-eu/opencloud/services/collaboration/pkg/helpers"
"github.com/opencloud-eu/opencloud/services/collaboration/pkg/middleware"
"github.com/opencloud-eu/opencloud/services/collaboration/pkg/wopisrc"
ctxpkg "github.com/opencloud-eu/reva/v2/pkg/ctx"
"github.com/opencloud-eu/reva/v2/pkg/rgrpc/todo/pool"
"github.com/opencloud-eu/reva/v2/pkg/storagespace"
"github.com/opencloud-eu/reva/v2/pkg/utils"
"github.com/rs/zerolog"
microstore "go-micro.dev/v4/store"
"github.com/opencloud-eu/opencloud/services/collaboration/pkg/config"
"github.com/opencloud-eu/opencloud/services/collaboration/pkg/connector/fileinfo"
"github.com/opencloud-eu/opencloud/services/collaboration/pkg/helpers"
"github.com/opencloud-eu/opencloud/services/collaboration/pkg/middleware"
"github.com/opencloud-eu/opencloud/services/collaboration/pkg/wopisrc"
)
const (
@@ -1578,7 +1579,6 @@ func (f *FileConnector) GetAvatar(ctx context.Context, userID string) (*Connecto
}
return nil, NewConnectorError(http.StatusBadGateway, "failed to fetch avatar")
}
defer photoFile.Close()
data, err := io.ReadAll(photoFile)
if err != nil {
+3 -3
View File
@@ -43,9 +43,9 @@ type Store struct {
TTL time.Duration `yaml:"ttl" env:"OC_PERSISTENT_STORE_TTL;EVENTHISTORY_STORE_TTL" desc:"Time to live for events in the store. Defaults to '336h' (2 weeks). See the Environment Variable Types description for more details." introductionVersion:"1.0.0"`
AuthUsername string `yaml:"username" env:"OC_PERSISTENT_STORE_AUTH_USERNAME;EVENTHISTORY_STORE_AUTH_USERNAME" desc:"The username to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
AuthPassword string `yaml:"password" env:"OC_PERSISTENT_STORE_AUTH_PASSWORD;EVENTHISTORY_STORE_AUTH_PASSWORD" desc:"The password to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
EnableTLS bool `yaml:"enable_tls" env:"OC_PERSISTENT_STORE_ENABLE_TLS;EVENTHISTORY_STORE_ENABLE_TLS" desc:"Enable TLS for the connection to the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"%%NEXT%%"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_PERSISTENT_STORE_TLS_INSECURE;EVENTHISTORY_STORE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"%%NEXT%%"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_PERSISTENT_STORE_TLS_ROOT_CA_CERTIFICATE;EVENTHISTORY_STORE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided EVENTHISTORY_STORE_TLS_INSECURE will be seen as false." introductionVersion:"%%NEXT%%"`
EnableTLS bool `yaml:"enable_tls" env:"OC_PERSISTENT_STORE_ENABLE_TLS;EVENTHISTORY_STORE_ENABLE_TLS" desc:"Enable TLS for the connection to the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"7.3.0"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_PERSISTENT_STORE_TLS_INSECURE;EVENTHISTORY_STORE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"7.3.0"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_PERSISTENT_STORE_TLS_ROOT_CA_CERTIFICATE;EVENTHISTORY_STORE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided EVENTHISTORY_STORE_TLS_INSECURE will be seen as false." introductionVersion:"7.3.0"`
}
// Events combines the configuration options for the event bus.
+3 -3
View File
@@ -133,9 +133,9 @@ type OCS struct {
StatCacheDisablePersistence bool `yaml:"stat_cache_disable_persistence" env:"OC_CACHE_DISABLE_PERSISTENCE;FRONTEND_OCS_STAT_CACHE_DISABLE_PERSISTENCE" desc:"Disable persistence of the cache. Only applies when using the 'nats-js-kv' store type. Defaults to false." introductionVersion:"1.0.0" deprecationVersion:"1.0.0" removalVersion:"%%NEXT_PRODUCTION_VERSION%%" deprecationInfo:"FRONTEND_OCS_STAT_CACHE_DISABLE_PERSISTENCE, the OCS API is deprecated" deprecationReplacement:""`
StatCacheAuthUsername string `yaml:"stat_cache_auth_username" env:"OC_CACHE_AUTH_USERNAME;FRONTEND_OCS_STAT_CACHE_AUTH_USERNAME" desc:"The username to use for authentication. Only applies when using the 'nats-js-kv' store type." introductionVersion:"1.0.0" deprecationVersion:"1.0.0" removalVersion:"%%NEXT_PRODUCTION_VERSION%%" deprecationInfo:"FRONTEND_OCS_STAT_CACHE_AUTH_USERNAME, the OCS API is deprecated" deprecationReplacement:""`
StatCacheAuthPassword string `yaml:"stat_cache_auth_password" env:"OC_CACHE_AUTH_PASSWORD;FRONTEND_OCS_STAT_CACHE_AUTH_PASSWORD" desc:"The password to use for authentication. Only applies when using the 'nats-js-kv' store type." introductionVersion:"1.0.0" deprecationVersion:"1.0.0" removalVersion:"%%NEXT_PRODUCTION_VERSION%%" deprecationInfo:"FRONTEND_OCS_STAT_CACHE_AUTH_PASSWORD, the OCS API is deprecated" deprecationReplacement:""`
StatCacheEnableTLS bool `yaml:"stat_cache_enable_tls" env:"OC_CACHE_ENABLE_TLS;FRONTEND_OCS_STAT_CACHE_ENABLE_TLS" desc:"Enable TLS for the connection to file metadata cache." introductionVersion:"%%NEXT%%"`
StatCacheTLSInsecure bool `yaml:"stat_cache_tls_insecure" env:"OC_INSECURE;OC_CACHE_TLS_INSECURE;FRONTEND_OCS_STAT_CACHE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"%%NEXT%%"`
StatCacheTLSRootCACertificate string `yaml:"stat_cache_tls_root_ca_certificate" env:"OC_CACHE_TLS_ROOT_CA_CERTIFICATE;FRONTEND_OCS_STAT_CACHE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided FRONTEND_OCS_STAT_CACHE_TLS_INSECURE will be seen as false." introductionVersion:"%%NEXT%%"`
StatCacheEnableTLS bool `yaml:"stat_cache_enable_tls" env:"OC_CACHE_ENABLE_TLS;FRONTEND_OCS_STAT_CACHE_ENABLE_TLS" desc:"Enable TLS for the connection to file metadata cache." introductionVersion:"7.3.0"`
StatCacheTLSInsecure bool `yaml:"stat_cache_tls_insecure" env:"OC_INSECURE;OC_CACHE_TLS_INSECURE;FRONTEND_OCS_STAT_CACHE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"7.3.0"`
StatCacheTLSRootCACertificate string `yaml:"stat_cache_tls_root_ca_certificate" env:"OC_CACHE_TLS_ROOT_CA_CERTIFICATE;FRONTEND_OCS_STAT_CACHE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided FRONTEND_OCS_STAT_CACHE_TLS_INSECURE will be seen as false." introductionVersion:"7.3.0"`
CacheWarmupDriver string `yaml:"cache_warmup_driver,omitempty"` // not supported by the OpenCloud product, therefore not part of docs
CacheWarmupDrivers CacheWarmupDrivers `yaml:"cache_warmup_drivers,omitempty"` // not supported by the OpenCloud product, therefore not part of docs
+6 -6
View File
@@ -84,9 +84,9 @@ type Cache struct {
ProviderCacheDisablePersistence bool `yaml:"provider_cache_disable_persistence" env:"OC_CACHE_DISABLE_PERSISTENCE;GATEWAY_PROVIDER_CACHE_DISABLE_PERSISTENCE" desc:"Disables persistence of the provider cache. Only applies when store type 'nats-js-kv' is configured. Defaults to false." introductionVersion:"1.0.0"`
ProviderCacheAuthUsername string `yaml:"provider_cache_auth_username" env:"OC_CACHE_AUTH_USERNAME;GATEWAY_PROVIDER_CACHE_AUTH_USERNAME" desc:"The username to use for authentication. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
ProviderCacheAuthPassword string `yaml:"provider_cache_auth_password" env:"OC_CACHE_AUTH_PASSWORD;GATEWAY_PROVIDER_CACHE_AUTH_PASSWORD" desc:"The password to use for authentication. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
ProviderCacheEnableTLS bool `yaml:"provider_cache_enable_tls" env:"OC_CACHE_ENABLE_TLS;GATEWAY_PROVIDER_CACHE_ENABLE_TLS" desc:"Enable TLS for the connection to file metadata cache." introductionVersion:"%%NEXT%%"`
ProviderCacheTLSInsecure bool `yaml:"provider_cache_tls_insecure" env:"OC_INSECURE;OC_CACHE_TLS_INSECURE;GATEWAY_PROVIDER_CACHE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"%%NEXT%%"`
ProviderCacheTLSRootCACertificate string `yaml:"provider_cache_tls_root_ca_certificate" env:"OC_CACHE_TLS_ROOT_CA_CERTIFICATE;GATEWAY_PROVIDER_CACHE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided GATEWAY_PROVIDER_CACHE_TLS_INSECURE will be seen as false." introductionVersion:"%%NEXT%%"`
ProviderCacheEnableTLS bool `yaml:"provider_cache_enable_tls" env:"OC_CACHE_ENABLE_TLS;GATEWAY_PROVIDER_CACHE_ENABLE_TLS" desc:"Enable TLS for the connection to file metadata cache." introductionVersion:"7.3.0"`
ProviderCacheTLSInsecure bool `yaml:"provider_cache_tls_insecure" env:"OC_INSECURE;OC_CACHE_TLS_INSECURE;GATEWAY_PROVIDER_CACHE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"7.3.0"`
ProviderCacheTLSRootCACertificate string `yaml:"provider_cache_tls_root_ca_certificate" env:"OC_CACHE_TLS_ROOT_CA_CERTIFICATE;GATEWAY_PROVIDER_CACHE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided GATEWAY_PROVIDER_CACHE_TLS_INSECURE will be seen as false." introductionVersion:"7.3.0"`
CreateHomeCacheStore string `yaml:"create_home_cache_store" env:"OC_CACHE_STORE;GATEWAY_CREATE_HOME_CACHE_STORE" desc:"The type of the cache store. Supported values are: 'memory', 'redis-sentinel', 'nats-js-kv', 'noop'. See the text description for details." introductionVersion:"1.0.0"`
CreateHomeCacheNodes []string `yaml:"create_home_cache_nodes" env:"OC_CACHE_STORE_NODES;GATEWAY_CREATE_HOME_CACHE_STORE_NODES" desc:"A list of nodes to access the configured store. This has no effect when 'memory' store is configured. Note that the behaviour how nodes are used is dependent on the library of the configured store. See the Environment Variable Types description for more details." introductionVersion:"1.0.0"`
@@ -95,7 +95,7 @@ type Cache struct {
CreateHomeCacheDisablePersistence bool `yaml:"create_home_cache_disable_persistence" env:"OC_CACHE_DISABLE_PERSISTENCE;GATEWAY_CREATE_HOME_CACHE_DISABLE_PERSISTENCE" desc:"Disables persistence of the create home cache. Only applies when store type 'nats-js-kv' is configured. Defaults to false." introductionVersion:"1.0.0"`
CreateHomeCacheAuthUsername string `yaml:"create_home_cache_auth_username" env:"OC_CACHE_AUTH_USERNAME;GATEWAY_CREATE_HOME_CACHE_AUTH_USERNAME" desc:"The username to use for authentication. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
CreateHomeCacheAuthPassword string `yaml:"create_home_cache_auth_password" env:"OC_CACHE_AUTH_PASSWORD;GATEWAY_CREATE_HOME_CACHE_AUTH_PASSWORD" desc:"The password to use for authentication. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
CreateHomeCacheEnableTLS bool `yaml:"create_home_cache_enable_tls" env:"OC_CACHE_ENABLE_TLS;GATEWAY_CREATE_HOME_CACHE_ENABLE_TLS" desc:"Enable TLS for the connection to file metadata cache." introductionVersion:"%%NEXT%%"`
CreateHomeCacheTLSInsecure bool `yaml:"create_home_cache_tls_insecure" env:"OC_INSECURE;OC_CACHE_TLS_INSECURE;GATEWAY_CREATE_HOME_CACHE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"%%NEXT%%"`
CreateHomeCacheTLSRootCACertificate string `yaml:"create_home_cache_tls_root_ca_certificate" env:"OC_CACHE_TLS_ROOT_CA_CERTIFICATE;GATEWAY_CREATE_HOME_CACHE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided GATEWAY_CREATE_HOME_CACHE_TLS_INSECURE will be seen as false." introductionVersion:"%%NEXT%%"`
CreateHomeCacheEnableTLS bool `yaml:"create_home_cache_enable_tls" env:"OC_CACHE_ENABLE_TLS;GATEWAY_CREATE_HOME_CACHE_ENABLE_TLS" desc:"Enable TLS for the connection to file metadata cache." introductionVersion:"7.3.0"`
CreateHomeCacheTLSInsecure bool `yaml:"create_home_cache_tls_insecure" env:"OC_INSECURE;OC_CACHE_TLS_INSECURE;GATEWAY_CREATE_HOME_CACHE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"7.3.0"`
CreateHomeCacheTLSRootCACertificate string `yaml:"create_home_cache_tls_root_ca_certificate" env:"OC_CACHE_TLS_ROOT_CA_CERTIFICATE;GATEWAY_CREATE_HOME_CACHE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided GATEWAY_CREATE_HOME_CACHE_TLS_INSECURE will be seen as false." introductionVersion:"7.3.0"`
}
+3 -3
View File
@@ -12,7 +12,7 @@ type Cache struct {
DisablePersistence bool `yaml:"disable_persistence" env:"OC_CACHE_DISABLE_PERSISTENCE;GRAPH_CACHE_DISABLE_PERSISTENCE" desc:"Disables persistence of the cache. Only applies when store type 'nats-js-kv' is configured. Defaults to false." introductionVersion:"1.0.0"`
AuthUsername string `yaml:"username" env:"OC_CACHE_AUTH_USERNAME;GRAPH_CACHE_AUTH_USERNAME" desc:"The username to authenticate with the cache. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
AuthPassword string `yaml:"password" env:"OC_CACHE_AUTH_PASSWORD;GRAPH_CACHE_AUTH_PASSWORD" desc:"The password to authenticate with the cache. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
EnableTLS bool `yaml:"enable_tls" env:"OC_CACHE_ENABLE_TLS;GRAPH_CACHE_ENABLE_TLS" desc:"Enable TLS for the connection to file metadata cache." introductionVersion:"%%NEXT%%"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_CACHE_TLS_INSECURE;GRAPH_CACHE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"%%NEXT%%"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_CACHE_TLS_ROOT_CA_CERTIFICATE;GRAPH_CACHE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided GRAPH_CACHE_TLS_INSECURE will be seen as false." introductionVersion:"%%NEXT%%"`
EnableTLS bool `yaml:"enable_tls" env:"OC_CACHE_ENABLE_TLS;GRAPH_CACHE_ENABLE_TLS" desc:"Enable TLS for the connection to file metadata cache." introductionVersion:"7.3.0"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_CACHE_TLS_INSECURE;GRAPH_CACHE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"7.3.0"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_CACHE_TLS_ROOT_CA_CERTIFICATE;GRAPH_CACHE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided GRAPH_CACHE_TLS_INSECURE will be seen as false." introductionVersion:"7.3.0"`
}
+3 -3
View File
@@ -176,7 +176,7 @@ type Store struct {
Database string `yaml:"database" env:"GRAPH_STORE_DATABASE" desc:"The database name the configured store should use." introductionVersion:"1.0.0"`
AuthUsername string `yaml:"username" env:"OC_PERSISTENT_STORE_AUTH_USERNAME;GRAPH_STORE_AUTH_USERNAME" desc:"The username to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
AuthPassword string `yaml:"password" env:"OC_PERSISTENT_STORE_AUTH_PASSWORD;GRAPH_STORE_AUTH_PASSWORD" desc:"The password to authenticate with the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"1.0.0"`
EnableTLS bool `yaml:"enable_tls" env:"OC_PERSISTENT_STORE_ENABLE_TLS;GRAPH_STORE_ENABLE_TLS" desc:"Enable TLS for the connection to the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"%%NEXT%%"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_PERSISTENT_STORE_TLS_INSECURE;GRAPH_STORE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"%%NEXT%%"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_PERSISTENT_STORE_TLS_ROOT_CA_CERTIFICATE;GRAPH_STORE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided GRAPH_STORE_TLS_INSECURE will be seen as false." introductionVersion:"%%NEXT%%"`
EnableTLS bool `yaml:"enable_tls" env:"OC_PERSISTENT_STORE_ENABLE_TLS;GRAPH_STORE_ENABLE_TLS" desc:"Enable TLS for the connection to the store. Only applies when store type 'nats-js-kv' is configured." introductionVersion:"7.3.0"`
TLSInsecure bool `yaml:"tls_insecure" env:"OC_INSECURE;OC_PERSISTENT_STORE_TLS_INSECURE;GRAPH_STORE_TLS_INSECURE" desc:"Whether to verify the server TLS certificates." introductionVersion:"7.3.0"`
TLSRootCACertificate string `yaml:"tls_root_ca_certificate" env:"OC_PERSISTENT_STORE_TLS_ROOT_CA_CERTIFICATE;GRAPH_STORE_TLS_ROOT_CA_CERTIFICATE" desc:"The root CA certificate used to validate the server's TLS certificate. If provided GRAPH_STORE_TLS_INSECURE will be seen as false." introductionVersion:"7.3.0"`
}
@@ -15,6 +15,7 @@ var (
// but can be enabled by the user.
_disabledByDefaultUnifiedRoleRoleIDs = []string{
unifiedrole.UnifiedRoleSecureViewerID,
unifiedrole.UnifiedRoleSpaceViewerWithVersionsID,
unifiedrole.UnifiedRoleSpaceEditorWithoutVersionsID,
unifiedrole.UnifiedRoleViewerListGrantsID,
unifiedrole.UnifiedRoleEditorListGrantsID,
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-08-11 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Ivan Fustero, 2025\n"
"Language-Team: Catalan (https://app.transifex.com/opencloud-eu/teams/204053/ca/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Pot editar"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Pot editar sense versions"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Pot gestionar"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Pot pujar"
@@ -55,23 +55,25 @@ msgstr "Pot pujar"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Pot veure"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Pot veure (de forma segura)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "No pot accedir"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Denega tot accés."
@@ -81,74 +83,75 @@ msgid "Here you can add a description for this Space."
msgstr "Aquí podeu afegir una descripció per a aquest espai."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Visualitza i descarrega."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr "View only documents, images and PDFs. Watermarks will be applied."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Visualitza, descarrega i edita."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Visualitza, descarrega i mostra totes les persones convidades."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Visualitza, descarrega i puja."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr "Visualitza, descarrega, edita i mostra totes les persones convidades."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Visualitza, descarrega, puja, edita, afegeix i suprimeix."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr ""
"Visualitza, descarrega, puja, edita, afegeix, suprimeix i gestiona els "
"membres."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Visualitza, descarregar, pujar, editar, afegir, esborrar i mostrar totes les"
" persones convidades."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr ""
"Visualitza, baixa, puja, edita, afegeix, suprimeix incloent l'historial."
@@ -13,7 +13,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-08-11 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: OpenCloud Ops, 2026\n"
"Language-Team: German (https://app.transifex.com/opencloud-eu/teams/204053/de/)\n"
@@ -30,26 +30,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Kann bearbeiten"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Kann bearbeiten ohne Historie"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Kann verwalten"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Kann hochladen"
@@ -57,23 +57,25 @@ msgstr "Kann hochladen"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Kann anzeigen"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Kann anzeigen (sichere Ansicht)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Kann nicht zugreifen"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Jeder Zugriff verboten"
@@ -83,50 +85,51 @@ msgid "Here you can add a description for this Space."
msgstr "Hier können Sie eine Beschreibung für diesen Space einfügen."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr "Ansehen, herunterladen und Historie ansehen."
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Ansehen und herunterladen."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr ""
"Ansehen von Dokumenten, Bildern und PDFs. Wasserzeichen werden angewendet."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr "Ansehen, herunterladen, bearbeiten und Historie ansehen."
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Ansehen, herunterladen und bearbeiten."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Ansehen, herunterladen und anzeigen aller eingeladenen Personen."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Ansehen, herunterladen und hochladen."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr ""
"Ansehen, herunterladen, bearbeiten und anzeigen aller eingeladenen Personen."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
"Ansehen, herunterladen, hochladen, bearbeiten, hinzufügen, löschen und "
@@ -135,26 +138,26 @@ msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Ansehen, herunterladen, hochladen, bearbeiten, hinzufügen, löschen."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr ""
"Ansehen, herunterladen, hochladen, bearbeiten, hinzufügen, löschen, teilen "
"und Mitglieder verwalten."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Ansehen, herunterladen, hochladen, bearbeiten, löschen und anzeigen aller "
"eingeladenen Benutzer."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr ""
"Ansehen, herunterladen, hochladen, bearbeiten, hinzufügen, löschen - "
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-08-11 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Efstathios Iosifidis <eiosifidis@gmail.com>, 2026\n"
"Language-Team: Greek (https://app.transifex.com/opencloud-eu/teams/204053/el/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Δυνατότητα επεξεργασίας"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Δυνατότητα επεξεργασίας χωρίς εκδόσεις"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Δυνατότητα διαχείρισης"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Δυνατότητα μεταφόρτωσης"
@@ -55,23 +55,25 @@ msgstr "Δυνατότητα μεταφόρτωσης"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Δυνατότητα προβολής"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Δυνατότητα προβολής (ασφαλής)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Δεν υπάρχει πρόσβαση"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Άρνηση κάθε πρόσβασης."
@@ -81,76 +83,77 @@ msgid "Here you can add a description for this Space."
msgstr "Εδώ μπορείτε να προσθέσετε μια περιγραφή για αυτόν τον Χώρο."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Προβολή και λήψη."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr ""
"Προβολή μόνο εγγράφων, εικόνων και PDF. Θα εφαρμοστούν υδατογραφήματα."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Προβολή, λήψη και επεξεργασία."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Προβολή, λήψη και εμφάνιση όλων των προσκεκλημένων ατόμων."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Προβολή, λήψη και μεταφόρτωση."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr ""
"Προβολή, λήψη, επεξεργασία και εμφάνιση όλων των προσκεκλημένων ατόμων."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Προβολή, λήψη, μεταφόρτωση, επεξεργασία, προσθήκη και διαγραφή."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr ""
"Προβολή, λήψη, μεταφόρτωση, επεξεργασία, προσθήκη, διαγραφή και διαχείριση "
"μελών."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Προβολή, λήψη, μεταφόρτωση, επεξεργασία, προσθήκη, διαγραφή και εμφάνιση "
"όλων των προσκεκλημένων ατόμων."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr ""
"Προβολή, λήψη, μεταφόρτωση, επεξεργασία, προσθήκη, διαγραφή "
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-08-11 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Elías Martín, 2025\n"
"Language-Team: Spanish (https://app.transifex.com/opencloud-eu/teams/204053/es/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Puede editar"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Se puede editar sin versiones"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Se puede gestionar"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Se puede subir"
@@ -55,23 +55,25 @@ msgstr "Se puede subir"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Se puede visualizar"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Se puede visualizar (de forma segura)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "No se puede acceder"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Prohibir todo el acceso"
@@ -81,74 +83,75 @@ msgid "Here you can add a description for this Space."
msgstr "Aquí puedes agregar una descripción a este Espacio."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Ver y descargar"
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr ""
"Ver solamente documentos, imágenes y archivos PDF. Será aplicada una marca "
"de agua."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Ver. descargar y editar."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Ver, descargar y mostrar a todas las personas invitadas."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Ver, descargar y subir."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr "Ver, descargar, editar y mostrar a todas las perosnas invitadas."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Ver, descargar, subuir, editar, añadir y eliminar."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr "Ver, descargar, subir, editar, añadir, eliminar y gestionar miembros."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Ver, descargar, subir, editar, añadir, eliminar y mostrar a todas las "
"personas invitadas."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr ""
"Ver, descargar, subir, editar, añadir y borrar incluyendo el historial."
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-08-11 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Jiri Grönroos <jiri.gronroos@iki.fi>, 2025\n"
"Language-Team: Finnish (https://app.transifex.com/opencloud-eu/teams/204053/fi/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Voi muokata"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Voi muokata ilman versioita"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Voi hallita"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Voi lähettää"
@@ -55,23 +55,25 @@ msgstr "Voi lähettää"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Voi nähdä"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Voi nähdä (turvallinen)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Ei pääsyä"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Estä kaikki pääsy."
@@ -81,71 +83,72 @@ msgid "Here you can add a description for this Space."
msgstr "Täällä voit lisätä kuvauksen avaruudelle."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Näytä ja lataa."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr "Näytä vain asiakirjat, kuvat ja PDF:t. Vesileimat lisätään."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Näytä, lataa ja muokkaa."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Näytä, lataa ja näytä kaikki kutsutut henkilöt."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Näytä, lataa ja lähetä."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr "Näytä, lataa, muokkaa ja näytä kaikki kaikki kutsutut henkilöt."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Näytä, lataa lähetä, muokkaa, lisää ja poista."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr "Näytä, lataa, lähetä, muokkaa, lisää, poista ja hallitse jäseniä."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Näytä, lataa, lähetä, muokkaa, lisää, poista ja näytä kaikki kutsutut "
"henkilöt."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr "Näytä, lataa, lähetä, muokkaa, lisää, poista mukaan lukien historia."
@@ -13,7 +13,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-08-11 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Jérôme HERBINET, 2026\n"
"Language-Team: French (https://app.transifex.com/opencloud-eu/teams/204053/fr/)\n"
@@ -30,26 +30,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Peut éditer"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Peut éditer sans versions"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Peut gérer"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Peut téléverser"
@@ -57,23 +57,25 @@ msgstr "Peut téléverser"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Peut visualiser"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Peut visualiser (sécurisé)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Accès impossible"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Refuser tout accès."
@@ -83,77 +85,78 @@ msgid "Here you can add a description for this Space."
msgstr "Vous pouvez ajouter une description pour cet espace."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Consulter et télécharger."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr ""
"Visualiser uniquement les documents, les images et les fichiers PDF. Des "
"filigranes seront appliqués."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Consulter, télécharger et modifier."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Consulter, télécharger et montrer toutes les personnes invitées."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Consulter, télécharger et téléverser."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr ""
"Consulter, télécharger, modifier et montrer toutes les personnes invitées."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Consulter, télécharger, téléverser, modifier, ajouter et supprimer."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr ""
"Consulter, télécharger, téléverser, modifier, ajouter, supprimer et gérer "
"les membres."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Consulter, télécharger, téléverser, modifier, ajouter, supprimer et montrer "
"toutes les personnes invitées."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr ""
"Consulter, télécharger, téléverser, modifier, ajouter, supprimer, y compris "
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-08-11 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Simone Broglia, 2025\n"
"Language-Team: Italian (https://app.transifex.com/opencloud-eu/teams/204053/it/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Può modificare"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Può modificare senza versioni"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Può gestire"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Può caricare"
@@ -55,23 +55,25 @@ msgstr "Può caricare"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Può visualizzare"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Può visualizzare (protetto)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Accesso non consentito"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Blocca tutti gli accessi"
@@ -81,74 +83,75 @@ msgid "Here you can add a description for this Space."
msgstr "Qui puoi aggiungere una descrizione per questo Spazio."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Visualizza e scarica."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr ""
"Visualizza solo documenti, immagini e PDF. Verranno applicate filigrane."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Visualizza, scarica e modifica."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Visualizza, scarica e mostra tutte le persone invitate."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Visualizza, scarica e carica."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr "Visualizza, scarica, modifica e mostra tutte le persone invitate."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Visualizza, scarica, carica, modifica, aggiungi ed elimina."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr ""
"Visualizza, scarica, carica, modifica, aggiungi, elimina e gestisci i "
"membri."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Visualizza, scarica, carica, modifica, aggiungi, elimina e mostra tutte le "
"persone invitate."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr "View, download, upload, edit, add, delete including the history."
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-08-11 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: iikaka88, 2025\n"
"Language-Team: Japanese (https://app.transifex.com/opencloud-eu/teams/204053/ja/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "編集可"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "編集 (履歴なし)"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "管理可能"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "アップロード可能"
@@ -55,23 +55,25 @@ msgstr "アップロード可能"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "閲覧可能"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "セキュア閲覧(閲覧のみ)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "アクセス不可"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "すべてのアクセスを拒否"
@@ -81,69 +83,70 @@ msgid "Here you can add a description for this Space."
msgstr "説明を追加"
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "閲覧とダウンロード"
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr "ドキュメント、画像、PDFの閲覧のみ。透かし(ウォーターマーク)が適用"
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "閲覧、ダウンロード、編集"
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "閲覧、ダウンロード、および全招待ユーザーの表示"
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "閲覧、ダウンロード、アップロード"
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr "閲覧、ダウンロード、編集、および全招待ユーザーの表示"
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "閲覧、ダウンロード、アップロード、編集、追加、削除"
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr "閲覧、ダウンロード、アップロード、編集、追加、削除、およびメンバー管理"
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr "閲覧、ダウンロード、アップロード、編集、追加、削除、および全招待ユーザーの表示"
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr "閲覧、ダウンロード、アップロード、編集、追加、削除(履歴を含む)"
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-08-11 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: gapho shin, 2025\n"
"Language-Team: Korean (https://app.transifex.com/opencloud-eu/teams/204053/ko/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "편집 가능"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "버전 없이 편집 가능"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "관리 가능"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "업로드 가능"
@@ -55,23 +55,25 @@ msgstr "업로드 가능"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "보기 가능"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "보기 가능 (보안)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "접근 불가"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "모든 접근 거부"
@@ -81,69 +83,70 @@ msgid "Here you can add a description for this Space."
msgstr "여기에 이 공간에 대한 설명을 추가할 수 있습니다."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "보기 및 다운로드."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr "문서, 이미지 및 PDF만 보기. 워터마크가 적용됩니다."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "보기, 다운로드 및 편집."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "모든 초대받은 사람들을 보고, 다운로드하고, 보여줍니다."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "보기, 다운로드 및 업로드."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr "모든 초대받은 사람들을 보고, 다운로드하고, 편집하고, 보여줍니다."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "보기, 다운로드, 업로드, 편집, 추가 및 삭제."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr "회원 보기, 다운로드, 업로드, 편집, 추가, 삭제 및 관리."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr "모든 초대받은 사람들을 보고, 다운로드하고, 업로드하고, 편집하고, 추가하고, 삭제하고, 보여줍니다."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr "기록을 포함하여 보기, 다운로드, 업로드, 편집, 추가, 삭제합니다."
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-03 23:15+0000\n"
"POT-Creation-Date: 2026-08-11 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Stephan Paternotte <stephan@paternottes.net>, 2026\n"
"Language-Team: Dutch (https://app.transifex.com/opencloud-eu/teams/204053/nl/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Kan bewerken"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Kan bewerken zonder versies"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Kan beheren"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Kan uploaden"
@@ -55,23 +55,25 @@ msgstr "Kan uploaden"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Kan weergeven"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Kan weergeven (beveiligd)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Heeft geen toegang"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Alle toegang weigeren."
@@ -81,50 +83,51 @@ msgid "Here you can add a description for this Space."
msgstr "Hier kunt u een beschrijving voor deze ruimte toevoegen."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr "Incl. geschiedenis weergeven en downloaden."
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Weergeven en downloaden."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr ""
"Alleen documenten, afbeeldingen en PDF's weergeven. Met toepassing van "
"watermerken."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr "Incl. geschiedenis weergeven, downloaden en bewerken."
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Weergeven, downloaden en bewerken."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Weergeven, downloaden en alle genodigde personen zien."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Weergeven, downloaden en uploaden."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr "Weergeven, downloaden, bewerken en alle genodigde personen zien."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
"Incl. geschiedenis weergeven, downloaden, uploaden, bewerken, toevoegen en "
@@ -133,26 +136,26 @@ msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Weergeven, downloaden, uploaden, bewerken, toevoegen en verwijderen."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr ""
"Weergeven, downloaden, uploaden, bewerken, toevoegen, verwijderen en leden "
"beheren."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Weergeven, downloaden, uploaden, bewerken, toevoegen, verwijderen en alle "
"genodigde personen zien."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr ""
"Weergeven, downloaden, uploaden, bewerken, toevoegen, verwijderen, incl. "
@@ -15,7 +15,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-08-11 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Matt, 2026\n"
"Language-Team: Polish (https://app.transifex.com/opencloud-eu/teams/204053/pl/)\n"
@@ -32,26 +32,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Może edytować"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Może edytować bez wersji"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Może zarządzać"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Może przesyłać pliki"
@@ -59,23 +59,25 @@ msgstr "Może przesyłać pliki"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Może oglądać"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Mogę zobaczyć ( źródło) "
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Nie ma dostępu"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Odmów dostępu wszystkim."
@@ -85,76 +87,77 @@ msgid "Here you can add a description for this Space."
msgstr "Tutaj możesz dodać opis dla tej Przestrzeni"
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Zobacz i pobierz"
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr ""
"Wyświetlanie tylko dokumentów, obrazów i PDF. Zostaną nałożone znaki wodne."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Wyświetl , Pobierz i edytuj "
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Wyświetlanie, pobieranie i pokazywanie wszystkich zaproszonych."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Wyświetlanie, pobieranie i przesyłanie."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr ""
"Wyświetlanie, pobieranie, edycja i pokazywanie wszystkich zaproszonych."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Wyświetlanie, pobieranie, przesyłanie, edycja, dodawanie i usuwanie."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr ""
"Wyświetlanie, pobieranie, przesyłanie, edycja, dodawanie, usuwanie i "
"zarządzanie członkami."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Wyświetlanie, pobieranie, przesyłanie, edycja, dodawanie, usuwanie i "
"wyświetlanie wszystkich zaproszonych osób."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr ""
"Wyświetlanie, pobieranie, przesyłanie, edycja, dodawanie, usuwanie włącznie "
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-08-11 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Mário Machado, 2025\n"
"Language-Team: Portuguese (https://app.transifex.com/opencloud-eu/teams/204053/pt/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Pode editar"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Pode editar sem versões"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Pode gerir"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Pode carregar"
@@ -55,23 +55,25 @@ msgstr "Pode carregar"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Pode visualizar"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Pode visualizar (seguro)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Não pode aceder"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Negar todo o acesso."
@@ -81,77 +83,78 @@ msgid "Here you can add a description for this Space."
msgstr "Aqui pode adicionar uma descrição para este Espaço."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Visualizar e descarregar."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr ""
"Visualizar apenas documentos, imagens e PDFs. Serão aplicadas marcas de "
"água."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Visualizar, descarregar e editar."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Visualizar, descarregar e mostrar todas as pessoas convidadas."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Visualizar, descarregar e carregar."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr ""
"Visualizar, descarregar, editar e mostrar todas as pessoas convidadas."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Visualizar, descarregar, carregar, editar, adicionar e eliminar."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr ""
"Visualizar, descarregar, carregar, editar, adicionar, eliminar e gerir "
"membros."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Visualizar, descarregar, carregar, editar, adicionar, eliminar e mostrar "
"todas as pessoas convidadas."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr ""
"Visualizar, descarregar, carregar, editar, adicionar, eliminar, incluindo o "
@@ -12,7 +12,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-08-11 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Lulufox, 2025\n"
"Language-Team: Russian (https://app.transifex.com/opencloud-eu/teams/204053/ru/)\n"
@@ -29,26 +29,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Может редактировать"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Может редактировать без версионирования"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Может управлять"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Может загружать"
@@ -56,23 +56,25 @@ msgstr "Может загружать"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Можно смотреть"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Можно смотреть (защищено)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Не имеет доступа"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Отказать во всех доступах"
@@ -82,77 +84,78 @@ msgid "Here you can add a description for this Space."
msgstr "Здесь вы можете добавить описание для Пространства"
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Просмотреть и скачать"
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr ""
"Просмотреть только документы, изображения и файлы PDF. Будут присутствовать "
"вотермарки."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Просмотреть, скачать и редактировать."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Просмотреть, скачать и показать всех приглашенных людей."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Просмотреть, скачать и загрузить."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr ""
"Просмотреть, скачать, отредактировать и показать всех приглашенных людей."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Просмотреть, скачать, загрузить, редактировать, добавить и удалить."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr ""
"Просмотреть, скачать, загрузить, редактировать, добавить, удалить и "
"управлять командой."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Просмотреть, скачать, загрузить, редактировать, добавить, удалить и показать"
" всех приглашенных людей."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr ""
"Просмотреть, скачать, загрузить, редактировать, добавить, удалить включая "
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-08-11 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Daniel Nylander <po@danielnylander.se>, 2025\n"
"Language-Team: Swedish (https://app.transifex.com/opencloud-eu/teams/204053/sv/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Kan redigera"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Kan redigera utan versioner"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Kan hantera"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Kan skicka upp"
@@ -55,23 +55,25 @@ msgstr "Kan skicka upp"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Kan visa"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Kan visa (säkert)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Kan inte komma åt"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Neka all åtkomst."
@@ -81,75 +83,76 @@ msgid "Here you can add a description for this Space."
msgstr "Här kan du lägga till en beskrivning av denna arbetsyta."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Visa och hämta ner."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr ""
"Visa endast dokument, bilder och PDF. Vattenstämplar kommer att tillämpas."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Visa, hämta ner och redigera."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Visa, hämta ner och visa alla inbjudna personer."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Visa. hämta ner och skicka upp."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr "Visa, hämta ner, redigera och visa alla inbjudna personer."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Visa, hämta ner, skicka upp, redigera, lägga till och ta bort."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr ""
"Visa, hämta ner, skicka upp, redigera, lägga till, ta bort och hantera "
"medlemmar."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Visa, hämta ner, skicka upp, redigera, lägga till, ta bort och visa alla "
"inbjudna personer."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr ""
"Visa, hämta ner, skicka upp, redigera, lägga till, ta bort inklusive "
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-08-11 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: LinkinWires <darkinsonic13@gmail.com>, 2025\n"
"Language-Team: Ukrainian (https://app.transifex.com/opencloud-eu/teams/204053/uk/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Може редагувати"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Може редагувати (без версій)"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Може керувати"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Може вивантажувати"
@@ -55,23 +55,25 @@ msgstr "Може вивантажувати"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Може переглядати"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Може переглядати (обмежено)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Не має доступу"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Заборонити будь-який доступ."
@@ -81,80 +83,81 @@ msgid "Here you can add a description for this Space."
msgstr "Тут можна додати опис до цього простору."
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Може переглядати та завантажувати файли."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr ""
"Може переглядати лише документи, зображення та PDF-файли. Будуть застосовані"
" водяні знаки."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Може переглядати, завантажувати та редагувати файли."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Може переглядати, завантажувати та показувати усіх запрошених людей."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Може переглядати, завантажувати та вивантажувати файли."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr ""
"Може переглядати, завантажувати, редагувати та показувати усіх запрошених "
"людей."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr ""
"Може переглядати, завантажувати, вивантажувати, редагувати, додавати та "
"видаляти файли."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr ""
"Може переглядати, завантажувати, вивантажувати, редагувати, додавати та "
"видаляти файли, а також може керувати учасниками."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Може переглядати, завантажувати, редагувати, додавати, видаляти та "
"показувати усіх запрошених людей."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr ""
"Може переглядати, завантажувати, вивантажувати, редагувати, додавати та "
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-08-11 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: Quan Tran, 2025\n"
"Language-Team: Vietnamese (https://app.transifex.com/opencloud-eu/teams/204053/vi/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "Có quyền chỉnh sửa"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "Có quyền chỉnh sửa không tạo phiên bản"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "Có quyền quản lý"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "Có quyền đăng tải"
@@ -55,23 +55,25 @@ msgstr "Có quyền đăng tải"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "Có quyền xem"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "Có quyền xem (bảo mật)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "Không có quyền truy cập"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "Cấm mọi quyền truy cập."
@@ -81,71 +83,72 @@ msgid "Here you can add a description for this Space."
msgstr ""
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "Xem và tải về."
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr "Chỉ được xem tài liệu, hình ảnh và PDF. Sẽ hiển thị hình mờ."
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "Xem, tải về và chỉnh sửa."
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "Xem, tải về và hiển thị danh sách người được mời."
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "Xem, tải về và tải lên."
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr "Xem, tải về, chỉnh sửa và hiển thị danh sách người được mời."
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "Xem, tải về, tải lên, chỉnh sửa, thêm và xóa."
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr "Xem, tải về, tải lên, chỉnh sửa, thêm, xóa và quản lý thành viên."
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr ""
"Xem, tải về, tải lên, chỉnh sửa, thêm, xóa và hiển thị danh sách người được "
"mời."
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr "Xem, tải về, tải lên, chỉnh sửa, thêm và xóa bao gồm lịch sử."
@@ -11,7 +11,7 @@ msgid ""
msgstr ""
"Project-Id-Version: \n"
"Report-Msgid-Bugs-To: EMAIL\n"
"POT-Creation-Date: 2026-07-02 23:15+0000\n"
"POT-Creation-Date: 2026-08-11 23:16+0000\n"
"PO-Revision-Date: 2025-01-27 10:17+0000\n"
"Last-Translator: YQS Yang, 2025\n"
"Language-Team: Chinese (https://app.transifex.com/opencloud-eu/teams/204053/zh/)\n"
@@ -28,26 +28,26 @@ msgstr ""
#. UnifiedRole FileEditor, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole FileEditorListGrants, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:128 pkg/unifiedrole/roles.go:134
#: pkg/unifiedrole/roles.go:140 pkg/unifiedrole/roles.go:146
#: pkg/unifiedrole/roles.go:158 pkg/unifiedrole/roles.go:164
#: pkg/unifiedrole/roles.go:170
#: pkg/unifiedrole/roles.go:137 pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:149 pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:167 pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:179
msgid "Can edit"
msgstr "可编辑"
#. UnifiedRole SpaseEditorWithoutVersions, Role DisplayName (resolves
#. directly)
#: pkg/unifiedrole/roles.go:152
#: pkg/unifiedrole/roles.go:161
msgid "Can edit without versions"
msgstr "可编辑(无版本控制)"
#. UnifiedRole Manager, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:182
#: pkg/unifiedrole/roles.go:191
msgid "Can manage"
msgstr "可管理"
#. UnifiedRole EditorLite, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:176
#: pkg/unifiedrole/roles.go:185
msgid "Can upload"
msgstr "可上传"
@@ -55,23 +55,25 @@ msgstr "可上传"
#. UnifiedRole ViewerWithVersions, Role DisplayName (resolves directly)
#. UnifiedRole Viewer, Role DisplayName (resolves directly)
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:110
#: pkg/unifiedrole/roles.go:116 pkg/unifiedrole/roles.go:122
#. UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:107 pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:119 pkg/unifiedrole/roles.go:125
#: pkg/unifiedrole/roles.go:131
msgid "Can view"
msgstr "可查看"
#. UnifiedRole SecureViewer, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:188
#: pkg/unifiedrole/roles.go:197
msgid "Can view (secure)"
msgstr "可查看(安全)"
#. UnifiedRole FullDenial, Role DisplayName (resolves directly)
#: pkg/unifiedrole/roles.go:194
#: pkg/unifiedrole/roles.go:203
msgid "Cannot access"
msgstr "无法访问"
#. UnifiedRole FullDenial, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:191
#: pkg/unifiedrole/roles.go:200
msgid "Deny all access."
msgstr "拒绝所有访问。"
@@ -81,69 +83,70 @@ msgid "Here you can add a description for this Space."
msgstr "此处可为该空间添加描述。"
#. UnifiedRole ViewerWithVersions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:107
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:110 pkg/unifiedrole/roles.go:128
msgid "View and download including the history."
msgstr ""
#. UnifiedRole Viewer, Role Description (resolves directly)
#. UnifiedRole SpaceViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:101 pkg/unifiedrole/roles.go:119
#: pkg/unifiedrole/roles.go:104 pkg/unifiedrole/roles.go:122
msgid "View and download."
msgstr "查看和下载。"
#. UnifiedRole SecureViewer, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:185
#: pkg/unifiedrole/roles.go:194
msgid "View only documents, images and PDFs. Watermarks will be applied."
msgstr "仅可查看文档、图片和PDF,且会添加水印。"
#. UnifiedRole FileEditorWithVErsions, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:167
#: pkg/unifiedrole/roles.go:176
msgid "View, download and edit including the history."
msgstr ""
#. UnifiedRole FileEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:155
#: pkg/unifiedrole/roles.go:164
msgid "View, download and edit."
msgstr "查看、下载和编辑。"
#. UnifiedRole ViewerListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:113
#: pkg/unifiedrole/roles.go:116
msgid "View, download and show all invited people."
msgstr "查看、下载并显示所有受邀人员。"
#. UnifiedRole EditorLite, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:173
#: pkg/unifiedrole/roles.go:182
msgid "View, download and upload."
msgstr "查看、下载和上传。"
#. UnifiedRole FileEditorListGrants, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:161
#: pkg/unifiedrole/roles.go:170
msgid "View, download, edit and show all invited people."
msgstr "查看、下载、编辑并显示所有受邀人员。"
#. UnifiedRole Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:131
#: pkg/unifiedrole/roles.go:140
msgid "View, download, upload, edit, add and delete including the history."
msgstr ""
#. UnifiedRole Editor, Role Description (resolves directly)
#. UnifiedRole SpaseEditorWithoutVersions, Role Description (resolves
#. directly)
#: pkg/unifiedrole/roles.go:125 pkg/unifiedrole/roles.go:149
#: pkg/unifiedrole/roles.go:134 pkg/unifiedrole/roles.go:158
msgid "View, download, upload, edit, add and delete."
msgstr "查看、下载、上传、编辑、添加和删除。"
#. UnifiedRole Manager, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:179
#: pkg/unifiedrole/roles.go:188
msgid "View, download, upload, edit, add, delete and manage members."
msgstr "查看、下载、上传、编辑、添加、删除和管理成员。"
#. UnifiedRoleListGrants Editor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:137
#: pkg/unifiedrole/roles.go:146
msgid "View, download, upload, edit, add, delete and show all invited people."
msgstr "查看、下载、上传、编辑、添加、删除并显示所有受邀人员。"
#. UnifiedRole SpaseEditor, Role Description (resolves directly)
#: pkg/unifiedrole/roles.go:143
#: pkg/unifiedrole/roles.go:152
msgid "View, download, upload, edit, add, delete including the history."
msgstr "查看、下载、上传、编辑、添加和删除(含历史版本)。"
+10 -121
View File
@@ -9,9 +9,7 @@ import (
"net/http"
"net/url"
"path"
"reflect"
"strconv"
"strings"
"time"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
@@ -28,6 +26,7 @@ import (
"github.com/opencloud-eu/opencloud/pkg/log"
"github.com/opencloud-eu/opencloud/services/graph/pkg/errorcode"
"github.com/opencloud-eu/opencloud/services/search/pkg/mapping"
)
// CreateUploadSession create an upload session to allow your app to upload files up to the maximum file size.
@@ -452,130 +451,20 @@ func cs3ResourceToDriveItem(logger *log.Logger, publicBaseURL *url.URL, res *sto
}
}
if res.GetArbitraryMetadata() != nil {
driveItem.Audio = cs3ResourceToDriveItemAudioFacet(logger, res)
driveItem.Image = cs3ResourceToDriveItemImageFacet(logger, res)
driveItem.Location = cs3ResourceToDriveItemLocationFacet(logger, res)
driveItem.Photo = cs3ResourceToDriveItemPhotoFacet(logger, res)
if metadata := res.GetArbitraryMetadata().GetMetadata(); metadata != nil {
driveItem.Audio = metadataToFacet[libregraph.Audio](metadata, "audio")
driveItem.Image = metadataToFacet[libregraph.Image](metadata, "image")
driveItem.Location = metadataToFacet[libregraph.GeoCoordinates](metadata, "location")
driveItem.Photo = metadataToFacet[libregraph.Photo](metadata, "photo")
}
return driveItem, nil
}
func cs3ResourceToDriveItemAudioFacet(logger *log.Logger, res *storageprovider.ResourceInfo) *libregraph.Audio {
if !strings.HasPrefix(res.GetMimeType(), "audio/") {
return nil
}
k := res.GetArbitraryMetadata().GetMetadata()
if k == nil {
return nil
}
var audio = &libregraph.Audio{}
if ok := unmarshalStringMap(logger, audio, k, "libre.graph.audio."); ok {
return audio
}
return nil
}
func cs3ResourceToDriveItemImageFacet(logger *log.Logger, res *storageprovider.ResourceInfo) *libregraph.Image {
k := res.GetArbitraryMetadata().GetMetadata()
if k == nil {
return nil
}
var image = &libregraph.Image{}
if ok := unmarshalStringMap(logger, image, k, "libre.graph.image."); ok {
return image
}
return nil
}
func cs3ResourceToDriveItemLocationFacet(logger *log.Logger, res *storageprovider.ResourceInfo) *libregraph.GeoCoordinates {
k := res.GetArbitraryMetadata().GetMetadata()
if k == nil {
return nil
}
var location = &libregraph.GeoCoordinates{}
if ok := unmarshalStringMap(logger, location, k, "libre.graph.location."); ok {
return location
}
return nil
}
func cs3ResourceToDriveItemPhotoFacet(logger *log.Logger, res *storageprovider.ResourceInfo) *libregraph.Photo {
k := res.GetArbitraryMetadata().GetMetadata()
if k == nil {
return nil
}
var photo = &libregraph.Photo{}
if ok := unmarshalStringMap(logger, photo, k, "libre.graph.photo."); ok {
return photo
}
return nil
}
func getFieldName(structField reflect.StructField) string {
tag := structField.Tag.Get("json")
if tag == "" {
return structField.Name
}
return strings.Split(tag, ",")[0]
}
func unmarshalStringMap(logger *log.Logger, out any, flatMap map[string]string, prefix string) bool {
nonEmpty := false
obj := reflect.ValueOf(out).Elem()
timeKind := reflect.TypeOf(&time.Time{}).Elem().Kind()
for i := 0; i < obj.NumField(); i++ {
field := obj.Field(i)
structField := obj.Type().Field(i)
mapKey := prefix + getFieldName(structField)
if value, ok := flatMap[mapKey]; ok {
if field.Kind() == reflect.Ptr {
newValue := reflect.New(field.Type().Elem())
var tmp any
var err error
switch t := newValue.Type().Elem().Kind(); t {
case reflect.String:
tmp = value
case reflect.Int32:
tmp, err = strconv.ParseInt(value, 10, 32)
case reflect.Int64:
tmp, err = strconv.ParseInt(value, 10, 64)
case reflect.Float32:
tmp, err = strconv.ParseFloat(value, 32)
case reflect.Float64:
tmp, err = strconv.ParseFloat(value, 64)
case reflect.Bool:
tmp, err = strconv.ParseBool(value)
case timeKind:
tmp, err = time.Parse(time.RFC3339, value)
default:
err = errors.New("unsupported type")
logger.Error().Err(err).Str("type", t.String()).Str("mapKey", mapKey).Msg("target field type for value of mapKey is not supported")
}
if err != nil {
logger.Error().Err(err).Str("mapKey", mapKey).Msg("unmarshalling failed")
continue
}
newValue.Elem().Set(reflect.ValueOf(tmp).Convert(field.Type().Elem()))
field.Set(newValue)
nonEmpty = true
}
}
}
return nonEmpty
// metadataToFacet builds a DriveItem facet *T from CS3 arbitrary metadata under
// the "libre.graph.<facet>." key prefix. Nil when no such keys are present.
func metadataToFacet[T any](metadata map[string]string, facet string) *T {
return mapping.DeserializeStringsAt[T](metadata, "libre.graph."+facet+".")
}
func cs3ResourceToRemoteItem(res *storageprovider.ResourceInfo) (*libregraph.RemoteItem, error) {
Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 167 KiB

@@ -5,6 +5,7 @@ import (
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
libregraph "github.com/opencloud-eu/libre-graph-api-go"
"github.com/opencloud-eu/reva/v2/pkg/conversions"
)
@@ -210,6 +211,8 @@ func cs3RoleToDisplayName(role *conversions.Role) string {
return _viewerListGrantsUnifiedRoleDisplayName
case conversions.RoleSpaceViewer:
return _spaceViewerUnifiedRoleDisplayName
case conversions.RoleSpaceViewerWithVersions:
return _spaceViewerWithVersionsUnifiedRoleDisplayName
case conversions.RoleEditor:
return _editorUnifiedRoleDisplayName
case conversions.RoleEditorWithVersions:
@@ -71,7 +71,7 @@ func TestCS3ResourcePermissionsToRole(t *testing.T) {
cs3Conversions.RoleFileEditorWithVersions: {cs3Conversions.NewFileEditorWithVersionsRole().CS3ResourcePermissions(), unifiedrole.RoleFileEditorWithVersions, unifiedrole.UnifiedRoleConditionFile},
cs3Conversions.RoleManager: {cs3Conversions.NewManagerRole().CS3ResourcePermissions(), unifiedrole.RoleManager, unifiedrole.UnifiedRoleConditionDrive},
cs3Conversions.RoleSpaceViewer: {cs3Conversions.NewSpaceViewerRole().CS3ResourcePermissions(), unifiedrole.RoleSpaceViewer, unifiedrole.UnifiedRoleConditionDrive},
cs3Conversions.RoleSpaceEditor: {cs3Conversions.NewSpaceEditorRole().CS3ResourcePermissions(), unifiedrole.RoleSpaceEditor, unifiedrole.UnifiedRoleConditionDrive},
cs3Conversions.RoleSpaceEditor: {cs3Conversions.NewSpaceEditorRole().CS3ResourcePermissions(), unifiedrole.RoleSpaceEditorWithVersions, unifiedrole.UnifiedRoleConditionDrive},
cs3Conversions.RoleSecureViewer + "1": {cs3Conversions.NewSecureViewerRole().CS3ResourcePermissions(), unifiedrole.RoleSecureViewer, unifiedrole.UnifiedRoleConditionFile},
cs3Conversions.RoleSecureViewer + "2": {cs3Conversions.NewSecureViewerRole().CS3ResourcePermissions(), unifiedrole.RoleSecureViewer, unifiedrole.UnifiedRoleConditionFolder},
cs3Conversions.RoleDenied: {cs3Conversions.NewDeniedRole().CS3ResourcePermissions(), unifiedrole.RoleDenied, unifiedrole.UnifiedRoleConditionFolder},
+17 -16
View File
@@ -1,22 +1,23 @@
package unifiedrole
var (
RoleViewer = roleViewer
RoleViewerWithVersions = roleViewerWithVersions
RoleViewerListGrants = roleViewerListGrants
RoleSpaceViewer = roleSpaceViewer
RoleEditor = roleEditor
RoleEditorWithVersions = roleEditorWithVersions
RoleEditorListGrants = roleEditorListGrants
RoleSpaceEditor = roleSpaceEditor
RoleSpaceEditorWithoutVersions = roleSpaceEditorWithoutVersions
RoleFileEditor = roleFileEditor
RoleFileEditorWithVersions = roleFileEditorWithVersions
RoleFileEditorListGrants = roleFileEditorListGrants
RoleEditorLite = roleEditorLite
RoleManager = roleManager
RoleSecureViewer = roleSecureViewer
RoleDenied = roleDenied
RoleViewer = roleViewer
RoleViewerWithVersions = roleViewerWithVersions
RoleViewerListGrants = roleViewerListGrants
RoleSpaceViewer = roleSpaceViewer
RoleSpaceViewerWithVersions = roleSpaceViewerWithVersions
RoleEditor = roleEditor
RoleEditorWithVersions = roleEditorWithVersions
RoleEditorListGrants = roleEditorListGrants
RoleSpaceEditor = roleSpaceEditor
RoleSpaceEditorWithVersions = roleSpaceEditorWithVersions
RoleFileEditor = roleFileEditor
RoleFileEditorWithVersions = roleFileEditorWithVersions
RoleFileEditorListGrants = roleFileEditorListGrants
RoleEditorLite = roleEditorLite
RoleManager = roleManager
RoleSecureViewer = roleSecureViewer
RoleDenied = roleDenied
BuildInRoles = buildInRoles
+33 -6
View File
@@ -6,9 +6,10 @@ import (
"strings"
libregraph "github.com/opencloud-eu/libre-graph-api-go"
"github.com/opencloud-eu/reva/v2/pkg/conversions"
"google.golang.org/protobuf/proto"
"github.com/opencloud-eu/reva/v2/pkg/conversions"
"github.com/opencloud-eu/opencloud/pkg/l10n"
graphl10n "github.com/opencloud-eu/opencloud/services/graph/pkg/l10n"
)
@@ -22,6 +23,8 @@ const (
UnifiedRoleViewerListGrantsID = "d5041006-ebb3-4b4a-b6a4-7c180ecfb17d"
// UnifiedRoleSpaceViewerID Unified role space viewer id.
UnifiedRoleSpaceViewerID = "a8d5fe5e-96e3-418d-825b-534dbdf22b99"
// UnifiedRoleSpaceViewerWithVersionsID
UnifiedRoleSpaceViewerWithVersionsID = "3de465fc-6e17-4839-8b8a-a77cc497878b"
// UnifiedRoleEditorID Unified role editor id.
UnifiedRoleEditorID = "fb6c3e19-e378-47e5-b277-9732f9de6e21"
// UnifiedRoleEditorWithVersionsID
@@ -121,6 +124,12 @@ var (
// UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
_spaceViewerUnifiedRoleDisplayName = l10n.Template("Can view")
// UnifiedRole SpaceViewer, Role Description (resolves directly)
_spaceViewerWithVersionsUnifiedRoleDescription = l10n.Template("View and download including the history.")
// UnifiedRole SpaseViewer, Role DisplayName (resolves directly)
_spaceViewerWithVersionsUnifiedRoleDisplayName = l10n.Template("Can view")
// UnifiedRole Editor, Role Description (resolves directly)
_editorUnifiedRoleDescription = l10n.Template("View, download, upload, edit, add and delete.")
@@ -214,11 +223,12 @@ var (
roleViewerWithVersions,
roleViewerListGrants,
roleSpaceViewer,
roleSpaceViewerWithVersions,
roleEditor,
roleEditorListGrants,
roleEditorWithVersions,
roleSpaceEditorWithVersions,
roleSpaceEditor,
roleSpaceEditorWithoutVersions,
roleFileEditor,
roleFileEditorWithVersions,
roleFileEditorListGrants,
@@ -345,6 +355,23 @@ var (
}
}()
// roleSpaceViewer creates a spaceviewer role
roleSpaceViewerWithVersions = func() *libregraph.UnifiedRoleDefinition {
r := conversions.NewSpaceViewerWithVersionsRole()
return &libregraph.UnifiedRoleDefinition{
Id: proto.String(UnifiedRoleSpaceViewerWithVersionsID),
Description: proto.String(_spaceViewerWithVersionsUnifiedRoleDescription),
DisplayName: proto.String(cs3RoleToDisplayName(r)),
RolePermissions: []libregraph.UnifiedRolePermission{
{
AllowedResourceActions: CS3ResourcePermissionsToLibregraphActions(r.CS3ResourcePermissions()),
Condition: proto.String(UnifiedRoleConditionDrive),
},
},
LibreGraphWeight: proto.Int32(40),
}
}()
// roleEditorLite creates an editor-lite role
roleEditorLite = func() *libregraph.UnifiedRoleDefinition {
r := conversions.NewEditorLiteRole()
@@ -420,8 +447,8 @@ var (
}
}()
// roleSpaceEditorWithoutVersions creates an editor without versions role
roleSpaceEditorWithoutVersions = func() *libregraph.UnifiedRoleDefinition {
// roleSpaceEditor creates an editor without versions role
roleSpaceEditor = func() *libregraph.UnifiedRoleDefinition {
r := conversions.NewSpaceEditorWithoutVersionsRole()
return &libregraph.UnifiedRoleDefinition{
Id: proto.String(UnifiedRoleSpaceEditorWithoutVersionsID),
@@ -437,8 +464,8 @@ var (
}
}()
// roleSpaceEditor creates an editor role
roleSpaceEditor = func() *libregraph.UnifiedRoleDefinition {
// roleSpaceEditorWithVersions creates an editor role
roleSpaceEditorWithVersions = func() *libregraph.UnifiedRoleDefinition {
r := conversions.NewSpaceEditorRole()
return &libregraph.UnifiedRoleDefinition{
Id: proto.String(UnifiedRoleSpaceEditorID),
Loaded 100 of 1240 files, more files were not shown because too many files have changed in this diff. Show more