-
Notifications
You must be signed in to change notification settings - Fork 566
support for authentication using sp from auth file #2231
Conversation
amarzavery
commented
Jul 22, 2017
•
edited
Loading
edited
- @balajikris @yugangw-msft - Please review
dfa4c13
to
6bbc5da
Compare
runtime/ms-rest-azure/package.json
Outdated
@@ -22,11 +34,12 @@ | |||
"@types/node": "^7.0.10" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
min dependency for ms-rest should go to ^2.2.2 as the _withAuthFile()
function in login.js depends on a function homeDir() added in msRest in this PR. After the CI for first commit is green will update this dep in second commit. until the ms-rest version is not published this PR will fail in the second commit due to this reason.
rpName.should.equal('Microsoft.Devices'); | ||
done(); | ||
}); | ||
it('should correctly parse the error message from service for an existing subscription where the RP was manually unregistered', (done) => { | ||
let msg = "{\"error\":{\"code\":\"MissingSubscriptionRegistration\",\"message\":\"The subscription registration is in 'Unregistered' state. The subscription must be registered to use namespace 'Microsoft.Devices'. See https://aka.ms/rps-not-found for how to register subscriptions.\"}}"; | ||
var msg = "{\"error\":{\"code\":\"MissingSubscriptionRegistration\",\"message\":\"The subscription registration is in 'Unregistered' state. The subscription must be registered to use namespace 'Microsoft.Devices'. See https://aka.ms/rps-not-found for how to register subscriptions.\"}}"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a reason to go from let
to var
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
jshint was complaining. So changed it.
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. See License.txt in the project root for license information. | ||
|
||
var assert = require('assert'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
const
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should be ok for now
var dummyCreds = { | ||
tokenAudience: undefined, | ||
environment: {}, | ||
authorizattionScheme: 'Bearer', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo. authorizationScheme
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
thanks for pointing
}); | ||
}); | ||
|
||
it('should add custom env to AzureEnvironment and authenticate against it', (done) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
2 more scenarios come to mind -
- authfile with insufficient data (if az-cli encounters a bug while generating auth file)
- foreign cloud environments? not sure if this is testable with stubs, so i'll leave it to you to decide.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for 2. what i intend to test here is that: if someone wants to test against dogfood or other env that is not predefined then our code can correctly add that environment and try to authenticate using the sp info
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
for 1. I have the _validateAuthFileContent that throws an error if something is incorrect.
I can add a test for that scenario.
runtime/ms-rest-azure/lib/login.js
Outdated
content = fs.readFileSync(filePath, {encoding: 'utf8'}); | ||
credsObj = JSON.parse(content); | ||
_validateAuthFileContent(credsObj, filePath); | ||
if (!process.env[subscriptionEnvVariableName]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move this to outside of the try-catch
. The code in its current shape reads like - read and parse a json.. if an environment variable isn't set, then set it and the flow breaks there. which makes me wonder, why read and parse at all if the env var is already set. The answer is few lines below here, where we continue to use credsObj
. So, move the setting of subscription
to outside the try-catch
and it doesn't need a try-catch anyway.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The environment variable that we are setting over here is the env. variable for subscriptionId. It is not the env. var for auth location. Node sdk has a recommended set of environment variables for things like subscriptionId, clientId, username, password, domain, etc.
So in this case, if the user provides his custom environment variable name that is being used in his app then we use that env. variable to set the value of subscriptionId. IF not then we set the subscriptionId to AZURE_SUBSCRIPTION_ID env. variable.
This subscription Id will be the only subscriptionId that the customer can use while instantiating the client since the SP is linked to that subscription. Using any other subscriptionId will be setting him up for failure.
I know this is a bit confusing. But whatever I said above, does that make sense or clear the initial question that you asked?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the check is incorrect. It should actually be like this:
//just set the environment variable to correct subscriptionId from the auth file if it is not present.
if (process.env[subscriptionEnvVariableName] && process.env[subscriptionEnvVariableName] !== credsObj.subscriptionId) {
process.env[subscriptionEnvVariableName] = credsObj.subscriptionId;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hope I understand the context correctly, the subscription from the auth file should be precedent the environment variable. You can overwrite the environment variable here, but that should be just an implementation detail being transparent to users. Same with other fields.
If I got it right, then we don't need an if
condition, just overwrite it, optionally emit out a warning if you still like users to know.
runtime/ms-rest-azure/lib/login.js
Outdated
break; | ||
} | ||
} | ||
if (envFound.state) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
dont think you need state
field. can simply check if name is not null or empty?
runtime/ms-rest-azure/lib/login.js
Outdated
let msg = `Either provide an absolute file path to the auth file or set/export the environment variable - ${azureConstants.AZURE_AUTH_LOCATION}.`; | ||
return callback(new Error(msg)); | ||
} | ||
filePath = authLocation; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if the filePath is not provided then we look for the authLocation (env. var). If that is not provided as well then we throw. If it is provided then we set the value of authlocation env. var to the filePath parameter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM overall
runtime/ms-rest-azure/lib/login.js
Outdated
if (!credsObj.sqlManagementEndpointUrl) { | ||
throw new Error(`"sqlManagementEndpointUrl" is missing from the auth file: ${filePath}.`); | ||
} | ||
if (!credsObj.galleryEndpointUrl) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest we don't throw on this as this gallery endpoint is not being used by any clients, which we can consider to pulling it out in future
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
runtime/ms-rest-azure/lib/login.js
Outdated
if (!credsObj.galleryEndpointUrl) { | ||
throw new Error(`"galleryEndpointUrl" is missing from the auth file: ${filePath}.`); | ||
} | ||
if (!credsObj.managementEndpointUrl) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest we don't error on this as well, rather SDK should default to resourceManagerEndpointUrl
for management client
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
runtime/ms-rest-azure/lib/login.js
Outdated
throw new Error('callback cannot be null or undefined.'); | ||
} | ||
|
||
let filePath = options.filePath; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
in case it helps, will the following code simplify it?
let filePath = options.filePath || process.env[azureConstants.AZURE_AUTH_LOCATION]`
if !filepath:
return callback(new Error(...))
runtime/ms-rest-azure/lib/login.js
Outdated
content = fs.readFileSync(filePath, {encoding: 'utf8'}); | ||
credsObj = JSON.parse(content); | ||
_validateAuthFileContent(credsObj, filePath); | ||
if (!process.env[subscriptionEnvVariableName]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hope I understand the context correctly, the subscription from the auth file should be precedent the environment variable. You can overwrite the environment variable here, but that should be just an implementation detail being transparent to users. Same with other fields.
If I got it right, then we don't need an if
condition, just overwrite it, optionally emit out a warning if you still like users to know.
envParams.activeDirectoryResourceId = credsObj.managementEndpointUrl; | ||
} | ||
if (!envParams.portalUrl) { | ||
envParams.portalUrl = 'https://portal.azure.com'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is not an environment aware url. If SDK never uses it, which I believe is the case, then maybe we just remove it from the environment
@@ -0,0 +1,12 @@ | |||
{ | |||
"clientId": "0b868e09-1547-4721-9a57-705a15328409", | |||
"clientSecret": "005937fd-3a0f-4cf2-84da-da7388241b9f", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assume this is a faked secret?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes
…H with 201 initial response.