github.com/gravitational/teleport/api@v0.0.0-20240507183017-3110591cbafc/types/usergroup.go (about)

     1  /*
     2  Copyright 2023 Gravitational, Inc.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package types
    18  
    19  import (
    20  	"fmt"
    21  	"sort"
    22  	"strings"
    23  
    24  	"github.com/gravitational/trace"
    25  
    26  	"github.com/gravitational/teleport/api/types/compare"
    27  	"github.com/gravitational/teleport/api/utils"
    28  )
    29  
    30  var _ compare.IsEqual[UserGroup] = (*UserGroupV1)(nil)
    31  
    32  // UserGroup specifies an externally sourced group.
    33  type UserGroup interface {
    34  	ResourceWithLabels
    35  
    36  	// GetApplications will return a list of application IDs associated with the user group.
    37  	GetApplications() []string
    38  	// SetApplications will set the list of application IDs associated with the user group.
    39  	SetApplications([]string)
    40  }
    41  
    42  var _ ResourceWithLabels = (*UserGroupV1)(nil)
    43  
    44  // NewUserGroup returns a new UserGroup.
    45  func NewUserGroup(metadata Metadata, spec UserGroupSpecV1) (UserGroup, error) {
    46  	g := &UserGroupV1{
    47  		ResourceHeader: ResourceHeader{
    48  			Metadata: metadata,
    49  		},
    50  		Spec: spec,
    51  	}
    52  	if err := g.CheckAndSetDefaults(); err != nil {
    53  		return nil, trace.Wrap(err)
    54  	}
    55  	return g, nil
    56  }
    57  
    58  // GetApplications will return a list of application IDs associated with the user group.
    59  func (g *UserGroupV1) GetApplications() []string {
    60  	return g.Spec.Applications
    61  }
    62  
    63  // SetApplications will set the list of application IDs associated with the user group.
    64  func (g *UserGroupV1) SetApplications(applications []string) {
    65  	g.Spec.Applications = applications
    66  }
    67  
    68  // String returns the user group string representation.
    69  func (g *UserGroupV1) String() string {
    70  	return fmt.Sprintf("UserGroupV1(Name=%v, Labels=%v)",
    71  		g.GetName(), g.GetAllLabels())
    72  }
    73  
    74  // MatchSearch goes through select field values and tries to
    75  // match against the list of search values.
    76  func (g *UserGroupV1) MatchSearch(values []string) bool {
    77  	fieldVals := append(utils.MapToStrings(g.GetAllLabels()), g.GetName(), g.GetMetadata().Description)
    78  	return MatchSearch(fieldVals, values, nil)
    79  }
    80  
    81  // setStaticFields sets static resource header and metadata fields.
    82  func (g *UserGroupV1) setStaticFields() {
    83  	g.Kind = KindUserGroup
    84  	g.Version = V1
    85  }
    86  
    87  // CheckAndSetDefaults checks and sets default values
    88  func (g *UserGroupV1) CheckAndSetDefaults() error {
    89  	g.setStaticFields()
    90  	if err := g.ResourceHeader.CheckAndSetDefaults(); err != nil {
    91  		return trace.Wrap(err)
    92  	}
    93  
    94  	return nil
    95  }
    96  
    97  // IsEqual determines if two user group resources are equivalent to one another.
    98  func (g *UserGroupV1) IsEqual(i UserGroup) bool {
    99  	if other, ok := i.(*UserGroupV1); ok {
   100  		return deriveTeleportEqualUserGroupV1(g, other)
   101  	}
   102  	return false
   103  }
   104  
   105  // UserGroups is a list of UserGroup resources.
   106  type UserGroups []UserGroup
   107  
   108  // AsResources returns these groups as resources with labels.
   109  func (g UserGroups) AsResources() []ResourceWithLabels {
   110  	resources := make([]ResourceWithLabels, len(g))
   111  	for i, group := range g {
   112  		resources[i] = group
   113  	}
   114  	return resources
   115  }
   116  
   117  // SortByCustom custom sorts by given sort criteria.
   118  func (g UserGroups) SortByCustom(sortBy SortBy) error {
   119  	if sortBy.Field == "" {
   120  		return nil
   121  	}
   122  
   123  	isDesc := sortBy.IsDesc
   124  	switch sortBy.Field {
   125  	case ResourceMetadataName:
   126  		sort.SliceStable(g, func(i, j int) bool {
   127  			groupA := g[i]
   128  			groupB := g[j]
   129  
   130  			groupAName := FriendlyName(groupA)
   131  			groupBName := FriendlyName(groupB)
   132  
   133  			if groupAName == "" {
   134  				groupAName = groupA.GetName()
   135  			}
   136  			if groupBName == "" {
   137  				groupBName = groupB.GetName()
   138  			}
   139  
   140  			return stringCompare(strings.ToLower(groupAName), strings.ToLower(groupBName), isDesc)
   141  		})
   142  	case ResourceSpecDescription:
   143  		sort.SliceStable(g, func(i, j int) bool {
   144  			groupA := g[i]
   145  			groupB := g[j]
   146  
   147  			groupADescription := groupA.GetMetadata().Description
   148  			groupBDescription := groupB.GetMetadata().Description
   149  
   150  			if oktaDescription, ok := groupA.GetLabel(OktaGroupDescriptionLabel); ok {
   151  				groupADescription = oktaDescription
   152  			}
   153  			if oktaDescription, ok := groupB.GetLabel(OktaGroupDescriptionLabel); ok {
   154  				groupBDescription = oktaDescription
   155  			}
   156  
   157  			return stringCompare(strings.ToLower(groupADescription), strings.ToLower(groupBDescription), isDesc)
   158  		})
   159  
   160  	default:
   161  		return trace.NotImplemented("sorting by field %q for resource %q is not supported", sortBy.Field, KindKubeServer)
   162  	}
   163  
   164  	return nil
   165  }
   166  
   167  // Len returns the slice length.
   168  func (g UserGroups) Len() int { return len(g) }
   169  
   170  // Less compares user groups by name.
   171  func (g UserGroups) Less(i, j int) bool { return g[i].GetName() < g[j].GetName() }
   172  
   173  // Swap swaps two user groups.
   174  func (g UserGroups) Swap(i, j int) { g[i], g[j] = g[j], g[i] }