Merge pull request #7720 from dragonchaser/ocis-5455-language-setting
Ocis 5455 language setting
This commit is contained in:
@@ -0,0 +1,7 @@
|
|||||||
|
Enhancement: Add preferred language to user settings
|
||||||
|
|
||||||
|
We have added the preferred language to the libre-graph api & added endpoints for that to ocis.
|
||||||
|
|
||||||
|
https://github.com/owncloud/ocis/pull/7720
|
||||||
|
https://github.com/owncloud/ocis/issues/5455
|
||||||
|
https://github.com/owncloud/libre-graph-api/pull/130
|
||||||
@@ -67,7 +67,7 @@ require (
|
|||||||
github.com/onsi/gomega v1.29.0
|
github.com/onsi/gomega v1.29.0
|
||||||
github.com/open-policy-agent/opa v0.51.0
|
github.com/open-policy-agent/opa v0.51.0
|
||||||
github.com/orcaman/concurrent-map v1.0.0
|
github.com/orcaman/concurrent-map v1.0.0
|
||||||
github.com/owncloud/libre-graph-api-go v1.0.5-0.20231107135330-011e9d4c45e3
|
github.com/owncloud/libre-graph-api-go v1.0.5-0.20231113143725-09bf34dc9afb
|
||||||
github.com/pkg/errors v0.9.1
|
github.com/pkg/errors v0.9.1
|
||||||
github.com/pkg/xattr v0.4.9
|
github.com/pkg/xattr v0.4.9
|
||||||
github.com/prometheus/client_golang v1.17.0
|
github.com/prometheus/client_golang v1.17.0
|
||||||
|
|||||||
@@ -1774,8 +1774,8 @@ github.com/oracle/oci-go-sdk v24.3.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35uk
|
|||||||
github.com/orcaman/concurrent-map v1.0.0 h1:I/2A2XPCb4IuQWcQhBhSwGfiuybl/J0ev9HDbW65HOY=
|
github.com/orcaman/concurrent-map v1.0.0 h1:I/2A2XPCb4IuQWcQhBhSwGfiuybl/J0ev9HDbW65HOY=
|
||||||
github.com/orcaman/concurrent-map v1.0.0/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI=
|
github.com/orcaman/concurrent-map v1.0.0/go.mod h1:Lu3tH6HLW3feq74c2GC+jIMS/K2CFcDWnWD9XkenwhI=
|
||||||
github.com/ovh/go-ovh v1.1.0/go.mod h1:AxitLZ5HBRPyUd+Zl60Ajaag+rNTdVXWIkzfrVuTXWA=
|
github.com/ovh/go-ovh v1.1.0/go.mod h1:AxitLZ5HBRPyUd+Zl60Ajaag+rNTdVXWIkzfrVuTXWA=
|
||||||
github.com/owncloud/libre-graph-api-go v1.0.5-0.20231107135330-011e9d4c45e3 h1:eUE3kNgr8PwcXeUKFkuEuz1+4hfCCmq+rKYQzk0OxtY=
|
github.com/owncloud/libre-graph-api-go v1.0.5-0.20231113143725-09bf34dc9afb h1:KFnmkGvHY+6k6IZ9I1w5Ia24VbALYms+Y6W7LrsUbsE=
|
||||||
github.com/owncloud/libre-graph-api-go v1.0.5-0.20231107135330-011e9d4c45e3/go.mod h1:v2aAl5IwEI8t+GmcWvBd+bvJMYp9Vf1hekLuRf0UnEs=
|
github.com/owncloud/libre-graph-api-go v1.0.5-0.20231113143725-09bf34dc9afb/go.mod h1:v2aAl5IwEI8t+GmcWvBd+bvJMYp9Vf1hekLuRf0UnEs=
|
||||||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw=
|
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw=
|
||||||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0=
|
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0=
|
||||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||||
|
|||||||
@@ -0,0 +1,164 @@
|
|||||||
|
// Code generated by mockery v0.0.0-dev. DO NOT EDIT.
|
||||||
|
|
||||||
|
package mocks
|
||||||
|
|
||||||
|
import (
|
||||||
|
context "context"
|
||||||
|
|
||||||
|
client "go-micro.dev/v4/client"
|
||||||
|
|
||||||
|
mock "github.com/stretchr/testify/mock"
|
||||||
|
|
||||||
|
v0 "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
|
||||||
|
)
|
||||||
|
|
||||||
|
// ValueService is an autogenerated mock type for the ValueService type
|
||||||
|
type ValueService struct {
|
||||||
|
mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetValue provides a mock function with given fields: ctx, in, opts
|
||||||
|
func (_m *ValueService) GetValue(ctx context.Context, in *v0.GetValueRequest, opts ...client.CallOption) (*v0.GetValueResponse, error) {
|
||||||
|
_va := make([]interface{}, len(opts))
|
||||||
|
for _i := range opts {
|
||||||
|
_va[_i] = opts[_i]
|
||||||
|
}
|
||||||
|
var _ca []interface{}
|
||||||
|
_ca = append(_ca, ctx, in)
|
||||||
|
_ca = append(_ca, _va...)
|
||||||
|
ret := _m.Called(_ca...)
|
||||||
|
|
||||||
|
var r0 *v0.GetValueResponse
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, *v0.GetValueRequest, ...client.CallOption) (*v0.GetValueResponse, error)); ok {
|
||||||
|
return rf(ctx, in, opts...)
|
||||||
|
}
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, *v0.GetValueRequest, ...client.CallOption) *v0.GetValueResponse); ok {
|
||||||
|
r0 = rf(ctx, in, opts...)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*v0.GetValueResponse)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rf, ok := ret.Get(1).(func(context.Context, *v0.GetValueRequest, ...client.CallOption) error); ok {
|
||||||
|
r1 = rf(ctx, in, opts...)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetValueByUniqueIdentifiers provides a mock function with given fields: ctx, in, opts
|
||||||
|
func (_m *ValueService) GetValueByUniqueIdentifiers(ctx context.Context, in *v0.GetValueByUniqueIdentifiersRequest, opts ...client.CallOption) (*v0.GetValueResponse, error) {
|
||||||
|
_va := make([]interface{}, len(opts))
|
||||||
|
for _i := range opts {
|
||||||
|
_va[_i] = opts[_i]
|
||||||
|
}
|
||||||
|
var _ca []interface{}
|
||||||
|
_ca = append(_ca, ctx, in)
|
||||||
|
_ca = append(_ca, _va...)
|
||||||
|
ret := _m.Called(_ca...)
|
||||||
|
|
||||||
|
var r0 *v0.GetValueResponse
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, *v0.GetValueByUniqueIdentifiersRequest, ...client.CallOption) (*v0.GetValueResponse, error)); ok {
|
||||||
|
return rf(ctx, in, opts...)
|
||||||
|
}
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, *v0.GetValueByUniqueIdentifiersRequest, ...client.CallOption) *v0.GetValueResponse); ok {
|
||||||
|
r0 = rf(ctx, in, opts...)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*v0.GetValueResponse)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rf, ok := ret.Get(1).(func(context.Context, *v0.GetValueByUniqueIdentifiersRequest, ...client.CallOption) error); ok {
|
||||||
|
r1 = rf(ctx, in, opts...)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
|
// ListValues provides a mock function with given fields: ctx, in, opts
|
||||||
|
func (_m *ValueService) ListValues(ctx context.Context, in *v0.ListValuesRequest, opts ...client.CallOption) (*v0.ListValuesResponse, error) {
|
||||||
|
_va := make([]interface{}, len(opts))
|
||||||
|
for _i := range opts {
|
||||||
|
_va[_i] = opts[_i]
|
||||||
|
}
|
||||||
|
var _ca []interface{}
|
||||||
|
_ca = append(_ca, ctx, in)
|
||||||
|
_ca = append(_ca, _va...)
|
||||||
|
ret := _m.Called(_ca...)
|
||||||
|
|
||||||
|
var r0 *v0.ListValuesResponse
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, *v0.ListValuesRequest, ...client.CallOption) (*v0.ListValuesResponse, error)); ok {
|
||||||
|
return rf(ctx, in, opts...)
|
||||||
|
}
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, *v0.ListValuesRequest, ...client.CallOption) *v0.ListValuesResponse); ok {
|
||||||
|
r0 = rf(ctx, in, opts...)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*v0.ListValuesResponse)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rf, ok := ret.Get(1).(func(context.Context, *v0.ListValuesRequest, ...client.CallOption) error); ok {
|
||||||
|
r1 = rf(ctx, in, opts...)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
|
// SaveValue provides a mock function with given fields: ctx, in, opts
|
||||||
|
func (_m *ValueService) SaveValue(ctx context.Context, in *v0.SaveValueRequest, opts ...client.CallOption) (*v0.SaveValueResponse, error) {
|
||||||
|
_va := make([]interface{}, len(opts))
|
||||||
|
for _i := range opts {
|
||||||
|
_va[_i] = opts[_i]
|
||||||
|
}
|
||||||
|
var _ca []interface{}
|
||||||
|
_ca = append(_ca, ctx, in)
|
||||||
|
_ca = append(_ca, _va...)
|
||||||
|
ret := _m.Called(_ca...)
|
||||||
|
|
||||||
|
var r0 *v0.SaveValueResponse
|
||||||
|
var r1 error
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, *v0.SaveValueRequest, ...client.CallOption) (*v0.SaveValueResponse, error)); ok {
|
||||||
|
return rf(ctx, in, opts...)
|
||||||
|
}
|
||||||
|
if rf, ok := ret.Get(0).(func(context.Context, *v0.SaveValueRequest, ...client.CallOption) *v0.SaveValueResponse); ok {
|
||||||
|
r0 = rf(ctx, in, opts...)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*v0.SaveValueResponse)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rf, ok := ret.Get(1).(func(context.Context, *v0.SaveValueRequest, ...client.CallOption) error); ok {
|
||||||
|
r1 = rf(ctx, in, opts...)
|
||||||
|
} else {
|
||||||
|
r1 = ret.Error(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewValueService creates a new instance of ValueService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||||
|
// The first argument is typically a *testing.T value.
|
||||||
|
func NewValueService(t interface {
|
||||||
|
mock.TestingT
|
||||||
|
Cleanup(func())
|
||||||
|
}) *ValueService {
|
||||||
|
mock := &ValueService{}
|
||||||
|
mock.Mock.Test(t)
|
||||||
|
|
||||||
|
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||||
|
|
||||||
|
return mock
|
||||||
|
}
|
||||||
@@ -83,6 +83,7 @@ func Server(opts ...Option) (http.Service, error) {
|
|||||||
// how do we secure the api?
|
// how do we secure the api?
|
||||||
var requireAdminMiddleware func(stdhttp.Handler) stdhttp.Handler
|
var requireAdminMiddleware func(stdhttp.Handler) stdhttp.Handler
|
||||||
var roleService svc.RoleService
|
var roleService svc.RoleService
|
||||||
|
var valueService settingssvc.ValueService
|
||||||
var gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
|
var gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
|
||||||
grpcClient, err := grpc.NewClient(append(grpc.GetClientOptions(options.Config.GRPCClientTLS), grpc.WithTraceProvider(options.TraceProvider))...)
|
grpcClient, err := grpc.NewClient(append(grpc.GetClientOptions(options.Config.GRPCClientTLS), grpc.WithTraceProvider(options.TraceProvider))...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -95,6 +96,7 @@ func Server(opts ...Option) (http.Service, error) {
|
|||||||
account.JWTSecret(options.Config.TokenManager.JWTSecret),
|
account.JWTSecret(options.Config.TokenManager.JWTSecret),
|
||||||
))
|
))
|
||||||
roleService = settingssvc.NewRoleService("com.owncloud.api.settings", grpcClient)
|
roleService = settingssvc.NewRoleService("com.owncloud.api.settings", grpcClient)
|
||||||
|
valueService = settingssvc.NewValueService("com.owncloud.api.settings", grpcClient)
|
||||||
gatewaySelector, err = pool.GatewaySelector(
|
gatewaySelector, err = pool.GatewaySelector(
|
||||||
options.Config.Reva.Address,
|
options.Config.Reva.Address,
|
||||||
append(
|
append(
|
||||||
@@ -133,6 +135,7 @@ func Server(opts ...Option) (http.Service, error) {
|
|||||||
svc.Middleware(middlewares...),
|
svc.Middleware(middlewares...),
|
||||||
svc.EventsPublisher(publisher),
|
svc.EventsPublisher(publisher),
|
||||||
svc.WithRoleService(roleService),
|
svc.WithRoleService(roleService),
|
||||||
|
svc.WithValueService(valueService),
|
||||||
svc.WithRequireAdminMiddleware(requireAdminMiddleware),
|
svc.WithRequireAdminMiddleware(requireAdminMiddleware),
|
||||||
svc.WithGatewaySelector(gatewaySelector),
|
svc.WithGatewaySelector(gatewaySelector),
|
||||||
svc.WithSearchService(searchsvc.NewSearchProviderService("com.owncloud.api.search", grpcClient)),
|
svc.WithSearchService(searchsvc.NewSearchProviderService("com.owncloud.api.search", grpcClient)),
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ type Graph struct {
|
|||||||
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
|
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
|
||||||
roleService RoleService
|
roleService RoleService
|
||||||
permissionsService Permissions
|
permissionsService Permissions
|
||||||
|
valueService settingssvc.ValueService
|
||||||
specialDriveItemsCache *ttlcache.Cache[string, interface{}]
|
specialDriveItemsCache *ttlcache.Cache[string, interface{}]
|
||||||
identityCache identity.IdentityCache
|
identityCache identity.IdentityCache
|
||||||
eventsPublisher events.Publisher
|
eventsPublisher events.Publisher
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ type Options struct {
|
|||||||
IdentityEducationBackend identity.EducationBackend
|
IdentityEducationBackend identity.EducationBackend
|
||||||
RoleService RoleService
|
RoleService RoleService
|
||||||
PermissionService Permissions
|
PermissionService Permissions
|
||||||
|
ValueService settingssvc.ValueService
|
||||||
RoleManager *roles.Manager
|
RoleManager *roles.Manager
|
||||||
EventsPublisher events.Publisher
|
EventsPublisher events.Publisher
|
||||||
SearchService searchsvc.SearchProviderService
|
SearchService searchsvc.SearchProviderService
|
||||||
@@ -106,6 +107,13 @@ func WithRoleService(val RoleService) Option {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WithValueService provides a function to set the ValueService option.
|
||||||
|
func WithValueService(val settingssvc.ValueService) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.ValueService = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// WithSearchService provides a function to set the SearchService option.
|
// WithSearchService provides a function to set the SearchService option.
|
||||||
func WithSearchService(val searchsvc.SearchProviderService) Option {
|
func WithSearchService(val searchsvc.SearchProviderService) Option {
|
||||||
return func(o *Options) {
|
return func(o *Options) {
|
||||||
|
|||||||
@@ -146,6 +146,7 @@ func NewService(opts ...Option) (Graph, error) {
|
|||||||
keycloakClient: options.KeycloakClient,
|
keycloakClient: options.KeycloakClient,
|
||||||
historyClient: options.EventHistoryClient,
|
historyClient: options.EventHistoryClient,
|
||||||
traceProvider: options.TraceProvider,
|
traceProvider: options.TraceProvider,
|
||||||
|
valueService: options.ValueService,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := setIdentityBackends(options, &svc); err != nil {
|
if err := setIdentityBackends(options, &svc); err != nil {
|
||||||
@@ -212,9 +213,12 @@ func NewService(opts ...Option) (Graph, error) {
|
|||||||
r.Route("/me", func(r chi.Router) {
|
r.Route("/me", func(r chi.Router) {
|
||||||
r.Get("/", svc.GetMe)
|
r.Get("/", svc.GetMe)
|
||||||
r.Get("/drive", svc.GetUserDrive)
|
r.Get("/drive", svc.GetUserDrive)
|
||||||
r.Get("/drives", svc.GetDrives)
|
r.Route("/drives", func(r chi.Router) {
|
||||||
|
r.Get("/", svc.GetDrives)
|
||||||
|
})
|
||||||
r.Get("/drive/root/children", svc.GetRootDriveChildren)
|
r.Get("/drive/root/children", svc.GetRootDriveChildren)
|
||||||
r.Post("/changePassword", svc.ChangeOwnPassword)
|
r.Post("/changePassword", svc.ChangeOwnPassword)
|
||||||
|
r.Patch("/", svc.PatchMe)
|
||||||
})
|
})
|
||||||
r.Route("/users", func(r chi.Router) {
|
r.Route("/users", func(r chi.Router) {
|
||||||
r.With(requireAdmin).Get("/", svc.GetUsers)
|
r.With(requireAdmin).Get("/", svc.GetUsers)
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/owncloud/ocis/v2/services/settings/pkg/store/defaults"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"reflect"
|
"reflect"
|
||||||
@@ -22,10 +24,12 @@ import (
|
|||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
"github.com/go-chi/render"
|
"github.com/go-chi/render"
|
||||||
libregraph "github.com/owncloud/libre-graph-api-go"
|
libregraph "github.com/owncloud/libre-graph-api-go"
|
||||||
|
settingsmsg "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/settings/v0"
|
||||||
settings "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
|
settings "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
|
||||||
|
settingssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
|
||||||
"github.com/owncloud/ocis/v2/services/graph/pkg/identity"
|
"github.com/owncloud/ocis/v2/services/graph/pkg/identity"
|
||||||
"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
|
"github.com/owncloud/ocis/v2/services/graph/pkg/service/v0/errorcode"
|
||||||
settingssvc "github.com/owncloud/ocis/v2/services/settings/pkg/service/v0"
|
ocissettingssvc "github.com/owncloud/ocis/v2/services/settings/pkg/service/v0"
|
||||||
"golang.org/x/exp/slices"
|
"golang.org/x/exp/slices"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -85,6 +89,15 @@ func (g Graph) GetMe(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
preferedLanguage, _, err := getUserLanguage(r.Context(), g.valueService, me.GetId())
|
||||||
|
if err != nil {
|
||||||
|
logger.Error().Err(err).Msg("could not get user language")
|
||||||
|
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "could not get user language")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
me.PreferredLanguage = &preferedLanguage
|
||||||
|
|
||||||
render.Status(r, http.StatusOK)
|
render.Status(r, http.StatusOK)
|
||||||
render.JSON(w, r, me)
|
render.JSON(w, r, me)
|
||||||
}
|
}
|
||||||
@@ -319,10 +332,10 @@ func (g Graph) PostUser(w http.ResponseWriter, r *http.Request) {
|
|||||||
// to all new users for now, as create Account request does not have any role field
|
// to all new users for now, as create Account request does not have any role field
|
||||||
if _, err = g.roleService.AssignRoleToUser(r.Context(), &settings.AssignRoleToUserRequest{
|
if _, err = g.roleService.AssignRoleToUser(r.Context(), &settings.AssignRoleToUserRequest{
|
||||||
AccountUuid: *u.Id,
|
AccountUuid: *u.Id,
|
||||||
RoleId: settingssvc.BundleUUIDRoleUser,
|
RoleId: ocissettingssvc.BundleUUIDRoleUser,
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
// log as error, admin eventually needs to do something
|
// log as error, admin eventually needs to do something
|
||||||
logger.Error().Err(err).Str("id", *u.Id).Str("role", settingssvc.BundleUUIDRoleUser).Msg("could not create user: role assignment failed")
|
logger.Error().Err(err).Str("id", *u.Id).Str("role", ocissettingssvc.BundleUUIDRoleUser).Msg("could not create user: role assignment failed")
|
||||||
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "role assignment failed")
|
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "role assignment failed")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -479,6 +492,23 @@ func (g Graph) GetUser(w http.ResponseWriter, r *http.Request) {
|
|||||||
render.JSON(w, r, user)
|
render.JSON(w, r, user)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// getUserLanguage returns the language of the user in the context.
|
||||||
|
func getUserLanguage(ctx context.Context, valueService settingssvc.ValueService, userID string) (string, string, error) {
|
||||||
|
gvr, err := valueService.GetValueByUniqueIdentifiers(ctx, &settingssvc.GetValueByUniqueIdentifiersRequest{
|
||||||
|
AccountUuid: userID,
|
||||||
|
SettingId: defaults.SettingUUIDProfileLanguage,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
langVal := gvr.GetValue().GetValue().GetListValue().GetValues()
|
||||||
|
if len(langVal) > 0 && langVal[0] != nil {
|
||||||
|
return langVal[0].GetStringValue(), gvr.GetValue().GetValue().GetId(), nil
|
||||||
|
}
|
||||||
|
return "", "", errors.New("no language value found")
|
||||||
|
}
|
||||||
|
|
||||||
// DeleteUser implements the Service interface.
|
// DeleteUser implements the Service interface.
|
||||||
func (g Graph) DeleteUser(w http.ResponseWriter, r *http.Request) {
|
func (g Graph) DeleteUser(w http.ResponseWriter, r *http.Request) {
|
||||||
logger := g.logger.SubloggerWithRequestID(r.Context())
|
logger := g.logger.SubloggerWithRequestID(r.Context())
|
||||||
@@ -599,11 +629,41 @@ func (g Graph) DeleteUser(w http.ResponseWriter, r *http.Request) {
|
|||||||
render.NoContent(w, r)
|
render.NoContent(w, r)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PatchMe implements the Service Interface. Updates the specified attributes of the current user
|
||||||
|
func (g Graph) PatchMe(w http.ResponseWriter, r *http.Request) {
|
||||||
|
logger := g.logger.SubloggerWithRequestID(r.Context())
|
||||||
|
logger.Debug().Msg("calling patch me")
|
||||||
|
userID := revactx.ContextMustGetUser(r.Context()).GetId().GetOpaqueId()
|
||||||
|
if userID == "" {
|
||||||
|
logger.Debug().Msg("could not update user: missing user id")
|
||||||
|
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing user id")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
changes := libregraph.NewUser()
|
||||||
|
err := StrictJSONUnmarshal(r.Body, changes)
|
||||||
|
if err != nil {
|
||||||
|
logger.Debug().Err(err).Interface("body", r.Body).Msg("could not update user: invalid request body")
|
||||||
|
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest,
|
||||||
|
fmt.Sprintf("invalid request body: %s", err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, ok := changes.GetDisplayNameOk(); ok {
|
||||||
|
logger.Info().Interface("user", changes).Msg("could not update user: user is not allowed to change own displayname")
|
||||||
|
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "user is not allowed to change own displayname")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, ok := changes.GetMailOk(); ok {
|
||||||
|
logger.Info().Interface("user", changes).Msg("could not update user: user is not allowed to change own mail")
|
||||||
|
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "user is not allowed to change own mail")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
g.patchUser(w, r, userID, changes)
|
||||||
|
}
|
||||||
|
|
||||||
// PatchUser implements the Service Interface. Updates the specified attributes of an
|
// PatchUser implements the Service Interface. Updates the specified attributes of an
|
||||||
// ExistingUser
|
// ExistingUser
|
||||||
func (g Graph) PatchUser(w http.ResponseWriter, r *http.Request) {
|
func (g Graph) PatchUser(w http.ResponseWriter, r *http.Request) {
|
||||||
logger := g.logger.SubloggerWithRequestID(r.Context())
|
logger := g.logger.SubloggerWithRequestID(r.Context())
|
||||||
logger.Debug().Msg("calling patch user")
|
|
||||||
nameOrID := chi.URLParam(r, "userID")
|
nameOrID := chi.URLParam(r, "userID")
|
||||||
nameOrID, err := url.PathUnescape(nameOrID)
|
nameOrID, err := url.PathUnescape(nameOrID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -611,6 +671,26 @@ func (g Graph) PatchUser(w http.ResponseWriter, r *http.Request) {
|
|||||||
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping user id failed")
|
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping user id failed")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
changes := libregraph.NewUser()
|
||||||
|
err = StrictJSONUnmarshal(r.Body, changes)
|
||||||
|
if err != nil {
|
||||||
|
logger.Debug().Err(err).Interface("body", r.Body).Msg("could not update user: invalid request body")
|
||||||
|
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest,
|
||||||
|
fmt.Sprintf("invalid request body: %s", err.Error()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if _, ok := changes.GetPreferredLanguageOk(); ok {
|
||||||
|
logger.Info().Interface("user", changes).Msg("could not update user: user is not allowed to change other users language")
|
||||||
|
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "user is not allowed to change other users language")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
g.patchUser(w, r, nameOrID, changes)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (g Graph) patchUser(w http.ResponseWriter, r *http.Request, nameOrID string, changes *libregraph.User) {
|
||||||
|
logger := g.logger.SubloggerWithRequestID(r.Context())
|
||||||
|
logger.Debug().Msg("calling patch user")
|
||||||
|
|
||||||
sanitizedPath := strings.TrimPrefix(r.URL.Path, "/graph/v1.0/")
|
sanitizedPath := strings.TrimPrefix(r.URL.Path, "/graph/v1.0/")
|
||||||
|
|
||||||
@@ -633,14 +713,6 @@ func (g Graph) PatchUser(w http.ResponseWriter, r *http.Request) {
|
|||||||
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing user id")
|
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing user id")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
changes := libregraph.NewUser()
|
|
||||||
err = StrictJSONUnmarshal(r.Body, changes)
|
|
||||||
if err != nil {
|
|
||||||
logger.Debug().Err(err).Interface("body", r.Body).Msg("could not update user: invalid request body")
|
|
||||||
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest,
|
|
||||||
fmt.Sprintf("invalid request body: %s", err.Error()))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if reflect.ValueOf(*changes).IsZero() {
|
if reflect.ValueOf(*changes).IsZero() {
|
||||||
logger.Debug().Interface("body", r.Body).Msg("ignoring empty request body")
|
logger.Debug().Interface("body", r.Body).Msg("ignoring empty request body")
|
||||||
@@ -657,6 +729,47 @@ func (g Graph) PatchUser(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
preferredLanguage, ok := changes.GetPreferredLanguageOk()
|
||||||
|
if ok {
|
||||||
|
_, vID, err := getUserLanguage(r.Context(), g.valueService, oldUserValues.GetId())
|
||||||
|
if err != nil {
|
||||||
|
logger.Error().Err(err).Msg("could not get user language")
|
||||||
|
tvID, err := uuid.NewUUID()
|
||||||
|
if err != nil {
|
||||||
|
logger.Error().Err(err).Msg("could not create user: error generating uuid")
|
||||||
|
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "error generating uuid")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
vID = tvID.String()
|
||||||
|
}
|
||||||
|
_, err = g.valueService.SaveValue(r.Context(), &settings.SaveValueRequest{
|
||||||
|
Value: &settingsmsg.Value{
|
||||||
|
Id: vID,
|
||||||
|
BundleId: defaults.BundleUUIDProfile,
|
||||||
|
SettingId: defaults.SettingUUIDProfileLanguage,
|
||||||
|
AccountUuid: oldUserValues.GetId(),
|
||||||
|
Resource: &settingsmsg.Resource{
|
||||||
|
Type: settingsmsg.Resource_TYPE_USER,
|
||||||
|
},
|
||||||
|
Value: &settingsmsg.Value_ListValue{
|
||||||
|
ListValue: &settingsmsg.ListValue{Values: []*settingsmsg.ListOptionValue{
|
||||||
|
{
|
||||||
|
Option: &settingsmsg.ListOptionValue_StringValue{
|
||||||
|
StringValue: *preferredLanguage,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
logger.Error().Err(err).Msg("could not update user: error saving language setting")
|
||||||
|
errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, "error saving language setting")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
var features []events.UserFeature
|
var features []events.UserFeature
|
||||||
if mail, ok := changes.GetMailOk(); ok {
|
if mail, ok := changes.GetMailOk(); ok {
|
||||||
if !isValidEmail(*mail) {
|
if !isValidEmail(*mail) {
|
||||||
@@ -715,6 +828,7 @@ func (g Graph) PatchUser(w http.ResponseWriter, r *http.Request) {
|
|||||||
errorcode.RenderError(w, r, err)
|
errorcode.RenderError(w, r, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
u.PreferredLanguage = preferredLanguage
|
||||||
|
|
||||||
e := events.UserFeatureChanged{
|
e := events.UserFeatureChanged{
|
||||||
UserID: nameOrID,
|
UserID: nameOrID,
|
||||||
|
|||||||
@@ -13,14 +13,18 @@ import (
|
|||||||
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||||
typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||||
revactx "github.com/cs3org/reva/v2/pkg/ctx"
|
|
||||||
"github.com/cs3org/reva/v2/pkg/rgrpc/status"
|
|
||||||
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
|
|
||||||
cs3mocks "github.com/cs3org/reva/v2/tests/cs3mocks/mocks"
|
|
||||||
"github.com/go-chi/chi/v5"
|
"github.com/go-chi/chi/v5"
|
||||||
. "github.com/onsi/ginkgo/v2"
|
. "github.com/onsi/ginkgo/v2"
|
||||||
. "github.com/onsi/gomega"
|
. "github.com/onsi/gomega"
|
||||||
libregraph "github.com/owncloud/libre-graph-api-go"
|
libregraph "github.com/owncloud/libre-graph-api-go"
|
||||||
|
"github.com/stretchr/testify/mock"
|
||||||
|
"go-micro.dev/v4/client"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
|
||||||
|
revactx "github.com/cs3org/reva/v2/pkg/ctx"
|
||||||
|
"github.com/cs3org/reva/v2/pkg/rgrpc/status"
|
||||||
|
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
|
||||||
|
cs3mocks "github.com/cs3org/reva/v2/tests/cs3mocks/mocks"
|
||||||
"github.com/owncloud/ocis/v2/ocis-pkg/shared"
|
"github.com/owncloud/ocis/v2/ocis-pkg/shared"
|
||||||
settingsmsg "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/settings/v0"
|
settingsmsg "github.com/owncloud/ocis/v2/protogen/gen/ocis/messages/settings/v0"
|
||||||
settings "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
|
settings "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
|
||||||
@@ -29,9 +33,6 @@ import (
|
|||||||
"github.com/owncloud/ocis/v2/services/graph/pkg/config/defaults"
|
"github.com/owncloud/ocis/v2/services/graph/pkg/config/defaults"
|
||||||
identitymocks "github.com/owncloud/ocis/v2/services/graph/pkg/identity/mocks"
|
identitymocks "github.com/owncloud/ocis/v2/services/graph/pkg/identity/mocks"
|
||||||
service "github.com/owncloud/ocis/v2/services/graph/pkg/service/v0"
|
service "github.com/owncloud/ocis/v2/services/graph/pkg/service/v0"
|
||||||
"github.com/stretchr/testify/mock"
|
|
||||||
"go-micro.dev/v4/client"
|
|
||||||
"google.golang.org/grpc"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type userList struct {
|
type userList struct {
|
||||||
@@ -47,6 +48,7 @@ var _ = Describe("Users", func() {
|
|||||||
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
|
gatewaySelector pool.Selectable[gateway.GatewayAPIClient]
|
||||||
eventsPublisher mocks.Publisher
|
eventsPublisher mocks.Publisher
|
||||||
roleService *mocks.RoleService
|
roleService *mocks.RoleService
|
||||||
|
valueService *mocks.ValueService
|
||||||
identityBackend *identitymocks.Backend
|
identityBackend *identitymocks.Backend
|
||||||
|
|
||||||
rr *httptest.ResponseRecorder
|
rr *httptest.ResponseRecorder
|
||||||
@@ -73,6 +75,7 @@ var _ = Describe("Users", func() {
|
|||||||
|
|
||||||
identityBackend = &identitymocks.Backend{}
|
identityBackend = &identitymocks.Backend{}
|
||||||
roleService = &mocks.RoleService{}
|
roleService = &mocks.RoleService{}
|
||||||
|
valueService = &mocks.ValueService{}
|
||||||
|
|
||||||
rr = httptest.NewRecorder()
|
rr = httptest.NewRecorder()
|
||||||
ctx = context.Background()
|
ctx = context.Background()
|
||||||
@@ -90,6 +93,7 @@ var _ = Describe("Users", func() {
|
|||||||
service.EventsPublisher(&eventsPublisher),
|
service.EventsPublisher(&eventsPublisher),
|
||||||
service.WithIdentityBackend(identityBackend),
|
service.WithIdentityBackend(identityBackend),
|
||||||
service.WithRoleService(roleService),
|
service.WithRoleService(roleService),
|
||||||
|
service.WithValueService(valueService),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -102,6 +106,25 @@ var _ = Describe("Users", func() {
|
|||||||
})
|
})
|
||||||
|
|
||||||
It("gets the information", func() {
|
It("gets the information", func() {
|
||||||
|
valueService.On("GetValueByUniqueIdentifiers", mock.Anything, mock.Anything, mock.Anything).
|
||||||
|
Return(&settings.GetValueResponse{
|
||||||
|
Value: &settingsmsg.ValueWithIdentifier{
|
||||||
|
Value: &settingsmsg.Value{
|
||||||
|
Value: &settingsmsg.Value_ListValue{
|
||||||
|
ListValue: &settingsmsg.ListValue{
|
||||||
|
Values: []*settingsmsg.ListOptionValue{
|
||||||
|
{
|
||||||
|
Option: &settingsmsg.ListOptionValue_StringValue{
|
||||||
|
StringValue: "it",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
|
|
||||||
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/me", nil)
|
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/me", nil)
|
||||||
r = r.WithContext(revactx.ContextSetUser(ctx, currentUser))
|
r = r.WithContext(revactx.ContextSetUser(ctx, currentUser))
|
||||||
svc.GetMe(rr, r)
|
svc.GetMe(rr, r)
|
||||||
@@ -117,7 +140,24 @@ var _ = Describe("Users", func() {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
identityBackend.On("GetUser", mock.Anything, mock.Anything, mock.Anything).Return(user, nil)
|
identityBackend.On("GetUser", mock.Anything, mock.Anything, mock.Anything).Return(user, nil)
|
||||||
|
valueService.On("GetValueByUniqueIdentifiers", mock.Anything, mock.Anything, mock.Anything).
|
||||||
|
Return(&settings.GetValueResponse{
|
||||||
|
Value: &settingsmsg.ValueWithIdentifier{
|
||||||
|
Value: &settingsmsg.Value{
|
||||||
|
Value: &settingsmsg.Value_ListValue{
|
||||||
|
ListValue: &settingsmsg.ListValue{
|
||||||
|
Values: []*settingsmsg.ListOptionValue{
|
||||||
|
{
|
||||||
|
Option: &settingsmsg.ListOptionValue_StringValue{
|
||||||
|
StringValue: "it",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/me?$expand=memberOf", nil)
|
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/me?$expand=memberOf", nil)
|
||||||
r = r.WithContext(revactx.ContextSetUser(ctx, currentUser))
|
r = r.WithContext(revactx.ContextSetUser(ctx, currentUser))
|
||||||
svc.GetMe(rr, r)
|
svc.GetMe(rr, r)
|
||||||
@@ -145,7 +185,24 @@ var _ = Describe("Users", func() {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
roleService.On("ListRoleAssignments", mock.Anything, mock.Anything, mock.Anything).Return(&settings.ListRoleAssignmentsResponse{Assignments: assignments}, nil)
|
roleService.On("ListRoleAssignments", mock.Anything, mock.Anything, mock.Anything).Return(&settings.ListRoleAssignmentsResponse{Assignments: assignments}, nil)
|
||||||
|
valueService.On("GetValueByUniqueIdentifiers", mock.Anything, mock.Anything, mock.Anything).
|
||||||
|
Return(&settings.GetValueResponse{
|
||||||
|
Value: &settingsmsg.ValueWithIdentifier{
|
||||||
|
Value: &settingsmsg.Value{
|
||||||
|
Value: &settingsmsg.Value_ListValue{
|
||||||
|
ListValue: &settingsmsg.ListValue{
|
||||||
|
Values: []*settingsmsg.ListOptionValue{
|
||||||
|
{
|
||||||
|
Option: &settingsmsg.ListOptionValue_StringValue{
|
||||||
|
StringValue: "it",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/me?$expand=appRoleAssignments", nil)
|
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/me?$expand=appRoleAssignments", nil)
|
||||||
r = r.WithContext(revactx.ContextSetUser(ctx, currentUser))
|
r = r.WithContext(revactx.ContextSetUser(ctx, currentUser))
|
||||||
svc.GetMe(rr, r)
|
svc.GetMe(rr, r)
|
||||||
@@ -413,6 +470,24 @@ var _ = Describe("Users", func() {
|
|||||||
user.SetId("user1")
|
user.SetId("user1")
|
||||||
|
|
||||||
identityBackend.On("GetUser", mock.Anything, mock.Anything, mock.Anything).Return(user, nil)
|
identityBackend.On("GetUser", mock.Anything, mock.Anything, mock.Anything).Return(user, nil)
|
||||||
|
valueService.On("GetValueByUniqueIdentifiers", mock.Anything, mock.Anything, mock.Anything).
|
||||||
|
Return(&settings.GetValueResponse{
|
||||||
|
Value: &settingsmsg.ValueWithIdentifier{
|
||||||
|
Value: &settingsmsg.Value{
|
||||||
|
Value: &settingsmsg.Value_ListValue{
|
||||||
|
ListValue: &settingsmsg.ListValue{
|
||||||
|
Values: []*settingsmsg.ListOptionValue{
|
||||||
|
{
|
||||||
|
Option: &settingsmsg.ListOptionValue_StringValue{
|
||||||
|
StringValue: "it",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/users", nil)
|
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/users", nil)
|
||||||
rctx := chi.NewRouteContext()
|
rctx := chi.NewRouteContext()
|
||||||
rctx.URLParams.Add("userID", *user.Id)
|
rctx.URLParams.Add("userID", *user.Id)
|
||||||
@@ -455,7 +530,24 @@ var _ = Describe("Users", func() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, nil)
|
}, nil)
|
||||||
|
valueService.On("GetValueByUniqueIdentifiers", mock.Anything, mock.Anything, mock.Anything).
|
||||||
|
Return(&settings.GetValueResponse{
|
||||||
|
Value: &settingsmsg.ValueWithIdentifier{
|
||||||
|
Value: &settingsmsg.Value{
|
||||||
|
Value: &settingsmsg.Value_ListValue{
|
||||||
|
ListValue: &settingsmsg.ListValue{
|
||||||
|
Values: []*settingsmsg.ListOptionValue{
|
||||||
|
{
|
||||||
|
Option: &settingsmsg.ListOptionValue_StringValue{
|
||||||
|
StringValue: "it",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/users?$expand=drive", nil)
|
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/users?$expand=drive", nil)
|
||||||
rctx := chi.NewRouteContext()
|
rctx := chi.NewRouteContext()
|
||||||
rctx.URLParams.Add("userID", *user.Id)
|
rctx.URLParams.Add("userID", *user.Id)
|
||||||
@@ -490,7 +582,24 @@ var _ = Describe("Users", func() {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
}, nil)
|
}, nil)
|
||||||
|
valueService.On("GetValueByUniqueIdentifiers", mock.Anything, mock.Anything, mock.Anything).
|
||||||
|
Return(&settings.GetValueResponse{
|
||||||
|
Value: &settingsmsg.ValueWithIdentifier{
|
||||||
|
Value: &settingsmsg.Value{
|
||||||
|
Value: &settingsmsg.Value_ListValue{
|
||||||
|
ListValue: &settingsmsg.ListValue{
|
||||||
|
Values: []*settingsmsg.ListOptionValue{
|
||||||
|
{
|
||||||
|
Option: &settingsmsg.ListOptionValue_StringValue{
|
||||||
|
StringValue: "it",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/users?$expand=drives", nil)
|
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/users?$expand=drives", nil)
|
||||||
rctx := chi.NewRouteContext()
|
rctx := chi.NewRouteContext()
|
||||||
rctx.URLParams.Add("userID", *user.Id)
|
rctx.URLParams.Add("userID", *user.Id)
|
||||||
@@ -521,7 +630,24 @@ var _ = Describe("Users", func() {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
roleService.On("ListRoleAssignments", mock.Anything, mock.Anything, mock.Anything).Return(&settings.ListRoleAssignmentsResponse{Assignments: assignments}, nil)
|
roleService.On("ListRoleAssignments", mock.Anything, mock.Anything, mock.Anything).Return(&settings.ListRoleAssignmentsResponse{Assignments: assignments}, nil)
|
||||||
|
valueService.On("GetValueByUniqueIdentifiers", mock.Anything, mock.Anything, mock.Anything).
|
||||||
|
Return(&settings.GetValueResponse{
|
||||||
|
Value: &settingsmsg.ValueWithIdentifier{
|
||||||
|
Value: &settingsmsg.Value{
|
||||||
|
Value: &settingsmsg.Value_ListValue{
|
||||||
|
ListValue: &settingsmsg.ListValue{
|
||||||
|
Values: []*settingsmsg.ListOptionValue{
|
||||||
|
{
|
||||||
|
Option: &settingsmsg.ListOptionValue_StringValue{
|
||||||
|
StringValue: "it",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil)
|
||||||
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/users/user1?$expand=appRoleAssignments", nil)
|
r := httptest.NewRequest(http.MethodGet, "/graph/v1.0/users/user1?$expand=appRoleAssignments", nil)
|
||||||
rctx := chi.NewRouteContext()
|
rctx := chi.NewRouteContext()
|
||||||
rctx.URLParams.Add("userID", user.GetId())
|
rctx.URLParams.Add("userID", user.GetId())
|
||||||
|
|||||||
@@ -274,7 +274,6 @@ func (g Service) RemoveSettingFromBundle(ctx context.Context, req *settingssvc.R
|
|||||||
// SaveValue implements the ValueServiceHandler interface
|
// SaveValue implements the ValueServiceHandler interface
|
||||||
func (g Service) SaveValue(ctx context.Context, req *settingssvc.SaveValueRequest, res *settingssvc.SaveValueResponse) error {
|
func (g Service) SaveValue(ctx context.Context, req *settingssvc.SaveValueRequest, res *settingssvc.SaveValueResponse) error {
|
||||||
req.Value.AccountUuid = getValidatedAccountUUID(ctx, req.Value.AccountUuid)
|
req.Value.AccountUuid = getValidatedAccountUUID(ctx, req.Value.AccountUuid)
|
||||||
|
|
||||||
if !g.isCurrentUser(ctx, req.Value.AccountUuid) {
|
if !g.isCurrentUser(ctx, req.Value.AccountUuid) {
|
||||||
return merrors.Forbidden(g.id, "can't save value for another user")
|
return merrors.Forbidden(g.id, "can't save value for another user")
|
||||||
}
|
}
|
||||||
|
|||||||
+1
@@ -134,6 +134,7 @@ Class | Method | HTTP request | Description
|
|||||||
*MeDriveRootChildrenApi* | [**HomeGetChildren**](docs/MeDriveRootChildrenApi.md#homegetchildren) | **Get** /v1.0/me/drive/root/children | Get children from drive
|
*MeDriveRootChildrenApi* | [**HomeGetChildren**](docs/MeDriveRootChildrenApi.md#homegetchildren) | **Get** /v1.0/me/drive/root/children | Get children from drive
|
||||||
*MeDrivesApi* | [**ListMyDrives**](docs/MeDrivesApi.md#listmydrives) | **Get** /v1.0/me/drives | Get all drives where the current user is a regular member of
|
*MeDrivesApi* | [**ListMyDrives**](docs/MeDrivesApi.md#listmydrives) | **Get** /v1.0/me/drives | Get all drives where the current user is a regular member of
|
||||||
*MeUserApi* | [**GetOwnUser**](docs/MeUserApi.md#getownuser) | **Get** /v1.0/me | Get current user
|
*MeUserApi* | [**GetOwnUser**](docs/MeUserApi.md#getownuser) | **Get** /v1.0/me | Get current user
|
||||||
|
*MeUserApi* | [**UpdateOwnUser**](docs/MeUserApi.md#updateownuser) | **Patch** /v1.0/me | Update the current user
|
||||||
*RoleManagementApi* | [**GetPermissionRoleDefinition**](docs/RoleManagementApi.md#getpermissionroledefinition) | **Get** /v1beta1/roleManagement/permissions/roleDefinitions/{role-id} | Get unifiedRoleDefinition
|
*RoleManagementApi* | [**GetPermissionRoleDefinition**](docs/RoleManagementApi.md#getpermissionroledefinition) | **Get** /v1beta1/roleManagement/permissions/roleDefinitions/{role-id} | Get unifiedRoleDefinition
|
||||||
*RoleManagementApi* | [**ListPermissionRoleDefinitions**](docs/RoleManagementApi.md#listpermissionroledefinitions) | **Get** /v1beta1/roleManagement/permissions/roleDefinitions | List roleDefinitions
|
*RoleManagementApi* | [**ListPermissionRoleDefinitions**](docs/RoleManagementApi.md#listpermissionroledefinitions) | **Get** /v1beta1/roleManagement/permissions/roleDefinitions | List roleDefinitions
|
||||||
*TagsApi* | [**AssignTags**](docs/TagsApi.md#assigntags) | **Put** /v1.0/extensions/org.libregraph/tags | Assign tags to a resource
|
*TagsApi* | [**AssignTags**](docs/TagsApi.md#assigntags) | **Put** /v1.0/extensions/org.libregraph/tags | Assign tags to a resource
|
||||||
|
|||||||
+114
@@ -135,3 +135,117 @@ func (a *MeUserApiService) GetOwnUserExecute(r ApiGetOwnUserRequest) (*User, *ht
|
|||||||
|
|
||||||
return localVarReturnValue, localVarHTTPResponse, nil
|
return localVarReturnValue, localVarHTTPResponse, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type ApiUpdateOwnUserRequest struct {
|
||||||
|
ctx context.Context
|
||||||
|
ApiService *MeUserApiService
|
||||||
|
user *User
|
||||||
|
}
|
||||||
|
|
||||||
|
// New user values
|
||||||
|
func (r ApiUpdateOwnUserRequest) User(user User) ApiUpdateOwnUserRequest {
|
||||||
|
r.user = &user
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r ApiUpdateOwnUserRequest) Execute() (*User, *http.Response, error) {
|
||||||
|
return r.ApiService.UpdateOwnUserExecute(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
UpdateOwnUser Update the current user
|
||||||
|
|
||||||
|
@param ctx context.Context - for authentication, logging, cancellation, deadlines, tracing, etc. Passed from http.Request or context.Background().
|
||||||
|
@return ApiUpdateOwnUserRequest
|
||||||
|
*/
|
||||||
|
func (a *MeUserApiService) UpdateOwnUser(ctx context.Context) ApiUpdateOwnUserRequest {
|
||||||
|
return ApiUpdateOwnUserRequest{
|
||||||
|
ApiService: a,
|
||||||
|
ctx: ctx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Execute executes the request
|
||||||
|
// @return User
|
||||||
|
func (a *MeUserApiService) UpdateOwnUserExecute(r ApiUpdateOwnUserRequest) (*User, *http.Response, error) {
|
||||||
|
var (
|
||||||
|
localVarHTTPMethod = http.MethodPatch
|
||||||
|
localVarPostBody interface{}
|
||||||
|
formFiles []formFile
|
||||||
|
localVarReturnValue *User
|
||||||
|
)
|
||||||
|
|
||||||
|
localBasePath, err := a.client.cfg.ServerURLWithContext(r.ctx, "MeUserApiService.UpdateOwnUser")
|
||||||
|
if err != nil {
|
||||||
|
return localVarReturnValue, nil, &GenericOpenAPIError{error: err.Error()}
|
||||||
|
}
|
||||||
|
|
||||||
|
localVarPath := localBasePath + "/v1.0/me"
|
||||||
|
|
||||||
|
localVarHeaderParams := make(map[string]string)
|
||||||
|
localVarQueryParams := url.Values{}
|
||||||
|
localVarFormParams := url.Values{}
|
||||||
|
|
||||||
|
// to determine the Content-Type header
|
||||||
|
localVarHTTPContentTypes := []string{"application/json"}
|
||||||
|
|
||||||
|
// set Content-Type header
|
||||||
|
localVarHTTPContentType := selectHeaderContentType(localVarHTTPContentTypes)
|
||||||
|
if localVarHTTPContentType != "" {
|
||||||
|
localVarHeaderParams["Content-Type"] = localVarHTTPContentType
|
||||||
|
}
|
||||||
|
|
||||||
|
// to determine the Accept header
|
||||||
|
localVarHTTPHeaderAccepts := []string{"application/json"}
|
||||||
|
|
||||||
|
// set Accept header
|
||||||
|
localVarHTTPHeaderAccept := selectHeaderAccept(localVarHTTPHeaderAccepts)
|
||||||
|
if localVarHTTPHeaderAccept != "" {
|
||||||
|
localVarHeaderParams["Accept"] = localVarHTTPHeaderAccept
|
||||||
|
}
|
||||||
|
// body params
|
||||||
|
localVarPostBody = r.user
|
||||||
|
req, err := a.client.prepareRequest(r.ctx, localVarPath, localVarHTTPMethod, localVarPostBody, localVarHeaderParams, localVarQueryParams, localVarFormParams, formFiles)
|
||||||
|
if err != nil {
|
||||||
|
return localVarReturnValue, nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
localVarHTTPResponse, err := a.client.callAPI(req)
|
||||||
|
if err != nil || localVarHTTPResponse == nil {
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, err
|
||||||
|
}
|
||||||
|
|
||||||
|
localVarBody, err := io.ReadAll(localVarHTTPResponse.Body)
|
||||||
|
localVarHTTPResponse.Body.Close()
|
||||||
|
localVarHTTPResponse.Body = io.NopCloser(bytes.NewBuffer(localVarBody))
|
||||||
|
if err != nil {
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if localVarHTTPResponse.StatusCode >= 300 {
|
||||||
|
newErr := &GenericOpenAPIError{
|
||||||
|
body: localVarBody,
|
||||||
|
error: localVarHTTPResponse.Status,
|
||||||
|
}
|
||||||
|
var v OdataError
|
||||||
|
err = a.client.decode(&v, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
newErr.error = err.Error()
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||||
|
}
|
||||||
|
newErr.error = formatErrorMessage(localVarHTTPResponse.Status, &v)
|
||||||
|
newErr.model = v
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||||
|
}
|
||||||
|
|
||||||
|
err = a.client.decode(&localVarReturnValue, localVarBody, localVarHTTPResponse.Header.Get("Content-Type"))
|
||||||
|
if err != nil {
|
||||||
|
newErr := &GenericOpenAPIError{
|
||||||
|
body: localVarBody,
|
||||||
|
error: err.Error(),
|
||||||
|
}
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, newErr
|
||||||
|
}
|
||||||
|
|
||||||
|
return localVarReturnValue, localVarHTTPResponse, nil
|
||||||
|
}
|
||||||
|
|||||||
+37
@@ -45,6 +45,8 @@ type User struct {
|
|||||||
GivenName *string `json:"givenName,omitempty"`
|
GivenName *string `json:"givenName,omitempty"`
|
||||||
// The user`s type. This can be either \"Member\" for regular user, or \"Guest\" for guest users.
|
// The user`s type. This can be either \"Member\" for regular user, or \"Guest\" for guest users.
|
||||||
UserType *string `json:"userType,omitempty"`
|
UserType *string `json:"userType,omitempty"`
|
||||||
|
// Represents the users language setting, ISO-639-1 Code
|
||||||
|
PreferredLanguage *string `json:"preferredLanguage,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewUser instantiates a new User object
|
// NewUser instantiates a new User object
|
||||||
@@ -512,6 +514,38 @@ func (o *User) SetUserType(v string) {
|
|||||||
o.UserType = &v
|
o.UserType = &v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GetPreferredLanguage returns the PreferredLanguage field value if set, zero value otherwise.
|
||||||
|
func (o *User) GetPreferredLanguage() string {
|
||||||
|
if o == nil || IsNil(o.PreferredLanguage) {
|
||||||
|
var ret string
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
return *o.PreferredLanguage
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetPreferredLanguageOk returns a tuple with the PreferredLanguage field value if set, nil otherwise
|
||||||
|
// and a boolean to check if the value has been set.
|
||||||
|
func (o *User) GetPreferredLanguageOk() (*string, bool) {
|
||||||
|
if o == nil || IsNil(o.PreferredLanguage) {
|
||||||
|
return nil, false
|
||||||
|
}
|
||||||
|
return o.PreferredLanguage, true
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasPreferredLanguage returns a boolean if a field has been set.
|
||||||
|
func (o *User) HasPreferredLanguage() bool {
|
||||||
|
if o != nil && !IsNil(o.PreferredLanguage) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetPreferredLanguage gets a reference to the given string and assigns it to the PreferredLanguage field.
|
||||||
|
func (o *User) SetPreferredLanguage(v string) {
|
||||||
|
o.PreferredLanguage = &v
|
||||||
|
}
|
||||||
|
|
||||||
func (o User) MarshalJSON() ([]byte, error) {
|
func (o User) MarshalJSON() ([]byte, error) {
|
||||||
toSerialize, err := o.ToMap()
|
toSerialize, err := o.ToMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -564,6 +598,9 @@ func (o User) ToMap() (map[string]interface{}, error) {
|
|||||||
if !IsNil(o.UserType) {
|
if !IsNil(o.UserType) {
|
||||||
toSerialize["userType"] = o.UserType
|
toSerialize["userType"] = o.UserType
|
||||||
}
|
}
|
||||||
|
if !IsNil(o.PreferredLanguage) {
|
||||||
|
toSerialize["preferredLanguage"] = o.PreferredLanguage
|
||||||
|
}
|
||||||
return toSerialize, nil
|
return toSerialize, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+1
-1
@@ -1555,7 +1555,7 @@ github.com/opentracing/opentracing-go/log
|
|||||||
# github.com/orcaman/concurrent-map v1.0.0
|
# github.com/orcaman/concurrent-map v1.0.0
|
||||||
## explicit
|
## explicit
|
||||||
github.com/orcaman/concurrent-map
|
github.com/orcaman/concurrent-map
|
||||||
# github.com/owncloud/libre-graph-api-go v1.0.5-0.20231107135330-011e9d4c45e3
|
# github.com/owncloud/libre-graph-api-go v1.0.5-0.20231113143725-09bf34dc9afb
|
||||||
## explicit; go 1.18
|
## explicit; go 1.18
|
||||||
github.com/owncloud/libre-graph-api-go
|
github.com/owncloud/libre-graph-api-go
|
||||||
# github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c
|
# github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c
|
||||||
|
|||||||
Reference in New Issue
Block a user