mirror of
				https://github.com/juanfont/headscale.git
				synced 2025-11-04 01:51:04 +01:00 
			
		
		
		
	Add helper function to create a unique givenname
This commit is contained in:
		
							parent
							
								
									f4873d9387
								
							
						
					
					
						commit
						177c21b294
					
				
							
								
								
									
										30
									
								
								machine.go
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								machine.go
									
									
									
									
									
								
							@ -26,6 +26,7 @@ const (
 | 
			
		||||
	)
 | 
			
		||||
	errCouldNotConvertMachineInterface = Error("failed to convert machine interface")
 | 
			
		||||
	errHostnameTooLong                 = Error("Hostname too long")
 | 
			
		||||
	MachineGivenNameHashLength         = 8
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
@ -813,3 +814,32 @@ func (machine *Machine) RoutesToProto() *v1.Routes {
 | 
			
		||||
		EnabledRoutes:    ipPrefixToString(enabledRoutes),
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (h *Headscale) GenerateGivenName(suppliedName string) (string, error) {
 | 
			
		||||
	// If a hostname is or will be longer than 63 chars after adding the hash,
 | 
			
		||||
	// it needs to be trimmed.
 | 
			
		||||
	trimmedHostnameLength := labelHostnameLength - MachineGivenNameHashLength - 2
 | 
			
		||||
 | 
			
		||||
	normalizedHostname, err := NormalizeToFQDNRules(
 | 
			
		||||
		suppliedName,
 | 
			
		||||
		h.cfg.OIDC.StripEmaildomain,
 | 
			
		||||
	)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	postfix, err := GenerateRandomStringDNSSafe(MachineGivenNameHashLength)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return "", err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Verify that that the new unique name is shorter than the maximum allowed
 | 
			
		||||
	// DNS segment.
 | 
			
		||||
	if len(normalizedHostname) <= trimmedHostnameLength {
 | 
			
		||||
		normalizedHostname = fmt.Sprintf("%s-%s", normalizedHostname, postfix)
 | 
			
		||||
	} else {
 | 
			
		||||
		normalizedHostname = fmt.Sprintf("%s-%s", normalizedHostname[:trimmedHostnameLength], postfix)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return normalizedHostname, nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										134
									
								
								machine_test.go
									
									
									
									
									
								
							
							
						
						
									
										134
									
								
								machine_test.go
									
									
									
									
									
								
							@ -4,6 +4,7 @@ import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"reflect"
 | 
			
		||||
	"strconv"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"testing"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
@ -654,3 +655,136 @@ func Test_getFilteredByACLPeers(t *testing.T) {
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestHeadscale_GenerateGivenName(t *testing.T) {
 | 
			
		||||
	type args struct {
 | 
			
		||||
		suppliedName string
 | 
			
		||||
	}
 | 
			
		||||
	tests := []struct {
 | 
			
		||||
		name    string
 | 
			
		||||
		h       *Headscale
 | 
			
		||||
		args    args
 | 
			
		||||
		want    string
 | 
			
		||||
		wantErr bool
 | 
			
		||||
	}{
 | 
			
		||||
		{
 | 
			
		||||
			name: "simple machine name generation",
 | 
			
		||||
			h: &Headscale{
 | 
			
		||||
				cfg: Config{
 | 
			
		||||
					OIDC: OIDCConfig{
 | 
			
		||||
						StripEmaildomain: true,
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			args: args{
 | 
			
		||||
				suppliedName: "testmachine",
 | 
			
		||||
			},
 | 
			
		||||
			want:    "testmachine",
 | 
			
		||||
			wantErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "machine name with 53 chars",
 | 
			
		||||
			h: &Headscale{
 | 
			
		||||
				cfg: Config{
 | 
			
		||||
					OIDC: OIDCConfig{
 | 
			
		||||
						StripEmaildomain: true,
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			args: args{
 | 
			
		||||
				suppliedName: "testmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaachine",
 | 
			
		||||
			},
 | 
			
		||||
			want:    "testmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaachine",
 | 
			
		||||
			wantErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "machine name with 60 chars",
 | 
			
		||||
			h: &Headscale{
 | 
			
		||||
				cfg: Config{
 | 
			
		||||
					OIDC: OIDCConfig{
 | 
			
		||||
						StripEmaildomain: true,
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			args: args{
 | 
			
		||||
				suppliedName: "testmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaachine1234567",
 | 
			
		||||
			},
 | 
			
		||||
			want:    "testmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaachine",
 | 
			
		||||
			wantErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "machine name with 63 chars",
 | 
			
		||||
			h: &Headscale{
 | 
			
		||||
				cfg: Config{
 | 
			
		||||
					OIDC: OIDCConfig{
 | 
			
		||||
						StripEmaildomain: true,
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			args: args{
 | 
			
		||||
				suppliedName: "testmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaachine1234567890",
 | 
			
		||||
			},
 | 
			
		||||
			want:    "testmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
 | 
			
		||||
			wantErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "machine name with 64 chars",
 | 
			
		||||
			h: &Headscale{
 | 
			
		||||
				cfg: Config{
 | 
			
		||||
					OIDC: OIDCConfig{
 | 
			
		||||
						StripEmaildomain: true,
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			args: args{
 | 
			
		||||
				suppliedName: "testmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaachine1234567891",
 | 
			
		||||
			},
 | 
			
		||||
			want:    "testmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
 | 
			
		||||
			wantErr: false,
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "machine name with 73 chars",
 | 
			
		||||
			h: &Headscale{
 | 
			
		||||
				cfg: Config{
 | 
			
		||||
					OIDC: OIDCConfig{
 | 
			
		||||
						StripEmaildomain: true,
 | 
			
		||||
					},
 | 
			
		||||
				},
 | 
			
		||||
			},
 | 
			
		||||
			args: args{
 | 
			
		||||
				suppliedName: "testmaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaachine12345678901234567890",
 | 
			
		||||
			},
 | 
			
		||||
			want:    "",
 | 
			
		||||
			wantErr: true,
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for _, tt := range tests {
 | 
			
		||||
		t.Run(tt.name, func(t *testing.T) {
 | 
			
		||||
			got, err := tt.h.GenerateGivenName(tt.args.suppliedName)
 | 
			
		||||
			if (err != nil) != tt.wantErr {
 | 
			
		||||
				t.Errorf(
 | 
			
		||||
					"Headscale.GenerateGivenName() error = %v, wantErr %v",
 | 
			
		||||
					err,
 | 
			
		||||
					tt.wantErr,
 | 
			
		||||
				)
 | 
			
		||||
				return
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if tt.want != "" && strings.Contains(tt.want, got) {
 | 
			
		||||
				t.Errorf(
 | 
			
		||||
					"Headscale.GenerateGivenName() = %v, is not a substring of %v",
 | 
			
		||||
					tt.want,
 | 
			
		||||
					got,
 | 
			
		||||
				)
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			if len(got) > labelHostnameLength {
 | 
			
		||||
				t.Errorf(
 | 
			
		||||
					"Headscale.GenerateGivenName() = %v is larger than allowed DNS segment %d",
 | 
			
		||||
					got,
 | 
			
		||||
					labelHostnameLength,
 | 
			
		||||
				)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										13
									
								
								utils.go
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								utils.go
									
									
									
									
									
								
							@ -317,3 +317,16 @@ func GenerateRandomStringURLSafe(n int) (string, error) {
 | 
			
		||||
 | 
			
		||||
	return base64.RawURLEncoding.EncodeToString(b), err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GenerateRandomStringDNSSafe returns a DNS-safe
 | 
			
		||||
// securely generated random string.
 | 
			
		||||
// It will return an error if the system's secure random
 | 
			
		||||
// number generator fails to function correctly, in which
 | 
			
		||||
// case the caller should not continue.
 | 
			
		||||
func GenerateRandomStringDNSSafe(n int) (string, error) {
 | 
			
		||||
	str, err := GenerateRandomStringURLSafe(n)
 | 
			
		||||
 | 
			
		||||
	str = strings.ReplaceAll(str, "_", "-")
 | 
			
		||||
 | 
			
		||||
	return str[:n], err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user