mattermost-community-enterp.../cmd/mmctl/commands/permissions_role.go
Claude ec1f89217a Merge: Complete Mattermost Server with Community Enterprise
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>
2025-12-17 23:59:07 +09:00

228 lines
6.1 KiB
Go

// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
// See LICENSE.txt for license information.
package commands
import (
"context"
"fmt"
"sort"
"strings"
"text/tabwriter"
"github.com/mattermost/mattermost/server/public/model"
"github.com/mattermost/mattermost/server/v8/cmd/mmctl/client"
"github.com/mattermost/mattermost/server/v8/cmd/mmctl/printer"
"github.com/hashicorp/go-multierror"
"github.com/spf13/cobra"
)
var RoleCmd = &cobra.Command{
Use: "role",
Short: "Management of roles",
}
var ShowCmd = &cobra.Command{
Use: "show <role_name>",
Short: "Show the role information",
Long: "Show all the information about a role.",
Example: ` permissions role show system_user`,
Args: cobra.ExactArgs(1),
RunE: withClient(showRoleCmdF),
}
var AssignCmd = &cobra.Command{
Use: "assign <role_name> <username...>",
Short: "Assign users to role (EE Only)",
Long: "Assign users to a role by username (Only works in Enterprise Edition).",
Example: ` # Assign users with usernames 'john.doe' and 'jane.doe' to the role named 'system_admin'.
permissions assign system_admin john.doe jane.doe
# Examples using other system roles
permissions assign system_manager john.doe jane.doe
permissions assign system_user_manager john.doe jane.doe
permissions assign system_read_only_admin john.doe jane.doe`,
Args: cobra.MinimumNArgs(2),
RunE: withClient(assignUsersCmdF),
}
var UnassignCmd = &cobra.Command{
Use: "unassign <role_name> <username...>",
Short: "Unassign users from role (EE Only)",
Long: "Unassign users from a role by username (Only works in Enterprise Edition).",
Example: ` # Unassign users with usernames 'john.doe' and 'jane.doe' from the role named 'system_admin'.
permissions unassign system_admin john.doe jane.doe
# Examples using other system roles
permissions unassign system_manager john.doe jane.doe
permissions unassign system_user_manager john.doe jane.doe
permissions unassign system_read_only_admin john.doe jane.doe`,
Args: cobra.MinimumNArgs(2),
RunE: withClient(unassignUsersCmdF),
}
func init() {
RoleCmd.AddCommand(
AssignCmd,
UnassignCmd,
ShowCmd,
)
PermissionsCmd.AddCommand(
RoleCmd,
)
}
func prettyRole(role *model.Role) string {
sort.Strings(role.Permissions)
consolePermissionMap := map[string]bool{}
for _, perm := range role.Permissions {
if strings.HasPrefix(perm, "sysconsole_") {
consolePermissionMap[perm] = true
}
}
getUsedBy := func(permissionID string) []string {
var usedByIDs []string
if !strings.HasPrefix(permissionID, "sysconsole_") {
usedBy := map[string]bool{} // map to make a unique set
for key, vals := range model.SysconsoleAncillaryPermissions {
for _, val := range vals {
if val.Id == permissionID {
if _, ok := consolePermissionMap[key]; ok {
usedBy[key] = true
}
}
}
}
for key := range usedBy {
usedByIDs = append(usedByIDs, key)
}
}
return usedByIDs
}
var b strings.Builder
w := tabwriter.NewWriter(&b, 0, 0, 1, ' ', 0)
// Only show the 3-column view if the role has sysconsole permissions
// sysadmin has every permission, so no point in showing the "Used by"
// column.
if len(consolePermissionMap) > 0 && role.Name != "system_admin" {
fmt.Fprintf(w, "\nProperty\tValue\tUsed by\n")
fmt.Fprintf(w, "--------\t-----\t-------\n")
fmt.Fprintf(w, "Name\t%s\t\n", role.Name)
fmt.Fprintf(w, "DisplayName\t%s\t\n", role.DisplayName)
fmt.Fprintf(w, "BuiltIn\t%v\t\n", role.BuiltIn)
fmt.Fprintf(w, "SchemeManaged\t%v\t\n", role.SchemeManaged)
for i, perm := range role.Permissions {
if i == 0 {
fmt.Fprintf(w, "Permissions\t%s\t%v\n", role.Permissions[0], strings.Join(getUsedBy(role.Permissions[0]), ", "))
} else {
fmt.Fprintf(w, "\t%s\t%v\n", perm, strings.Join(getUsedBy(perm), ", "))
}
}
} else {
fmt.Fprintf(w, "\nProperty\tValue\n")
fmt.Fprintf(w, "--------\t-----\n")
fmt.Fprintf(w, "Name\t%s\n", role.Name)
fmt.Fprintf(w, "DisplayName\t%s\n", role.DisplayName)
fmt.Fprintf(w, "BuiltIn\t%v\n", role.BuiltIn)
fmt.Fprintf(w, "SchemeManaged\t%v\n", role.SchemeManaged)
for i, perm := range role.Permissions {
if i == 0 {
fmt.Fprintf(w, "Permissions\t%s\n", role.Permissions[0])
} else {
fmt.Fprintf(w, "\t%s\n", perm)
}
}
}
w.Flush()
return b.String()
}
func showRoleCmdF(c client.Client, cmd *cobra.Command, args []string) error {
role, _, err := c.GetRoleByName(context.TODO(), args[0])
if err != nil {
return err
}
printer.PrintT(prettyRole(role), nil)
return nil
}
func assignUsersCmdF(c client.Client, cmd *cobra.Command, args []string) error {
role, _, err := c.GetRoleByName(context.TODO(), args[0])
if err != nil {
return err
}
users := getUsersFromUserArgs(c, args[1:])
var errs *multierror.Error
for i, user := range users {
if user == nil {
printer.PrintError("Couldn't find user '" + args[i+1] + "'.")
errs = multierror.Append(errs, fmt.Errorf("couldn't find user '%s'", args[i+1]))
continue
}
var userHasRequestedRole bool
startingRoles := strings.Fields(user.Roles)
for _, roleName := range startingRoles {
if roleName == role.Name {
userHasRequestedRole = true
}
}
if userHasRequestedRole {
continue
}
userRoles := startingRoles
userRoles = append(userRoles, role.Name)
_, err = c.UpdateUserRoles(context.TODO(), user.Id, strings.Join(userRoles, " "))
if err != nil {
return err
}
}
return errs.ErrorOrNil()
}
func unassignUsersCmdF(c client.Client, cmd *cobra.Command, args []string) error {
users := getUsersFromUserArgs(c, args[1:])
for i, user := range users {
if user == nil {
printer.PrintError("Couldn't find user '" + args[i+1] + "'.")
continue
}
userRoles := strings.Fields(user.Roles)
originalCount := len(userRoles)
for j := 0; j < len(userRoles); j++ {
if userRoles[j] == args[0] {
userRoles = append(userRoles[:j], userRoles[j+1:]...)
j--
}
}
if originalCount > len(userRoles) {
_, err := c.UpdateUserRoles(context.TODO(), user.Id, strings.Join(userRoles, " "))
if err != nil {
return err
}
}
}
return nil
}