diff --git a/services/graph/pkg/service/v0/service.go b/services/graph/pkg/service/v0/service.go index f2566e30dd..ae0f0433f5 100644 --- a/services/graph/pkg/service/v0/service.go +++ b/services/graph/pkg/service/v0/service.go @@ -247,7 +247,7 @@ func NewService(opts ...Option) (Graph, error) { r.Post("/changePassword", svc.ChangeOwnPassword) }) r.Route("/users", func(r chi.Router) { - r.With(requireAdmin).Get("/", svc.GetUsers) + r.Get("/", svc.GetUsers) r.With(requireAdmin).Post("/", svc.PostUser) r.Route("/{userID}", func(r chi.Router) { r.Get("/", svc.GetUser) diff --git a/services/graph/pkg/service/v0/users.go b/services/graph/pkg/service/v0/users.go index 04e4a2c23e..cb6d7bbca5 100644 --- a/services/graph/pkg/service/v0/users.go +++ b/services/graph/pkg/service/v0/users.go @@ -195,6 +195,21 @@ func (g Graph) GetUserDrive(w http.ResponseWriter, r *http.Request) { } } +func (g Graph) contextUserHasFullAccountPerms(reqctx context.Context) bool { + // mostly copied from the canCreateSpace method + pr, err := g.permissionsService.GetPermissionByID(reqctx, &settingssvc.GetPermissionByIDRequest{ + PermissionId: defaults.AccountManagementPermission(0).Id, + }) + if err != nil || pr.Permission == nil { + return false + } + + if pr.Permission.Constraint != defaults.All { + return false + } + return true +} + // GetUsers implements the Service interface. func (g Graph) GetUsers(w http.ResponseWriter, r *http.Request) { logger := g.logger.SubloggerWithRequestID(r.Context()) @@ -207,6 +222,21 @@ func (g Graph) GetUsers(w http.ResponseWriter, r *http.Request) { return } + ctxHasFullPerms := g.contextUserHasFullAccountPerms(r.Context()) + if !ctxHasFullPerms && (odataReq.Query == nil || odataReq.Query.Search == nil || len(odataReq.Query.Search.RawValue) < 3) { + // regular user must search with at least 3 chars + logger.Debug().Interface("query", r.URL.Query()).Msg("search with less than 3 chars for a regular user") + errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "regular users must enter at least 3 characters to search") + return + } + + if !ctxHasFullPerms && (odataReq.Query.Filter != nil || odataReq.Query.Apply != nil || odataReq.Query.Expand != nil || odataReq.Query.Compute != nil) { + // regular users can't use filter, apply, expand and compute + logger.Debug().Interface("query", r.URL.Query()).Msg("forbidden query elements for a regular user") + errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "query has forbidden elements for regular users") + return + } + logger.Debug().Interface("query", r.URL.Query()).Msg("calling get users on backend") var users []*libregraph.User @@ -232,6 +262,15 @@ func (g Graph) GetUsers(w http.ResponseWriter, r *http.Request) { return } + // If the user isn't admin, we'll show just the minimum user attibutes + if !ctxHasFullPerms { + finalUsers := make([]*libregraph.User, len(users)) + for i, u := range users { + finalUsers[i] = &libregraph.User{Id: u.Id, DisplayName: u.DisplayName, Mail: u.Mail} + } + users = finalUsers + } + exp, err := identity.GetExpandValues(odataReq.Query) if err != nil { logger.Debug().Err(err).Interface("query", r.URL.Query()).Msg("could not get users: $expand error")