Merge branch 'master' into no-additional-init
This commit is contained in:
+21
-210
@@ -1,177 +1,39 @@
|
||||
SHELL := bash
|
||||
NAME := settings
|
||||
IMPORT := github.com/owncloud/ocis/$(NAME)
|
||||
BIN := bin
|
||||
DIST := dist
|
||||
PROTO_VERSION := v0
|
||||
PROTO_SRC := pkg/proto/$(PROTO_VERSION)
|
||||
|
||||
ifeq ($(OS), Windows_NT)
|
||||
EXECUTABLE := $(NAME).exe
|
||||
UNAME := Windows
|
||||
else
|
||||
EXECUTABLE := $(NAME)
|
||||
UNAME := $(shell uname -s)
|
||||
endif
|
||||
|
||||
ifeq ($(UNAME), Darwin)
|
||||
GOBUILD ?= go build -i
|
||||
else
|
||||
GOBUILD ?= go build
|
||||
endif
|
||||
|
||||
PACKAGES ?= $(shell go list ./...)
|
||||
SOURCES ?= $(shell find . -name "*.go" -type f -not -path "./node_modules/*")
|
||||
GENERATE ?= $(PACKAGES)
|
||||
FEATURE_PATH ?= "ui/tests/acceptance/features"
|
||||
|
||||
TAGS ?=
|
||||
|
||||
ifndef GOPATH
|
||||
export GOPATH := $(shell go env GOPATH)
|
||||
endif
|
||||
export PATH := $(PATH):$(GOPATH)/bin
|
||||
|
||||
ifndef OUTPUT
|
||||
ifneq ($(DRONE_TAG),)
|
||||
OUTPUT ?= $(subst v,,$(DRONE_TAG))
|
||||
else
|
||||
OUTPUT ?= testing
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef VERSION
|
||||
ifneq ($(DRONE_TAG),)
|
||||
VERSION ?= $(subst v,,$(DRONE_TAG))
|
||||
else
|
||||
VERSION ?= $(shell git rev-parse --short HEAD)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifndef DATE
|
||||
DATE := $(shell date -u '+%Y%m%d')
|
||||
endif
|
||||
|
||||
LDFLAGS += -s -w -X "$(IMPORT)/pkg/version.String=$(VERSION)" -X "$(IMPORT)/pkg/version.Date=$(DATE)"
|
||||
DEBUG_LDFLAGS += -X "$(IMPORT)/pkg/version.String=$(VERSION)" -X "$(IMPORT)/pkg/version.Date=$(DATE)"
|
||||
GCFLAGS += all=-N -l
|
||||
|
||||
.PHONY: all
|
||||
all: build
|
||||
|
||||
.PHONY: sync
|
||||
sync:
|
||||
go mod download
|
||||
|
||||
.PHONY: clean
|
||||
clean:
|
||||
go clean -i ./...
|
||||
rm -rf $(BIN) $(DIST)
|
||||
|
||||
.PHONY: go-mod-tidy
|
||||
go-mod-tidy:
|
||||
@go mod tidy
|
||||
|
||||
.PHONY: fmt
|
||||
fmt:
|
||||
gofmt -s -w $(SOURCES)
|
||||
|
||||
.PHONY: vet
|
||||
vet:
|
||||
go vet $(PACKAGES)
|
||||
|
||||
.PHONY: staticcheck
|
||||
staticcheck:
|
||||
go run honnef.co/go/tools/cmd/staticcheck -tags '$(TAGS)' $(PACKAGES)
|
||||
|
||||
.PHONY: lint
|
||||
lint:
|
||||
for PKG in $(PACKAGES); do go run golang.org/x/lint/golint -set_exit_status $$PKG || exit 1; done;
|
||||
|
||||
.PHONY: changelog
|
||||
changelog:
|
||||
go run github.com/restic/calens >| CHANGELOG.md
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
go run github.com/haya14busa/goverage -v -coverprofile coverage.out $(PACKAGES)
|
||||
|
||||
.PHONY: go-coverage
|
||||
go-coverage:
|
||||
@if [ ! -f coverage.out ]; then $(MAKE) test &>/dev/null; fi;
|
||||
@go tool cover -func coverage.out | tail -1 | grep -Eo "[0-9]+\.[0-9]+"
|
||||
|
||||
.PHONY: install
|
||||
install: $(SOURCES)
|
||||
go install -v -tags '$(TAGS)' -ldflags '$(LDFLAGS)' ./cmd/$(NAME)
|
||||
|
||||
.PHONY: build
|
||||
build: $(BIN)/$(EXECUTABLE) $(BIN)/$(EXECUTABLE)-debug
|
||||
|
||||
$(BIN)/$(EXECUTABLE): $(SOURCES)
|
||||
$(GOBUILD) -v -tags '$(TAGS)' -ldflags '$(LDFLAGS)' -o $@ ./cmd/$(NAME)
|
||||
|
||||
$(BIN)/$(EXECUTABLE)-debug: $(SOURCES)
|
||||
$(GOBUILD) -v -tags '$(TAGS)' -ldflags '$(DEBUG_LDFLAGS)' -gcflags '$(GCFLAGS)' -o $@ ./cmd/$(NAME)
|
||||
|
||||
.PHONY: release
|
||||
release: release-dirs release-linux release-windows release-darwin release-copy release-check
|
||||
|
||||
.PHONY: release-dirs
|
||||
release-dirs:
|
||||
mkdir -p $(DIST)/binaries $(DIST)/release
|
||||
|
||||
.PHONY: release-linux
|
||||
release-linux: release-dirs
|
||||
go run github.com/mitchellh/gox -tags 'netgo $(TAGS)' -ldflags '-extldflags "-static" $(LDFLAGS)' -os 'linux' -arch 'amd64 386 arm64 arm' -output '$(DIST)/binaries/$(EXECUTABLE)-$(OUTPUT)-{{.OS}}-{{.Arch}}' ./cmd/$(NAME)
|
||||
|
||||
.PHONY: release-windows
|
||||
release-windows: release-dirs
|
||||
go run github.com/mitchellh/gox -tags 'netgo $(TAGS)' -ldflags '-extldflags "-static" $(LDFLAGS)' -os 'windows' -arch 'amd64' -output '$(DIST)/binaries/$(EXECUTABLE)-$(OUTPUT)-{{.OS}}-{{.Arch}}' ./cmd/$(NAME)
|
||||
|
||||
.PHONY: release-darwin
|
||||
release-darwin: release-dirs
|
||||
go run github.com/mitchellh/gox -tags 'netgo $(TAGS)' -ldflags '$(LDFLAGS)' -os 'darwin' -arch 'amd64' -output '$(DIST)/binaries/$(EXECUTABLE)-$(OUTPUT)-{{.OS}}-{{.Arch}}' ./cmd/$(NAME)
|
||||
|
||||
.PHONY: release-copy
|
||||
release-copy:
|
||||
$(foreach file,$(wildcard $(DIST)/binaries/$(EXECUTABLE)-*),cp $(file) $(DIST)/release/$(notdir $(file));)
|
||||
|
||||
.PHONY: release-check
|
||||
release-check:
|
||||
cd $(DIST)/release; $(foreach file,$(wildcard $(DIST)/release/$(EXECUTABLE)-*),sha256sum $(notdir $(file)) > $(notdir $(file)).sha256;)
|
||||
|
||||
.PHONY: release-finish
|
||||
release-finish: release-copy release-check
|
||||
|
||||
.PHONY: test-acceptance-webui
|
||||
test-acceptance-webui:
|
||||
./ui/tests/run-acceptance-test.sh $(FEATURE_PATH)
|
||||
|
||||
.PHONY: watch
|
||||
watch:
|
||||
go run github.com/cespare/reflex -c reflex.conf
|
||||
|
||||
############ tooling ############
|
||||
ifneq (, $(shell which go 2> /dev/null)) # supress `command not found warnings` for non go targets in CI
|
||||
include ../.bingo/Variables.mk
|
||||
endif
|
||||
|
||||
############ go tooling ############
|
||||
include ../.make/go.mk
|
||||
|
||||
|
||||
############ release ############
|
||||
include ../.make/release.mk
|
||||
|
||||
############ docs generate ############
|
||||
include ../.make/docs.mk
|
||||
|
||||
############ l10n ############
|
||||
include ../.make/l10n.mk
|
||||
|
||||
.PHONY: docs-generate
|
||||
docs-generate: config-docs-generate \
|
||||
grpc-docs-generate
|
||||
|
||||
.PHONY: config-docs-generate
|
||||
config-docs-generate:
|
||||
go run github.com/owncloud/flaex >| ../docs/extensions/$(NAME)/configuration.md
|
||||
|
||||
.PHONY: grpc-docs-generate
|
||||
grpc-docs-generate: ../docs/extensions/${NAME}/grpc.md
|
||||
|
||||
############ generate ############
|
||||
.PHONY: generate
|
||||
generate: ci-node-generate ci-go-generate
|
||||
include ../.make/generate.mk
|
||||
|
||||
.PHONY: ci-go-generate
|
||||
ci-go-generate: protobuf # CI runs ci-node-generate automatically before this target
|
||||
go generate $(GENERATE)
|
||||
@go generate $(GENERATE)
|
||||
|
||||
.PHONY: ci-node-generate
|
||||
ci-node-generate: yarn-build
|
||||
@@ -187,61 +49,10 @@ node_modules:
|
||||
yarn install --frozen-lockfile
|
||||
|
||||
############ protobuf ############
|
||||
$(GOPATH)/bin/protoc-gen-go:
|
||||
go get -v google.golang.org/protobuf/cmd/protoc-gen-go@v1.25.0
|
||||
PROTO_VERSION := v0
|
||||
PROTO_SRC := pkg/proto/$(PROTO_VERSION)
|
||||
|
||||
$(GOPATH)/bin/protoc-gen-micro:
|
||||
GO111MODULE=on go get -v github.com/asim/go-micro/cmd/protoc-gen-micro/v3
|
||||
|
||||
$(GOPATH)/bin/protoc-gen-microweb:
|
||||
GO111MODULE=off go get -v github.com/owncloud/protoc-gen-microweb
|
||||
|
||||
$(GOPATH)/bin/protoc-gen-openapiv2:
|
||||
GO111MODULE=off go get -v github.com/grpc-ecosystem/grpc-gateway/protoc-gen-openapiv2
|
||||
|
||||
$(GOPATH)/bin/protoc-gen-doc:
|
||||
GO111MODULE=off go get -v github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc
|
||||
|
||||
.PHONY: $(PROTO_SRC)/${NAME}.pb.go
|
||||
$(PROTO_SRC)/${NAME}.pb.go: $(GOPATH)/bin/protoc-gen-openapiv2 $(GOPATH)/bin/protoc-gen-go
|
||||
protoc \
|
||||
-I=../third_party/ \
|
||||
-I=$(PROTO_SRC)/ \
|
||||
-I=$(GOPATH)/src/github.com/grpc-ecosystem/grpc-gateway/ \
|
||||
--go_out=. ${NAME}.proto
|
||||
|
||||
.PHONY: $(PROTO_SRC)/${NAME}.pb.micro.go
|
||||
$(PROTO_SRC)/${NAME}.pb.micro.go: $(GOPATH)/bin/protoc-gen-openapiv2 $(GOPATH)/bin/protoc-gen-micro
|
||||
protoc \
|
||||
-I=../third_party/ \
|
||||
-I=$(PROTO_SRC)/ \
|
||||
-I=$(GOPATH)/src/github.com/grpc-ecosystem/grpc-gateway/ \
|
||||
--micro_out=. ${NAME}.proto
|
||||
|
||||
.PHONY: $(PROTO_SRC)/${NAME}.pb.web.go
|
||||
$(PROTO_SRC)/${NAME}.pb.web.go: $(GOPATH)/bin/protoc-gen-openapiv2 $(GOPATH)/bin/protoc-gen-microweb
|
||||
protoc \
|
||||
-I=../third_party/ \
|
||||
-I=$(PROTO_SRC)/ \
|
||||
-I=$(GOPATH)/src/github.com/grpc-ecosystem/grpc-gateway/ \
|
||||
--microweb_out=. ${NAME}.proto
|
||||
|
||||
.PHONY: $(PROTO_SRC)/${NAME}.swagger.json
|
||||
$(PROTO_SRC)/${NAME}.swagger.json: $(GOPATH)/bin/protoc-gen-openapiv2
|
||||
protoc \
|
||||
-I=../third_party/ \
|
||||
-I=$(PROTO_SRC)/ \
|
||||
-I=$(GOPATH)/src/github.com/grpc-ecosystem/grpc-gateway/ \
|
||||
--openapiv2_out=$(PROTO_SRC)/ ${NAME}.proto
|
||||
|
||||
.PHONY: ../docs/extensions/${NAME}/grpc.md
|
||||
../docs/extensions/${NAME}/grpc.md: $(GOPATH)/bin/protoc-gen-openapiv2 $(GOPATH)/bin/protoc-gen-doc
|
||||
protoc \
|
||||
-I=../third_party/ \
|
||||
-I=$(PROTO_SRC)/ \
|
||||
-I=$(GOPATH)/src/github.com/grpc-ecosystem/grpc-gateway/ \
|
||||
--doc_opt=./templates/GRPC.tmpl,grpc.md \
|
||||
--doc_out=../docs/extensions/${NAME} $(PROTO_SRC)/${NAME}.proto
|
||||
include ../.make/protobuf.mk
|
||||
|
||||
.PHONY: protobuf
|
||||
protobuf: $(PROTO_SRC)/${NAME}.pb.go \
|
||||
|
||||
@@ -4,10 +4,11 @@ import (
|
||||
"os"
|
||||
|
||||
"github.com/owncloud/ocis/settings/pkg/command"
|
||||
"github.com/owncloud/ocis/settings/pkg/config"
|
||||
)
|
||||
|
||||
func main() {
|
||||
if err := command.Execute(); err != nil {
|
||||
if err := command.Execute(config.New()); err != nil {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
+13
-23
@@ -1,48 +1,38 @@
|
||||
module github.com/owncloud/ocis/settings
|
||||
|
||||
go 1.15
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
contrib.go.opencensus.io/exporter/jaeger v0.2.1
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.6.0
|
||||
contrib.go.opencensus.io/exporter/zipkin v0.1.1
|
||||
github.com/Masterminds/sprig/v3 v3.2.2 // indirect
|
||||
github.com/UnnoTed/fileb0x v1.1.4
|
||||
contrib.go.opencensus.io/exporter/ocagent v0.7.0
|
||||
contrib.go.opencensus.io/exporter/zipkin v0.1.2
|
||||
github.com/asim/go-micro/v3 v3.5.1-0.20210217182006-0f0ace1a44a9
|
||||
github.com/go-chi/chi v4.1.2+incompatible
|
||||
github.com/go-chi/render v1.0.1
|
||||
github.com/go-ozzo/ozzo-validation/v4 v4.2.1
|
||||
github.com/gofrs/uuid v3.3.0+incompatible
|
||||
github.com/golang/protobuf v1.4.3
|
||||
github.com/golang/protobuf v1.5.2
|
||||
github.com/grpc-ecosystem/grpc-gateway/v2 v2.2.0
|
||||
github.com/huandu/xstrings v1.3.2 // indirect
|
||||
github.com/micro/cli/v2 v2.1.2
|
||||
github.com/mitchellh/copystructure v1.1.1 // indirect
|
||||
github.com/mitchellh/gox v1.0.1
|
||||
github.com/oklog/run v1.1.0
|
||||
github.com/olekukonko/tablewriter v0.0.4
|
||||
github.com/openzipkin/zipkin-go v0.2.2
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/openzipkin/zipkin-go v0.2.5
|
||||
github.com/owncloud/ocis/ocis-pkg v0.0.0-20210216094451-dc73176dc62d
|
||||
github.com/prometheus/client_golang v1.7.1
|
||||
github.com/restic/calens v0.2.0
|
||||
github.com/spf13/viper v1.7.0
|
||||
github.com/prometheus/client_golang v1.10.0
|
||||
github.com/spf13/viper v1.7.1
|
||||
github.com/stretchr/testify v1.7.0
|
||||
go.opencensus.io v0.22.6
|
||||
golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad // indirect
|
||||
golang.org/x/lint v0.0.0-20201208152925-83fdc39ff7b5
|
||||
golang.org/x/mod v0.4.1 // indirect
|
||||
golang.org/x/net v0.0.0-20201224014010-6772e930b67b
|
||||
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c // indirect
|
||||
github.com/thejerf/suture/v4 v4.0.0
|
||||
go.opencensus.io v0.23.0
|
||||
golang.org/x/net v0.0.0-20210428140749-89ef3d95e781
|
||||
google.golang.org/genproto v0.0.0-20210207032614-bba0dbe2a9ea
|
||||
google.golang.org/protobuf v1.25.0
|
||||
google.golang.org/protobuf v1.27.0
|
||||
gotest.tools v2.2.0+incompatible
|
||||
)
|
||||
|
||||
replace (
|
||||
github.com/owncloud/ocis/ocis-pkg => ../ocis-pkg
|
||||
github.com/owncloud/ocis/store => ../store
|
||||
// taken from https://github.com/asim/go-micro/blob/master/plugins/registry/etcd/go.mod#L14-L16
|
||||
go.etcd.io/etcd/api/v3 => go.etcd.io/etcd/api/v3 v3.0.0-20210204162551-dae29bb719dd
|
||||
go.etcd.io/etcd/pkg/v3 => go.etcd.io/etcd/pkg/v3 v3.0.0-20210204162551-dae29bb719dd
|
||||
// latest version compatible with etcd
|
||||
google.golang.org/grpc => google.golang.org/grpc v1.29.1
|
||||
)
|
||||
|
||||
+551
-188
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,9 @@
|
||||
[main]
|
||||
host = https://www.transifex.com
|
||||
|
||||
[owncloud.ocis-settings]
|
||||
file_filter = locale/<lang>/LC_MESSAGES/app.po
|
||||
minimum_perc = 0
|
||||
source_file = template.pot
|
||||
source_lang = en
|
||||
type = PO
|
||||
@@ -0,0 +1 @@
|
||||
{"de":{"{{ bundle.displayName }}":"{{ bundle.displayName }}","Account":"Konto","Cancel":"Abbrechen","Hello":"Hallo","Language":"Sprache","Loading personal settings":"Lade persönliche Einstellungen","Loading personal settings...":"Lade persönliche Einstellungen...","msg":"msg","No settings available":"Keine Einstellungen verfügbar","Save":"Speichern","Settings":"Einstellungen","Settings type not implemented: %{type}":"Einstellungs-Typ nicht verfügbar: %{type}"},"de_DE":{"{{ bundle.displayName }}":"{{ bundle.displayName }}","Account":"Benutzerkonto","Cancel":"Abbrechen","Hello":"Hallo","Language":"Sprache","Loading personal settings":"Lade persönliche Einstellungen","Loading personal settings...":"Lade persönliche Einstellungen...","msg":"msg","No settings available":"Keine Einstellungen verfügbar","Save":"Speichern","Settings":"Einstellungen","Settings type not implemented: %{type}":"Einstellungs-Typ nicht verfügbar: %{type}"},"es":{"{{ bundle.displayName }}":"{{bundle.displayName}}","Account":"Cuenta","Cancel":"Cancelar","Hello":"Hola","Language":"Idioma","Loading personal settings":"Cargando configuraciones personales","Loading personal settings...":"Cargando configuración personal ...","msg":"msg","No settings available":"No hay configuraciones disponibles","Save":"Guardar","Settings":"Configuración","Settings type not implemented: %{type}":"Tipo de configuración no implementado: %{type}"},"pl":{"{{ bundle.displayName }}":"{{ bundle.displayName }}","Account":"Konto","Cancel":"Anuluj","Hello":"Witaj","Language":"Język","Loading personal settings":"Ładowanie ustawień osobistych","Loading personal settings...":"Ładowanie ustawień osobistych...","msg":"wiad","No settings available":"Brak dostępnych ustawień","Save":"Zapisz","Settings":"Ustawienia","Settings type not implemented: %{type}":"Typ ustawień nie jest wdrożony: %{type}"},"pt_BR":{"{{ bundle.displayName }}":"{{ bundle.displayName }}","Account":"Conta","Cancel":"Cancelar","Hello":"Olá","Language":"Idioma","Loading personal settings":"Carregando configurações pessoais ","Loading personal settings...":"Carregando configurações pessoais... ","msg":"msg","No settings available":"Nenhuma configuração disponível ","Save":"Salvar","Settings":"Configurações","Settings type not implemented: %{type}":"Tipo de configuração não implementado: %{type}"},"ru":{"{{ bundle.displayName }}":"{{ bundle.displayName }}","Account":"Уч.запись","Cancel":"Отмена","Hello":"Здравствуйте","Language":"Язык","Loading personal settings":"Загрузка личных настроек","Loading personal settings...":"Загрузка личных настроек…","msg":"сообщ","No settings available":"Нет доступных настроек","Save":"Сохранить","Settings":"Настройки","Settings type not implemented: %{type}":"Тип настроек не реализован: %{type}"},"sq":{"{{ bundle.displayName }}":"{{ bundle.displayName }}","Account":"Llogari","Cancel":"Anuloje","Hello":"Tungjatjeta","Language":"Gjuhë","Loading personal settings":"Ngarkim rregullimesh personale","Loading personal settings...":"Po ngarkohen rregullime personale…","msg":"msz","No settings available":"S’ka rregullime","Save":"Ruaje","Settings":"Rregullime","Settings type not implemented: %{type}":"Lloj rregullimi i pasendërtuar: %{type}"},"th_TH":{"{{ bundle.displayName }}":"{{ bundle.displayName }}","Account":"บัญชี","Cancel":"ยกเลิก","Hello":"สวัสดี","Language":"ภาษา","Loading personal settings":"กำลังโหลดการตั้งค่าส่วนบุคคล","Loading personal settings...":"กำลังโหลดการตั้งค่าส่วนบุคคล...","msg":"msg","No settings available":"ไม่มีการตั้งค่า","Save":"บันทึก","Settings":"ตั้งค่า","Settings type not implemented: %{type}":"ประเภทการตั้งค่าที่ยังไม่ถูกดำเนินการ: %{type}"}}
|
||||
@@ -1,15 +1,10 @@
|
||||
const path = require('path')
|
||||
const WEB_PATH = process.env.WEB_PATH
|
||||
const TEST_INFRA_DIRECTORY = process.env.TEST_INFRA_DIRECTORY
|
||||
const OCIS_SETTINGS_STORE = process.env.OCIS_SETTINGS_STORE || './ocis-settings-store'
|
||||
|
||||
const config = require(path.join(WEB_PATH, 'nightwatch.conf.js'))
|
||||
|
||||
config.page_objects_path = [TEST_INFRA_DIRECTORY + '/acceptance/pageObjects', 'ui/tests/acceptance/pageobjects']
|
||||
config.custom_commands_path = TEST_INFRA_DIRECTORY + '/acceptance/customCommands'
|
||||
|
||||
config.test_settings.default.globals = { ...config.test_settings.default.globals, settings_store: OCIS_SETTINGS_STORE }
|
||||
|
||||
module.exports = {
|
||||
...config
|
||||
}
|
||||
module.exports = config
|
||||
|
||||
+18
-16
@@ -8,7 +8,7 @@
|
||||
"author": "ownCloud GmbH <devops@owncloud.com>",
|
||||
"repository": "https://github.com/owncloud/ocis-settings.git",
|
||||
"bugs": {
|
||||
"url": "https://github.com/owncloud/ocis/settings/issues",
|
||||
"url": "https://github.com/owncloud/ocis/issues",
|
||||
"email": "support@owncloud.com"
|
||||
},
|
||||
"scripts": {
|
||||
@@ -17,46 +17,46 @@
|
||||
"watch": "rollup -c -w",
|
||||
"test": "echo 'Not implemented'",
|
||||
"generate-api": "node node_modules/swagger-vue-generator/bin/generate-api.js --package-version v0 --source pkg/proto/v0/settings.swagger.json --moduleName settings --destination ui/client/settings/index.js",
|
||||
"acceptance-tests": "cucumber-js --require-module @babel/register --require-module @babel/polyfill --require ${TEST_INFRA_DIRECTORY}/acceptance/setup.js --require ui/tests/acceptance/stepDefinitions --require ${TEST_INFRA_DIRECTORY}/acceptance/stepDefinitions --format node_modules/cucumber-pretty -t \"${TEST_TAGS:-not @skip and not @skipOnOC10}\""
|
||||
"acceptance-tests": "cucumber-js --retry 1 --require-module @babel/register --require-module @babel/polyfill --require ${TEST_INFRA_DIRECTORY}/acceptance/setup.js --require ui/tests/acceptance/stepDefinitions --require ${TEST_INFRA_DIRECTORY}/acceptance/stepDefinitions --format node_modules/cucumber-pretty -t \"${TEST_TAGS:-not @skip and not @skipOnOC10}\""
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.7.7",
|
||||
"@babel/core": "^7.13.10",
|
||||
"@babel/plugin-proposal-class-properties": "^7.7.4",
|
||||
"@babel/plugin-proposal-export-default-from": "^7.7.4",
|
||||
"@babel/plugin-proposal-object-rest-spread": "^7.7.7",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.7.4",
|
||||
"@babel/plugin-transform-runtime": "^7.8.0",
|
||||
"@babel/plugin-transform-runtime": "^7.13.10",
|
||||
"@babel/polyfill": "^7.10.1",
|
||||
"@babel/preset-env": "^7.7.7",
|
||||
"@babel/preset-env": "^7.13.12",
|
||||
"@babel/register": "^7.10.1",
|
||||
"@erquhart/rollup-plugin-node-builtins": "^2.1.5",
|
||||
"@rollup/plugin-commonjs": "^17.1.0",
|
||||
"@rollup/plugin-json": "^4.0.1",
|
||||
"@rollup/plugin-replace": "^2.3.0",
|
||||
"archiver": "^5.2.0",
|
||||
"@rollup/plugin-replace": "^2.4.2",
|
||||
"archiver": "^5.3.0",
|
||||
"axios": "^0.21.1",
|
||||
"core-js": "3",
|
||||
"core-js": "3.9.1",
|
||||
"cross-env": "^7.0.3",
|
||||
"cucumber": "^6.0.5",
|
||||
"cucumber-pretty": ">=6.0.0",
|
||||
"debounce": "^1.2.0",
|
||||
"debounce": "^1.2.1",
|
||||
"easygettext": "^2.7.0",
|
||||
"eslint": "7.20.0",
|
||||
"eslint": "7.22.0",
|
||||
"eslint-config-standard": "^16.0.2",
|
||||
"eslint-plugin-import": "^2.17.3",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"eslint-plugin-promise": "^4.1.1",
|
||||
"eslint-plugin-standard": "^5.0.0",
|
||||
"eslint-plugin-vue": "^7.6.0",
|
||||
"eslint-plugin-vue": "^7.8.0",
|
||||
"fs-extra": "^9.0.1",
|
||||
"join-path": "^1.1.1",
|
||||
"ldap": "^0.7.1",
|
||||
"nightwatch": "^1.3.6",
|
||||
"nightwatch": "^1.6.0",
|
||||
"nightwatch-api": "^3.0.1",
|
||||
"node-fetch": "^2.6.1",
|
||||
"qs": "^6.9.1",
|
||||
"qs": "^6.10.1",
|
||||
"rimraf": "^3.0.0",
|
||||
"rollup": "^2.39.0",
|
||||
"rollup": "^2.42.2",
|
||||
"rollup-plugin-babel": "^4.3.3",
|
||||
"rollup-plugin-eslint": "^7.0.0",
|
||||
"rollup-plugin-filesize": "^9.1.0",
|
||||
@@ -65,7 +65,7 @@
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"rollup-plugin-vue": "^5.1.9",
|
||||
"swagger-vue-generator": "^1.0.6",
|
||||
"url-search-params-polyfill": "^8.1.0",
|
||||
"url-search-params-polyfill": "^8.1.1",
|
||||
"vue-template-compiler": "^2.6.11",
|
||||
"xml-js": "^1.6.11"
|
||||
},
|
||||
@@ -74,10 +74,12 @@
|
||||
"not dead"
|
||||
],
|
||||
"peerDependencies": {
|
||||
"owncloud-design-system": "^1.7.0"
|
||||
"owncloud-design-system": "^7.4.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"ldapjs": "^2.2.4",
|
||||
"lodash": "^4.17.15",
|
||||
"nightwatch-vrt": "^0.2.10",
|
||||
"vuex": "^3.2.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
_ "golang.org/x/net/webdav"
|
||||
)
|
||||
|
||||
//go:generate go run github.com/UnnoTed/fileb0x embed.yml
|
||||
//go:generate make -C ../.. embed.yml
|
||||
|
||||
// assets gets initialized by New and provides the handler.
|
||||
type assets struct {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -1,21 +1,24 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/owncloud/ocis/ocis-pkg/sync"
|
||||
|
||||
"github.com/micro/cli/v2"
|
||||
ociscfg "github.com/owncloud/ocis/ocis-pkg/config"
|
||||
"github.com/owncloud/ocis/ocis-pkg/log"
|
||||
"github.com/owncloud/ocis/settings/pkg/config"
|
||||
"github.com/owncloud/ocis/settings/pkg/flagset"
|
||||
"github.com/owncloud/ocis/settings/pkg/version"
|
||||
"github.com/spf13/viper"
|
||||
"github.com/thejerf/suture/v4"
|
||||
)
|
||||
|
||||
// Execute is the entry point for the ocis-settings command.
|
||||
func Execute() error {
|
||||
cfg := config.New()
|
||||
|
||||
func Execute(cfg *config.Config) error {
|
||||
app := &cli.App{
|
||||
Name: "ocis-settings",
|
||||
Version: version.String,
|
||||
@@ -63,11 +66,14 @@ func NewLogger(cfg *config.Config) log.Logger {
|
||||
log.Level(cfg.Log.Level),
|
||||
log.Pretty(cfg.Log.Pretty),
|
||||
log.Color(cfg.Log.Color),
|
||||
log.File(cfg.Log.File),
|
||||
)
|
||||
}
|
||||
|
||||
// ParseConfig loads settings configuration from Viper known paths.
|
||||
func ParseConfig(c *cli.Context, cfg *config.Config) error {
|
||||
sync.ParsingViperConfig.Lock()
|
||||
defer sync.ParsingViperConfig.Unlock()
|
||||
logger := NewLogger(cfg)
|
||||
|
||||
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
||||
@@ -108,3 +114,28 @@ func ParseConfig(c *cli.Context, cfg *config.Config) error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SutureService allows for the settings command to be embedded and supervised by a suture supervisor tree.
|
||||
type SutureService struct {
|
||||
cfg *config.Config
|
||||
}
|
||||
|
||||
// NewSutureService creates a new settings.SutureService
|
||||
func NewSutureService(cfg *ociscfg.Config) suture.Service {
|
||||
if cfg.Mode == 0 {
|
||||
cfg.Settings.Supervised = true
|
||||
}
|
||||
cfg.Settings.Log.File = cfg.Log.File
|
||||
return SutureService{
|
||||
cfg: cfg.Settings,
|
||||
}
|
||||
}
|
||||
|
||||
func (s SutureService) Serve(ctx context.Context) error {
|
||||
s.cfg.Context = ctx
|
||||
if err := Execute(s.cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
+50
-185
@@ -2,27 +2,18 @@ package command
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"os/signal"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/owncloud/ocis/settings/pkg/metrics"
|
||||
|
||||
"contrib.go.opencensus.io/exporter/jaeger"
|
||||
"contrib.go.opencensus.io/exporter/ocagent"
|
||||
"contrib.go.opencensus.io/exporter/zipkin"
|
||||
"github.com/micro/cli/v2"
|
||||
"github.com/oklog/run"
|
||||
openzipkin "github.com/openzipkin/zipkin-go"
|
||||
zipkinhttp "github.com/openzipkin/zipkin-go/reporter/http"
|
||||
"github.com/owncloud/ocis/ocis-pkg/sync"
|
||||
"github.com/owncloud/ocis/settings/pkg/config"
|
||||
"github.com/owncloud/ocis/settings/pkg/flagset"
|
||||
"github.com/owncloud/ocis/settings/pkg/metrics"
|
||||
"github.com/owncloud/ocis/settings/pkg/server/debug"
|
||||
"github.com/owncloud/ocis/settings/pkg/server/grpc"
|
||||
"github.com/owncloud/ocis/settings/pkg/server/http"
|
||||
"go.opencensus.io/stats/view"
|
||||
"go.opencensus.io/trace"
|
||||
"github.com/owncloud/ocis/settings/pkg/tracing"
|
||||
)
|
||||
|
||||
// Server is the entrypoint for the server command.
|
||||
@@ -32,202 +23,76 @@ func Server(cfg *config.Config) *cli.Command {
|
||||
Usage: "Start integrated server",
|
||||
Flags: flagset.ServerWithConfig(cfg),
|
||||
Before: func(ctx *cli.Context) error {
|
||||
logger := NewLogger(cfg)
|
||||
if cfg.HTTP.Root != "/" {
|
||||
cfg.HTTP.Root = strings.TrimSuffix(cfg.HTTP.Root, "/")
|
||||
}
|
||||
|
||||
// When running on single binary mode the before hook from the root command won't get called. We manually
|
||||
// call this before hook from ocis command, so the configuration can be loaded.
|
||||
return ParseConfig(ctx, cfg)
|
||||
if !cfg.Supervised {
|
||||
return ParseConfig(ctx, cfg)
|
||||
}
|
||||
logger.Debug().Str("service", "settings").Msg("ignoring config file parsing when running supervised")
|
||||
return nil
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
logger := NewLogger(cfg)
|
||||
|
||||
if cfg.Tracing.Enabled {
|
||||
switch t := cfg.Tracing.Type; t {
|
||||
case "agent":
|
||||
exporter, err := ocagent.NewExporter(
|
||||
ocagent.WithReconnectionPeriod(5*time.Second),
|
||||
ocagent.WithAddress(cfg.Tracing.Endpoint),
|
||||
ocagent.WithServiceName(cfg.Tracing.Service),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
logger.Error().
|
||||
Err(err).
|
||||
Str("endpoint", cfg.Tracing.Endpoint).
|
||||
Str("collector", cfg.Tracing.Collector).
|
||||
Msg("Failed to create agent tracing")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
trace.RegisterExporter(exporter)
|
||||
view.RegisterExporter(exporter)
|
||||
|
||||
case "jaeger":
|
||||
exporter, err := jaeger.NewExporter(
|
||||
jaeger.Options{
|
||||
AgentEndpoint: cfg.Tracing.Endpoint,
|
||||
CollectorEndpoint: cfg.Tracing.Collector,
|
||||
Process: jaeger.Process{
|
||||
ServiceName: cfg.Tracing.Service,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
logger.Error().
|
||||
Err(err).
|
||||
Str("endpoint", cfg.Tracing.Endpoint).
|
||||
Str("collector", cfg.Tracing.Collector).
|
||||
Msg("Failed to create jaeger tracing")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
trace.RegisterExporter(exporter)
|
||||
|
||||
case "zipkin":
|
||||
endpoint, err := openzipkin.NewEndpoint(
|
||||
cfg.Tracing.Service,
|
||||
cfg.Tracing.Endpoint,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
logger.Error().
|
||||
Err(err).
|
||||
Str("endpoint", cfg.Tracing.Endpoint).
|
||||
Str("collector", cfg.Tracing.Collector).
|
||||
Msg("Failed to create zipkin tracing")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
exporter := zipkin.NewExporter(
|
||||
zipkinhttp.NewReporter(
|
||||
cfg.Tracing.Collector,
|
||||
),
|
||||
endpoint,
|
||||
)
|
||||
|
||||
trace.RegisterExporter(exporter)
|
||||
|
||||
default:
|
||||
logger.Warn().
|
||||
Str("type", t).
|
||||
Msg("Unknown tracing backend")
|
||||
}
|
||||
|
||||
trace.ApplyConfig(
|
||||
trace.Config{
|
||||
DefaultSampler: trace.AlwaysSample(),
|
||||
},
|
||||
)
|
||||
} else {
|
||||
logger.Debug().
|
||||
Msg("Tracing is not enabled")
|
||||
err := tracing.Configure(cfg, logger)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var (
|
||||
gr = run.Group{}
|
||||
ctx, cancel = context.WithCancel(context.Background())
|
||||
mtrcs = metrics.New()
|
||||
)
|
||||
|
||||
servers := run.Group{}
|
||||
ctx, cancel := func() (context.Context, context.CancelFunc) {
|
||||
if cfg.Context == nil {
|
||||
return context.WithCancel(context.Background())
|
||||
}
|
||||
return context.WithCancel(cfg.Context)
|
||||
}()
|
||||
defer cancel()
|
||||
|
||||
mtrcs := metrics.New()
|
||||
mtrcs.BuildInfo.WithLabelValues(cfg.Service.Version).Set(1)
|
||||
|
||||
{
|
||||
server := http.Server(
|
||||
http.Name(cfg.Service.Name),
|
||||
http.Logger(logger),
|
||||
http.Context(ctx),
|
||||
http.Config(cfg),
|
||||
http.Metrics(mtrcs),
|
||||
http.Flags(flagset.RootWithConfig(config.New())),
|
||||
http.Flags(flagset.ServerWithConfig(config.New())),
|
||||
)
|
||||
// prepare an HTTP server and add it to the group run.
|
||||
httpServer := http.Server(
|
||||
http.Name(cfg.Service.Name),
|
||||
http.Logger(logger),
|
||||
http.Context(ctx),
|
||||
http.Config(cfg),
|
||||
http.Metrics(mtrcs),
|
||||
)
|
||||
servers.Add(httpServer.Run, func(_ error) {
|
||||
logger.Info().Str("server", "http").Msg("Shutting down server")
|
||||
cancel()
|
||||
})
|
||||
|
||||
gr.Add(server.Run, func(_ error) {
|
||||
logger.Info().
|
||||
Str("server", "http").
|
||||
Msg("Shutting down server")
|
||||
// prepare a gRPC server and add it to the group run.
|
||||
grpcServer := grpc.Server(grpc.Name(cfg.Service.Name), grpc.Logger(logger), grpc.Context(ctx), grpc.Config(cfg), grpc.Metrics(mtrcs))
|
||||
servers.Add(grpcServer.Run, func(_ error) {
|
||||
logger.Info().Str("server", "grpc").Msg("Shutting down server")
|
||||
cancel()
|
||||
})
|
||||
|
||||
cancel()
|
||||
})
|
||||
// prepare a debug server and add it to the group run.
|
||||
debugServer, err := debug.Server(debug.Logger(logger), debug.Context(ctx), debug.Config(cfg))
|
||||
if err != nil {
|
||||
logger.Error().Err(err).Str("server", "debug").Msg("Failed to initialize server")
|
||||
return err
|
||||
}
|
||||
|
||||
{
|
||||
server := grpc.Server(
|
||||
grpc.Name(cfg.Service.Name),
|
||||
grpc.Logger(logger),
|
||||
grpc.Context(ctx),
|
||||
grpc.Config(cfg),
|
||||
grpc.Metrics(mtrcs),
|
||||
)
|
||||
servers.Add(debugServer.ListenAndServe, func(_ error) {
|
||||
_ = debugServer.Shutdown(ctx)
|
||||
cancel()
|
||||
})
|
||||
|
||||
gr.Add(server.Run, func(_ error) {
|
||||
logger.Info().
|
||||
Str("server", "grpc").
|
||||
Msg("Shutting down server")
|
||||
|
||||
cancel()
|
||||
})
|
||||
if !cfg.Supervised {
|
||||
sync.Trap(&servers, cancel)
|
||||
}
|
||||
|
||||
{
|
||||
server, err := debug.Server(
|
||||
debug.Logger(logger),
|
||||
debug.Context(ctx),
|
||||
debug.Config(cfg),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
logger.Error().
|
||||
Err(err).
|
||||
Str("server", "debug").
|
||||
Msg("Failed to initialize server")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
gr.Add(server.ListenAndServe, func(_ error) {
|
||||
ctx, timeout := context.WithTimeout(ctx, 5*time.Second)
|
||||
|
||||
defer timeout()
|
||||
defer cancel()
|
||||
|
||||
if err := server.Shutdown(ctx); err != nil {
|
||||
logger.Error().
|
||||
Err(err).
|
||||
Str("server", "debug").
|
||||
Msg("Failed to shutdown server")
|
||||
} else {
|
||||
logger.Info().
|
||||
Str("server", "debug").
|
||||
Msg("Shutting down server")
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
{
|
||||
stop := make(chan os.Signal, 1)
|
||||
|
||||
gr.Add(func() error {
|
||||
signal.Notify(stop, os.Interrupt)
|
||||
|
||||
<-stop
|
||||
|
||||
return nil
|
||||
}, func(err error) {
|
||||
close(stop)
|
||||
cancel()
|
||||
})
|
||||
}
|
||||
|
||||
return gr.Run()
|
||||
return servers.Run()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
package config
|
||||
|
||||
import "context"
|
||||
|
||||
// Log defines the available logging configuration.
|
||||
type Log struct {
|
||||
Level string
|
||||
Pretty bool
|
||||
Color bool
|
||||
File string
|
||||
}
|
||||
|
||||
// Debug defines the available debug configuration.
|
||||
@@ -66,6 +69,9 @@ type Config struct {
|
||||
Tracing Tracing
|
||||
Asset Asset
|
||||
TokenManager TokenManager
|
||||
|
||||
Context context.Context
|
||||
Supervised bool
|
||||
}
|
||||
|
||||
// New initializes a new configuration with or without defaults.
|
||||
|
||||
@@ -2,6 +2,7 @@ package flagset
|
||||
|
||||
import (
|
||||
"github.com/micro/cli/v2"
|
||||
"github.com/owncloud/ocis/ocis-pkg/flags"
|
||||
"github.com/owncloud/ocis/settings/pkg/config"
|
||||
)
|
||||
|
||||
@@ -10,23 +11,20 @@ func RootWithConfig(cfg *config.Config) []cli.Flag {
|
||||
return []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "log-level",
|
||||
Value: "info",
|
||||
Usage: "Set logging level",
|
||||
EnvVars: []string{"SETTINGS_LOG_LEVEL"},
|
||||
EnvVars: []string{"SETTINGS_LOG_LEVEL", "OCIS_LOG_LEVEL"},
|
||||
Destination: &cfg.Log.Level,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "log-pretty",
|
||||
Value: true,
|
||||
Usage: "Enable pretty logging",
|
||||
EnvVars: []string{"SETTINGS_LOG_PRETTY"},
|
||||
EnvVars: []string{"SETTINGS_LOG_PRETTY", "OCIS_LOG_PRETTY"},
|
||||
Destination: &cfg.Log.Pretty,
|
||||
},
|
||||
&cli.BoolFlag{
|
||||
Name: "log-color",
|
||||
Value: true,
|
||||
Usage: "Enable colored logging",
|
||||
EnvVars: []string{"SETTINGS_LOG_COLOR"},
|
||||
EnvVars: []string{"SETTINGS_LOG_COLOR", "OCIS_LOG_COLOR"},
|
||||
Destination: &cfg.Log.Color,
|
||||
},
|
||||
}
|
||||
@@ -37,7 +35,7 @@ func HealthWithConfig(cfg *config.Config) []cli.Flag {
|
||||
return []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "debug-addr",
|
||||
Value: "0.0.0.0:9194",
|
||||
Value: flags.OverrideDefaultString(cfg.Debug.Addr, "0.0.0.0:9194"),
|
||||
Usage: "Address to debug endpoint",
|
||||
EnvVars: []string{"SETTINGS_DEBUG_ADDR"},
|
||||
Destination: &cfg.Debug.Addr,
|
||||
@@ -63,42 +61,42 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag {
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "tracing-type",
|
||||
Value: "jaeger",
|
||||
Value: flags.OverrideDefaultString(cfg.Tracing.Type, "jaeger"),
|
||||
Usage: "Tracing backend type",
|
||||
EnvVars: []string{"SETTINGS_TRACING_TYPE"},
|
||||
Destination: &cfg.Tracing.Type,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "tracing-endpoint",
|
||||
Value: "",
|
||||
Value: flags.OverrideDefaultString(cfg.Tracing.Endpoint, ""),
|
||||
Usage: "Endpoint for the agent",
|
||||
EnvVars: []string{"SETTINGS_TRACING_ENDPOINT"},
|
||||
Destination: &cfg.Tracing.Endpoint,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "tracing-collector",
|
||||
Value: "",
|
||||
Value: flags.OverrideDefaultString(cfg.Tracing.Collector, ""),
|
||||
Usage: "Endpoint for the collector",
|
||||
EnvVars: []string{"SETTINGS_TRACING_COLLECTOR"},
|
||||
Destination: &cfg.Tracing.Collector,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "tracing-service",
|
||||
Value: "settings",
|
||||
Value: flags.OverrideDefaultString(cfg.Tracing.Service, "settings"),
|
||||
Usage: "Service name for tracing",
|
||||
EnvVars: []string{"SETTINGS_TRACING_SERVICE"},
|
||||
Destination: &cfg.Tracing.Service,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "debug-addr",
|
||||
Value: "0.0.0.0:9194",
|
||||
Value: flags.OverrideDefaultString(cfg.Debug.Addr, "0.0.0.0:9194"),
|
||||
Usage: "Address to bind debug server",
|
||||
EnvVars: []string{"SETTINGS_DEBUG_ADDR"},
|
||||
Destination: &cfg.Debug.Addr,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "debug-token",
|
||||
Value: "",
|
||||
Value: flags.OverrideDefaultString(cfg.Debug.Token, ""),
|
||||
Usage: "Token to grant metrics access",
|
||||
EnvVars: []string{"SETTINGS_DEBUG_TOKEN"},
|
||||
Destination: &cfg.Debug.Token,
|
||||
@@ -117,74 +115,78 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag {
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "http-addr",
|
||||
Value: "0.0.0.0:9190",
|
||||
Value: flags.OverrideDefaultString(cfg.HTTP.Addr, "0.0.0.0:9190"),
|
||||
Usage: "Address to bind http server",
|
||||
EnvVars: []string{"SETTINGS_HTTP_ADDR"},
|
||||
Destination: &cfg.HTTP.Addr,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "http-namespace",
|
||||
Value: "com.owncloud.web",
|
||||
Value: flags.OverrideDefaultString(cfg.HTTP.Namespace, "com.owncloud.web"),
|
||||
Usage: "Set the base namespace for the http namespace",
|
||||
EnvVars: []string{"SETTINGS_HTTP_NAMESPACE"},
|
||||
Destination: &cfg.HTTP.Namespace,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "http-root",
|
||||
Value: "/",
|
||||
Value: flags.OverrideDefaultString(cfg.HTTP.Root, "/"),
|
||||
Usage: "Root path of http server",
|
||||
EnvVars: []string{"SETTINGS_HTTP_ROOT"},
|
||||
Destination: &cfg.HTTP.Root,
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "http-cache-ttl",
|
||||
Value: 604800, // 7 days
|
||||
Value: flags.OverrideDefaultInt(cfg.HTTP.CacheTTL, 604800), // 10 days
|
||||
Usage: "Set the static assets caching duration in seconds",
|
||||
EnvVars: []string{"SETTINGS_CACHE_TTL"},
|
||||
Destination: &cfg.HTTP.CacheTTL,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "grpc-addr",
|
||||
Value: "0.0.0.0:9191",
|
||||
Value: flags.OverrideDefaultString(cfg.GRPC.Addr, "0.0.0.0:9191"),
|
||||
Usage: "Address to bind grpc server",
|
||||
EnvVars: []string{"SETTINGS_GRPC_ADDR"},
|
||||
Destination: &cfg.GRPC.Addr,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "asset-path",
|
||||
Value: "",
|
||||
Value: flags.OverrideDefaultString(cfg.Asset.Path, ""),
|
||||
Usage: "Path to custom assets",
|
||||
EnvVars: []string{"SETTINGS_ASSET_PATH"},
|
||||
Destination: &cfg.Asset.Path,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "grpc-namespace",
|
||||
Value: "com.owncloud.api",
|
||||
Value: flags.OverrideDefaultString(cfg.GRPC.Namespace, "com.owncloud.api"),
|
||||
Usage: "Set the base namespace for the grpc namespace",
|
||||
EnvVars: []string{"SETTINGS_GRPC_NAMESPACE"},
|
||||
Destination: &cfg.GRPC.Namespace,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "name",
|
||||
Value: "settings",
|
||||
Value: flags.OverrideDefaultString(cfg.Service.Name, "settings"),
|
||||
Usage: "service name",
|
||||
EnvVars: []string{"SETTINGS_NAME"},
|
||||
Destination: &cfg.Service.Name,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "data-path",
|
||||
Value: "/var/tmp/ocis/settings",
|
||||
Value: flags.OverrideDefaultString(cfg.Service.DataPath, "/var/tmp/ocis/settings"),
|
||||
Usage: "Mount path for the storage",
|
||||
EnvVars: []string{"SETTINGS_DATA_PATH"},
|
||||
Destination: &cfg.Service.DataPath,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "jwt-secret",
|
||||
Value: "Pive-Fumkiu4",
|
||||
Value: flags.OverrideDefaultString(cfg.TokenManager.JWTSecret, "Pive-Fumkiu4"),
|
||||
Usage: "Used to create JWT to talk to reva, should equal reva's jwt-secret",
|
||||
EnvVars: []string{"SETTINGS_JWT_SECRET", "OCIS_JWT_SECRET"},
|
||||
Destination: &cfg.TokenManager.JWTSecret,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "extensions",
|
||||
Usage: "Run specific extensions during supervised mode. This flag is set by the runtime",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -193,14 +195,14 @@ func ListSettingsWithConfig(cfg *config.Config) []cli.Flag {
|
||||
return []cli.Flag{
|
||||
&cli.StringFlag{
|
||||
Name: "grpc-namespace",
|
||||
Value: "com.owncloud.api",
|
||||
Value: flags.OverrideDefaultString(cfg.GRPC.Namespace, "com.owncloud.api"),
|
||||
Usage: "Set the base namespace for the grpc namespace",
|
||||
EnvVars: []string{"SETTINGS_GRPC_NAMESPACE"},
|
||||
Destination: &cfg.GRPC.Namespace,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "name",
|
||||
Value: "settings",
|
||||
Value: flags.OverrideDefaultString(cfg.Service.Name, "settings"),
|
||||
Usage: "service name",
|
||||
EnvVars: []string{"SETTINGS_NAME"},
|
||||
Destination: &cfg.Service.Name,
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1005,7 +1005,6 @@ func TestListRolesAfterSavingBundle(t *testing.T) {
|
||||
name: bundle.Name,
|
||||
})
|
||||
}
|
||||
assert.Equal(t, len(tt.expectedBundles), len(rolesRes.Bundles))
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1267,13 +1266,19 @@ func TestListFilteredBundle(t *testing.T) {
|
||||
listRes, err := bundleService.ListBundles(ctx, &proto.ListBundlesRequest{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
for _, bundle := range listRes.Bundles {
|
||||
assert.Contains(t, tt.expectedBundles, expectedBundle{
|
||||
displayName: bundle.DisplayName,
|
||||
name: bundle.Name,
|
||||
// we don't want to deep-assert the values returned only add checks on name and displayName
|
||||
// this will suffice.
|
||||
listResAsExpectedBundle := make([]expectedBundle, 0)
|
||||
for i := range listRes.Bundles {
|
||||
listResAsExpectedBundle = append(listResAsExpectedBundle, expectedBundle{
|
||||
displayName: listRes.Bundles[i].DisplayName,
|
||||
name: listRes.Bundles[i].Name,
|
||||
})
|
||||
}
|
||||
assert.Equal(t, len(tt.expectedBundles), len(listRes.Bundles))
|
||||
|
||||
for _, bundle := range tt.expectedBundles {
|
||||
assert.Contains(t, listResAsExpectedBundle, bundle)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1568,13 +1573,19 @@ func TestListGetBundleSettingMixedPermission(t *testing.T) {
|
||||
listRes, err := bundleService.ListBundles(ctx, &proto.ListBundlesRequest{})
|
||||
assert.NoError(t, err)
|
||||
|
||||
for _, setting := range listRes.Bundles[0].Settings {
|
||||
assert.Contains(t, tt.expectedSettings, expectedSetting{
|
||||
displayName: setting.DisplayName,
|
||||
name: setting.Name,
|
||||
})
|
||||
listedSettings := make([]expectedSetting, 0)
|
||||
for i := range listRes.Bundles {
|
||||
for _, setting := range listRes.Bundles[i].Settings {
|
||||
listedSettings = append(listedSettings, expectedSetting{
|
||||
displayName: setting.DisplayName,
|
||||
name: setting.Name,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
for i := range tt.expectedSettings {
|
||||
assert.Contains(t, listedSettings, tt.expectedSettings[i])
|
||||
}
|
||||
assert.Equal(t, len(tt.expectedSettings), len(listRes.Bundles[0].Settings))
|
||||
|
||||
getRes, err := bundleService.GetBundle(ctx, &proto.GetBundleRequest{BundleId: bundle.Id})
|
||||
assert.NoError(t, err)
|
||||
@@ -1585,59 +1596,6 @@ func TestListGetBundleSettingMixedPermission(t *testing.T) {
|
||||
name: setting.Name,
|
||||
})
|
||||
}
|
||||
assert.Equal(t, len(tt.expectedSettings), len(getRes.Bundle.Settings))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestListFilteredBundle_SetPermissionsOnSettingAndBundle(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
settingPermission proto.Permission_Operation
|
||||
bundlePermission proto.Permission_Operation
|
||||
expectedAmountOfSettings int
|
||||
}{
|
||||
{
|
||||
"setting has read permission bundle not",
|
||||
proto.Permission_OPERATION_READ,
|
||||
proto.Permission_OPERATION_UNKNOWN,
|
||||
1,
|
||||
},
|
||||
{
|
||||
"bundle has read permission setting not",
|
||||
proto.Permission_OPERATION_UNKNOWN,
|
||||
proto.Permission_OPERATION_READ,
|
||||
5,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
teardown := setup()
|
||||
defer teardown()
|
||||
|
||||
ctx := metadata.Set(context.Background(), middleware.AccountID, testAccountID)
|
||||
ctx = metadata.Set(ctx, middleware.RoleIDs, getRoleIDAsJSON(svc.BundleUUIDRoleAdmin))
|
||||
|
||||
_, err := bundleService.SaveBundle(ctx, &proto.SaveBundleRequest{
|
||||
Bundle: &bundleStub,
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
setPermissionOnBundleOrSetting(
|
||||
ctx, t, bundleStub.Id, proto.Resource_TYPE_BUNDLE, tt.bundlePermission, svc.BundleUUIDRoleAdmin,
|
||||
)
|
||||
|
||||
setPermissionOnBundleOrSetting(
|
||||
ctx, t, bundleStub.Settings[0].Id, proto.Resource_TYPE_SETTING,
|
||||
tt.settingPermission, svc.BundleUUIDRoleAdmin,
|
||||
)
|
||||
|
||||
listRes, err := bundleService.ListBundles(ctx, &proto.ListBundlesRequest{})
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, 1, len(listRes.Bundles))
|
||||
assert.Equal(t, tt.expectedAmountOfSettings, len(listRes.Bundles[0].Settings))
|
||||
assert.Equal(t, bundleStub.Id, listRes.Bundles[0].Id)
|
||||
assert.Equal(t, bundleStub.Settings[0].Id, listRes.Bundles[0].Settings[0].Id)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package proto;
|
||||
option go_package = "pkg/proto/v0;proto";
|
||||
package com.owncloud.ocis.settings.v0;
|
||||
|
||||
option go_package = "github.com/owncloud/ocis/settings/pkg/proto/v0;proto";
|
||||
|
||||
import "google/api/annotations.proto";
|
||||
import "google/protobuf/empty.proto";
|
||||
@@ -9,28 +10,28 @@ import "google/protobuf/empty.proto";
|
||||
import "protoc-gen-openapiv2/options/annotations.proto";
|
||||
|
||||
option (grpc.gateway.protoc_gen_openapiv2.options.openapiv2_swagger) = {
|
||||
info: {
|
||||
title: "ownCloud Infinite Scale settings";
|
||||
version: "1.0.0";
|
||||
contact: {
|
||||
name: "ownCloud GmbH";
|
||||
url: "https://github.com/owncloud/ocis";
|
||||
email: "support@owncloud.com";
|
||||
};
|
||||
license: {
|
||||
name: "Apache-2.0";
|
||||
url: "https://github.com/owncloud/ocis/blob/master/LICENSE";
|
||||
};
|
||||
};
|
||||
schemes: HTTP;
|
||||
schemes: HTTPS;
|
||||
consumes: "application/json";
|
||||
produces: "application/json";
|
||||
external_docs: {
|
||||
description: "Developer Manual";
|
||||
url: "https://owncloud.github.io/extensions/settings/";
|
||||
};
|
||||
};
|
||||
info: {
|
||||
title: "ownCloud Infinite Scale settings";
|
||||
version: "1.0.0";
|
||||
contact: {
|
||||
name: "ownCloud GmbH";
|
||||
url: "https://github.com/owncloud/ocis";
|
||||
email: "support@owncloud.com";
|
||||
};
|
||||
license: {
|
||||
name: "Apache-2.0";
|
||||
url: "https://github.com/owncloud/ocis/blob/master/LICENSE";
|
||||
};
|
||||
};
|
||||
schemes: HTTP;
|
||||
schemes: HTTPS;
|
||||
consumes: "application/json";
|
||||
produces: "application/json";
|
||||
external_docs: {
|
||||
description: "Developer Manual";
|
||||
url: "https://owncloud.dev/extensions/settings/";
|
||||
};
|
||||
};
|
||||
|
||||
service BundleService {
|
||||
rpc SaveBundle(SaveBundleRequest) returns (SaveBundleResponse) {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -65,6 +65,12 @@ func (g Service) RegisterDefaultRoles() {
|
||||
Msg("failed to register permission")
|
||||
}
|
||||
}
|
||||
|
||||
for _, req := range defaultRoleAssignments() {
|
||||
if _, err := g.manager.WriteRoleAssignment(req.AccountUuid, req.RoleId); err != nil {
|
||||
g.logger.Error().Err(err).Msg("failed to register role assignment")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: check permissions on every request
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package svc
|
||||
|
||||
import settings "github.com/owncloud/ocis/settings/pkg/proto/v0"
|
||||
import (
|
||||
settings "github.com/owncloud/ocis/settings/pkg/proto/v0"
|
||||
)
|
||||
|
||||
const (
|
||||
// BundleUUIDRoleAdmin represents the admin role
|
||||
@@ -21,6 +23,21 @@ const (
|
||||
SettingsManagementPermissionID string = "79e13b30-3e22-11eb-bc51-0b9f0bad9a58"
|
||||
// SettingsManagementPermissionName is the hardcoded setting name for the settings management permission
|
||||
SettingsManagementPermissionName string = "settings-management"
|
||||
|
||||
settingUUIDProfileLanguage = "aa8cfbe5-95d4-4f7e-a032-c3c01f5f062f"
|
||||
|
||||
// AccountManagementPermissionID is the hardcoded setting UUID for the account management permission
|
||||
AccountManagementPermissionID string = "8e587774-d929-4215-910b-a317b1e80f73"
|
||||
// AccountManagementPermissionName is the hardcoded setting name for the account management permission
|
||||
AccountManagementPermissionName string = "account-management"
|
||||
// GroupManagementPermissionID is the hardcoded setting UUID for the group management permission
|
||||
GroupManagementPermissionID string = "522adfbe-5908-45b4-b135-41979de73245"
|
||||
// GroupManagementPermissionName is the hardcoded setting name for the group management permission
|
||||
GroupManagementPermissionName string = "group-management"
|
||||
// SelfManagementPermissionID is the hardcoded setting UUID for the self management permission
|
||||
SelfManagementPermissionID string = "e03070e9-4362-4cc6-a872-1c7cb2eb2b8e"
|
||||
// SelfManagementPermissionName is the hardcoded setting name for the self management permission
|
||||
SelfManagementPermissionName string = "self-management"
|
||||
)
|
||||
|
||||
// generateBundlesDefaultRoles bootstraps the default roles.
|
||||
@@ -29,6 +46,7 @@ func generateBundlesDefaultRoles() []*settings.Bundle {
|
||||
generateBundleAdminRole(),
|
||||
generateBundleUserRole(),
|
||||
generateBundleGuestRole(),
|
||||
generateBundleProfileRequest(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,6 +92,94 @@ func generateBundleGuestRole() *settings.Bundle {
|
||||
}
|
||||
}
|
||||
|
||||
var languageSetting = settings.Setting_SingleChoiceValue{
|
||||
SingleChoiceValue: &settings.SingleChoiceList{
|
||||
Options: []*settings.ListOption{
|
||||
{
|
||||
Value: &settings.ListOptionValue{
|
||||
Option: &settings.ListOptionValue_StringValue{
|
||||
StringValue: "cs",
|
||||
},
|
||||
},
|
||||
DisplayValue: "Czech",
|
||||
},
|
||||
{
|
||||
Value: &settings.ListOptionValue{
|
||||
Option: &settings.ListOptionValue_StringValue{
|
||||
StringValue: "de",
|
||||
},
|
||||
},
|
||||
DisplayValue: "Deutsch",
|
||||
},
|
||||
{
|
||||
Value: &settings.ListOptionValue{
|
||||
Option: &settings.ListOptionValue_StringValue{
|
||||
StringValue: "en",
|
||||
},
|
||||
},
|
||||
DisplayValue: "English",
|
||||
},
|
||||
{
|
||||
Value: &settings.ListOptionValue{
|
||||
Option: &settings.ListOptionValue_StringValue{
|
||||
StringValue: "es",
|
||||
},
|
||||
},
|
||||
DisplayValue: "Español",
|
||||
},
|
||||
{
|
||||
Value: &settings.ListOptionValue{
|
||||
Option: &settings.ListOptionValue_StringValue{
|
||||
StringValue: "fr",
|
||||
},
|
||||
},
|
||||
DisplayValue: "Français",
|
||||
},
|
||||
{
|
||||
Value: &settings.ListOptionValue{
|
||||
Option: &settings.ListOptionValue_StringValue{
|
||||
StringValue: "gl",
|
||||
},
|
||||
},
|
||||
DisplayValue: "Galego",
|
||||
},
|
||||
{
|
||||
Value: &settings.ListOptionValue{
|
||||
Option: &settings.ListOptionValue_StringValue{
|
||||
StringValue: "it",
|
||||
},
|
||||
},
|
||||
DisplayValue: "Italiano",
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
func generateBundleProfileRequest() *settings.Bundle {
|
||||
return &settings.Bundle{
|
||||
Id: "2a506de7-99bd-4f0d-994e-c38e72c28fd9",
|
||||
Name: "profile",
|
||||
Extension: "ocis-accounts",
|
||||
Type: settings.Bundle_TYPE_DEFAULT,
|
||||
Resource: &settings.Resource{
|
||||
Type: settings.Resource_TYPE_SYSTEM,
|
||||
},
|
||||
DisplayName: "Profile",
|
||||
Settings: []*settings.Setting{
|
||||
{
|
||||
Id: settingUUIDProfileLanguage,
|
||||
Name: "language",
|
||||
DisplayName: "Language",
|
||||
Description: "User language",
|
||||
Resource: &settings.Resource{
|
||||
Type: settings.Resource_TYPE_USER,
|
||||
},
|
||||
Value: &languageSetting,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func generatePermissionRequests() []*settings.AddSettingToBundleRequest {
|
||||
return []*settings.AddSettingToBundleRequest{
|
||||
{
|
||||
@@ -114,5 +220,146 @@ func generatePermissionRequests() []*settings.AddSettingToBundleRequest {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
BundleId: BundleUUIDRoleAdmin,
|
||||
Setting: &settings.Setting{
|
||||
Id: "7d81f103-0488-4853-bce5-98dcce36d649",
|
||||
Name: "language-readwrite",
|
||||
DisplayName: "Permission to read and set the language (anyone)",
|
||||
Resource: &settings.Resource{
|
||||
Type: settings.Resource_TYPE_SETTING,
|
||||
Id: settingUUIDProfileLanguage,
|
||||
},
|
||||
Value: &settings.Setting_PermissionValue{
|
||||
PermissionValue: &settings.Permission{
|
||||
Operation: settings.Permission_OPERATION_READWRITE,
|
||||
Constraint: settings.Permission_CONSTRAINT_ALL,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
BundleId: BundleUUIDRoleUser,
|
||||
Setting: &settings.Setting{
|
||||
Id: "640e00d2-4df8-41bd-b1c2-9f30a01e0e99",
|
||||
Name: "language-readwrite",
|
||||
DisplayName: "Permission to read and set the language (self)",
|
||||
Resource: &settings.Resource{
|
||||
Type: settings.Resource_TYPE_SETTING,
|
||||
Id: settingUUIDProfileLanguage,
|
||||
},
|
||||
Value: &settings.Setting_PermissionValue{
|
||||
PermissionValue: &settings.Permission{
|
||||
Operation: settings.Permission_OPERATION_READWRITE,
|
||||
Constraint: settings.Permission_CONSTRAINT_OWN,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
BundleId: BundleUUIDRoleGuest,
|
||||
Setting: &settings.Setting{
|
||||
Id: "ca878636-8b1a-4fae-8282-8617a4c13597",
|
||||
Name: "language-readwrite",
|
||||
DisplayName: "Permission to read and set the language (self)",
|
||||
Resource: &settings.Resource{
|
||||
Type: settings.Resource_TYPE_SETTING,
|
||||
Id: settingUUIDProfileLanguage,
|
||||
},
|
||||
Value: &settings.Setting_PermissionValue{
|
||||
PermissionValue: &settings.Permission{
|
||||
Operation: settings.Permission_OPERATION_READWRITE,
|
||||
Constraint: settings.Permission_CONSTRAINT_OWN,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
BundleId: BundleUUIDRoleAdmin,
|
||||
Setting: &settings.Setting{
|
||||
Id: AccountManagementPermissionID,
|
||||
Name: AccountManagementPermissionName,
|
||||
DisplayName: "Account Management",
|
||||
Description: "This permission gives full access to everything that is related to account management.",
|
||||
Resource: &settings.Resource{
|
||||
Type: settings.Resource_TYPE_USER,
|
||||
Id: "all",
|
||||
},
|
||||
Value: &settings.Setting_PermissionValue{
|
||||
PermissionValue: &settings.Permission{
|
||||
Operation: settings.Permission_OPERATION_READWRITE,
|
||||
Constraint: settings.Permission_CONSTRAINT_ALL,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
BundleId: BundleUUIDRoleAdmin,
|
||||
Setting: &settings.Setting{
|
||||
Id: GroupManagementPermissionID,
|
||||
Name: GroupManagementPermissionName,
|
||||
DisplayName: "Group Management",
|
||||
Description: "This permission gives full access to everything that is related to group management.",
|
||||
Resource: &settings.Resource{
|
||||
Type: settings.Resource_TYPE_GROUP,
|
||||
Id: "all",
|
||||
},
|
||||
Value: &settings.Setting_PermissionValue{
|
||||
PermissionValue: &settings.Permission{
|
||||
Operation: settings.Permission_OPERATION_READWRITE,
|
||||
Constraint: settings.Permission_CONSTRAINT_ALL,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
BundleId: BundleUUIDRoleUser,
|
||||
Setting: &settings.Setting{
|
||||
Id: SelfManagementPermissionID,
|
||||
Name: SelfManagementPermissionName,
|
||||
DisplayName: "Self Management",
|
||||
Description: "This permission gives access to self management.",
|
||||
Resource: &settings.Resource{
|
||||
Type: settings.Resource_TYPE_USER,
|
||||
Id: "me",
|
||||
},
|
||||
Value: &settings.Setting_PermissionValue{
|
||||
PermissionValue: &settings.Permission{
|
||||
Operation: settings.Permission_OPERATION_READWRITE,
|
||||
Constraint: settings.Permission_CONSTRAINT_OWN,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func defaultRoleAssignments() []*settings.UserRoleAssignment {
|
||||
return []*settings.UserRoleAssignment{
|
||||
// default admin users
|
||||
{
|
||||
AccountUuid: "058bff95-6708-4fe5-91e4-9ea3d377588b",
|
||||
RoleId: BundleUUIDRoleAdmin,
|
||||
}, {
|
||||
AccountUuid: "ddc2004c-0977-11eb-9d3f-a793888cd0f8",
|
||||
RoleId: BundleUUIDRoleAdmin,
|
||||
}, {
|
||||
AccountUuid: "820ba2a1-3f54-4538-80a4-2d73007e30bf",
|
||||
RoleId: BundleUUIDRoleAdmin,
|
||||
}, {
|
||||
AccountUuid: "bc596f3c-c955-4328-80a0-60d018b4ad57",
|
||||
RoleId: BundleUUIDRoleAdmin,
|
||||
},
|
||||
// default users with role "user"
|
||||
{
|
||||
AccountUuid: "4c510ada-c86b-4815-8820-42cdf82c3d51",
|
||||
RoleId: BundleUUIDRoleUser,
|
||||
}, {
|
||||
AccountUuid: "f7fbf8c8-139b-4376-b307-cf0a8c2d0d9c",
|
||||
RoleId: BundleUUIDRoleUser,
|
||||
}, {
|
||||
AccountUuid: "932b4540-8d16-481e-8ef4-588e4b6b151c",
|
||||
RoleId: BundleUUIDRoleUser,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ func New(cfg *config.Config) settings.Manager {
|
||||
olog.Color(cfg.Log.Color),
|
||||
olog.Pretty(cfg.Log.Pretty),
|
||||
olog.Level(cfg.Log.Level),
|
||||
olog.File(cfg.Log.File),
|
||||
),
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
package tracing
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"contrib.go.opencensus.io/exporter/jaeger"
|
||||
"contrib.go.opencensus.io/exporter/ocagent"
|
||||
"contrib.go.opencensus.io/exporter/zipkin"
|
||||
openzipkin "github.com/openzipkin/zipkin-go"
|
||||
zipkinhttp "github.com/openzipkin/zipkin-go/reporter/http"
|
||||
"github.com/owncloud/ocis/ocis-pkg/log"
|
||||
"github.com/owncloud/ocis/settings/pkg/config"
|
||||
"go.opencensus.io/stats/view"
|
||||
"go.opencensus.io/trace"
|
||||
)
|
||||
|
||||
// Configure tracing from config
|
||||
func Configure(cfg *config.Config, logger log.Logger) error {
|
||||
if cfg.Tracing.Enabled {
|
||||
switch t := cfg.Tracing.Type; t {
|
||||
case "agent":
|
||||
exporter, err := ocagent.NewExporter(
|
||||
ocagent.WithReconnectionPeriod(5*time.Second),
|
||||
ocagent.WithAddress(cfg.Tracing.Endpoint),
|
||||
ocagent.WithServiceName(cfg.Tracing.Service),
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
logger.Error().
|
||||
Err(err).
|
||||
Str("endpoint", cfg.Tracing.Endpoint).
|
||||
Str("collector", cfg.Tracing.Collector).
|
||||
Msg("Failed to create agent tracing")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
trace.RegisterExporter(exporter)
|
||||
view.RegisterExporter(exporter)
|
||||
|
||||
case "jaeger":
|
||||
exporter, err := jaeger.NewExporter(
|
||||
jaeger.Options{
|
||||
AgentEndpoint: cfg.Tracing.Endpoint,
|
||||
CollectorEndpoint: cfg.Tracing.Collector,
|
||||
Process: jaeger.Process{
|
||||
ServiceName: cfg.Tracing.Service,
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
logger.Error().
|
||||
Err(err).
|
||||
Str("endpoint", cfg.Tracing.Endpoint).
|
||||
Str("collector", cfg.Tracing.Collector).
|
||||
Msg("Failed to create jaeger tracing")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
trace.RegisterExporter(exporter)
|
||||
|
||||
case "zipkin":
|
||||
endpoint, err := openzipkin.NewEndpoint(
|
||||
cfg.Tracing.Service,
|
||||
cfg.Tracing.Endpoint,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
logger.Error().
|
||||
Err(err).
|
||||
Str("endpoint", cfg.Tracing.Endpoint).
|
||||
Str("collector", cfg.Tracing.Collector).
|
||||
Msg("Failed to create zipkin tracing")
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
exporter := zipkin.NewExporter(
|
||||
zipkinhttp.NewReporter(
|
||||
cfg.Tracing.Collector,
|
||||
),
|
||||
endpoint,
|
||||
)
|
||||
|
||||
trace.RegisterExporter(exporter)
|
||||
|
||||
default:
|
||||
logger.Warn().
|
||||
Str("type", t).
|
||||
Msg("Unknown tracing backend")
|
||||
}
|
||||
|
||||
trace.ApplyConfig(
|
||||
trace.Config{
|
||||
DefaultSampler: trace.AlwaysSample(),
|
||||
},
|
||||
)
|
||||
} else {
|
||||
logger.Debug().
|
||||
Msg("Tracing is not enabled")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -7,8 +7,9 @@ geekdocEditPath: edit/master/settings/templates
|
||||
geekdocFilePath: CONFIGURATION.tmpl
|
||||
---
|
||||
{{- define "options"}}
|
||||
{{ $fnName := (last . ).Flags -}}
|
||||
{{ range $opt := first . }}{{ with list $fnName $opt -}}
|
||||
{{ $fnNames := (last . ).Flags -}}
|
||||
{{ range $opt := first . }}
|
||||
{{ range $fnName := $fnNames }}{{ with list $fnName $opt -}}
|
||||
{{ $o := last . -}}
|
||||
{{ if eq $o.FnName $fnName -}}
|
||||
-{{ $o.Name }} | {{ range $i, $e := $o.Env }} {{ if $i }}, {{ end }}${{ $e }}{{ end }}
|
||||
@@ -17,6 +18,7 @@ geekdocFilePath: CONFIGURATION.tmpl
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
{{ end -}}
|
||||
{{ end }}
|
||||
|
||||
{{`{{< toc >}}`}}
|
||||
@@ -35,7 +37,7 @@ $HOME/.ocis
|
||||
|
||||
For this configuration to be picked up, have a look at your extension `root` command and look for which default config name it has assigned. *i.e: ocis-proxy reads `proxy.json | yaml | toml ...`*.
|
||||
|
||||
So far we support the file formats `JSON` and `YAML`, if you want to get a full example configuration just take a look at [our repository](https://github.com/owncloud/ocis/tree/master/config), there you can always see the latest configuration format. These example configurations include all available options and the default values. The configuration file will be automatically loaded if it's placed at `/etc/ocis/ocis.yml`, `${HOME}/.ocis/ocis.yml` or `$(pwd)/config/ocis.yml`.
|
||||
So far we support the file formats `JSON` and `YAML`, if you want to get a full example configuration just take a look at [our repository](https://github.com/owncloud/ocis/tree/master/settings/config), there you can always see the latest configuration format. These example configurations include all available options and the default values. The configuration file will be automatically loaded if it's placed at `/etc/ocis/ocis.yml`, `${HOME}/.ocis/ocis.yml` or `$(pwd)/config/ocis.yml`.
|
||||
|
||||
### Environment variables
|
||||
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
// +build tools
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
_ "github.com/UnnoTed/fileb0x"
|
||||
_ "github.com/mitchellh/gox"
|
||||
_ "github.com/restic/calens"
|
||||
_ "golang.org/x/lint/golint"
|
||||
// _ "honnef.co/go/tools/cmd/staticcheck"
|
||||
)
|
||||
+3
-1
@@ -1,6 +1,7 @@
|
||||
import 'regenerator-runtime/runtime'
|
||||
import SettingsApp from './components/SettingsApp.vue'
|
||||
import store from './store'
|
||||
import translations from './../l10n/translations.json'
|
||||
|
||||
// just a dummy function to trick gettext tools
|
||||
function $gettext (msg) {
|
||||
@@ -41,5 +42,6 @@ export default {
|
||||
appInfo,
|
||||
store,
|
||||
routes,
|
||||
navItems
|
||||
navItems,
|
||||
translations
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="oc-p">
|
||||
<div class="uk-flex uk-flex-column" id="settings-app">
|
||||
<main class="uk-flex uk-flex-column" id="settings-app">
|
||||
<template v-if="initialized">
|
||||
<oc-alert v-if="extensions.length === 0" variation="primary" no-close>
|
||||
<p class="uk-flex uk-flex-middle">
|
||||
@@ -34,7 +34,7 @@
|
||||
</template>
|
||||
</template>
|
||||
<oc-loader v-else />
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="uk-width-1-1 uk-width-2-3@m uk-width-1-2@l uk-width-1-3@xl">
|
||||
<div class="oc-text-bold oc-mb-s">
|
||||
<h2 class="oc-mb-s">
|
||||
<translate>{{ bundle.displayName }}</translate>
|
||||
</div>
|
||||
</h2>
|
||||
<oc-grid gutter="small">
|
||||
<template>
|
||||
<div class="uk-width-1-1" v-for="setting in bundle.settings" :key="setting.id">
|
||||
|
||||
@@ -1,36 +1,11 @@
|
||||
<template>
|
||||
<div>
|
||||
<oc-button :id="buttonElementId" class="uk-width-expand" justify-content="space-between">
|
||||
<span v-if="selectedOptions !== null && selectedOptions.length > 0">
|
||||
{{ selectedOptionsDisplayValues }}
|
||||
</span>
|
||||
<span v-else>
|
||||
{{ setting.placeholder || $gettext('Please select') }}
|
||||
</span>
|
||||
<oc-icon name="expand_more" />
|
||||
</oc-button>
|
||||
<oc-drop
|
||||
:drop-id="dropElementId"
|
||||
:toggle="`#${buttonElementId}`"
|
||||
mode="click"
|
||||
position="bottom-justify"
|
||||
:options="{ offset: 0, delayHide: 200, flip: false }"
|
||||
>
|
||||
<ul class="uk-list">
|
||||
<li
|
||||
v-for="(option, index) in setting.multiChoiceValue.options"
|
||||
:key="getOptionElementId(index)"
|
||||
>
|
||||
<oc-checkbox
|
||||
v-model="selectedOptions"
|
||||
:option="option"
|
||||
@input="onSelectedOption"
|
||||
:label="option.displayValue"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</oc-drop>
|
||||
</div>
|
||||
<oc-select
|
||||
v-model="selectedOptions"
|
||||
:clearable="false"
|
||||
:options="displayOptions"
|
||||
@input="onSelectedOption"
|
||||
multiple
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -53,28 +28,21 @@ export default {
|
||||
},
|
||||
data () {
|
||||
return {
|
||||
selectedOptions: null
|
||||
selectedOptions: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
selectedOptionsDisplayValues () {
|
||||
return Array.from(this.selectedOptions).map(option => option.displayValue).join(', ')
|
||||
},
|
||||
dropElementId () {
|
||||
return `multi-choice-drop-${this.setting.id}`
|
||||
},
|
||||
buttonElementId () {
|
||||
return `multi-choice-toggle-${this.setting.id}`
|
||||
displayOptions () {
|
||||
return this.setting.multiChoiceValue.options.map(val => val.displayValue)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getOptionElementId (index) {
|
||||
return `${this.setting.id}-${index}`
|
||||
},
|
||||
async onSelectedOption () {
|
||||
const values = []
|
||||
if (!isNil(this.selectedOptions)) {
|
||||
this.selectedOptions.forEach(option => {
|
||||
this.selectedOptions.forEach(displayValue => {
|
||||
const option = this.setting.multiChoiceValue.options.find(val => val.displayValue === displayValue)
|
||||
|
||||
if (option.value.intValue) {
|
||||
values.push({ intValue: option.value.intValue })
|
||||
}
|
||||
@@ -123,13 +91,15 @@ export default {
|
||||
return selectedValues.includes(option.value.stringValue)
|
||||
}
|
||||
return false
|
||||
})
|
||||
}).map(val => val.displayValue)
|
||||
}
|
||||
}
|
||||
// TODO: load the settings value of the authenticated user and set it in `selectedOptions`
|
||||
// if not set, yet, apply defaults from settings bundle definition
|
||||
if (this.selectedOptions === null) {
|
||||
this.selectedOptions = this.setting.multiChoiceValue.options.filter(option => option.default)
|
||||
this.selectedOptions = this.setting.multiChoiceValue.options
|
||||
.filter(option => option.default)
|
||||
.map(val => val.displayValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,36 +1,11 @@
|
||||
<template>
|
||||
<div>
|
||||
<oc-button :id="buttonElementId" class="uk-width-expand" justify-content="space-between">
|
||||
<span v-if="selectedOption">
|
||||
{{ selectedOption.displayValue }}
|
||||
</span>
|
||||
<span v-else>
|
||||
{{ setting.placeholder || $gettext('Please select') }}
|
||||
</span>
|
||||
<oc-icon name="expand_more" />
|
||||
</oc-button>
|
||||
<oc-drop
|
||||
:drop-id="dropElementId"
|
||||
:toggle="`#${buttonElementId}`"
|
||||
mode="click"
|
||||
close-on-click
|
||||
position="bottom-justify"
|
||||
:options="{ offset: 0, delayHide: 200, flip: false }"
|
||||
>
|
||||
<ul class="uk-list">
|
||||
<li
|
||||
v-for="(option, index) in setting.singleChoiceValue.options"
|
||||
:key="getOptionElementId(index)"
|
||||
>
|
||||
<oc-radio
|
||||
v-model="selectedOption"
|
||||
:option="option"
|
||||
@input="onSelectedOption"
|
||||
:label="option.displayValue"
|
||||
/>
|
||||
</li>
|
||||
</ul>
|
||||
</oc-drop>
|
||||
<oc-select
|
||||
v-model="selectedOption"
|
||||
:clearable="false"
|
||||
:options="displayOptions"
|
||||
@input="onSelectedOption"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -58,25 +33,21 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
dropElementId () {
|
||||
return `single-choice-drop-${this.setting.id}`
|
||||
},
|
||||
buttonElementId () {
|
||||
return `single-choice-toggle-${this.setting.id}`
|
||||
displayOptions () {
|
||||
return this.setting.singleChoiceValue.options.map(val => val.displayValue)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
getOptionElementId (index) {
|
||||
return `${this.setting.id}-${index}`
|
||||
},
|
||||
async onSelectedOption () {
|
||||
const values = []
|
||||
if (!isNil(this.selectedOption)) {
|
||||
if (this.selectedOption.value.intValue) {
|
||||
values.push({ intValue: this.selectedOption.value.intValue })
|
||||
const option = this.setting.singleChoiceValue.options.find(val => val.displayValue === this.selectedOption)
|
||||
|
||||
if (option.value.intValue) {
|
||||
values.push({ intValue: option.value.intValue })
|
||||
}
|
||||
if (this.selectedOption.value.stringValue) {
|
||||
values.push({ stringValue: this.selectedOption.value.stringValue })
|
||||
if (option.value.stringValue) {
|
||||
values.push({ stringValue: option.value.stringValue })
|
||||
}
|
||||
}
|
||||
const payload = {
|
||||
@@ -106,14 +77,14 @@ export default {
|
||||
}
|
||||
})
|
||||
if (filtered.length > 0) {
|
||||
this.selectedOption = filtered[0]
|
||||
this.selectedOption = filtered[0].displayValue
|
||||
}
|
||||
}
|
||||
// if not set, yet, apply default from settings bundle definition
|
||||
if (isNil(this.selectedOption)) {
|
||||
const defaults = this.setting.singleChoiceValue.options.filter(option => option.default)
|
||||
if (defaults.length === 1) {
|
||||
this.selectedOption = defaults[0]
|
||||
this.selectedOption = defaults[0].displayValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* This file contains strings that should be synced to transifex but not exist in the UI directly,
|
||||
* moreover, they get loaded for example by API requests
|
||||
*/
|
||||
|
||||
// just a dummy function to trick gettext tools
|
||||
function $gettext (msg) {
|
||||
return msg
|
||||
}
|
||||
|
||||
// eslint-disable-next-line no-unused-vars
|
||||
const dictionary = [
|
||||
$gettext('Language')
|
||||
]
|
||||
@@ -4,26 +4,36 @@ Feature: Set user specific settings
|
||||
So that I can customize my OCIS experience to my liking
|
||||
|
||||
Background:
|
||||
Given these users have been created with default attributes:
|
||||
Given these users have been created with default attributes and without skeleton files:
|
||||
| username |
|
||||
| user1 |
|
||||
| user2 |
|
||||
And user "user1" has created folder "simple-folder"
|
||||
|
||||
Scenario: Check the default settings
|
||||
Given user "user1" has logged in using the webUI
|
||||
And the user browses to the settings page
|
||||
Then the setting "Language" should have value "Please select"
|
||||
Then the setting "Language" should not have any value
|
||||
When the user browses to the files page
|
||||
Then the files menu should be listed in language "English"
|
||||
|
||||
Scenario: changing the language
|
||||
Scenario: changing the language (reactive and with page reload)
|
||||
Given user "user1" has logged in using the webUI
|
||||
And the user browses to the settings page
|
||||
When the user changes the language to "Deutsch"
|
||||
Then the setting "Language" should have value "Deutsch"
|
||||
When the user browses to the files page
|
||||
And the user reloads the current page of the webUI
|
||||
Then the files menu should be listed in language "Deutsch"
|
||||
And the account menu should be listed in language "Deutsch"
|
||||
And the files header should be displayed in language "Deutsch"
|
||||
When the user reloads the current page of the webUI
|
||||
Then the files menu should be listed in language "Deutsch"
|
||||
And the account menu should be listed in language "Deutsch"
|
||||
And the files header should be displayed in language "Deutsch"
|
||||
When the user browses to the settings page
|
||||
And the user changes the language to "English"
|
||||
And the user browses to the files page
|
||||
Then the files menu should be listed in language "English"
|
||||
|
||||
Scenario: changing the language only affects one user
|
||||
Given user "user2" has logged in using the webUI
|
||||
@@ -31,27 +41,6 @@ Feature: Set user specific settings
|
||||
When the user changes the language to "Español"
|
||||
Then the setting "Language" should have value "Español"
|
||||
When the user browses to the files page
|
||||
And the user reloads the current page of the webUI
|
||||
Then the files menu should be listed in language "Español"
|
||||
When the user re-logs in as "user1" using the webUI
|
||||
And the user reloads the current page of the webUI
|
||||
Then the files menu should be listed in language "English"
|
||||
|
||||
Scenario: Check the accounts menu when the language is changed
|
||||
Given user "user2" has logged in using the webUI
|
||||
And the user browses to the settings page
|
||||
When the user changes the language to "Deutsch"
|
||||
And the user reloads the current page of the webUI
|
||||
Then the setting "Language" should have value "Deutsch"
|
||||
And the account menu should be listed in language "Deutsch"
|
||||
When the user changes the language to "Français"
|
||||
Then the account menu should be listed in language "Français"
|
||||
|
||||
Scenario: Check the files table header menu when the language is changed
|
||||
Given user "user2" has logged in using the webUI
|
||||
And the user browses to the settings page
|
||||
When the user changes the language to "Deutsch"
|
||||
Then the setting "Language" should have value "Deutsch"
|
||||
When the user browses to the files page
|
||||
And the user reloads the current page of the webUI
|
||||
Then the files header should be displayed in language "Deutsch"
|
||||
|
||||
@@ -3,43 +3,51 @@ const filesMenu = {
|
||||
'All files',
|
||||
'Shared with me',
|
||||
'Shared with others',
|
||||
'Trash bin'
|
||||
'Shared via link',
|
||||
'Deleted files'
|
||||
],
|
||||
Deutsch: [
|
||||
'Alle Dateien',
|
||||
'Mit mir geteilt',
|
||||
'Mit anderen geteilt',
|
||||
'Papierkorb'
|
||||
'Per Link geteilt',
|
||||
'Gelöschte Dateien'
|
||||
],
|
||||
Español: [
|
||||
'Todos los archivos',
|
||||
'Compartido conmigo',
|
||||
'Compartido con otros',
|
||||
'Papelera de reciclaje'
|
||||
'Shared via link',
|
||||
'Archivos borrados'
|
||||
],
|
||||
Français: [
|
||||
'Tous les fichiers',
|
||||
'Partagé avec moi',
|
||||
'Partagé avec autres',
|
||||
'Corbeille'
|
||||
'Shared via link',
|
||||
'Fichiers supprimés'
|
||||
]
|
||||
}
|
||||
|
||||
const accountMenu = {
|
||||
English: [
|
||||
'Manage your account',
|
||||
'Profile',
|
||||
'Settings',
|
||||
'Log out'
|
||||
],
|
||||
Deutsch: [
|
||||
'Verwalten Sie Ihr Benutzerkonto',
|
||||
'Profil',
|
||||
'Einstellungen',
|
||||
'Abmelden'
|
||||
],
|
||||
Español: [
|
||||
'Administra tu cuenta',
|
||||
'Profile',
|
||||
'Configuración',
|
||||
'Salir'
|
||||
],
|
||||
Français: [
|
||||
'Modifier votre compte',
|
||||
'Profil',
|
||||
'Settings',
|
||||
'Se déconnecter'
|
||||
]
|
||||
}
|
||||
@@ -48,19 +56,19 @@ const filesListHeaderMenu = {
|
||||
English: [
|
||||
'Name',
|
||||
'Size',
|
||||
'Updated',
|
||||
'Modified',
|
||||
'Actions'
|
||||
],
|
||||
Deutsch: [
|
||||
'Name',
|
||||
'Größe',
|
||||
'Erneuert',
|
||||
'Geändert',
|
||||
'Aktionen'
|
||||
],
|
||||
Español: [
|
||||
'Nombre',
|
||||
'Tamaño',
|
||||
'Actualizado',
|
||||
'Modificado',
|
||||
'Acciones'
|
||||
],
|
||||
Français: [
|
||||
|
||||
@@ -33,9 +33,8 @@ module.exports = {
|
||||
})
|
||||
})
|
||||
await this
|
||||
.waitForElementVisible('@userMenuBtn')
|
||||
.click('@userMenuBtn')
|
||||
.waitForElementNotVisible('@userMenuContainer')
|
||||
.waitForElementNotPresent('@userMenuContainer')
|
||||
return menu
|
||||
},
|
||||
getFileHeaderItems: async function () {
|
||||
@@ -57,10 +56,6 @@ module.exports = {
|
||||
pageHeader: {
|
||||
selector: '.oc-page-title'
|
||||
},
|
||||
languageValue: {
|
||||
selector: "//button[@id='single-choice-toggle-profile-language']",
|
||||
locateStrategy: 'xpath'
|
||||
},
|
||||
fileSidebarNavItem: {
|
||||
selector: '.oc-sidebar-nav-item'
|
||||
},
|
||||
@@ -78,7 +73,7 @@ module.exports = {
|
||||
selector: '#account-info-container'
|
||||
},
|
||||
fileTableHeaderItems: {
|
||||
selector: '//*[@id="files-table-header"]//span[not(*) and not(ancestor::label)]',
|
||||
selector: '//*[@id="files-personal-table"]//th[not(.//div)]',
|
||||
locateStrategy: 'xpath'
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,19 @@ module.exports = {
|
||||
let output
|
||||
switch (key) {
|
||||
case 'Language':
|
||||
let elemfound = true
|
||||
|
||||
// Language value is set to empty at beginning
|
||||
// In that case jsut return false
|
||||
await this.api.element('@languageValue', result => {
|
||||
if (result.status < 0) {
|
||||
elemfound = false
|
||||
}
|
||||
})
|
||||
if (!elemfound) {
|
||||
output = false
|
||||
break
|
||||
}
|
||||
await this.waitForElementVisible('@languageValue')
|
||||
.getText('@languageValue', (result) => {
|
||||
output = result.value
|
||||
@@ -42,16 +55,11 @@ module.exports = {
|
||||
return output
|
||||
},
|
||||
changeSettings: async function (key, value) {
|
||||
const selectXpath = util.format(this.elements.languageSelect.selector, value)
|
||||
switch (key) {
|
||||
case 'Language':
|
||||
await this.waitForElementVisible('@languageValue')
|
||||
.click('@languageValue')
|
||||
.useXpath()
|
||||
.waitForElementVisible(this.elements.languageDropdown.selector)
|
||||
.click(selectXpath)
|
||||
.waitForElementNotVisible(this.elements.languageDropdown.selector)
|
||||
.useCss()
|
||||
await this
|
||||
.waitForElementVisible('@languageInput')
|
||||
.setValue('@languageInput', value + '\n')
|
||||
break
|
||||
default:
|
||||
throw new Error('failed to find the setting')
|
||||
@@ -64,16 +72,12 @@ module.exports = {
|
||||
selector: '.oc-page-title'
|
||||
},
|
||||
languageValue: {
|
||||
selector: "//label[.='Language']/..//button[starts-with(@id, 'single-choice-toggle')]",
|
||||
selector: "//label[.='Language']/..//span[@class='vs__selected']",
|
||||
locateStrategy: 'xpath'
|
||||
},
|
||||
languageDropdown: {
|
||||
selector: "//label[.='Language']/..//div[starts-with(@id, 'single-choice-drop')]",
|
||||
languageInput: {
|
||||
selector: "//label[.='Language']/..//input",
|
||||
locateStrategy: 'xpath'
|
||||
},
|
||||
languageSelect: {
|
||||
selector: "//label[.='Language']/..//div[starts-with(@id, 'single-choice-drop')]//label[normalize-space()='%s']",
|
||||
locateStrategy: 'xpath'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,11 @@ const assert = require('assert')
|
||||
const path = require('path')
|
||||
const fs = require('fs-extra')
|
||||
const { client } = require('nightwatch-api')
|
||||
const { Given, When, Then, After } = require('cucumber')
|
||||
const { Given, When, Then, After, Before } = require('cucumber')
|
||||
const languageHelper = require('../helpers/language')
|
||||
|
||||
const initialLanguageAssignments = []
|
||||
|
||||
Given('the user browses to the settings page', function () {
|
||||
return client.page.settingsPage().navigateAndWaitTillLoaded()
|
||||
})
|
||||
@@ -14,6 +16,11 @@ Then('the setting {string} should have value {string}', async function (setting,
|
||||
assert.strictEqual(actual, result, 'The setting value doesnt matches to ' + result)
|
||||
})
|
||||
|
||||
Then('the setting {string} should not have any value', async function (setting) {
|
||||
const actual = await client.page.settingsPage().getSettingsValue(setting)
|
||||
assert.strictEqual(actual, false, 'The setting value was expected not to be present but was')
|
||||
})
|
||||
|
||||
When('the user changes the language to {string}', async function (value) {
|
||||
await client.page.settingsPage().changeSettings('Language', value)
|
||||
})
|
||||
@@ -21,35 +28,17 @@ When('the user changes the language to {string}', async function (value) {
|
||||
Then('the files menu should be listed in language {string}', async function (language) {
|
||||
const menu = await client.page.filesPageSettingsContext().getMenuList()
|
||||
const expected = languageHelper.getFilesMenuForLanguage(language)
|
||||
assert.deepEqual(menu, expected, 'the menu list were not same')
|
||||
assert.deepStrictEqual(menu, expected, 'the menu list were not same')
|
||||
})
|
||||
|
||||
Then('the account menu should be listed in language {string}', async function (language) {
|
||||
const menu = await client.page.filesPageSettingsContext().getUserMenu()
|
||||
const expected = languageHelper.getUserMenuForLanguage(language)
|
||||
assert.deepEqual(menu, expected, 'the menu list were not same')
|
||||
assert.deepStrictEqual(menu, expected, 'the menu list were not same')
|
||||
})
|
||||
|
||||
Then('the files header should be displayed in language {string}', async function (language) {
|
||||
const items = await client.page.filesPageSettingsContext().getFileHeaderItems()
|
||||
const expected = languageHelper.getFilesHeaderMenuForLanguage(language)
|
||||
assert.deepEqual(items, expected, 'the menu list were not same')
|
||||
})
|
||||
|
||||
After(async function () {
|
||||
const directory = path.join(client.globals.settings_store, 'values')
|
||||
try {
|
||||
console.log('Elements')
|
||||
fs.readdirSync(directory).map(element => {
|
||||
console.log(element)
|
||||
})
|
||||
} catch (err) {
|
||||
console.log('Error while reading the settings values from file system... ')
|
||||
}
|
||||
try {
|
||||
fs.emptyDirSync(directory)
|
||||
} catch (err) {
|
||||
console.log('Error while clearing settings values from file system')
|
||||
console.log('No settings may have been changed by the tests')
|
||||
}
|
||||
assert.deepStrictEqual(items, expected, 'the menu list were not same')
|
||||
})
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
---
|
||||
|
||||
# OpenID Connect client registry.
|
||||
clients:
|
||||
- id: web
|
||||
name: OCIS
|
||||
application_type: web
|
||||
insecure: yes
|
||||
trusted: yes
|
||||
redirect_uris:
|
||||
- https://ocis-server:9200/oidc-callback.html
|
||||
- https://ocis-server:9200/
|
||||
origins:
|
||||
- https://ocis-server:9200
|
||||
|
||||
authorities:
|
||||
@@ -1,27 +0,0 @@
|
||||
{
|
||||
"server": "https://ocis-server:9200",
|
||||
"theme": "owncloud",
|
||||
"version": "0.1.0",
|
||||
"openIdConnect": {
|
||||
"metadata_url": "https://ocis-server:9200/.well-known/openid-configuration",
|
||||
"authority": "https://ocis-server:9200",
|
||||
"client_id": "web",
|
||||
"response_type": "code",
|
||||
"scope": "openid profile email"
|
||||
},
|
||||
"apps": [
|
||||
"files",
|
||||
"draw-io",
|
||||
"markdown-editor",
|
||||
"media-viewer"
|
||||
],
|
||||
"external_apps": [
|
||||
{
|
||||
"id": "settings",
|
||||
"path": "https://ocis-server:9200/settings.js",
|
||||
"config": {
|
||||
"url": "https://ocis-server:9200"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
{
|
||||
"HTTP": {
|
||||
"Namespace": "com.owncloud"
|
||||
},
|
||||
"policy_selector": {
|
||||
"static": {
|
||||
"policy": "reva"
|
||||
}
|
||||
},
|
||||
"policies": [
|
||||
{
|
||||
"name": "reva",
|
||||
"routes": [
|
||||
{
|
||||
"endpoint": "/",
|
||||
"backend": "http://localhost:9100"
|
||||
},
|
||||
{
|
||||
"endpoint": "/.well-known/",
|
||||
"backend": "http://localhost:9130"
|
||||
},
|
||||
{
|
||||
"endpoint": "/konnect/",
|
||||
"backend": "http://localhost:9130"
|
||||
},
|
||||
{
|
||||
"endpoint": "/signin/",
|
||||
"backend": "http://localhost:9130"
|
||||
},
|
||||
{
|
||||
"endpoint": "/ocs/",
|
||||
"backend": "http://localhost:9140"
|
||||
},
|
||||
{
|
||||
"type": "regex",
|
||||
"endpoint": "/ocs/v[12].php/cloud/user",
|
||||
"backend": "http://localhost:9110"
|
||||
},
|
||||
{
|
||||
"endpoint": "/remote.php/",
|
||||
"backend": "http://localhost:9140"
|
||||
},
|
||||
{
|
||||
"endpoint": "/dav/",
|
||||
"backend": "http://localhost:9140"
|
||||
},
|
||||
{
|
||||
"endpoint": "/webdav/",
|
||||
"backend": "http://localhost:9140"
|
||||
},
|
||||
{
|
||||
"endpoint": "/status.php",
|
||||
"backend": "http://localhost:9140"
|
||||
},
|
||||
{
|
||||
"endpoint": "/index.php/",
|
||||
"backend": "http://localhost:9140"
|
||||
},
|
||||
{
|
||||
"endpoint": "/data",
|
||||
"backend": "http://localhost:9140"
|
||||
},
|
||||
{
|
||||
"endpoint": "/api/v0/accounts",
|
||||
"backend": "http://localhost:9181"
|
||||
},
|
||||
{
|
||||
"endpoint": "/accounts.js",
|
||||
"backend": "http://localhost:9181"
|
||||
},
|
||||
{
|
||||
"endpoint": "/api/v0/settings",
|
||||
"backend": "http://localhost:9190"
|
||||
},
|
||||
{
|
||||
"endpoint": "/settings.js",
|
||||
"backend": "http://localhost:9190"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -6,15 +6,9 @@ then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$OCIS_SKELETON_DIR" ]
|
||||
then
|
||||
echo "OCIS_SKELETON_DIR env variable is not set, cannot find skeleton directory"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$WEB_UI_CONFIG" ]
|
||||
then
|
||||
echo "WEB_UI_CONFIG env variable is not set, cannot find ownCloud Web config file"
|
||||
echo "WEB_UI_CONFIG env variable is not set, cannot find web config file"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -29,9 +23,9 @@ trap clean_up SIGHUP SIGINT SIGTERM
|
||||
if [ -z "$TEST_INFRA_DIRECTORY" ]
|
||||
then
|
||||
cleanup=true
|
||||
testFolder=$(cat < /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
|
||||
testFolder=$(mktemp -d -p .)
|
||||
printf "creating folder $testFolder for Test infrastructure setup\n\n"
|
||||
export TEST_INFRA_DIRECTORY=$testFolder
|
||||
export TEST_INFRA_DIRECTORY=$testFolder/tests
|
||||
fi
|
||||
|
||||
clean_up() {
|
||||
@@ -46,13 +40,10 @@ clean_up() {
|
||||
|
||||
trap clean_up SIGHUP SIGINT SIGTERM EXIT
|
||||
|
||||
cp -r "$WEB_PATH/tests" "./$testFolder"
|
||||
cp -r "$WEB_PATH"/tests "$testFolder"
|
||||
|
||||
export NODE_TLS_REJECT_UNAUTHORIZED='0'
|
||||
export SERVER_HOST=${SERVER_HOST:-https://localhost:9200}
|
||||
export BACKEND_HOST=${BACKEND_HOST:-https://localhost:9200}
|
||||
export OCIS_SETTINGS_STORE=${OCIS_SETTINGS_STORE:-"/var/tmp/ocis/settings"}
|
||||
export RUN_ON_OCIS=true
|
||||
export TEST_TAGS=${TEST_TAGS:-"not @skip"}
|
||||
|
||||
yarn run acceptance-tests "$1"
|
||||
|
||||
+1286
-839
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user