github.com/Azure/go-autorest/autorest/azure/auth@v0.5.12/auth_test.go (about) 1 // Copyright 2017 Microsoft Corporation 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 auth 16 17 import ( 18 "os" 19 "path/filepath" 20 "reflect" 21 "testing" 22 23 "github.com/Azure/go-autorest/autorest" 24 "github.com/Azure/go-autorest/autorest/azure" 25 ) 26 27 var ( 28 expectedEnvironment = EnvironmentSettings{ 29 Values: map[string]string{ 30 SubscriptionID: "sub-abc-123", 31 TenantID: "tenant-abc-123", 32 ClientID: "client-abc-123", 33 ClientSecret: "client-secret-123", 34 CertificatePath: "~/some/path/cert.pfx", 35 CertificatePassword: "certificate-password", 36 Username: "user-name-abc", 37 Password: "user-password-123", 38 Resource: "my-resource", 39 }, 40 Environment: azure.PublicCloud, 41 } 42 expectedFile = FileSettings{ 43 Values: map[string]string{ 44 ClientID: "client-id-123", 45 ClientSecret: "client-secret-456", 46 SubscriptionID: "sub-id-789", 47 TenantID: "tenant-id-123", 48 ActiveDirectoryEndpoint: "https://login.microsoftonline.com", 49 ResourceManagerEndpoint: "https://management.azure.com/", 50 GraphResourceID: "https://graph.windows.net/", 51 SQLManagementEndpoint: "https://management.core.windows.net:8443/", 52 GalleryEndpoint: "https://gallery.azure.com/", 53 ManagementEndpoint: "https://management.core.windows.net/", 54 }, 55 } 56 ) 57 58 func setDefaultEnv() { 59 os.Setenv(SubscriptionID, expectedEnvironment.Values[SubscriptionID]) 60 os.Setenv(TenantID, expectedEnvironment.Values[TenantID]) 61 os.Setenv(ClientID, expectedEnvironment.Values[ClientID]) 62 os.Setenv(ClientSecret, expectedEnvironment.Values[ClientSecret]) 63 os.Setenv(CertificatePath, expectedEnvironment.Values[CertificatePath]) 64 os.Setenv(CertificatePassword, expectedEnvironment.Values[CertificatePassword]) 65 os.Setenv(Username, expectedEnvironment.Values[Username]) 66 os.Setenv(Password, expectedEnvironment.Values[Password]) 67 os.Setenv(Resource, expectedEnvironment.Values[Resource]) 68 } 69 70 func TestGetSettingsFromEnvironment(t *testing.T) { 71 setDefaultEnv() 72 settings, err := GetSettingsFromEnvironment() 73 if err != nil { 74 t.Logf("failed to get settings: %v", err) 75 t.Fail() 76 } 77 if !reflect.DeepEqual(expectedEnvironment, settings) { 78 t.Logf("expected %v, got %v", expectedEnvironment, settings) 79 t.Fail() 80 } 81 if settings.GetSubscriptionID() != expectedEnvironment.Values[SubscriptionID] { 82 t.Log("settings.GetSubscriptionID() return value didn't match") 83 t.Fail() 84 } 85 } 86 87 func TestGetSettingsFromEnvironmentBadEnvironmentName(t *testing.T) { 88 os.Setenv(EnvironmentName, "badenvironment") 89 defer func() { 90 // must undo this value else other tests will fail 91 os.Setenv(EnvironmentName, "") 92 }() 93 _, err := GetSettingsFromEnvironment() 94 if err == nil { 95 t.Log("unexpected nil error") 96 t.Fail() 97 } 98 } 99 100 func TestEnvGetClientCertificate(t *testing.T) { 101 setDefaultEnv() 102 settings, err := GetSettingsFromEnvironment() 103 if err != nil { 104 t.Logf("failed to get settings: %v", err) 105 t.Fail() 106 } 107 cfg, err := settings.GetClientCertificate() 108 if err != nil { 109 t.Logf("failed to get config for client cert: %v", err) 110 t.Fail() 111 } 112 if cfg.CertificatePath != expectedEnvironment.Values[CertificatePath] { 113 t.Log("bad certificate path") 114 t.Fail() 115 } 116 if cfg.CertificatePassword != expectedEnvironment.Values[CertificatePassword] { 117 t.Log("bad certificate password") 118 t.Fail() 119 } 120 // should fail as the certificate doesn't exist 121 _, err = cfg.Authorizer() 122 if err == nil { 123 t.Log("unexpected nil error") 124 t.Fail() 125 } 126 } 127 128 func TestEnvGetUsernamePassword(t *testing.T) { 129 setDefaultEnv() 130 settings, err := GetSettingsFromEnvironment() 131 if err != nil { 132 t.Logf("failed to get settings: %v", err) 133 t.Fail() 134 } 135 cfg, err := settings.GetUsernamePassword() 136 if err != nil { 137 t.Logf("failed to get config for username/password: %v", err) 138 t.Fail() 139 } 140 _, err = cfg.Authorizer() 141 if err != nil { 142 t.Logf("failed to get authorizer for username/password: %v", err) 143 t.Fail() 144 } 145 } 146 147 func TestEnvGetMSI(t *testing.T) { 148 setDefaultEnv() 149 settings, err := GetSettingsFromEnvironment() 150 if err != nil { 151 t.Logf("failed to get settings: %v", err) 152 t.Fail() 153 } 154 cfg := settings.GetMSI() 155 if cfg.Resource == "" { 156 t.Fatal("unexpected empty resource") 157 } 158 } 159 160 func TestEnvGetDeviceFlow(t *testing.T) { 161 setDefaultEnv() 162 settings, err := GetSettingsFromEnvironment() 163 if err != nil { 164 t.Logf("failed to get settings: %v", err) 165 t.Fail() 166 } 167 cfg := settings.GetDeviceFlow() 168 // TODO mock device flow? 169 if cfg.ClientID != expectedEnvironment.Values[ClientID] { 170 t.Log("bad client ID") 171 t.Fail() 172 } 173 if cfg.TenantID != expectedEnvironment.Values[TenantID] { 174 t.Log("bad tenant ID") 175 t.Fail() 176 } 177 } 178 179 func TestGetSettingsFromFile(t *testing.T) { 180 os.Setenv("AZURE_AUTH_LOCATION", "./testdata/credsutf16le.json") 181 settings, err := GetSettingsFromFile() 182 if err != nil { 183 t.Logf("failed to load config file: %v", err) 184 t.Fail() 185 } 186 if !reflect.DeepEqual(expectedFile, settings) { 187 t.Logf("expected %v, got %v", expectedFile, settings) 188 t.Fail() 189 } 190 if settings.GetSubscriptionID() != expectedFile.Values[SubscriptionID] { 191 t.Log("settings.GetSubscriptionID() return value didn't match") 192 t.Fail() 193 } 194 } 195 196 func TestNewAuthorizerFromFile(t *testing.T) { 197 os.Setenv("AZURE_AUTH_LOCATION", "./testdata/credsutf16le.json") 198 authorizer, err := NewAuthorizerFromFile("https://management.azure.com") 199 if err != nil || authorizer == nil { 200 t.Logf("NewAuthorizerFromFile failed, got error %v", err) 201 t.Fail() 202 } 203 } 204 205 func TestNewAuthorizerFromFileWithResource(t *testing.T) { 206 os.Setenv("AZURE_AUTH_LOCATION", "./testdata/credsutf16le.json") 207 authorizer, err := NewAuthorizerFromFileWithResource("https://my.vault.azure.net") 208 if err != nil || authorizer == nil { 209 t.Logf("NewAuthorizerFromFileWithResource failed, got error %v", err) 210 t.Fail() 211 } 212 } 213 214 func TestNewAuthorizerFromEnvironment(t *testing.T) { 215 setDefaultEnv() 216 authorizer, err := NewAuthorizerFromEnvironment() 217 218 if err != nil || authorizer == nil { 219 t.Logf("NewAuthorizerFromEnvironment failed, got error %v", err) 220 t.Fail() 221 } 222 } 223 224 func TestNewAuthorizerFromEnvironmentWithResource(t *testing.T) { 225 setDefaultEnv() 226 authorizer, err := NewAuthorizerFromEnvironmentWithResource("https://my.vault.azure.net") 227 228 if err != nil || authorizer == nil { 229 t.Logf("NewAuthorizerFromEnvironmentWithResource failed, got error %v", err) 230 t.Fail() 231 } 232 } 233 234 func TestDecodeAndUnmarshal(t *testing.T) { 235 tests := []string{ 236 "credsutf8.json", 237 "credsutf16le.json", 238 "credsutf16be.json", 239 } 240 for _, test := range tests { 241 os.Setenv("AZURE_AUTH_LOCATION", filepath.Join("./testdata/", test)) 242 settings, err := GetSettingsFromFile() 243 if err != nil { 244 t.Logf("error reading file '%s': %s", test, err) 245 t.Fail() 246 } 247 if !reflect.DeepEqual(expectedFile, settings) { 248 t.Logf("unmarshaled map expected %v, got %v", expectedFile, settings) 249 t.Fail() 250 } 251 } 252 } 253 254 func TestFileClientCertificateAuthorizer(t *testing.T) { 255 os.Setenv("AZURE_AUTH_LOCATION", "./testdata/credsutf8.json") 256 settings, err := GetSettingsFromFile() 257 if err != nil { 258 t.Logf("failed to load file settings: %v", err) 259 t.Fail() 260 } 261 // add certificate settings 262 settings.Values[CertificatePath] = "~/fake/path/cert.pfx" 263 settings.Values[CertificatePassword] = "fake-password" 264 _, err = settings.ClientCertificateAuthorizer("https://management.azure.com") 265 if err == nil { 266 t.Log("unexpected nil error") 267 t.Fail() 268 } 269 } 270 271 func TestFileGetAuthorizerClientCert(t *testing.T) { 272 t.Setenv("AZURE_AUTH_LOCATION", "./testdata/credsutf8.json") 273 settings, err := GetSettingsFromFile() 274 if err != nil { 275 t.Logf("failed to load file settings: %v", err) 276 t.Fail() 277 } 278 // add certificate settings 279 settings.Values[CertificatePath] = "~/fake/path/cert.pfx" 280 settings.Values[CertificatePassword] = "fake-password" 281 auth, err := settings.GetAuthorizer("https://management.azure.com") 282 if err != nil { 283 t.Logf("failed to get authorizer: %v", err) 284 t.Fail() 285 } 286 if _, ok := auth.(*autorest.BearerAuthorizer); !ok { 287 t.Fatalf("unexpected authorizer type %T", auth) 288 } 289 } 290 291 func TestMultitenantClientCredentials(t *testing.T) { 292 setDefaultEnv() 293 os.Setenv(AuxiliaryTenantIDs, "aux-tenant-1;aux-tenant-2;aux-tenant3") 294 defer func() { 295 os.Setenv(AuxiliaryTenantIDs, "") 296 }() 297 settings, err := GetSettingsFromEnvironment() 298 if err != nil { 299 t.Fatalf("failed to get settings from environment: %v", err) 300 } 301 if settings.Values[AuxiliaryTenantIDs] == "" { 302 t.Fatal("auxiliary tenant IDs are missing in settings") 303 } 304 ccc, err := settings.GetClientCredentials() 305 if err != nil { 306 t.Fatalf("failed to get client credentials config: %v", err) 307 } 308 if len(ccc.AuxTenants) == 0 { 309 t.Fatal("auxiliary tenant IDs are missing in config") 310 } 311 expected := []string{"aux-tenant-1", "aux-tenant-2", "aux-tenant3"} 312 if !reflect.DeepEqual(ccc.AuxTenants, expected) { 313 t.Fatalf("expected auxiliary tenants '%s', got '%s'", expected, ccc.AuxTenants) 314 } 315 a, err := ccc.Authorizer() 316 if err != nil { 317 t.Fatalf("failed to create authorizer: %v", err) 318 } 319 if _, ok := a.(autorest.MultiTenantServicePrincipalTokenAuthorizer); !ok { 320 t.Fatal("authorizer doesn't implement MultiTenantServicePrincipalTokenAuthorizer") 321 } 322 }