* WIP * adding initial creategroup endpoint * fetching by group source * fixing startup error * updating create endpoint to take an array of user_ids, this will allow us to create the group with one request * adding delete group endpoint and appropriate test * adding source param for getGroups * adding add members and delete members endpoints * locking down crud endpoints to only be allowed for custom groups * user search stuff * allowing remoteid be null by changing field to pointer * code cleanup and store level tests * adding new tests and removing unused endpoint * resolving conflicts * Adds authz check for group. * Adds authz checks to groups APIs. * Updated create group authz tests. * Updates delete group tests. * Tests create group. * Adds some tests and validations. * adding new parameter so I can get users not in a group * Fixed all lint warnings. * Fix type. * fixing search users not in group * Fixes some lint errors. * Moves entry in JSON array. * Fixed SQL query. * Fixes permission migration test. * Fixes migration test. * Fixes some group store tests. * Fix test. * Fix test. * Revert lint change. * Migrated CreateWithUserIds to sqlx. * Adds tests for GetMember; migrates implementation to sqlx. * Tests GetNonMemberUsersPage and hanles wrong group id. * Fixes test. * Switches GetMaster to GetMasterX. * Switches GetReplica to GetReplicaX. * Fixes logic. * Fixes shadow declaration. * Adds include_member_count to get group API endpoint. * Adds filter_has_member param to getGroups. * Fixes. * Removes array of group sources. * fixing error * Testing reverting CreateWithUserIds back to gorp. * Added websocket event for CreateGroupWithUserIds. * Changed a few response status codes. Switched to correct permission. * Added member count to ws payload for group when updating or creating. * Adds feature flag checks for custom groups. * Added middleware function to require license. Added config to disable custom groups. * Change for function signature change of executePossiblyEmptyQuery. * Lint fixes. * Adds telemetry none comment. * Adds translations. * Migrated to sqlx. * Temp. removal of translation. * Fixed typo. * Added an intermediary model to query with a field that is now ignored by sqlx on read queries. * Re-used existing store struct. * Inludes member count. * Fix for merge error.' * Require license for group endpoints. * Updates translations. * Fix shadow declaration. * Renames permissions. Switches to new method to retrieve remoteid. * Added WS events for upsert and delete member(s). * Added new store error type ErrUniqueConstraint. * Added EnableCustonGroups to the client config. * Sanitized some user records. * Added parameter to include_total_count for listing groups. * Added translations. * adding deleteAt field to getByUsers query * Revert sanitize. * Added uniqueness constraint error to UpdateGroup. * Removed the FutureFeatures flag so that the feature is not enabled on old Enterprise licenses. * Renamed function. * Updates authz check for user search related to groups. * Removed debug statement. * Removed unused app method. * Added telemetry for enable_custom_groups. * Returns early from nil license. * Updates test. * Returned early to avoid nesting in (*SqlGroupStore).checkUserExist. Switched to reading from replica in (*SqlGroupStore).GetMember. Handled JSON marshal error in (*Client4).UpsertGroupMembers * Switched to SanitizeProfile. * Switched to model.NewInt. * Switched from status NotImplemented to Forbidden for missing license. * Removed deactivated users from 'exists' set. * Revert gotool update. * Ignored lint error that I think is invalid. * Added the approprate access tag for disabling custom groups. * Revert change to response status. * Fixed refactor mistake. * Limited the group member WS events to individual users. * Removed WS event of deleted groups. * Updated license check for searchUsers endpoint. * Switched from license feature to license sku. * Update app/group.go Co-authored-by: Claudio Costa <cstcld91@gmail.com> * Update app/group.go Co-authored-by: Claudio Costa <cstcld91@gmail.com> * Remove linter ignore comment. * Added function to create sku-specific license. * Fixed typo. Removed comment. * Fixed for wrong type. * Added missing param to client. Removed unnecessary props setting. Added test for retrieving groups by source. * Updated some tests now that we're validating group membership not created for deactivated user. * Fix for groups endpoint returning all group types by default. * Changes constant names. Adds migration for all users to manage custom group members. * Removes requirement for manage_system permission to filter user search by group. * Added migration mock. * Removes default permissions from custom_group_user role. * Fixes migration. * Fixes emoji migration test. * fixing issue with member counts * fixing search issue for deleted members Co-authored-by: Benjamin Cooke <benjamincooke@Benjamins-MacBook-Pro.local> Co-authored-by: Benjamin Cooke <benjamincooke@Benjamins-MBP.ht.home> Co-authored-by: Mattermod <mattermod@users.noreply.github.com> Co-authored-by: Benjamin Cooke <benjamincooke@Benjamins-MacBook-Pro.fritz.box> Co-authored-by: Claudio Costa <cstcld91@gmail.com>
212 строки
6.3 KiB
Go
212 строки
6.3 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
package api4
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/mattermost/gziphandler"
|
|
|
|
"github.com/mattermost/mattermost-server/v6/model"
|
|
"github.com/mattermost/mattermost-server/v6/web"
|
|
)
|
|
|
|
type Context = web.Context
|
|
|
|
type handlerFunc func(*Context, http.ResponseWriter, *http.Request)
|
|
|
|
// APIHandler provides a handler for API endpoints which do not require the user to be logged in order for access to be
|
|
// granted.
|
|
func (api *API) APIHandler(h handlerFunc) http.Handler {
|
|
handler := &web.Handler{
|
|
Srv: api.srv,
|
|
HandleFunc: h,
|
|
HandlerName: web.GetHandlerName(h),
|
|
RequireSession: false,
|
|
TrustRequester: false,
|
|
RequireMfa: false,
|
|
IsStatic: false,
|
|
IsLocal: false,
|
|
}
|
|
if *api.srv.Config().ServiceSettings.WebserverMode == "gzip" {
|
|
return gziphandler.GzipHandler(handler)
|
|
}
|
|
return handler
|
|
}
|
|
|
|
// APISessionRequired provides a handler for API endpoints which require the user to be logged in in order for access to
|
|
// be granted.
|
|
func (api *API) APISessionRequired(h handlerFunc) http.Handler {
|
|
handler := &web.Handler{
|
|
Srv: api.srv,
|
|
HandleFunc: h,
|
|
HandlerName: web.GetHandlerName(h),
|
|
RequireSession: true,
|
|
TrustRequester: false,
|
|
RequireMfa: true,
|
|
IsStatic: false,
|
|
IsLocal: false,
|
|
}
|
|
if *api.srv.Config().ServiceSettings.WebserverMode == "gzip" {
|
|
return gziphandler.GzipHandler(handler)
|
|
}
|
|
return handler
|
|
|
|
}
|
|
|
|
// CloudAPIKeyRequired provides a handler for webhook endpoints to access Cloud installations from CWS
|
|
func (api *API) CloudAPIKeyRequired(h handlerFunc) http.Handler {
|
|
handler := &web.Handler{
|
|
Srv: api.srv,
|
|
HandleFunc: h,
|
|
HandlerName: web.GetHandlerName(h),
|
|
RequireSession: false,
|
|
RequireCloudKey: true,
|
|
TrustRequester: false,
|
|
RequireMfa: false,
|
|
IsStatic: false,
|
|
IsLocal: false,
|
|
}
|
|
if *api.srv.Config().ServiceSettings.WebserverMode == "gzip" {
|
|
return gziphandler.GzipHandler(handler)
|
|
}
|
|
return handler
|
|
|
|
}
|
|
|
|
// RemoteClusterTokenRequired provides a handler for remote cluster requests to /remotecluster endpoints.
|
|
func (api *API) RemoteClusterTokenRequired(h handlerFunc) http.Handler {
|
|
handler := &web.Handler{
|
|
Srv: api.srv,
|
|
HandleFunc: h,
|
|
HandlerName: web.GetHandlerName(h),
|
|
RequireSession: false,
|
|
RequireCloudKey: false,
|
|
RequireRemoteClusterToken: true,
|
|
TrustRequester: false,
|
|
RequireMfa: false,
|
|
IsStatic: false,
|
|
IsLocal: false,
|
|
}
|
|
if *api.srv.Config().ServiceSettings.WebserverMode == "gzip" {
|
|
return gziphandler.GzipHandler(handler)
|
|
}
|
|
return handler
|
|
}
|
|
|
|
// APISessionRequiredMfa provides a handler for API endpoints which require a logged-in user session but when accessed,
|
|
// if MFA is enabled, the MFA process is not yet complete, and therefore the requirement to have completed the MFA
|
|
// authentication must be waived.
|
|
func (api *API) APISessionRequiredMfa(h handlerFunc) http.Handler {
|
|
handler := &web.Handler{
|
|
Srv: api.srv,
|
|
HandleFunc: h,
|
|
HandlerName: web.GetHandlerName(h),
|
|
RequireSession: true,
|
|
TrustRequester: false,
|
|
RequireMfa: false,
|
|
IsStatic: false,
|
|
IsLocal: false,
|
|
}
|
|
if *api.srv.Config().ServiceSettings.WebserverMode == "gzip" {
|
|
return gziphandler.GzipHandler(handler)
|
|
}
|
|
return handler
|
|
|
|
}
|
|
|
|
// APIHandlerTrustRequester provides a handler for API endpoints which do not require the user to be logged in and are
|
|
// allowed to be requested directly rather than via javascript/XMLHttpRequest, such as site branding images or the
|
|
// websocket.
|
|
func (api *API) APIHandlerTrustRequester(h handlerFunc) http.Handler {
|
|
handler := &web.Handler{
|
|
Srv: api.srv,
|
|
HandleFunc: h,
|
|
HandlerName: web.GetHandlerName(h),
|
|
RequireSession: false,
|
|
TrustRequester: true,
|
|
RequireMfa: false,
|
|
IsStatic: false,
|
|
IsLocal: false,
|
|
}
|
|
if *api.srv.Config().ServiceSettings.WebserverMode == "gzip" {
|
|
return gziphandler.GzipHandler(handler)
|
|
}
|
|
return handler
|
|
|
|
}
|
|
|
|
// APISessionRequiredTrustRequester provides a handler for API endpoints which do require the user to be logged in and
|
|
// are allowed to be requested directly rather than via javascript/XMLHttpRequest, such as emoji or file uploads.
|
|
func (api *API) APISessionRequiredTrustRequester(h handlerFunc) http.Handler {
|
|
handler := &web.Handler{
|
|
Srv: api.srv,
|
|
HandleFunc: h,
|
|
HandlerName: web.GetHandlerName(h),
|
|
RequireSession: true,
|
|
TrustRequester: true,
|
|
RequireMfa: true,
|
|
IsStatic: false,
|
|
IsLocal: false,
|
|
}
|
|
if *api.srv.Config().ServiceSettings.WebserverMode == "gzip" {
|
|
return gziphandler.GzipHandler(handler)
|
|
}
|
|
return handler
|
|
|
|
}
|
|
|
|
// DisableWhenBusy provides a handler for API endpoints which should be disabled when the server is under load,
|
|
// responding with HTTP 503 (Service Unavailable).
|
|
func (api *API) APISessionRequiredDisableWhenBusy(h handlerFunc) http.Handler {
|
|
handler := &web.Handler{
|
|
Srv: api.srv,
|
|
HandleFunc: h,
|
|
HandlerName: web.GetHandlerName(h),
|
|
RequireSession: true,
|
|
TrustRequester: false,
|
|
RequireMfa: false,
|
|
IsStatic: false,
|
|
IsLocal: false,
|
|
DisableWhenBusy: true,
|
|
}
|
|
if *api.srv.Config().ServiceSettings.WebserverMode == "gzip" {
|
|
return gziphandler.GzipHandler(handler)
|
|
}
|
|
return handler
|
|
|
|
}
|
|
|
|
// APILocal provides a handler for API endpoints to be used in local
|
|
// mode, this is, through a UNIX socket and without an authenticated
|
|
// session, but with one that has no user set and no permission
|
|
// restrictions
|
|
func (api *API) APILocal(h handlerFunc) http.Handler {
|
|
handler := &web.Handler{
|
|
Srv: api.srv,
|
|
HandleFunc: h,
|
|
HandlerName: web.GetHandlerName(h),
|
|
RequireSession: false,
|
|
TrustRequester: false,
|
|
RequireMfa: false,
|
|
IsStatic: false,
|
|
IsLocal: true,
|
|
}
|
|
|
|
if *api.srv.Config().ServiceSettings.WebserverMode == "gzip" {
|
|
return gziphandler.GzipHandler(handler)
|
|
}
|
|
return handler
|
|
}
|
|
|
|
func requireLicense(f handlerFunc) handlerFunc {
|
|
return func(c *Context, w http.ResponseWriter, r *http.Request) {
|
|
if c.App.Srv().License() == nil {
|
|
c.Err = model.NewAppError("", "api.license_error", nil, "", http.StatusNotImplemented)
|
|
return
|
|
}
|
|
f(c, w, r)
|
|
}
|
|
}
|