-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(private npm registry): Enable option to use private npm registry…
… Url in a11y ado extension (#2162) #### Details <!-- Usually a sentence or two describing what the PR changes --> Added two new optional parameter `npmRegistryUrl` and `npmRegistryCredential` to enable option to use private npm registry Url in a11y ado extension. If npmRegistryUrl is not set it will use https://registry.yarnpkg.com by default ##### Motivation <!-- This can be as simple as "addresses issue #123" --> [Feature 2207295](https://dev.azure.com/mseng/1ES/_workitems/edit/2207295): Enable option to use private npm registry Url in a11y ado extension ##### Context <!-- Are there any parts that you've intentionally left out-of-scope for a later PR to handle? --> <!-- Were there any alternative approaches you considered? What tradeoffs did you consider? --> #### Pull request checklist <!-- If a checklist item is not applicable to this change, write "n/a" in the checkbox --> - [ ] Addresses an existing issue: Fixes #0000 - [x] Added relevant unit test for your changes. (`yarn test`) - [x] Verified code coverage for the changes made. Check coverage report at: `<rootDir>/test-results/unit/coverage` - [x] Ran precheckin (`yarn precheckin`) --------- Co-authored-by: Vikash Yadav <[email protected]>
- Loading branch information
1 parent
0ff1498
commit e31b238
Showing
6 changed files
with
194 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,74 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
import * as adoTask from 'azure-pipelines-task-lib/task'; | ||
import * as NpmRegistryUtil from './npm-registry-util'; | ||
import { Mock } from 'typemoq'; | ||
|
||
describe('NpmRegistryUtil', () => { | ||
const authenticationMock = Mock.ofType<adoTask.EndpointAuthorization>(); | ||
|
||
describe('Improper Authentications', () => { | ||
it('should not get system access token authentication when scheme is not OAuth', () => { | ||
const auth = jest.spyOn(adoTask, 'getEndpointAuthorization'); | ||
auth.mockReturnValue(authenticationMock.object); | ||
const accessToken = NpmRegistryUtil.getSystemAccessToken(); | ||
expect(accessToken).toBeFalsy(); | ||
}); | ||
|
||
it('should not get npmAuthIdent from service connection when service connection does not exist', () => { | ||
const auth = jest.spyOn(adoTask, 'getEndpointAuthorization'); | ||
auth.mockReturnValue(undefined); | ||
expect(() => NpmRegistryUtil.getTokenFromServiceConnection('serviceConnectionName')).toThrowError( | ||
'Could not find the service connection', | ||
); | ||
}); | ||
|
||
it('should not get npmAuthIdent from service connection when service connection scheme is other than Token or UsernamePassword', () => { | ||
const auth = jest.spyOn(adoTask, 'getEndpointAuthorization'); | ||
auth.mockReturnValue(authenticationMock.object); | ||
expect(() => NpmRegistryUtil.getTokenFromServiceConnection('serviceConnectionName')).toThrowError( | ||
'Service connection auth scheme not supported', | ||
); | ||
}); | ||
}); | ||
|
||
describe('Proper Authentications', () => { | ||
it('should get system access token when scheme is OAuth', () => { | ||
authenticationMock.setup((x) => x.scheme).returns(() => 'OAuth'); | ||
authenticationMock | ||
.setup((x) => x.parameters) | ||
.returns(() => { | ||
return { AccessToken: 'token' }; | ||
}); | ||
const auth = jest.spyOn(adoTask, 'getEndpointAuthorization'); | ||
auth.mockReturnValue(authenticationMock.object); | ||
const accessToken = NpmRegistryUtil.getSystemAccessToken(); | ||
expect(accessToken).toEqual('token'); | ||
}); | ||
|
||
it('should get npmAuthIdent from service connection when service connection scheme is Token', () => { | ||
authenticationMock.setup((x) => x.scheme).returns(() => 'Token'); | ||
authenticationMock | ||
.setup((x) => x.parameters) | ||
.returns(() => { | ||
return { apitoken: 'token' }; | ||
}); | ||
const auth = jest.spyOn(adoTask, 'getEndpointAuthorization'); | ||
auth.mockReturnValue(authenticationMock.object); | ||
expect(NpmRegistryUtil.getTokenFromServiceConnection('serviceConnectionName')).toBeTruthy(); | ||
}); | ||
|
||
it('should get npmAuthIdent from service connection when service connection scheme is UsernamePassword', () => { | ||
authenticationMock.setup((x) => x.scheme).returns(() => 'UsernamePassword'); | ||
authenticationMock | ||
.setup((x) => x.parameters) | ||
.returns(() => { | ||
return { username: 'username', password: 'password' }; | ||
}); | ||
const auth = jest.spyOn(adoTask, 'getEndpointAuthorization'); | ||
auth.mockReturnValue(authenticationMock.object); | ||
expect(NpmRegistryUtil.getTokenFromServiceConnection('serviceConnectionName')).toBeTruthy(); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
import * as adoTask from 'azure-pipelines-task-lib/task'; | ||
|
||
export function getSystemAccessToken(): string { | ||
const authentication = adoTask.getEndpointAuthorization('SYSTEMVSSCONNECTION', false); | ||
|
||
if (authentication?.scheme === 'OAuth') { | ||
adoTask.setSecret(authentication.parameters['AccessToken']); | ||
return authentication.parameters['AccessToken']; | ||
} else { | ||
adoTask.warning('Not able to find the credential'); | ||
return ''; | ||
} | ||
} | ||
|
||
export function getTokenFromServiceConnection(serviceConnectionName: string): string { | ||
let serviceConnectionAuth: adoTask.EndpointAuthorization | undefined; | ||
let npmAuthIdent: string; | ||
try { | ||
serviceConnectionAuth = adoTask.getEndpointAuthorization(serviceConnectionName, false); | ||
} catch (exception) { | ||
throw new Error('Could not find the service connection'); | ||
} | ||
if (!serviceConnectionAuth) { | ||
throw new Error('Could not find the service connection'); | ||
} | ||
|
||
const serviceConnectionAuthScheme = serviceConnectionAuth?.scheme; | ||
|
||
if (serviceConnectionAuthScheme === 'Token') { | ||
const token = serviceConnectionAuth.parameters['apitoken']; | ||
// to mask the token in pipeline logs | ||
adoTask.setSecret(token); | ||
const usernameToken = `username:${token}`; | ||
adoTask.setSecret(usernameToken); | ||
const base64Token = Buffer.from(usernameToken).toString('base64'); | ||
// to mask the token in pipeline logs | ||
adoTask.setSecret(base64Token); | ||
npmAuthIdent = base64Token; | ||
} else if (serviceConnectionAuthScheme === 'UsernamePassword') { | ||
const username = serviceConnectionAuth.parameters['username']; | ||
const password = serviceConnectionAuth.parameters['password']; | ||
// to mask the token in pipeline logs | ||
adoTask.setSecret(password); | ||
const usernamePassword = `${username}:${password}`; | ||
// to mask the token in pipeline logs | ||
adoTask.setSecret(usernamePassword); | ||
const base64Password = Buffer.from(usernamePassword).toString('base64'); | ||
// to mask the token in pipeline logs | ||
adoTask.setSecret(base64Password); | ||
npmAuthIdent = base64Password; | ||
} else { | ||
throw new Error('Service connection auth scheme not supported'); | ||
} | ||
// to mask the token in pipeline logs | ||
adoTask.setSecret(npmAuthIdent); | ||
return npmAuthIdent; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters