Merge branch 'master' of github.com:mattermost/mattermost-server into MM-47853-true-up-review-telemetry-off-non-air-gapped

Этот коммит содержится в:
Conor Macpherson
2022-12-19 15:40:03 -05:00
родитель 96ed60a472 79193240e9
Коммит 12328278f8
100 изменённых файлов: 3145 добавлений и 493 удалений

Просмотреть файл

@@ -80,7 +80,6 @@ func getSubscription(c *Context, w http.ResponseWriter, r *http.Request) {
Seats: 0,
Status: "",
DNS: "",
IsPaidTier: "",
LastInvoice: &model.Invoice{},
DelinquentSince: subscription.DelinquentSince,
}

Просмотреть файл

@@ -124,7 +124,6 @@ func Test_GetSubscription(t *testing.T) {
Seats: 10,
IsFreeTrial: "true",
DNS: "some.dns.server",
IsPaidTier: "false",
TrialEndAt: 2000000000,
LastInvoice: &model.Invoice{},
DelinquentSince: &deliquencySince,
@@ -141,7 +140,6 @@ func Test_GetSubscription(t *testing.T) {
Seats: 0,
IsFreeTrial: "true",
DNS: "",
IsPaidTier: "",
TrialEndAt: 2000000000,
LastInvoice: &model.Invoice{},
DelinquentSince: &deliquencySince,
@@ -209,7 +207,6 @@ func Test_requestTrial(t *testing.T) {
CreateAt: 1000000000,
Seats: 10,
DNS: "some.dns.server",
IsPaidTier: "false",
}
newValidBusinessEmail := model.StartCloudTrialRequest{Email: ""}

Просмотреть файл

@@ -1185,8 +1185,8 @@ func restoreGroup(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if !c.App.SessionHasPermissionToGroup(*c.AppContext.Session(), c.Params.GroupId, model.PermissionDeleteCustomGroup) {
c.SetPermissionError(model.PermissionDeleteCustomGroup)
if !c.App.SessionHasPermissionToGroup(*c.AppContext.Session(), c.Params.GroupId, model.PermissionRestoreCustomGroup) {
c.SetPermissionError(model.PermissionRestoreCustomGroup)
return
}

Просмотреть файл

@@ -231,7 +231,13 @@ func TestUndeleteGroup(t *testing.T) {
_, response, err := th.Client.DeleteGroup(validGroup.Id)
require.NoError(t, err)
CheckOKStatus(t, response)
th.RemovePermissionFromRole(model.PermissionRestoreCustomGroup.Id, model.SystemUserRoleId)
// shouldn't allow restoring unless user has required permission
_, response, err = th.Client.RestoreGroup(validGroup.Id, "")
require.Error(t, err)
CheckForbiddenStatus(t, response)
th.AddPermissionToRole(model.PermissionRestoreCustomGroup.Id, model.SystemUserRoleId)
_, response, err = th.Client.RestoreGroup(validGroup.Id, "")
require.NoError(t, err)
CheckOKStatus(t, response)

Просмотреть файл

@@ -4,18 +4,35 @@
package api4
import (
"bytes"
"encoding/binary"
"encoding/json"
"fmt"
"io"
"net/http"
"reflect"
"time"
"github.com/mattermost/mattermost-server/v6/model"
"github.com/mattermost/mattermost-server/v6/shared/mlog"
"github.com/mattermost/mattermost-server/v6/utils"
)
// APIs for self-hosted workspaces to communicate with the backing customer & payments system.
// Endpoints for cloud installations should not go in this file.
func (api *API) InitHostedCustomer() {
// POST /api/v4/hosted_customer/available
api.BaseRoutes.HostedCustomer.Handle("/signup_available", api.APISessionRequired(handleSignupAvailable)).Methods("GET")
// POST /api/v4/hosted_customer/bootstrap
api.BaseRoutes.HostedCustomer.Handle("/bootstrap", api.APISessionRequired(selfHostedBootstrap)).Methods("POST")
// POST /api/v4/hosted_customer/customer
api.BaseRoutes.HostedCustomer.Handle("/customer", api.APISessionRequired(selfHostedCustomer)).Methods("POST")
// POST /api/v4/hosted_customer/confirm
api.BaseRoutes.HostedCustomer.Handle("/confirm", api.APISessionRequired(selfHostedConfirm)).Methods("POST")
// GET /api/v4/hosted_customer/invoices
api.BaseRoutes.HostedCustomer.Handle("/invoices", api.APISessionRequired(selfHostedInvoices)).Methods("GET")
// GET /api/v4/hosted_customer/invoices/{invoice_id:in_[A-Za-z0-9]+}/pdf
api.BaseRoutes.HostedCustomer.Handle("/invoices/{invoice_id:in_[A-Za-z0-9]+}/pdf", api.APISessionRequired(selfHostedInvoicePDF)).Methods("GET")
}
func ensureSelfHostedAdmin(c *Context, where string) {
@@ -32,21 +49,22 @@ func ensureSelfHostedAdmin(c *Context, where string) {
}
}
func checkSelfHostedFirstTimePurchaseEnabled(c *Context) bool {
func checkSelfHostedPurchaseEnabled(c *Context) bool {
config := c.App.Config()
if config == nil {
return false
}
enabled := config.ServiceSettings.SelfHostedFirstTimePurchase
enabled := config.ServiceSettings.SelfHostedPurchase
return enabled != nil && *enabled
}
func selfHostedBootstrap(c *Context, w http.ResponseWriter, r *http.Request) {
where := "Api4.selfHostedBootstrap"
if !checkSelfHostedFirstTimePurchaseEnabled(c) {
const where = "Api4.selfHostedBootstrap"
if !checkSelfHostedPurchaseEnabled(c) {
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusNotImplemented)
return
}
reset := r.URL.Query().Get("reset") == "true"
ensureSelfHostedAdmin(c, where)
if c.Err != nil {
return
@@ -58,7 +76,7 @@ func selfHostedBootstrap(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
signupProgress, err := c.App.Cloud().BootstrapSelfHostedSignup(model.BootstrapSelfHostedSignupRequest{Email: user.Email})
signupProgress, err := c.App.Cloud().BootstrapSelfHostedSignup(model.BootstrapSelfHostedSignupRequest{Email: user.Email, Reset: reset})
if err != nil {
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusInternalServerError)
return
@@ -71,3 +89,186 @@ func selfHostedBootstrap(c *Context, w http.ResponseWriter, r *http.Request) {
w.Write(json)
}
func selfHostedCustomer(c *Context, w http.ResponseWriter, r *http.Request) {
const where = "Api4.selfHostedCustomer"
ensureSelfHostedAdmin(c, where)
if c.Err != nil {
return
}
if !checkSelfHostedPurchaseEnabled(c) {
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusNotImplemented)
return
}
bodyBytes, err := io.ReadAll(r.Body)
if err != nil {
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusBadRequest).Wrap(err)
return
}
var form *model.SelfHostedCustomerForm
if err = json.Unmarshal(bodyBytes, &form); err != nil {
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusBadRequest).Wrap(err)
return
}
user, userErr := c.App.GetUser(c.AppContext.Session().UserId)
if userErr != nil {
c.Err = userErr
return
}
customerResponse, err := c.App.Cloud().CreateCustomerSelfHostedSignup(*form, user.Email)
if err != nil {
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
return
}
json, err := json.Marshal(customerResponse)
if err != nil {
c.Err = model.NewAppError(where, "api.cloud.request_error", nil, "", http.StatusInternalServerError).Wrap(err)
return
}
w.Write(json)
}
func selfHostedConfirm(c *Context, w http.ResponseWriter, r *http.Request) {
const where = "Api4.selfHostedConfirm"
ensureSelfHostedAdmin(c, where)
if c.Err != nil {
return
}
if !checkSelfHostedPurchaseEnabled(c) {
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusNotImplemented)
return
}
bodyBytes, err := io.ReadAll(r.Body)
if err != nil {
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusBadRequest).Wrap(err)
return
}
var confirm model.SelfHostedConfirmPaymentMethodRequest
err = json.Unmarshal(bodyBytes, &confirm)
if err != nil {
c.Err = model.NewAppError(where, "api.cloud.request_error", nil, "", http.StatusBadRequest).Wrap(err)
return
}
user, userErr := c.App.GetUser(c.AppContext.Session().UserId)
if userErr != nil {
c.Err = userErr
return
}
confirmResponse, err := c.App.Cloud().ConfirmSelfHostedSignup(confirm, user.Email)
if err != nil {
if confirmResponse != nil {
c.App.NotifySelfHostedSignupProgress(confirmResponse.Progress, user.Id)
}
if err.Error() == fmt.Sprintf("%d", http.StatusUnprocessableEntity) {
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusUnprocessableEntity).Wrap(err)
return
}
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
return
}
license, err := c.App.Srv().Platform().SaveLicense([]byte(confirmResponse.License))
// dealing with an AppError
if !(reflect.ValueOf(err).Kind() == reflect.Ptr && reflect.ValueOf(err).IsNil()) {
if confirmResponse != nil {
c.App.NotifySelfHostedSignupProgress(confirmResponse.Progress, user.Id)
}
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
return
}
clientResponse, err := json.Marshal(model.SelfHostedSignupConfirmClientResponse{
License: utils.GetClientLicense(license),
Progress: confirmResponse.Progress,
})
if err != nil {
if confirmResponse != nil {
c.App.NotifySelfHostedSignupProgress(confirmResponse.Progress, user.Id)
}
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
return
}
go func() {
err := c.App.Cloud().ConfirmSelfHostedSignupLicenseApplication()
if err != nil {
c.Logger.Warn("Unable to confirm license application", mlog.Err(err))
}
}()
_, _ = w.Write(clientResponse)
}
func handleSignupAvailable(c *Context, w http.ResponseWriter, r *http.Request) {
const where = "Api4.handleSignupAvailable"
ensureSelfHostedAdmin(c, where)
if c.Err != nil {
return
}
if !checkSelfHostedPurchaseEnabled(c) {
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusNotImplemented)
return
}
if err := c.App.Cloud().SelfHostedSignupAvailable(); err != nil {
c.Err = model.NewAppError(where, "api.server.hosted_signup_unavailable.error", nil, "", http.StatusNotImplemented)
return
}
ReturnStatusOK(w)
}
func selfHostedInvoices(c *Context, w http.ResponseWriter, r *http.Request) {
const where = "Api4.selfHostedInvoices"
ensureSelfHostedAdmin(c, where)
if c.Err != nil {
return
}
invoices, err := c.App.Cloud().GetSelfHostedInvoices()
if err != nil {
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
return
}
json, err := json.Marshal(invoices)
if err != nil {
c.Err = model.NewAppError(where, "api.cloud.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
return
}
w.Write(json)
}
func selfHostedInvoicePDF(c *Context, w http.ResponseWriter, r *http.Request) {
const where = "Api4.selfHostedInvoicePDF"
ensureSelfHostedAdmin(c, where)
if c.Err != nil {
return
}
pdfData, filename, appErr := c.App.Cloud().GetSelfHostedInvoicePDF(c.Params.InvoiceId)
if appErr != nil {
c.Err = model.NewAppError("Api4.getSubscriptionInvoicePDF", "api.cloud.request_error", nil, appErr.Error(), http.StatusInternalServerError)
return
}
writeFileResponse(
filename,
"application/pdf",
int64(binary.Size(pdfData)),
time.Now(),
*c.App.Config().ServiceSettings.WebserverMode,
bytes.NewReader(pdfData),
false,
w,
r,
)
}

Просмотреть файл

@@ -27,7 +27,7 @@ func TestSelfHostedBootstrap(t *testing.T) {
os.Setenv("MM_SERVICESETTINGS_SELFHOSTEDFIRSTTIMEPURCHASE", "false")
defer os.Unsetenv("MM_SERVICESETTINGS_SELFHOSTEDFIRSTTIMEPURCHASE")
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.SelfHostedFirstTimePurchase = &valFalse })
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.SelfHostedPurchase = &valFalse })
th.App.ReloadConfig()
_, r, err := th.Client.BootstrapSelfHostedSignup(model.BootstrapSelfHostedSignupRequest{Email: th.SystemAdminUser.Email})
@@ -45,7 +45,7 @@ func TestSelfHostedBootstrap(t *testing.T) {
th.App.Srv().SetLicense(model.NewTestLicense("cloud"))
os.Setenv("MM_SERVICESETTINGS_SELFHOSTEDFIRSTTIMEPURCHASE", "true")
defer os.Unsetenv("MM_SERVICESETTINGS_SELFHOSTEDFIRSTTIMEPURCHASE")
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.SelfHostedFirstTimePurchase = &valTrue })
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.SelfHostedPurchase = &valTrue })
th.App.ReloadConfig()
_, r, err := th.Client.BootstrapSelfHostedSignup(model.BootstrapSelfHostedSignupRequest{Email: th.SystemAdminUser.Email})
@@ -62,7 +62,7 @@ func TestSelfHostedBootstrap(t *testing.T) {
os.Setenv("MM_SERVICESETTINGS_SELFHOSTEDFIRSTTIMEPURCHASE", "true")
defer os.Unsetenv("MM_SERVICESETTINGS_SELFHOSTEDFIRSTTIMEPURCHASE")
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.SelfHostedFirstTimePurchase = &valTrue })
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.SelfHostedPurchase = &valTrue })
th.App.ReloadConfig()
_, r, err := th.Client.BootstrapSelfHostedSignup(model.BootstrapSelfHostedSignupRequest{Email: th.SystemAdminUser.Email})
@@ -79,7 +79,7 @@ func TestSelfHostedBootstrap(t *testing.T) {
os.Setenv("MM_SERVICESETTINGS_SELFHOSTEDFIRSTTIMEPURCHASE", "true")
defer os.Unsetenv("MM_SERVICESETTINGS_SELFHOSTEDFIRSTTIMEPURCHASE")
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.SelfHostedFirstTimePurchase = &valTrue })
th.App.UpdateConfig(func(cfg *model.Config) { cfg.ServiceSettings.SelfHostedPurchase = &valTrue })
th.App.ReloadConfig()
cloud := mocks.CloudInterface{}

Просмотреть файл

@@ -802,7 +802,8 @@ func patchPost(c *Context, w http.ResponseWriter, r *http.Request) {
}
auditRec := c.MakeAuditRecord("patchPost", audit.Fail)
auditRec.AddEventParameter("patch", post)
auditRec.AddEventParameter("id", c.Params.PostId)
auditRec.AddEventParameter("patch", post.Auditable())
defer c.LogAuditRecWithLevel(auditRec, app.LevelContent)
// Updating the file_ids of a post is not a supported operation and will be ignored

Просмотреть файл

@@ -9,6 +9,7 @@ import (
"net/http"
"time"
"github.com/mattermost/mattermost-server/v6/app"
"github.com/mattermost/mattermost-server/v6/audit"
"github.com/mattermost/mattermost-server/v6/model"
"github.com/mattermost/mattermost-server/v6/services/remotecluster"
@@ -194,7 +195,8 @@ func uploadRemoteData(c *Context, w http.ResponseWriter, r *http.Request) {
defer c.LogAuditRec(auditRec)
auditRec.AddEventParameter("upload_id", c.Params.UploadId)
us, err := c.App.GetUploadSession(c.Params.UploadId)
c.AppContext.SetContext(app.WithMaster(c.AppContext.Context()))
us, err := c.App.GetUploadSession(c.AppContext, c.Params.UploadId)
if err != nil {
c.Err = err
return

Просмотреть файл

@@ -10,6 +10,7 @@ import (
"mime/multipart"
"net/http"
"github.com/mattermost/mattermost-server/v6/app"
"github.com/mattermost/mattermost-server/v6/audit"
"github.com/mattermost/mattermost-server/v6/model"
"github.com/mattermost/mattermost-server/v6/shared/mlog"
@@ -91,7 +92,7 @@ func getUpload(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
us, err := c.App.GetUploadSession(c.Params.UploadId)
us, err := c.App.GetUploadSession(c.AppContext, c.Params.UploadId)
if err != nil {
c.Err = err
return
@@ -123,7 +124,8 @@ func uploadData(c *Context, w http.ResponseWriter, r *http.Request) {
defer c.LogAuditRec(auditRec)
auditRec.AddEventParameter("upload_id", c.Params.UploadId)
us, err := c.App.GetUploadSession(c.Params.UploadId)
c.AppContext.SetContext(app.WithMaster(c.AppContext.Context()))
us, err := c.App.GetUploadSession(c.AppContext, c.Params.UploadId)
if err != nil {
c.Err = err
return

Просмотреть файл

@@ -662,13 +662,14 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
if sort != "" && sort != "last_activity_at" && sort != "create_at" && sort != "status" && sort != "admin" {
if sort != "" && sort != "last_activity_at" && sort != "create_at" && sort != "status" && sort != "admin" && sort != "display_name" {
c.SetInvalidURLParam("sort")
return
}
// Currently only supports sorting on a team
// or sort="status" on inChannelId
// or sort="display_name" on inGroupId
if (sort == "last_activity_at" || sort == "create_at") && (inTeamId == "" || notInTeamId != "" || inChannelId != "" || notInChannelId != "" || withoutTeam != "" || inGroupId != "" || notInGroupId != "") {
c.SetInvalidURLParam("sort")
return
@@ -681,6 +682,10 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
c.SetInvalidURLParam("sort")
return
}
if sort == "display_name" && (inGroupId == "" || notInGroupId != "" || inTeamId != "" || notInTeamId != "" || inChannelId != "" || notInChannelId != "" || withoutTeam != "") {
c.SetInvalidURLParam("sort")
return
}
var (
withoutTeamBool, _ = strconv.ParseBool(withoutTeam)
@@ -693,14 +698,44 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
c.SetInvalidURLParam("inactive")
}
roleNamesAll := []string{}
// MM-47378: validate 'role' related parameters
if role != "" || rolesString != "" || channelRolesString != "" || teamRolesString != "" {
// fetch all role names
rolesAll, err := c.App.GetAllRoles()
if err != nil {
c.Err = model.NewAppError("Api4.getUsers", "api.user.get_users.validation.app_error", nil, "Error fetching roles during validation.", http.StatusBadRequest)
return
}
for _, role := range rolesAll {
roleNamesAll = append(roleNamesAll, role.Name)
}
}
roles := []string{}
var rolesValid bool
if role != "" {
roles, rolesValid = model.CleanRoleNames([]string{role})
if !rolesValid {
c.SetInvalidParam("role")
return
}
roleValid := utils.StringInSlice(role, roleNamesAll)
if !roleValid {
c.SetInvalidParam("role")
return
}
}
if rolesString != "" {
roles, rolesValid = model.CleanRoleNames(strings.Split(rolesString, ","))
if !rolesValid {
c.SetInvalidParam("roles")
return
}
validRoleNames := utils.StringArrayIntersection(roleNamesAll, roles)
if len(validRoleNames) != len(roles) {
c.SetInvalidParam("roles")
return
}
}
channelRoles := []string{}
if channelRolesString != "" && inChannelId != "" {
@@ -709,6 +744,11 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
c.SetInvalidParam("channelRoles")
return
}
validRoleNames := utils.StringArrayIntersection(roleNamesAll, channelRoles)
if len(validRoleNames) != len(channelRoles) {
c.SetInvalidParam("channelRoles")
return
}
}
teamRoles := []string{}
if teamRolesString != "" && inTeamId != "" {
@@ -717,6 +757,11 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
c.SetInvalidParam("teamRoles")
return
}
validRoleNames := utils.StringArrayIntersection(roleNamesAll, teamRoles)
if len(validRoleNames) != len(teamRoles) {
c.SetInvalidParam("teamRoles")
return
}
}
restrictions, appErr := c.App.GetViewUsersRestrictions(c.AppContext.Session().UserId)
@@ -829,10 +874,18 @@ func getUsers(c *Context, w http.ResponseWriter, r *http.Request) {
return
}
profiles, _, appErr = c.App.GetGroupMemberUsersPage(inGroupId, c.Params.Page, c.Params.PerPage, userGetOptions.ViewRestrictions)
if appErr != nil {
c.Err = appErr
return
if sort == "display_name" {
var user *model.User
user, appErr = c.App.GetUser(c.AppContext.Session().UserId)
if appErr != nil {
c.Err = appErr
return
}
profiles, _, appErr = c.App.GetGroupMemberUsersSortedPage(inGroupId, c.Params.Page, c.Params.PerPage, userGetOptions.ViewRestrictions, c.App.GetNotificationNameFormat(user))
} else {
profiles, _, appErr = c.App.GetGroupMemberUsersPage(inGroupId, c.Params.Page, c.Params.PerPage, userGetOptions.ViewRestrictions)
}
} else if notInGroupId != "" {
appErr = requireGroupAccess(c, notInGroupId)

Просмотреть файл

@@ -7,11 +7,13 @@ import (
"encoding/json"
"net/http"
"strconv"
"strings"
"github.com/mattermost/mattermost-server/v6/audit"
"github.com/mattermost/mattermost-server/v6/model"
"github.com/mattermost/mattermost-server/v6/shared/mlog"
"github.com/mattermost/mattermost-server/v6/store"
"github.com/mattermost/mattermost-server/v6/utils"
)
func (api *API) InitUserLocal() {
@@ -56,7 +58,78 @@ func localGetUsers(c *Context, w http.ResponseWriter, r *http.Request) {
active := r.URL.Query().Get("active")
inactive := r.URL.Query().Get("inactive")
role := r.URL.Query().Get("role")
rolesString := r.URL.Query().Get("roles")
channelRolesString := r.URL.Query().Get("channel_roles")
teamRolesString := r.URL.Query().Get("team_roles")
sort := r.URL.Query().Get("sort")
roleNamesAll := []string{}
// MM-47378: validate 'role' related parameters
if role != "" || rolesString != "" || channelRolesString != "" || teamRolesString != "" {
// fetch all role names
rolesAll, err := c.App.GetAllRoles()
if err != nil {
c.Err = model.NewAppError("Api4.getUsers", "api.user.get_users.validation.app_error", nil, "Error fetching roles during validation.", http.StatusBadRequest)
return
}
for _, role := range rolesAll {
roleNamesAll = append(roleNamesAll, role.Name)
}
}
var roles []string
var rolesValid bool
if role != "" {
_, rolesValid = model.CleanRoleNames([]string{role})
if !rolesValid {
c.SetInvalidParam("role")
return
}
roleValid := utils.StringInSlice(role, roleNamesAll)
if !roleValid {
c.SetInvalidParam("role")
return
}
}
if rolesString != "" {
roles, rolesValid = model.CleanRoleNames(strings.Split(rolesString, ","))
if !rolesValid {
c.SetInvalidParam("roles")
return
}
validRoleNames := utils.StringArrayIntersection(roleNamesAll, roles)
if len(validRoleNames) != len(roles) {
c.SetInvalidParam("roles")
return
}
}
var channelRoles []string
if channelRolesString != "" && inChannelId != "" {
channelRoles, rolesValid = model.CleanRoleNames(strings.Split(channelRolesString, ","))
if !rolesValid {
c.SetInvalidParam("channelRoles")
return
}
validRoleNames := utils.StringArrayIntersection(roleNamesAll, channelRoles)
if len(validRoleNames) != len(channelRoles) {
c.SetInvalidParam("channelRoles")
return
}
}
var teamRoles []string
if teamRolesString != "" && inTeamId != "" {
teamRoles, rolesValid = model.CleanRoleNames(strings.Split(teamRolesString, ","))
if !rolesValid {
c.SetInvalidParam("teamRoles")
return
}
validRoleNames := utils.StringArrayIntersection(roleNamesAll, teamRoles)
if len(validRoleNames) != len(teamRoles) {
c.SetInvalidParam("teamRoles")
return
}
}
if notInChannelId != "" && inTeamId == "" {
c.SetInvalidURLParam("team_id")

Просмотреть файл

@@ -2410,6 +2410,20 @@ func TestGetUsers(t *testing.T) {
// Check default params for page and per_page
_, err = client.DoAPIGet("/users", "")
require.NoError(t, err)
// Check role params validity
_, _, err = client.GetUsersWithCustomQueryParameters(0, 5, "in_channel=random_channel_id&channel_roles=random_role_doesnt_exist", "")
require.Error(t, err)
require.Equal(t, err.Error(), ": Invalid or missing channelRoles in request body.")
_, _, err = client.GetUsersWithCustomQueryParameters(0, 5, "in_team=random_channel_id&team_roles=random_role_doesnt_exist", "")
require.Error(t, err)
require.Equal(t, err.Error(), ": Invalid or missing teamRoles in request body.")
_, _, err = client.GetUsersWithCustomQueryParameters(0, 5, "roles=random_role_doesnt_exist%2Csystem_user", "")
require.Error(t, err)
require.Equal(t, err.Error(), ": Invalid or missing roles in request body.")
_, _, err = client.GetUsersWithCustomQueryParameters(0, 5, "role=random_role_doesnt_exist", "")
require.Error(t, err)
require.Equal(t, err.Error(), ": Invalid or missing role in request body.")
})
th.Client.Logout()
@@ -2823,6 +2837,64 @@ func TestGetUsersInGroup(t *testing.T) {
}
func TestGetUsersInGroupByDisplayName(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()
id := model.NewId()
group, appErr := th.App.CreateGroup(&model.Group{
DisplayName: "dn-foo_" + id,
Name: model.NewString("name" + id),
Source: model.GroupSourceLdap,
Description: "description_" + id,
RemoteId: model.NewString(model.NewId()),
})
assert.Nil(t, appErr)
user1, err := th.App.CreateUser(th.Context, &model.User{Email: th.GenerateTestEmail(), Nickname: "aaa", Password: "test-password-1", Username: "zzz", Roles: model.SystemUserRoleId})
assert.Nil(t, err)
user2, err := th.App.CreateUser(th.Context, &model.User{Email: th.GenerateTestEmail(), Password: "test-password-2", Username: "bbb", Roles: model.SystemUserRoleId})
assert.Nil(t, err)
_, err = th.App.UpsertGroupMember(group.Id, user1.Id)
assert.Nil(t, err)
_, err = th.App.UpsertGroupMember(group.Id, user2.Id)
assert.Nil(t, err)
th.App.Srv().SetLicense(model.NewTestLicenseSKU(model.LicenseShortSkuProfessional))
th.App.UpdateConfig(func(cfg *model.Config) {
*cfg.PrivacySettings.ShowFullName = true
})
preference := model.Preference{
UserId: th.SystemAdminUser.Id,
Category: model.PreferenceCategoryDisplaySettings,
Name: model.PreferenceNameNameFormat,
Value: model.ShowUsername,
}
err = th.App.UpdatePreferences(th.SystemAdminUser.Id, model.Preferences{preference})
assert.Nil(t, err)
t.Run("Returns users in group in right order for username", func(t *testing.T) {
users, _, err := th.SystemAdminClient.GetUsersInGroupByDisplayName(group.Id, 0, 1, "")
require.NoError(t, err)
assert.Equal(t, users[0].Id, user2.Id)
})
preference.Value = model.ShowNicknameFullName
err = th.App.UpdatePreferences(th.SystemAdminUser.Id, model.Preferences{preference})
assert.Nil(t, err)
t.Run("Returns users in group in right order for nickname", func(t *testing.T) {
users, _, err := th.SystemAdminClient.GetUsersInGroupByDisplayName(group.Id, 0, 1, "")
require.NoError(t, err)
assert.Equal(t, users[0].Id, user1.Id)
})
}
func TestUpdateUserMfa(t *testing.T) {
th := Setup(t).InitBasic()
defer th.TearDown()