Full Mattermost server source with integrated Community Enterprise features. Includes vendor directory for offline/air-gapped builds. Structure: - enterprise-impl/: Enterprise feature implementations - enterprise-community/: Init files that register implementations - enterprise/: Bridge imports (community_imports.go) - vendor/: All dependencies for offline builds Build (online): go build ./cmd/mattermost Build (offline/air-gapped): go build -mod=vendor ./cmd/mattermost 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1325 lines
55 KiB
Go
1325 lines
55 KiB
Go
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
|
// See LICENSE.txt for license information.
|
|
|
|
package app
|
|
|
|
import (
|
|
"errors"
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/mattermost/mattermost/server/public/model"
|
|
"github.com/mattermost/mattermost/server/v8/channels/store"
|
|
"github.com/mattermost/mattermost/server/v8/channels/store/sqlstore"
|
|
)
|
|
|
|
type permissionTransformation struct {
|
|
On func(*model.Role, map[string]map[string]bool) bool
|
|
Add []string
|
|
Remove []string
|
|
}
|
|
type permissionsMap []permissionTransformation
|
|
|
|
const (
|
|
PermissionManageSystem = "manage_system"
|
|
PermissionManageTeam = "manage_team"
|
|
PermissionManageEmojis = "manage_emojis"
|
|
PermissionManageOthersEmojis = "manage_others_emojis"
|
|
PermissionCreateEmojis = "create_emojis"
|
|
PermissionDeleteEmojis = "delete_emojis"
|
|
PermissionDeleteOthersEmojis = "delete_others_emojis"
|
|
PermissionManageWebhooks = "manage_webhooks"
|
|
PermissionManageOthersWebhooks = "manage_others_webhooks"
|
|
PermissionManageIncomingWebhooks = "manage_incoming_webhooks"
|
|
PermissionManageOwnIncomingWebhooks = "manage_own_incoming_webhooks"
|
|
PermissionManageOthersIncomingWebhooks = "manage_others_incoming_webhooks"
|
|
PermissionManageOutgoingWebhooks = "manage_outgoing_webhooks"
|
|
PermissionManageOwnOutgoingWebhooks = "manage_own_outgoing_webhooks"
|
|
PermissionManageOthersOutgoingWebhooks = "manage_others_outgoing_webhooks"
|
|
PermissionBypassIncomingWebhookChannelLock = "bypass_incoming_webhook_channel_lock"
|
|
PermissionListPublicTeams = "list_public_teams"
|
|
PermissionListPrivateTeams = "list_private_teams"
|
|
PermissionJoinPublicTeams = "join_public_teams"
|
|
PermissionJoinPrivateTeams = "join_private_teams"
|
|
PermissionPermanentDeleteUser = "permanent_delete_user"
|
|
PermissionCreateBot = "create_bot"
|
|
PermissionReadBots = "read_bots"
|
|
PermissionReadOthersBots = "read_others_bots"
|
|
PermissionManageBots = "manage_bots"
|
|
PermissionManageOthersBots = "manage_others_bots"
|
|
PermissionManageSlashCommands = "manage_slash_commands"
|
|
PermissionManageOwnSlashCommands = "manage_own_slash_commands"
|
|
PermissionDeletePublicChannel = "delete_public_channel"
|
|
PermissionDeletePrivateChannel = "delete_private_channel"
|
|
PermissionManagePublicChannelProperties = "manage_public_channel_properties"
|
|
PermissionManagePrivateChannelProperties = "manage_private_channel_properties"
|
|
PermissionConvertPublicChannelToPrivate = "convert_public_channel_to_private"
|
|
PermissionConvertPrivateChannelToPublic = "convert_private_channel_to_public"
|
|
PermissionViewMembers = "view_members"
|
|
PermissionInviteUser = "invite_user"
|
|
PermissionInviteGuest = "invite_guest"
|
|
PermissionPromoteGuest = "promote_guest"
|
|
PermissionDemoteToGuest = "demote_to_guest"
|
|
PermissionUseChannelMentions = "use_channel_mentions"
|
|
PermissionCreatePost = "create_post"
|
|
PermissionCreatePost_PUBLIC = "create_post_public"
|
|
PermissionUseGroupMentions = "use_group_mentions"
|
|
PermissionAddReaction = "add_reaction"
|
|
PermissionRemoveReaction = "remove_reaction"
|
|
PermissionManagePublicChannelMembers = "manage_public_channel_members"
|
|
PermissionManagePrivateChannelMembers = "manage_private_channel_members"
|
|
PermissionReadJobs = "read_jobs"
|
|
PermissionManageJobs = "manage_jobs"
|
|
PermissionReadOtherUsersTeams = "read_other_users_teams"
|
|
PermissionEditOtherUsers = "edit_other_users"
|
|
PermissionReadPublicChannelGroups = "read_public_channel_groups"
|
|
PermissionReadPrivateChannelGroups = "read_private_channel_groups"
|
|
PermissionEditBrand = "edit_brand"
|
|
PermissionManageSharedChannels = "manage_shared_channels"
|
|
PermissionManageSecureConnections = "manage_secure_connections"
|
|
PermissionManageOAuth = "manage_oauth"
|
|
PermissionManageRemoteClusters = "manage_remote_clusters" // deprecated; use `manage_secure_connections`
|
|
)
|
|
|
|
// Deprecated: This function should only be used if a case arises where team and/or channel scheme roles do not need to be migrated.
|
|
// Otherwise, use isRole.
|
|
func isExactRole(roleName string) func(*model.Role, map[string]map[string]bool) bool {
|
|
return func(role *model.Role, permissionsMap map[string]map[string]bool) bool {
|
|
return role.Name == roleName
|
|
}
|
|
}
|
|
|
|
// isRole returns true if roleName matches a role's name field or if the team
|
|
// or channel scheme role matches a "common name". A common name is one of the following role
|
|
// that is common among the system scheme and the team and/or channel schemes:
|
|
//
|
|
// TeamAdmin,
|
|
// TeamUser,
|
|
// TeamGuest,
|
|
// ChannelAdmin,
|
|
// ChannelUser,
|
|
// ChannelGuest,
|
|
// PlaybookAdmin,
|
|
// PlaybookMember,
|
|
// RunAdmin,
|
|
// RunMember
|
|
func isRole(roleName string) func(*model.Role, map[string]map[string]bool) bool {
|
|
return func(role *model.Role, permissionsMap map[string]map[string]bool) bool {
|
|
if role.Name == roleName {
|
|
return true
|
|
}
|
|
return isSchemeRoleAssociatedToCommonName(roleName, role)
|
|
}
|
|
}
|
|
|
|
// Deprecated: use isNotRole instead.
|
|
func isNotExactRole(roleName string) func(*model.Role, map[string]map[string]bool) bool {
|
|
return func(role *model.Role, permissionsMap map[string]map[string]bool) bool {
|
|
return role.Name != roleName
|
|
}
|
|
}
|
|
|
|
func isNotRole(roleName string) func(*model.Role, map[string]map[string]bool) bool {
|
|
return func(role *model.Role, permissionsMap map[string]map[string]bool) bool {
|
|
return role.Name != roleName && !isSchemeRoleAssociatedToCommonName(roleName, role)
|
|
}
|
|
}
|
|
|
|
func isSchemeRoleAssociatedToCommonName(roleName string, role *model.Role) bool {
|
|
roleIDToSchemeRoleDisplayName := map[string]string{
|
|
model.TeamAdminRoleId: sqlstore.SchemeRoleDisplayNameTeamAdmin,
|
|
model.TeamUserRoleId: sqlstore.SchemeRoleDisplayNameTeamUser,
|
|
model.TeamGuestRoleId: sqlstore.SchemeRoleDisplayNameTeamGuest,
|
|
|
|
model.ChannelAdminRoleId: sqlstore.SchemeRoleDisplayNameChannelAdmin,
|
|
model.ChannelUserRoleId: sqlstore.SchemeRoleDisplayNameChannelUser,
|
|
model.ChannelGuestRoleId: sqlstore.SchemeRoleDisplayNameChannelGuest,
|
|
|
|
model.PlaybookAdminRoleId: sqlstore.SchemeRoleDisplayNamePlaybookAdmin,
|
|
model.PlaybookMemberRoleId: sqlstore.SchemeRoleDisplayNamePlaybookMember,
|
|
|
|
model.RunAdminRoleId: sqlstore.SchemeRoleDisplayNameRunAdmin,
|
|
model.RunMemberRoleId: sqlstore.SchemeRoleDisplayNameRunMember,
|
|
}
|
|
displayName, ok := roleIDToSchemeRoleDisplayName[roleName]
|
|
if !ok {
|
|
return false
|
|
}
|
|
return strings.HasPrefix(role.DisplayName, displayName)
|
|
}
|
|
|
|
func isNotSchemeRole(roleName string) func(*model.Role, map[string]map[string]bool) bool {
|
|
return func(role *model.Role, permissionsMap map[string]map[string]bool) bool {
|
|
return !strings.Contains(role.DisplayName, roleName)
|
|
}
|
|
}
|
|
|
|
func permissionExists(permission string) func(*model.Role, map[string]map[string]bool) bool {
|
|
return func(role *model.Role, permissionsMap map[string]map[string]bool) bool {
|
|
val, ok := permissionsMap[role.Name][permission]
|
|
return ok && val
|
|
}
|
|
}
|
|
|
|
func permissionNotExists(permission string) func(*model.Role, map[string]map[string]bool) bool {
|
|
return func(role *model.Role, permissionsMap map[string]map[string]bool) bool {
|
|
val, ok := permissionsMap[role.Name][permission]
|
|
return !(ok && val)
|
|
}
|
|
}
|
|
|
|
func onOtherRole(otherRole string, function func(*model.Role, map[string]map[string]bool) bool) func(*model.Role, map[string]map[string]bool) bool {
|
|
return func(role *model.Role, permissionsMap map[string]map[string]bool) bool {
|
|
return function(&model.Role{Name: otherRole}, permissionsMap)
|
|
}
|
|
}
|
|
|
|
func permissionOr(funcs ...func(*model.Role, map[string]map[string]bool) bool) func(*model.Role, map[string]map[string]bool) bool {
|
|
return func(role *model.Role, permissionsMap map[string]map[string]bool) bool {
|
|
for _, f := range funcs {
|
|
if f(role, permissionsMap) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
}
|
|
|
|
func permissionAnd(funcs ...func(*model.Role, map[string]map[string]bool) bool) func(*model.Role, map[string]map[string]bool) bool {
|
|
return func(role *model.Role, permissionsMap map[string]map[string]bool) bool {
|
|
for _, f := range funcs {
|
|
if !f(role, permissionsMap) {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
}
|
|
|
|
func applyPermissionsMap(role *model.Role, roleMap map[string]map[string]bool, migrationMap permissionsMap) []string {
|
|
var result []string
|
|
|
|
roleName := role.Name
|
|
for _, transformation := range migrationMap {
|
|
if transformation.On(role, roleMap) {
|
|
for _, permission := range transformation.Add {
|
|
roleMap[roleName][permission] = true
|
|
}
|
|
for _, permission := range transformation.Remove {
|
|
roleMap[roleName][permission] = false
|
|
}
|
|
}
|
|
}
|
|
|
|
for key, active := range roleMap[roleName] {
|
|
if active {
|
|
result = append(result, key)
|
|
}
|
|
}
|
|
return result
|
|
}
|
|
|
|
func (s *Server) doPermissionsMigration(key string, migrationMap permissionsMap, roles []*model.Role) *model.AppError {
|
|
if _, err := s.Store().System().GetByName(key); err == nil {
|
|
return nil
|
|
}
|
|
|
|
roleMap := make(map[string]map[string]bool)
|
|
for _, role := range roles {
|
|
roleMap[role.Name] = make(map[string]bool)
|
|
for _, permission := range role.Permissions {
|
|
roleMap[role.Name][permission] = true
|
|
}
|
|
}
|
|
|
|
for _, role := range roles {
|
|
role.Permissions = applyPermissionsMap(role, roleMap, migrationMap)
|
|
if _, err := s.Store().Role().Save(role); err != nil {
|
|
var invErr *store.ErrInvalidInput
|
|
switch {
|
|
case errors.As(err, &invErr):
|
|
return model.NewAppError("doPermissionsMigration", "app.role.save.invalid_role.app_error", nil, "", http.StatusBadRequest).Wrap(err)
|
|
default:
|
|
return model.NewAppError("doPermissionsMigration", "app.role.save.insert.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
if err := s.Store().System().SaveOrUpdate(&model.System{Name: key, Value: "true"}); err != nil {
|
|
return model.NewAppError("doPermissionsMigration", "app.system.save.app_error", nil, "", http.StatusInternalServerError).Wrap(err)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (a *App) getEmojisPermissionsSplitMigration() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: permissionExists(PermissionManageEmojis),
|
|
Add: []string{PermissionCreateEmojis, PermissionDeleteEmojis},
|
|
Remove: []string{PermissionManageEmojis},
|
|
},
|
|
permissionTransformation{
|
|
On: permissionExists(PermissionManageOthersEmojis),
|
|
Add: []string{PermissionDeleteOthersEmojis},
|
|
Remove: []string{PermissionManageOthersEmojis},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getWebhooksPermissionsSplitMigration() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: permissionExists(PermissionManageWebhooks),
|
|
Add: []string{PermissionManageIncomingWebhooks, PermissionManageOutgoingWebhooks},
|
|
Remove: []string{PermissionManageWebhooks},
|
|
},
|
|
permissionTransformation{
|
|
On: permissionExists(PermissionManageOthersWebhooks),
|
|
Add: []string{PermissionManageOthersIncomingWebhooks, PermissionManageOthersOutgoingWebhooks},
|
|
Remove: []string{PermissionManageOthersWebhooks},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getIntegrationsOwnPermissionsMigration() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: permissionExists(PermissionManageIncomingWebhooks),
|
|
Add: []string{PermissionManageOwnIncomingWebhooks, PermissionBypassIncomingWebhookChannelLock},
|
|
Remove: []string{PermissionManageIncomingWebhooks},
|
|
},
|
|
permissionTransformation{
|
|
On: permissionExists(PermissionManageOutgoingWebhooks),
|
|
Add: []string{PermissionManageOwnOutgoingWebhooks},
|
|
Remove: []string{PermissionManageOutgoingWebhooks},
|
|
},
|
|
permissionTransformation{
|
|
On: permissionExists(PermissionManageSlashCommands),
|
|
Add: []string{PermissionManageOwnSlashCommands},
|
|
Remove: []string{PermissionManageSlashCommands},
|
|
},
|
|
// Ensure system admin has the new "manage others" permissions
|
|
permissionTransformation{
|
|
On: isExactRole(model.SystemAdminRoleId),
|
|
Add: []string{model.PermissionManageOthersIncomingWebhooks.Id, model.PermissionManageOthersOutgoingWebhooks.Id, model.PermissionManageOthersSlashCommands.Id},
|
|
},
|
|
// Ensure team admin (including scheme team admins) have the new "manage others" permissions
|
|
permissionTransformation{
|
|
On: isRole(model.TeamAdminRoleId),
|
|
Add: []string{model.PermissionManageOthersIncomingWebhooks.Id, model.PermissionManageOthersOutgoingWebhooks.Id, model.PermissionManageOthersSlashCommands.Id},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getListJoinPublicPrivateTeamsPermissionsMigration() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: isExactRole(model.SystemAdminRoleId),
|
|
Add: []string{PermissionListPrivateTeams, PermissionJoinPrivateTeams},
|
|
Remove: []string{},
|
|
},
|
|
permissionTransformation{
|
|
On: isExactRole(model.SystemUserRoleId),
|
|
Add: []string{PermissionListPublicTeams, PermissionJoinPublicTeams},
|
|
Remove: []string{},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) removePermanentDeleteUserMigration() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: permissionExists(PermissionPermanentDeleteUser),
|
|
Remove: []string{PermissionPermanentDeleteUser},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddBotPermissionsMigration() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: isExactRole(model.SystemAdminRoleId),
|
|
Add: []string{PermissionCreateBot, PermissionReadBots, PermissionReadOthersBots, PermissionManageBots, PermissionManageOthersBots},
|
|
Remove: []string{},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) applyChannelManageDeleteToChannelUser() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: permissionAnd(isExactRole(model.ChannelUserRoleId), onOtherRole(model.TeamUserRoleId, permissionExists(PermissionManagePrivateChannelProperties))),
|
|
Add: []string{PermissionManagePrivateChannelProperties},
|
|
},
|
|
permissionTransformation{
|
|
On: permissionAnd(isExactRole(model.ChannelUserRoleId), onOtherRole(model.TeamUserRoleId, permissionExists(PermissionDeletePrivateChannel))),
|
|
Add: []string{PermissionDeletePrivateChannel},
|
|
},
|
|
permissionTransformation{
|
|
On: permissionAnd(isExactRole(model.ChannelUserRoleId), onOtherRole(model.TeamUserRoleId, permissionExists(PermissionManagePublicChannelProperties))),
|
|
Add: []string{PermissionManagePublicChannelProperties},
|
|
},
|
|
permissionTransformation{
|
|
On: permissionAnd(isExactRole(model.ChannelUserRoleId), onOtherRole(model.TeamUserRoleId, permissionExists(PermissionDeletePublicChannel))),
|
|
Add: []string{PermissionDeletePublicChannel},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) removeChannelManageDeleteFromTeamUser() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: permissionAnd(isExactRole(model.TeamUserRoleId), permissionExists(PermissionManagePrivateChannelProperties)),
|
|
Remove: []string{PermissionManagePrivateChannelProperties},
|
|
},
|
|
permissionTransformation{
|
|
On: permissionAnd(isExactRole(model.TeamUserRoleId), permissionExists(PermissionDeletePrivateChannel)),
|
|
Remove: []string{model.PermissionDeletePrivateChannel.Id},
|
|
},
|
|
permissionTransformation{
|
|
On: permissionAnd(isExactRole(model.TeamUserRoleId), permissionExists(PermissionManagePublicChannelProperties)),
|
|
Remove: []string{PermissionManagePublicChannelProperties},
|
|
},
|
|
permissionTransformation{
|
|
On: permissionAnd(isExactRole(model.TeamUserRoleId), permissionExists(PermissionDeletePublicChannel)),
|
|
Remove: []string{PermissionDeletePublicChannel},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getViewMembersPermissionMigration() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: isExactRole(model.SystemUserRoleId),
|
|
Add: []string{PermissionViewMembers},
|
|
},
|
|
permissionTransformation{
|
|
On: isExactRole(model.SystemAdminRoleId),
|
|
Add: []string{PermissionViewMembers},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddManageGuestsPermissionsMigration() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: isExactRole(model.SystemAdminRoleId),
|
|
Add: []string{PermissionPromoteGuest, PermissionDemoteToGuest, PermissionInviteGuest},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) channelModerationPermissionsMigration() (permissionsMap, error) {
|
|
transformations := permissionsMap{}
|
|
|
|
var allTeamSchemes []*model.Scheme
|
|
next := a.SchemesIterator(model.SchemeScopeTeam, 100)
|
|
var schemeBatch []*model.Scheme
|
|
for schemeBatch = next(); len(schemeBatch) > 0; schemeBatch = next() {
|
|
allTeamSchemes = append(allTeamSchemes, schemeBatch...)
|
|
}
|
|
|
|
moderatedPermissionsMinusCreatePost := []string{
|
|
PermissionAddReaction,
|
|
PermissionRemoveReaction,
|
|
PermissionManagePublicChannelMembers,
|
|
PermissionManagePrivateChannelMembers,
|
|
PermissionUseChannelMentions,
|
|
}
|
|
|
|
teamAndChannelAdminConditionalTransformations := func(teamAdminID, channelAdminID, channelUserID, channelGuestID string) []permissionTransformation {
|
|
transformations := []permissionTransformation{}
|
|
|
|
for _, perm := range moderatedPermissionsMinusCreatePost {
|
|
// add each moderated permission to the channel admin if channel user or guest has the permission
|
|
trans := permissionTransformation{
|
|
On: permissionAnd(
|
|
isExactRole(channelAdminID),
|
|
permissionOr(
|
|
onOtherRole(channelUserID, permissionExists(perm)),
|
|
onOtherRole(channelGuestID, permissionExists(perm)),
|
|
),
|
|
),
|
|
Add: []string{perm},
|
|
}
|
|
transformations = append(transformations, trans)
|
|
|
|
// add each moderated permission to the team admin if channel admin, user, or guest has the permission
|
|
trans = permissionTransformation{
|
|
On: permissionAnd(
|
|
isExactRole(teamAdminID),
|
|
permissionOr(
|
|
onOtherRole(channelAdminID, permissionExists(perm)),
|
|
onOtherRole(channelUserID, permissionExists(perm)),
|
|
onOtherRole(channelGuestID, permissionExists(perm)),
|
|
),
|
|
),
|
|
Add: []string{perm},
|
|
}
|
|
transformations = append(transformations, trans)
|
|
}
|
|
|
|
return transformations
|
|
}
|
|
|
|
for _, ts := range allTeamSchemes {
|
|
// ensure all team scheme channel admins have create_post because it's not exposed via the UI
|
|
trans := permissionTransformation{
|
|
On: isExactRole(ts.DefaultChannelAdminRole),
|
|
Add: []string{PermissionCreatePost},
|
|
}
|
|
transformations = append(transformations, trans)
|
|
|
|
// ensure all team scheme team admins have create_post because it's not exposed via the UI
|
|
trans = permissionTransformation{
|
|
On: isExactRole(ts.DefaultTeamAdminRole),
|
|
Add: []string{PermissionCreatePost},
|
|
}
|
|
transformations = append(transformations, trans)
|
|
|
|
// conditionally add all other moderated permissions to team and channel admins
|
|
transformations = append(transformations, teamAndChannelAdminConditionalTransformations(
|
|
ts.DefaultTeamAdminRole,
|
|
ts.DefaultChannelAdminRole,
|
|
ts.DefaultChannelUserRole,
|
|
ts.DefaultChannelGuestRole,
|
|
)...)
|
|
}
|
|
|
|
// ensure team admins have create_post
|
|
transformations = append(transformations, permissionTransformation{
|
|
On: isExactRole(model.TeamAdminRoleId),
|
|
Add: []string{PermissionCreatePost},
|
|
})
|
|
|
|
// ensure channel admins have create_post
|
|
transformations = append(transformations, permissionTransformation{
|
|
On: isExactRole(model.ChannelAdminRoleId),
|
|
Add: []string{PermissionCreatePost},
|
|
})
|
|
|
|
// conditionally add all other moderated permissions to team and channel admins
|
|
transformations = append(transformations, teamAndChannelAdminConditionalTransformations(
|
|
model.TeamAdminRoleId,
|
|
model.ChannelAdminRoleId,
|
|
model.ChannelUserRoleId,
|
|
model.ChannelGuestRoleId,
|
|
)...)
|
|
|
|
// ensure system admin has all the moderated permissions
|
|
transformations = append(transformations, permissionTransformation{
|
|
On: isExactRole(model.SystemAdminRoleId),
|
|
Add: append(moderatedPermissionsMinusCreatePost, PermissionCreatePost),
|
|
})
|
|
|
|
// add the new use_channel_mentions permission to everyone who has create_post
|
|
transformations = append(transformations, permissionTransformation{
|
|
On: permissionOr(permissionExists(PermissionCreatePost), permissionExists(PermissionCreatePost_PUBLIC)),
|
|
Add: []string{PermissionUseChannelMentions},
|
|
})
|
|
|
|
return transformations, nil
|
|
}
|
|
|
|
func (a *App) getAddUseGroupMentionsPermissionMigration() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: permissionAnd(
|
|
isNotExactRole(model.ChannelGuestRoleId),
|
|
isNotSchemeRole(sqlstore.SchemeRoleDisplayNameChannelGuest),
|
|
permissionOr(permissionExists(PermissionCreatePost), permissionExists(PermissionCreatePost_PUBLIC)),
|
|
),
|
|
Add: []string{PermissionUseGroupMentions},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddSystemConsolePermissionsMigration() (permissionsMap, error) {
|
|
permissionsToAdd := []string{}
|
|
for _, permission := range append(model.SysconsoleReadPermissions, model.SysconsoleWritePermissions...) {
|
|
permissionsToAdd = append(permissionsToAdd, permission.Id)
|
|
}
|
|
|
|
return permissionsMap{
|
|
// add the new permissions to system admin
|
|
permissionTransformation{
|
|
On: isExactRole(model.SystemAdminRoleId),
|
|
Add: permissionsToAdd,
|
|
},
|
|
// add read_jobs to all roles with manage_jobs
|
|
permissionTransformation{
|
|
On: permissionExists(PermissionManageJobs),
|
|
Add: []string{PermissionReadJobs},
|
|
},
|
|
// add read_other_users_teams to all roles with edit_other_users
|
|
permissionTransformation{
|
|
On: permissionExists(PermissionEditOtherUsers),
|
|
Add: []string{PermissionReadOtherUsersTeams},
|
|
},
|
|
// add read_public_channel_groups to all roles with manage_public_channel_members
|
|
permissionTransformation{
|
|
On: permissionExists(PermissionManagePublicChannelMembers),
|
|
Add: []string{PermissionReadPublicChannelGroups},
|
|
},
|
|
// add read_private_channel_groups to all roles with manage_private_channel_members
|
|
permissionTransformation{
|
|
On: permissionExists(PermissionManagePrivateChannelMembers),
|
|
Add: []string{PermissionReadPrivateChannelGroups},
|
|
},
|
|
// add edit_brand to all roles with manage_system
|
|
permissionTransformation{
|
|
On: permissionExists(PermissionManageSystem),
|
|
Add: []string{PermissionEditBrand},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddConvertChannelPermissionsMigration() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: permissionExists(PermissionManageTeam),
|
|
Add: []string{PermissionConvertPublicChannelToPrivate, PermissionConvertPrivateChannelToPublic},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getSystemRolesPermissionsMigration() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: isExactRole(model.SystemAdminRoleId),
|
|
Add: []string{model.PermissionSysconsoleReadUserManagementSystemRoles.Id, model.PermissionSysconsoleWriteUserManagementSystemRoles.Id},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddManageSharedChannelsPermissionsMigration() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: isExactRole(model.SystemAdminRoleId),
|
|
Add: []string{PermissionManageSharedChannels},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getBillingPermissionsMigration() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: isExactRole(model.SystemAdminRoleId),
|
|
Add: []string{model.PermissionSysconsoleReadBilling.Id, model.PermissionSysconsoleWriteBilling.Id},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddManageSecureConnectionsPermissionsMigration() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
// add the new permission to system admin
|
|
permissionTransformation{
|
|
On: isExactRole(model.SystemAdminRoleId),
|
|
Add: []string{PermissionManageSecureConnections},
|
|
},
|
|
// remote the deprecated permission from system admin
|
|
permissionTransformation{
|
|
On: isExactRole(model.SystemAdminRoleId),
|
|
Remove: []string{PermissionManageRemoteClusters},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddDownloadComplianceExportResult() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
// add the new permissions to system admin
|
|
permissionTransformation{
|
|
On: isExactRole(model.SystemAdminRoleId),
|
|
Add: []string{model.PermissionDownloadComplianceExportResult.Id},
|
|
},
|
|
// add Download Compliance Export Result and Read Jobs to all roles with sysconsole_read_compliance
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleReadCompliance.Id),
|
|
Add: []string{model.PermissionDownloadComplianceExportResult.Id, model.PermissionReadDataRetentionJob.Id},
|
|
},
|
|
// add manage_jobs to all roles with sysconsole_write_compliance
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteCompliance.Id),
|
|
Add: []string{model.PermissionManageJobs.Id},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddExperimentalSubsectionPermissions() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
// Give the new subsection READ permissions to any user with READ_EXPERIMENTAL
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleReadExperimental.Id),
|
|
Add: []string{model.PermissionSysconsoleReadExperimentalFeatures.Id, model.PermissionSysconsoleReadExperimentalFeatureFlags.Id},
|
|
},
|
|
// Give the new subsection WRITE permissions to any user with WRITE_EXPERIMENTAL
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteExperimental.Id),
|
|
Add: []string{model.PermissionSysconsoleWriteExperimentalFeatures.Id, model.PermissionSysconsoleWriteExperimentalFeatureFlags.Id},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddIntegrationsSubsectionPermissions() (permissionsMap, error) {
|
|
permissionsIntegrationsRead := []string{model.PermissionSysconsoleReadIntegrationsIntegrationManagement.Id, model.PermissionSysconsoleReadIntegrationsBotAccounts.Id, model.PermissionSysconsoleReadIntegrationsGif.Id, model.PermissionSysconsoleReadIntegrationsCors.Id}
|
|
permissionsIntegrationsWrite := []string{model.PermissionSysconsoleWriteIntegrationsIntegrationManagement.Id, model.PermissionSysconsoleWriteIntegrationsBotAccounts.Id, model.PermissionSysconsoleWriteIntegrationsGif.Id, model.PermissionSysconsoleWriteIntegrationsCors.Id}
|
|
|
|
return permissionsMap{
|
|
// Give the new subsection READ permissions to any user with READ_INTEGRATIONS
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleReadIntegrations.Id),
|
|
Add: permissionsIntegrationsRead,
|
|
},
|
|
// Give the new subsection WRITE permissions to any user with WRITE_EXPERIMENTAL
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteIntegrations.Id),
|
|
Add: permissionsIntegrationsWrite,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddSiteSubsectionPermissions() (permissionsMap, error) {
|
|
permissionsSiteRead := []string{model.PermissionSysconsoleReadSiteCustomization.Id, model.PermissionSysconsoleReadSiteLocalization.Id, model.PermissionSysconsoleReadSiteUsersAndTeams.Id, model.PermissionSysconsoleReadSiteNotifications.Id, model.PermissionSysconsoleReadSiteAnnouncementBanner.Id, model.PermissionSysconsoleReadSiteEmoji.Id, model.PermissionSysconsoleReadSitePosts.Id, model.PermissionSysconsoleReadSiteFileSharingAndDownloads.Id, model.PermissionSysconsoleReadSitePublicLinks.Id, model.PermissionSysconsoleReadSiteNotices.Id}
|
|
permissionsSiteWrite := []string{model.PermissionSysconsoleWriteSiteCustomization.Id, model.PermissionSysconsoleWriteSiteLocalization.Id, model.PermissionSysconsoleWriteSiteUsersAndTeams.Id, model.PermissionSysconsoleWriteSiteNotifications.Id, model.PermissionSysconsoleWriteSiteAnnouncementBanner.Id, model.PermissionSysconsoleWriteSiteEmoji.Id, model.PermissionSysconsoleWriteSitePosts.Id, model.PermissionSysconsoleWriteSiteFileSharingAndDownloads.Id, model.PermissionSysconsoleWriteSitePublicLinks.Id, model.PermissionSysconsoleWriteSiteNotices.Id}
|
|
|
|
return permissionsMap{
|
|
// Give the new subsection READ permissions to any user with READ_SITE
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleReadSite.Id),
|
|
Add: permissionsSiteRead,
|
|
},
|
|
// Give the new subsection WRITE permissions to any user with WRITE_SITE
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteSite.Id),
|
|
Add: permissionsSiteWrite,
|
|
},
|
|
// Give the ancillary permissions EDIT_BRAND to anyone with WRITE_SITE_CUSTOMIZATION
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteSiteCustomization.Id),
|
|
Add: []string{model.PermissionEditBrand.Id},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddComplianceSubsectionPermissions() (permissionsMap, error) {
|
|
permissionsComplianceRead := []string{model.PermissionSysconsoleReadComplianceDataRetentionPolicy.Id, model.PermissionSysconsoleReadComplianceComplianceExport.Id, model.PermissionSysconsoleReadComplianceComplianceMonitoring.Id, model.PermissionSysconsoleReadComplianceCustomTermsOfService.Id}
|
|
permissionsComplianceWrite := []string{model.PermissionSysconsoleWriteComplianceDataRetentionPolicy.Id, model.PermissionSysconsoleWriteComplianceComplianceExport.Id, model.PermissionSysconsoleWriteComplianceComplianceMonitoring.Id, model.PermissionSysconsoleWriteComplianceCustomTermsOfService.Id}
|
|
|
|
return permissionsMap{
|
|
// Give the new subsection READ permissions to any user with READ_COMPLIANCE
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleReadCompliance.Id),
|
|
Add: permissionsComplianceRead,
|
|
},
|
|
// Give the new subsection WRITE permissions to any user with WRITE_COMPLIANCE
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteCompliance.Id),
|
|
Add: permissionsComplianceWrite,
|
|
},
|
|
// Ancillary permissions
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteComplianceDataRetentionPolicy.Id),
|
|
Add: []string{model.PermissionCreateDataRetentionJob.Id},
|
|
},
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleReadComplianceDataRetentionPolicy.Id),
|
|
Add: []string{model.PermissionReadDataRetentionJob.Id},
|
|
},
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteComplianceComplianceExport.Id),
|
|
Add: []string{model.PermissionCreateComplianceExportJob.Id, model.PermissionDownloadComplianceExportResult.Id},
|
|
},
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleReadComplianceComplianceExport.Id),
|
|
Add: []string{model.PermissionReadComplianceExportJob.Id, model.PermissionDownloadComplianceExportResult.Id},
|
|
},
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleReadComplianceCustomTermsOfService.Id),
|
|
Add: []string{model.PermissionReadAudits.Id},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddEnvironmentSubsectionPermissions() (permissionsMap, error) {
|
|
permissionsEnvironmentRead := []string{
|
|
model.PermissionSysconsoleReadEnvironmentWebServer.Id,
|
|
model.PermissionSysconsoleReadEnvironmentDatabase.Id,
|
|
model.PermissionSysconsoleReadEnvironmentElasticsearch.Id,
|
|
model.PermissionSysconsoleReadEnvironmentFileStorage.Id,
|
|
model.PermissionSysconsoleReadEnvironmentImageProxy.Id,
|
|
model.PermissionSysconsoleReadEnvironmentSMTP.Id,
|
|
model.PermissionSysconsoleReadEnvironmentPushNotificationServer.Id,
|
|
model.PermissionSysconsoleReadEnvironmentHighAvailability.Id,
|
|
model.PermissionSysconsoleReadEnvironmentRateLimiting.Id,
|
|
model.PermissionSysconsoleReadEnvironmentLogging.Id,
|
|
model.PermissionSysconsoleReadEnvironmentSessionLengths.Id,
|
|
model.PermissionSysconsoleReadEnvironmentPerformanceMonitoring.Id,
|
|
model.PermissionSysconsoleReadEnvironmentDeveloper.Id,
|
|
}
|
|
permissionsEnvironmentWrite := []string{
|
|
model.PermissionSysconsoleWriteEnvironmentWebServer.Id,
|
|
model.PermissionSysconsoleWriteEnvironmentDatabase.Id,
|
|
model.PermissionSysconsoleWriteEnvironmentElasticsearch.Id,
|
|
model.PermissionSysconsoleWriteEnvironmentFileStorage.Id,
|
|
model.PermissionSysconsoleWriteEnvironmentImageProxy.Id,
|
|
model.PermissionSysconsoleWriteEnvironmentSMTP.Id,
|
|
model.PermissionSysconsoleWriteEnvironmentPushNotificationServer.Id,
|
|
model.PermissionSysconsoleWriteEnvironmentHighAvailability.Id,
|
|
model.PermissionSysconsoleWriteEnvironmentRateLimiting.Id,
|
|
model.PermissionSysconsoleWriteEnvironmentLogging.Id,
|
|
model.PermissionSysconsoleWriteEnvironmentSessionLengths.Id,
|
|
model.PermissionSysconsoleWriteEnvironmentPerformanceMonitoring.Id,
|
|
model.PermissionSysconsoleWriteEnvironmentDeveloper.Id,
|
|
}
|
|
|
|
permissionsElasticsearchRead := []string{
|
|
model.PermissionReadElasticsearchPostIndexingJob.Id,
|
|
model.PermissionReadElasticsearchPostAggregationJob.Id,
|
|
}
|
|
|
|
permissionsElasticsearchWrite := []string{
|
|
model.PermissionTestElasticsearch.Id,
|
|
model.PermissionCreateElasticsearchPostIndexingJob.Id,
|
|
model.PermissionCreateElasticsearchPostAggregationJob.Id,
|
|
model.PermissionPurgeElasticsearchIndexes.Id,
|
|
}
|
|
|
|
permissionsWebServerWrite := []string{
|
|
model.PermissionTestSiteURL.Id,
|
|
model.PermissionReloadConfig.Id,
|
|
model.PermissionInvalidateCaches.Id,
|
|
}
|
|
|
|
return permissionsMap{
|
|
// Give the new subsection READ permissions to any user with READ_ENVIRONMENT
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleReadEnvironment.Id),
|
|
Add: permissionsEnvironmentRead,
|
|
},
|
|
// Give the new subsection WRITE permissions to any user with WRITE_ENVIRONMENT
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteEnvironment.Id),
|
|
Add: permissionsEnvironmentWrite,
|
|
},
|
|
// Give these ancillary permissions to anyone with READ_ENVIRONMENT_ELASTICSEARCH
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleReadEnvironmentElasticsearch.Id),
|
|
Add: permissionsElasticsearchRead,
|
|
},
|
|
// Give these ancillary permissions to anyone with WRITE_ENVIRONMENT_WEB_SERVER
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteEnvironmentWebServer.Id),
|
|
Add: permissionsWebServerWrite,
|
|
},
|
|
// Give these ancillary permissions to anyone with WRITE_ENVIRONMENT_DATABASE
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteEnvironmentDatabase.Id),
|
|
Add: []string{model.PermissionRecycleDatabaseConnections.Id},
|
|
},
|
|
// Give these ancillary permissions to anyone with WRITE_ENVIRONMENT_ELASTICSEARCH
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteEnvironmentElasticsearch.Id),
|
|
Add: permissionsElasticsearchWrite,
|
|
},
|
|
// Give these ancillary permissions to anyone with WRITE_ENVIRONMENT_FILE_STORAGE
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteEnvironmentFileStorage.Id),
|
|
Add: []string{model.PermissionTestS3.Id},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddAboutSubsectionPermissions() (permissionsMap, error) {
|
|
permissionsAboutRead := []string{model.PermissionSysconsoleReadAboutEditionAndLicense.Id}
|
|
permissionsAboutWrite := []string{model.PermissionSysconsoleWriteAboutEditionAndLicense.Id}
|
|
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleReadAbout.Id),
|
|
Add: permissionsAboutRead,
|
|
},
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteAbout.Id),
|
|
Add: permissionsAboutWrite,
|
|
},
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleReadAboutEditionAndLicense.Id),
|
|
Add: []string{model.PermissionReadLicenseInformation.Id},
|
|
},
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteAboutEditionAndLicense.Id),
|
|
Add: []string{model.PermissionManageLicenseInformation.Id},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddReportingSubsectionPermissions() (permissionsMap, error) {
|
|
permissionsReportingRead := []string{
|
|
model.PermissionSysconsoleReadReportingSiteStatistics.Id,
|
|
model.PermissionSysconsoleReadReportingTeamStatistics.Id,
|
|
model.PermissionSysconsoleReadReportingServerLogs.Id,
|
|
}
|
|
permissionsReportingWrite := []string{
|
|
model.PermissionSysconsoleWriteReportingSiteStatistics.Id,
|
|
model.PermissionSysconsoleWriteReportingTeamStatistics.Id,
|
|
model.PermissionSysconsoleWriteReportingServerLogs.Id,
|
|
}
|
|
|
|
return permissionsMap{
|
|
// Give the new subsection READ permissions to any user with READ_REPORTING
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleReadReporting.Id),
|
|
Add: permissionsReportingRead,
|
|
},
|
|
// Give the new subsection WRITE permissions to any user with WRITE_REPORTING
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteReporting.Id),
|
|
Add: permissionsReportingWrite,
|
|
},
|
|
|
|
// Give the ancillary permissions PERMISSION_GET_ANALYTICS to anyone with PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS or PERMISSION_SYSCONSOLE_READ_REPORTING_SITE_STATISTICS
|
|
permissionTransformation{
|
|
On: permissionOr(permissionExists(model.PermissionSysconsoleReadUserManagementUsers.Id), permissionExists(model.PermissionSysconsoleReadReportingSiteStatistics.Id)),
|
|
Add: []string{model.PermissionGetAnalytics.Id},
|
|
},
|
|
// Give the ancillary permissions PERMISSION_GET_LOGS to anyone with PERMISSION_SYSCONSOLE_READ_REPORTING_SERVER_LOGS
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleReadReportingServerLogs.Id),
|
|
Add: []string{model.PermissionGetLogs.Id},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddAuthenticationSubsectionPermissions() (permissionsMap, error) {
|
|
permissionsAuthenticationRead := []string{model.PermissionSysconsoleReadAuthenticationSignup.Id, model.PermissionSysconsoleReadAuthenticationEmail.Id, model.PermissionSysconsoleReadAuthenticationPassword.Id, model.PermissionSysconsoleReadAuthenticationMfa.Id, model.PermissionSysconsoleReadAuthenticationLdap.Id, model.PermissionSysconsoleReadAuthenticationSaml.Id, model.PermissionSysconsoleReadAuthenticationOpenid.Id, model.PermissionSysconsoleReadAuthenticationGuestAccess.Id}
|
|
permissionsAuthenticationWrite := []string{model.PermissionSysconsoleWriteAuthenticationSignup.Id, model.PermissionSysconsoleWriteAuthenticationEmail.Id, model.PermissionSysconsoleWriteAuthenticationPassword.Id, model.PermissionSysconsoleWriteAuthenticationMfa.Id, model.PermissionSysconsoleWriteAuthenticationLdap.Id, model.PermissionSysconsoleWriteAuthenticationSaml.Id, model.PermissionSysconsoleWriteAuthenticationOpenid.Id, model.PermissionSysconsoleWriteAuthenticationGuestAccess.Id}
|
|
|
|
return permissionsMap{
|
|
// Give the new subsection READ permissions to any user with READ_AUTHENTICATION
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleReadAuthentication.Id),
|
|
Add: permissionsAuthenticationRead,
|
|
},
|
|
// Give the new subsection WRITE permissions to any user with WRITE_AUTHENTICATION
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteAuthentication.Id),
|
|
Add: permissionsAuthenticationWrite,
|
|
},
|
|
// Give the ancillary permissions for LDAP to anyone with WRITE_AUTHENTICATION_LDAP
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteAuthenticationLdap.Id),
|
|
Add: []string{model.PermissionCreateLdapSyncJob.Id, model.PermissionTestLdap.Id, model.PermissionAddLdapPublicCert.Id, model.PermissionAddLdapPrivateCert.Id, model.PermissionRemoveLdapPublicCert.Id, model.PermissionRemoveLdapPrivateCert.Id},
|
|
},
|
|
// Give the ancillary permissions PERMISSION_TEST_LDAP to anyone with READ_AUTHENTICATION_LDAP
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleReadAuthenticationLdap.Id),
|
|
Add: []string{model.PermissionReadLdapSyncJob.Id},
|
|
},
|
|
// Give the ancillary permissions PERMISSION_INVALIDATE_EMAIL_INVITE to anyone with WRITE_AUTHENTICATION_EMAIL
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteAuthenticationEmail.Id),
|
|
Add: []string{model.PermissionInvalidateEmailInvite.Id},
|
|
},
|
|
// Give the ancillary permissions for SAML to anyone with WRITE_AUTHENTICATION_SAML
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteAuthenticationSaml.Id),
|
|
Add: []string{model.PermissionGetSamlMetadataFromIdp.Id, model.PermissionAddSamlPublicCert.Id, model.PermissionAddSamlPrivateCert.Id, model.PermissionAddSamlIdpCert.Id, model.PermissionRemoveSamlPublicCert.Id, model.PermissionRemoveSamlPrivateCert.Id, model.PermissionRemoveSamlIdpCert.Id, model.PermissionGetSamlCertStatus.Id},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
// This migration fixes https://github.com/mattermost/mattermost-server/issues/17642 where this particular ancillary permission was forgotten during the initial migrations
|
|
func (a *App) getAddTestEmailAncillaryPermission() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
// Give these ancillary permissions to anyone with WRITE_ENVIRONMENT_SMTP
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteEnvironmentSMTP.Id),
|
|
Add: []string{model.PermissionTestEmail.Id},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddCustomUserGroupsPermissions() (permissionsMap, error) {
|
|
customGroupPermissions := []string{
|
|
model.PermissionCreateCustomGroup.Id,
|
|
model.PermissionManageCustomGroupMembers.Id,
|
|
model.PermissionEditCustomGroup.Id,
|
|
model.PermissionDeleteCustomGroup.Id,
|
|
}
|
|
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: isExactRole(model.SystemUserRoleId),
|
|
Add: customGroupPermissions,
|
|
},
|
|
permissionTransformation{
|
|
On: isExactRole(model.SystemAdminRoleId),
|
|
Add: customGroupPermissions,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddCustomUserGroupsPermissionRestore() (permissionsMap, error) {
|
|
customGroupPermissions := []string{
|
|
model.PermissionRestoreCustomGroup.Id,
|
|
}
|
|
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: isExactRole(model.SystemUserRoleId),
|
|
Add: customGroupPermissions,
|
|
},
|
|
permissionTransformation{
|
|
On: isExactRole(model.SystemAdminRoleId),
|
|
Add: customGroupPermissions,
|
|
},
|
|
permissionTransformation{
|
|
On: isExactRole(model.SystemCustomGroupAdminRoleId),
|
|
Add: customGroupPermissions,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddPlaybooksPermissions() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: permissionOr(
|
|
permissionExists(model.PermissionCreatePublicChannel.Id),
|
|
permissionExists(model.PermissionCreatePrivateChannel.Id),
|
|
),
|
|
Add: []string{
|
|
model.PermissionPublicPlaybookCreate.Id,
|
|
model.PermissionPrivatePlaybookCreate.Id,
|
|
},
|
|
},
|
|
permissionTransformation{
|
|
On: isExactRole(model.SystemAdminRoleId),
|
|
Add: []string{
|
|
model.PermissionPublicPlaybookManageProperties.Id,
|
|
model.PermissionPublicPlaybookManageMembers.Id,
|
|
model.PermissionPublicPlaybookView.Id,
|
|
model.PermissionPublicPlaybookMakePrivate.Id,
|
|
model.PermissionPrivatePlaybookManageProperties.Id,
|
|
model.PermissionPrivatePlaybookManageMembers.Id,
|
|
model.PermissionPrivatePlaybookView.Id,
|
|
model.PermissionPrivatePlaybookMakePublic.Id,
|
|
model.PermissionRunCreate.Id,
|
|
model.PermissionRunManageProperties.Id,
|
|
model.PermissionRunManageMembers.Id,
|
|
model.PermissionRunView.Id,
|
|
},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getPlaybooksPermissionsAddManageRoles() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: permissionOr(
|
|
isExactRole(model.PlaybookAdminRoleId),
|
|
isExactRole(model.TeamAdminRoleId),
|
|
isExactRole(model.SystemAdminRoleId),
|
|
),
|
|
Add: []string{
|
|
model.PermissionPublicPlaybookManageRoles.Id,
|
|
model.PermissionPrivatePlaybookManageRoles.Id,
|
|
},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getProductsBoardsPermissions() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
// Give the new subsection READ permissions to any user with SYSTEM_MANAGER
|
|
permissionTransformation{
|
|
On: permissionOr(isExactRole(model.SystemManagerRoleId)),
|
|
Add: []string{model.PermissionSysconsoleReadProductsBoards.Id},
|
|
},
|
|
|
|
// Give the new subsection WRITE permissions to any user with SYSTEM_ADMIN
|
|
permissionTransformation{
|
|
On: permissionOr(isExactRole(model.SystemAdminRoleId)),
|
|
Add: []string{model.PermissionSysconsoleWriteProductsBoards.Id},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddChannelReadContentPermissions() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
// Migrate all roles including custom roles that have the read_channel permission
|
|
// but exclude system console roles system_read_only_admin system_user_manager & system_manager
|
|
// as this system roles are for the admin console use only
|
|
permissionTransformation{
|
|
On: permissionAnd(
|
|
permissionAnd(
|
|
isNotRole(model.SystemUserManagerRoleId),
|
|
isNotRole(model.SystemReadOnlyAdminRoleId),
|
|
isNotRole(model.SystemManagerRoleId),
|
|
),
|
|
permissionExists(model.PermissionReadChannel.Id),
|
|
),
|
|
Add: []string{
|
|
model.PermissionReadChannelContent.Id,
|
|
},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddIPFilterPermissionsMigration() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: permissionOr(isExactRole(model.SystemAdminRoleId)),
|
|
Add: []string{
|
|
model.PermissionSysconsoleReadIPFilters.Id,
|
|
},
|
|
},
|
|
|
|
permissionTransformation{
|
|
On: permissionOr(isExactRole(model.SystemAdminRoleId)),
|
|
Add: []string{
|
|
model.PermissionSysconsoleWriteIPFilters.Id,
|
|
},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddOutgoingOAuthConnectionsPermissions() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: permissionOr(isExactRole(model.SystemAdminRoleId)),
|
|
Add: []string{
|
|
model.PermissionManageOutgoingOAuthConnections.Id,
|
|
},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddChannelBookmarksPermissionsMigration() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: permissionOr(
|
|
isRole(model.ChannelUserRoleId),
|
|
isRole(model.ChannelAdminRoleId),
|
|
isRole(model.TeamAdminRoleId),
|
|
isRole(model.SystemAdminRoleId),
|
|
),
|
|
Add: []string{
|
|
model.PermissionAddBookmarkPublicChannel.Id,
|
|
model.PermissionEditBookmarkPublicChannel.Id,
|
|
model.PermissionDeleteBookmarkPublicChannel.Id,
|
|
model.PermissionOrderBookmarkPublicChannel.Id,
|
|
model.PermissionAddBookmarkPrivateChannel.Id,
|
|
model.PermissionEditBookmarkPrivateChannel.Id,
|
|
model.PermissionDeleteBookmarkPrivateChannel.Id,
|
|
model.PermissionOrderBookmarkPrivateChannel.Id,
|
|
},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddManageJobAncillaryPermissionsMigration() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteAuthenticationLdap.Id),
|
|
Add: []string{model.PermissionManageLdapSyncJob.Id},
|
|
},
|
|
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteComplianceDataRetentionPolicy.Id),
|
|
Add: []string{model.PermissionManageDataRetentionJob.Id},
|
|
},
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteComplianceComplianceExport.Id),
|
|
Add: []string{model.PermissionManageComplianceExportJob.Id},
|
|
},
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleWriteEnvironmentElasticsearch.Id),
|
|
Add: []string{
|
|
model.PermissionManageElasticsearchPostIndexingJob.Id,
|
|
model.PermissionManageElasticsearchPostAggregationJob.Id,
|
|
},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddUploadFilePermissionMigration() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: permissionExists(model.PermissionCreatePost.Id),
|
|
Add: []string{model.PermissionUploadFile.Id},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getFixReadAuditsPermissionMigration() (permissionsMap, error) {
|
|
transformations := []permissionTransformation{}
|
|
|
|
transformations = append(transformations, permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleReadComplianceCustomTermsOfService.Id),
|
|
Remove: []string{model.PermissionReadAudits.Id},
|
|
})
|
|
|
|
transformations = append(transformations, permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleReadComplianceComplianceMonitoring.Id),
|
|
Add: []string{model.PermissionReadAudits.Id},
|
|
})
|
|
return transformations, nil
|
|
}
|
|
|
|
func (a *App) removeGetAnalyticsPermissionMigration() (permissionsMap, error) {
|
|
transformations := []permissionTransformation{}
|
|
|
|
transformations = append(transformations, permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleReadUserManagementUsers.Id),
|
|
Remove: []string{model.PermissionGetAnalytics.Id},
|
|
})
|
|
|
|
transformations = append(transformations, permissionTransformation{
|
|
On: permissionExists(model.PermissionSysconsoleReadReportingTeamStatistics.Id),
|
|
Add: []string{model.PermissionGetAnalytics.Id},
|
|
})
|
|
return transformations, nil
|
|
}
|
|
|
|
func (a *App) addSysConsoleMobileSecurityPermission() (permissionsMap, error) {
|
|
transformations := []permissionTransformation{}
|
|
|
|
transformations = append(transformations, permissionTransformation{
|
|
On: isExactRole(model.SystemAdminRoleId),
|
|
Add: []string{model.PermissionSysconsoleWriteEnvironmentMobileSecurity.Id},
|
|
})
|
|
|
|
transformations = append(transformations, permissionTransformation{
|
|
On: permissionOr(
|
|
isExactRole(model.SystemAdminRoleId),
|
|
isExactRole(model.SystemReadOnlyAdminRoleId),
|
|
),
|
|
Add: []string{model.PermissionSysconsoleReadEnvironmentMobileSecurity.Id},
|
|
})
|
|
|
|
return transformations, nil
|
|
}
|
|
|
|
func (a *App) getAddChannelBannerPermissionMigration() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: permissionOr(
|
|
isRole(model.ChannelAdminRoleId),
|
|
isRole(model.TeamAdminRoleId),
|
|
isRole(model.SystemAdminRoleId),
|
|
),
|
|
Add: []string{
|
|
model.PermissionManagePublicChannelBanner.Id,
|
|
model.PermissionManagePrivateChannelBanner.Id,
|
|
},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (a *App) getAddChannelAccessRulesPermissionMigration() (permissionsMap, error) {
|
|
return permissionsMap{
|
|
permissionTransformation{
|
|
On: permissionOr(
|
|
isRole(model.ChannelAdminRoleId),
|
|
isRole(model.TeamAdminRoleId),
|
|
isRole(model.SystemAdminRoleId),
|
|
),
|
|
Add: []string{
|
|
model.PermissionManageChannelAccessRules.Id,
|
|
},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
// Only sysadmins, team admins, and users with channels and groups managements have access to "convert channel to public"
|
|
func (a *App) getRestrictAcessToChannelConversionToPublic() (permissionsMap, error) {
|
|
return []permissionTransformation{
|
|
{
|
|
On: permissionAnd(
|
|
isNotRole(model.SystemAdminRoleId),
|
|
isNotRole(model.TeamAdminRoleId),
|
|
permissionOr(
|
|
permissionNotExists(model.PermissionSysconsoleWriteUserManagementChannels.Id),
|
|
permissionNotExists(model.PermissionSysconsoleWriteUserManagementGroups.Id),
|
|
),
|
|
),
|
|
Remove: []string{PermissionConvertPrivateChannelToPublic},
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
// DoPermissionsMigrations execute all the permissions migrations need by the current version.
|
|
func (a *App) DoPermissionsMigrations() error {
|
|
return a.Srv().doPermissionsMigrations()
|
|
}
|
|
|
|
func (s *Server) doPermissionsMigrations() error {
|
|
a := New(ServerConnector(s.Channels()))
|
|
PermissionsMigrations := []struct {
|
|
Key string
|
|
Migration func() (permissionsMap, error)
|
|
}{
|
|
{Key: model.MigrationKeyEmojiPermissionsSplit, Migration: a.getEmojisPermissionsSplitMigration},
|
|
{Key: model.MigrationKeyWebhookPermissionsSplit, Migration: a.getWebhooksPermissionsSplitMigration},
|
|
{Key: model.MigrationKeyIntegrationsOwnPermissions, Migration: a.getIntegrationsOwnPermissionsMigration},
|
|
{Key: model.MigrationKeyListJoinPublicPrivateTeams, Migration: a.getListJoinPublicPrivateTeamsPermissionsMigration},
|
|
{Key: model.MigrationKeyRemovePermanentDeleteUser, Migration: a.removePermanentDeleteUserMigration},
|
|
{Key: model.MigrationKeyAddBotPermissions, Migration: a.getAddBotPermissionsMigration},
|
|
{Key: model.MigrationKeyApplyChannelManageDeleteToChannelUser, Migration: a.applyChannelManageDeleteToChannelUser},
|
|
{Key: model.MigrationKeyRemoveChannelManageDeleteFromTeamUser, Migration: a.removeChannelManageDeleteFromTeamUser},
|
|
{Key: model.MigrationKeyViewMembersNewPermission, Migration: a.getViewMembersPermissionMigration},
|
|
{Key: model.MigrationKeyAddManageGuestsPermissions, Migration: a.getAddManageGuestsPermissionsMigration},
|
|
{Key: model.MigrationKeyChannelModerationsPermissions, Migration: a.channelModerationPermissionsMigration},
|
|
{Key: model.MigrationKeyAddUseGroupMentionsPermission, Migration: a.getAddUseGroupMentionsPermissionMigration},
|
|
{Key: model.MigrationKeyAddSystemConsolePermissions, Migration: a.getAddSystemConsolePermissionsMigration},
|
|
{Key: model.MigrationKeyAddConvertChannelPermissions, Migration: a.getAddConvertChannelPermissionsMigration},
|
|
{Key: model.MigrationKeyAddManageSharedChannelPermissions, Migration: a.getAddManageSharedChannelsPermissionsMigration},
|
|
{Key: model.MigrationKeyAddManageSecureConnectionsPermissions, Migration: a.getAddManageSecureConnectionsPermissionsMigration},
|
|
{Key: model.MigrationKeyAddSystemRolesPermissions, Migration: a.getSystemRolesPermissionsMigration},
|
|
{Key: model.MigrationKeyAddBillingPermissions, Migration: a.getBillingPermissionsMigration},
|
|
{Key: model.MigrationKeyAddDownloadComplianceExportResults, Migration: a.getAddDownloadComplianceExportResult},
|
|
{Key: model.MigrationKeyAddExperimentalSubsectionPermissions, Migration: a.getAddExperimentalSubsectionPermissions},
|
|
{Key: model.MigrationKeyAddAuthenticationSubsectionPermissions, Migration: a.getAddAuthenticationSubsectionPermissions},
|
|
{Key: model.MigrationKeyAddIntegrationsSubsectionPermissions, Migration: a.getAddIntegrationsSubsectionPermissions},
|
|
{Key: model.MigrationKeyAddSiteSubsectionPermissions, Migration: a.getAddSiteSubsectionPermissions},
|
|
{Key: model.MigrationKeyAddComplianceSubsectionPermissions, Migration: a.getAddComplianceSubsectionPermissions},
|
|
{Key: model.MigrationKeyAddEnvironmentSubsectionPermissions, Migration: a.getAddEnvironmentSubsectionPermissions},
|
|
{Key: model.MigrationKeyAddAboutSubsectionPermissions, Migration: a.getAddAboutSubsectionPermissions},
|
|
{Key: model.MigrationKeyAddReportingSubsectionPermissions, Migration: a.getAddReportingSubsectionPermissions},
|
|
{Key: model.MigrationKeyAddTestEmailAncillaryPermission, Migration: a.getAddTestEmailAncillaryPermission},
|
|
{Key: model.MigrationKeyAddPlaybooksPermissions, Migration: a.getAddPlaybooksPermissions},
|
|
{Key: model.MigrationKeyAddCustomUserGroupsPermissions, Migration: a.getAddCustomUserGroupsPermissions},
|
|
{Key: model.MigrationKeyAddPlayboosksManageRolesPermissions, Migration: a.getPlaybooksPermissionsAddManageRoles},
|
|
{Key: model.MigrationKeyAddProductsBoardsPermissions, Migration: a.getProductsBoardsPermissions},
|
|
{Key: model.MigrationKeyAddCustomUserGroupsPermissionRestore, Migration: a.getAddCustomUserGroupsPermissionRestore},
|
|
{Key: model.MigrationKeyAddReadChannelContentPermissions, Migration: a.getAddChannelReadContentPermissions},
|
|
{Key: model.MigrationKeyAddIPFilteringPermissions, Migration: a.getAddIPFilterPermissionsMigration},
|
|
{Key: model.MigrationKeyAddOutgoingOAuthConnectionsPermissions, Migration: a.getAddOutgoingOAuthConnectionsPermissions},
|
|
{Key: model.MigrationKeyAddChannelBookmarksPermissions, Migration: a.getAddChannelBookmarksPermissionsMigration},
|
|
{Key: model.MigrationKeyAddManageJobAncillaryPermissions, Migration: a.getAddManageJobAncillaryPermissionsMigration},
|
|
{Key: model.MigrationKeyAddUploadFilePermission, Migration: a.getAddUploadFilePermissionMigration},
|
|
{Key: model.RestrictAccessToChannelConversionToPublic, Migration: a.getRestrictAcessToChannelConversionToPublic},
|
|
{Key: model.MigrationKeyFixReadAuditsPermission, Migration: a.getFixReadAuditsPermissionMigration},
|
|
{Key: model.MigrationRemoveGetAnalyticsPermission, Migration: a.removeGetAnalyticsPermissionMigration},
|
|
{Key: model.MigrationAddSysconsoleMobileSecurityPermission, Migration: a.addSysConsoleMobileSecurityPermission},
|
|
{Key: model.MigrationKeyAddChannelBannerPermissions, Migration: a.getAddChannelBannerPermissionMigration},
|
|
{Key: model.MigrationKeyAddChannelAccessRulesPermission, Migration: a.getAddChannelAccessRulesPermissionMigration},
|
|
}
|
|
|
|
roles, err := s.Store().Role().GetAll()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
for _, migration := range PermissionsMigrations {
|
|
migMap, err := migration.Migration()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
if err := s.doPermissionsMigration(migration.Key, migMap, roles); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|