github.com/google/osv-scalibr@v0.4.1/veles/secrets/hashicorpvault/hashicorpvault_test.go (about)

     1  // Copyright 2025 Google LLC
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package hashicorpvault
    16  
    17  import (
    18  	"testing"
    19  )
    20  
    21  func TestIsVaultToken(t *testing.T) {
    22  	tests := []struct {
    23  		name     string
    24  		token    string
    25  		expected bool
    26  	}{
    27  		{
    28  			name:     "hvs token",
    29  			token:    "hvs.CAESIB8KI2QJk0ePUYdOQXaxl0",
    30  			expected: true,
    31  		},
    32  		{
    33  			name:     "hvb token",
    34  			token:    "hvb.AAAAAQJz0zBvWUNOIKTkDhY",
    35  			expected: true,
    36  		},
    37  		{
    38  			name:     "legacy s token",
    39  			token:    "s.VUFMJlFreGZNZOeQQPiSSviF",
    40  			expected: true,
    41  		},
    42  		{
    43  			name:     "legacy b token",
    44  			token:    "b.AUFMJlFreGZNZOeQQPiSSviF",
    45  			expected: true,
    46  		},
    47  		{
    48  			name:     "legacy r token",
    49  			token:    "r.VUFMJlFreGZNZOeQQPiSSviF",
    50  			expected: true,
    51  		},
    52  		{
    53  			name:     "not a vault token",
    54  			token:    "some-other-token",
    55  			expected: false,
    56  		},
    57  		{
    58  			name:     "empty string",
    59  			token:    "",
    60  			expected: false,
    61  		},
    62  		{
    63  			name:     "prefix only hvs",
    64  			token:    "hvs.",
    65  			expected: true,
    66  		},
    67  		{
    68  			name:     "prefix only hvb",
    69  			token:    "hvb.",
    70  			expected: true,
    71  		},
    72  		{
    73  			name:     "prefix only s",
    74  			token:    "s.",
    75  			expected: true,
    76  		},
    77  		{
    78  			name:     "wrong prefix hvx",
    79  			token:    "hvx.CAESIB8KI2QJk0ePUYdOQXaxl0",
    80  			expected: false,
    81  		},
    82  		{
    83  			name:     "wrong prefix hvp (should be hvb)",
    84  			token:    "hvp.CAESIB8KI2QJk0ePUYdOQXaxl0",
    85  			expected: false,
    86  		},
    87  		{
    88  			name:     "case sensitive - HVS",
    89  			token:    "HVS.CAESIB8KI2QJk0ePUYdOQXaxl0",
    90  			expected: false,
    91  		},
    92  		{
    93  			name:     "invalid format - missing dot",
    94  			token:    "hvs_CAESIB8KI2QJk0ePUYdOQXaxl0",
    95  			expected: false,
    96  		},
    97  		{
    98  			name:     "invalid format - wrong separator",
    99  			token:    "hvs-CAESIB8KI2QJk0ePUYdOQXaxl0",
   100  			expected: false,
   101  		},
   102  		{
   103  			name:     "invalid format - double prefix",
   104  			token:    "hvshvs.CAESIB8KI2QJk0ePUYdOQXaxl0",
   105  			expected: false,
   106  		},
   107  	}
   108  
   109  	for _, test := range tests {
   110  		t.Run(test.name, func(t *testing.T) {
   111  			result := isVaultToken(test.token)
   112  			if result != test.expected {
   113  				t.Errorf("isVaultToken(%q) = %v, want %v", test.token, result, test.expected)
   114  			}
   115  		})
   116  	}
   117  }
   118  
   119  func TestIsUUID(t *testing.T) {
   120  	tests := []struct {
   121  		name     string
   122  		uuid     string
   123  		expected bool
   124  	}{
   125  		{
   126  			name:     "valid UUID v4",
   127  			uuid:     "12345678-1234-1234-1234-123456789012",
   128  			expected: true,
   129  		},
   130  		{
   131  			name:     "valid UUID with lowercase",
   132  			uuid:     "87654321-abcd-efgh-ijkl-210987654321",
   133  			expected: false, // 'g', 'h', 'i', 'j', 'k', 'l' are not valid hex characters
   134  		},
   135  		{
   136  			name:     "valid UUID with mixed case",
   137  			uuid:     "12345678-ABCD-1234-EFGH-123456789012",
   138  			expected: false, // 'G' and 'H' are not valid hex characters
   139  		},
   140  		{
   141  			name:     "valid UUID with valid hex only",
   142  			uuid:     "12345678-abcd-1234-efab-123456789012",
   143  			expected: true,
   144  		},
   145  		{
   146  			name:     "too short",
   147  			uuid:     "12345678-1234-1234-1234-12345678901",
   148  			expected: false,
   149  		},
   150  		{
   151  			name:     "too long",
   152  			uuid:     "12345678-1234-1234-1234-1234567890123",
   153  			expected: false,
   154  		},
   155  		{
   156  			name:     "missing hyphens",
   157  			uuid:     "123456781234123412341234567890123",
   158  			expected: false,
   159  		},
   160  		{
   161  			name:     "wrong hyphen positions",
   162  			uuid:     "1234567-8123-41234-1234-567890123",
   163  			expected: false,
   164  		},
   165  		{
   166  			name:     "empty string",
   167  			uuid:     "",
   168  			expected: false,
   169  		},
   170  		{
   171  			name:     "invalid characters",
   172  			uuid:     "12345678-1234-1234-1234-12345678901z",
   173  			expected: false,
   174  		},
   175  		{
   176  			name:     "all special characters",
   177  			uuid:     "!@#$%^&*-()_+-={}[]-\\|;':\",.<>?/~`",
   178  			expected: false,
   179  		},
   180  		{
   181  			name:     "numbers only",
   182  			uuid:     "123456789012345678901234567890123456",
   183  			expected: false,
   184  		},
   185  		{
   186  			name:     "letters only",
   187  			uuid:     "abcdefgh-ijkl-mnop-qrst-uvwxyzabcdef",
   188  			expected: false,
   189  		},
   190  		{
   191  			name:     "mixed valid and invalid hex",
   192  			uuid:     "12345678-abcd-xyzt-1234-123456789012",
   193  			expected: false,
   194  		},
   195  	}
   196  
   197  	for _, test := range tests {
   198  		t.Run(test.name, func(t *testing.T) {
   199  			result := isUUID(test.uuid)
   200  			if result != test.expected {
   201  				t.Errorf("isUUID(%q) = %v, want %v", test.uuid, result, test.expected)
   202  			}
   203  		})
   204  	}
   205  }
   206  
   207  func TestIsAppRoleCredential(t *testing.T) {
   208  	tests := []struct {
   209  		name     string
   210  		s        string
   211  		expected bool
   212  	}{
   213  		{
   214  			name:     "valid UUID",
   215  			s:        "12345678-1234-1234-1234-123456789012",
   216  			expected: true,
   217  		},
   218  		{
   219  			name:     "invalid format",
   220  			s:        "not-a-uuid",
   221  			expected: false,
   222  		},
   223  		{
   224  			name:     "empty string",
   225  			s:        "",
   226  			expected: false,
   227  		},
   228  		{
   229  			name:     "almost valid UUID - wrong format",
   230  			s:        "12345678_1234_1234_1234_123456789012",
   231  			expected: false,
   232  		},
   233  		{
   234  			name:     "truncated UUID",
   235  			s:        "12345678-1234-1234-1234",
   236  			expected: false,
   237  		},
   238  		{
   239  			name:     "extended UUID",
   240  			s:        "12345678-1234-1234-1234-123456789012-extra",
   241  			expected: false,
   242  		},
   243  		{
   244  			name:     "mixed case valid UUID",
   245  			s:        "12345678-ABCD-1234-EFAB-123456789012",
   246  			expected: true,
   247  		},
   248  	}
   249  
   250  	for _, test := range tests {
   251  		t.Run(test.name, func(t *testing.T) {
   252  			result := isAppRoleCredential(test.s)
   253  			if result != test.expected {
   254  				t.Errorf("isAppRoleCredential(%q) = %v, want %v", test.s, result, test.expected)
   255  			}
   256  		})
   257  	}
   258  }