src/server/auth/server/api_server.go
func (a *apiServer) setGroupsForUserInternal(ctx context.Context, subject string, groups []string) error {
	_, err := col.NewSTM(ctx, a.env.GetEtcdClient(), func(stm col.STM) error {
		members := a.members.ReadWrite(stm)

		// Get groups to remove/add user from/to
		var removeGroups authclient.Groups
		addGroups := addToSet(nil, groups...)
		if err := members.Get(subject, &removeGroups); err == nil {
			for _, group := range groups {
				if removeGroups.Groups[group] {
					removeGroups.Groups = removeFromSet(removeGroups.Groups, group)
					addGroups = removeFromSet(addGroups, group)
				}
			}
		}

		// Set groups for user
		if err := members.Put(subject, &authclient.Groups{
			Groups: addToSet(nil, groups...),
		}); err != nil {
			return err
		}

		// Remove user from previous groups
		groups := a.groups.ReadWrite(stm)
		var membersProto authclient.Users
		for group := range removeGroups.Groups {
			if err := groups.Upsert(group, &membersProto, func() error {
				membersProto.Usernames = removeFromSet(membersProto.Usernames, subject)
				return nil
			}); err != nil {
				return err
			}
		}

		// Add user to new groups
		for group := range addGroups {
			if err := groups.Upsert(group, &membersProto, func() error {
				membersProto.Usernames = addToSet(membersProto.Usernames, subject)
				return nil
			}); err != nil {
				return err
			}
		}

		return nil
	})
	return err
}
func (a *apiServer) setGroupsForUserInternal(ctx context.Context, subject string, groups []string) error {
	_, err := col.NewSTM(ctx, a.env.GetEtcdClient(), func(stm col.STM) error {
		members := a.members.ReadWrite(stm)

		// Get groups to remove/add user from/to
		var removeGroups authclient.Groups
		addGroups := addToSet(nil, groups...)
		if err := members.Get(subject, &removeGroups); err == nil {
			for _, group := range groups {
				if removeGroups.Groups[group] {
					removeGroups.Groups = removeFromSet(removeGroups.Groups, group)
					addGroups = removeFromSet(addGroups, group)
				}
			}
		}

		// Set groups for user
		if err := members.Put(subject, &authclient.Groups{
			Groups: addToSet(nil, groups...),
		}); err != nil {
			return err
		}

		// Remove user from previous groups
		groups := a.groups.ReadWrite(stm)
		var membersProto authclient.Users
		for group := range removeGroups.Groups {
			if err := groups.Upsert(group, &membersProto, func() error {
				membersProto.Usernames = removeFromSet(membersProto.Usernames, subject)
				return nil
			}); err != nil {
				return err
			}
		}

		// Add user to new groups
		for group := range addGroups {
			if err := groups.Upsert(group, &membersProto, func() error {
				membersProto.Usernames = addToSet(membersProto.Usernames, subject)
				return nil
			}); err != nil {
				return err
			}
		}

		return nil
	})
	return err
}
func ( a * apiServer ) setGroupsForUserInternal ( ctx context . Context , subject string , groups [ ] string ) error { _ , err := col . NewSTM ( ctx , a . env . GetEtcdClient ( ) , func ( stm col . STM ) error { members := a . members . ReadWrite ( stm ) // Get groups to remove/add user from/to var removeGroups authclient . Groups addGroups := addToSet ( nil , groups ... ) if err := members . Get ( subject , & removeGroups ) ; err == nil { for _ , group := range groups { if removeGroups . Groups [ group ] { removeGroups . Groups = removeFromSet ( removeGroups . Groups , group ) addGroups = removeFromSet ( addGroups , group ) } } } // Set groups for user if err := members . Put ( subject , & authclient . Groups { Groups : addToSet ( nil , groups ... ) , } ) ; err != nil { return err } // Remove user from previous groups groups := a . groups . ReadWrite ( stm ) var membersProto authclient . Users for group := range removeGroups . Groups { if err := groups . Upsert ( group , & membersProto , func ( ) error { membersProto . Usernames = removeFromSet ( membersProto . Usernames , subject ) return nil } ) ; err != nil { return err } } // Add user to new groups for group := range addGroups { if err := groups . Upsert ( group , & membersProto , func ( ) error { membersProto . Usernames = addToSet ( membersProto . Usernames , subject ) return nil } ) ; err != nil { return err } } return nil } ) return err }
// setGroupsForUserInternal is a helper function used by SetGroupsForUser, and
// also by handleSAMLResponse (which updates group membership information based
// on signed SAML assertions). This does no auth checks, so the caller must do
// all relevant authorization.
setGroupsForUserInternal is a helper function used by SetGroupsForUser and also by handleSAMLResponse ( which updates group membership information based on signed SAML assertions ) . This does no auth checks so the caller must do all relevant authorization .