MM-66092 - enhance user permissions data structure validations (#34654) (#35006)

Automatic Merge
Этот коммит содержится в:
Pablo Vélez
2026-01-21 05:48:52 -05:00
коммит произвёл GitHub
родитель ebe1bd4e31
Коммит 43e797010b
6 изменённых файлов: 309 добавлений и 25 удалений

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

@@ -1251,14 +1251,29 @@ func buildChannelModerations(c request.CTX, channelType model.ChannelType, membe
return channelModerations
}
func (a *App) UpdateChannelMemberRoles(c request.CTX, channelID string, userID string, newRoles string) (*model.ChannelMember, *model.AppError) {
// UpdateChannelMemberRoles updates the roles for a channel member.
// This is the public API used by REST endpoints and plugins.
// It enforces strict validation requiring either SchemeUser or SchemeGuest to be true.
func (a *App) UpdateChannelMemberRoles(rctx request.CTX, channelID string, userID string, newRoles string) (*model.ChannelMember, *model.AppError) {
return a.updateChannelMemberRolesInternal(rctx, channelID, userID, newRoles, false)
}
// updateChannelMemberRolesInternal is the internal implementation of UpdateChannelMemberRoles.
// The allowSchemeUserUnset parameter controls whether to enforce the requirement that members
// must have either SchemeUser or SchemeGuest set to true.
//
// When allowSchemeUserUnset is false (default for API/plugin calls), the function enforces
// that members must have a base scheme role. When true (bulk import only), this validation
// is skipped to support the two-phase import pattern where explicit roles are set first,
// then scheme roles are set via UpdateChannelMemberSchemeRoles immediately after.
func (a *App) updateChannelMemberRolesInternal(rctx request.CTX, channelID string, userID string, newRoles string, allowSchemeUserUnset bool) (*model.ChannelMember, *model.AppError) {
var member *model.ChannelMember
var err *model.AppError
if member, err = a.GetChannelMember(c, channelID, userID); err != nil {
if member, err = a.GetChannelMember(rctx, channelID, userID); err != nil {
return nil, err
}
schemeGuestRole, schemeUserRole, schemeAdminRole, err := a.GetSchemeRolesForChannel(c, channelID)
schemeGuestRole, schemeUserRole, schemeAdminRole, err := a.GetSchemeRolesForChannel(rctx, channelID)
if err != nil {
return nil, err
}
@@ -1305,9 +1320,16 @@ func (a *App) UpdateChannelMemberRoles(c request.CTX, channelID string, userID s
return nil, model.NewAppError("UpdateChannelMemberRoles", "api.channel.update_channel_member_roles.changing_guest_role.app_error", nil, "", http.StatusBadRequest)
}
// Validate that the member has a base scheme role (SchemeUser or SchemeGuest).
// This ensures members always have the minimum required permissions.
// Bulk import operations may skip this validation temporarily.
if !allowSchemeUserUnset && !member.SchemeGuest && !member.SchemeUser {
return nil, model.NewAppError("UpdateChannelMemberRoles", "api.channel.update_channel_member_roles.unset_user_scheme.app_error", nil, "", http.StatusBadRequest)
}
member.ExplicitRoles = strings.Join(newExplicitRoles, " ")
return a.updateChannelMember(c, member)
return a.updateChannelMember(rctx, member)
}
func (a *App) UpdateChannelMemberSchemeRoles(c request.CTX, channelID string, userID string, isSchemeGuest bool, isSchemeUser bool, isSchemeAdmin bool) (*model.ChannelMember, *model.AppError) {