-
Notifications
You must be signed in to change notification settings - Fork 235
Upgrade to latest typed-rest-client #206
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
7d4c99a
Upgrade to latest typed-rest-client
ff8ad0f
Missed 2 files
aa5b372
Was misusing some variables, had to do away with final callback option
b9a2dcd
Updated VSO Client to serialize nested objects correctly
b23584d
Updated handlers to match typed-rest-client
7ae7a55
Now uses the handlers from typed-rest-client
f3302dc
Revert "Now uses the handlers from typed-rest-client"
9c0e1b6
Updated handlers to use typed-rest-client logic without hurting backw…
619b8f9
Making getValueString private instead of protected
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 hidden or 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 |
|---|---|---|
| @@ -1,29 +1,11 @@ | ||
| // Copyright (c) Microsoft. All rights reserved. | ||
| // Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
|
||
| import VsoBaseInterfaces = require('../interfaces/common/VsoBaseInterfaces'); | ||
|
|
||
| export class BasicCredentialHandler implements VsoBaseInterfaces.IRequestHandler { | ||
| username: string; | ||
| password: string; | ||
| import ifm = require('../interfaces/common/VsoBaseInterfaces'); | ||
| import * as resthandlers from 'typed-rest-client/Handlers'; | ||
|
|
||
| export class BasicCredentialHandler extends resthandlers.BasicCredentialHandler implements ifm.IRequestHandler { | ||
| constructor(username: string, password: string) { | ||
| this.username = username; | ||
| this.password = password; | ||
| } | ||
|
|
||
| // currently implements pre-authorization | ||
| // TODO: support preAuth = false where it hooks on 401 | ||
| prepareRequest(options:any): void { | ||
| options.headers['Authorization'] = 'Basic ' + new Buffer(this.username + ':' + this.password).toString('base64'); | ||
| options.headers['X-TFS-FedAuthRedirect'] = 'Suppress'; | ||
| } | ||
|
|
||
| // This handler cannot handle 401 | ||
| canHandleAuthentication(res: VsoBaseInterfaces.IHttpResponse): boolean { | ||
| return false; | ||
| } | ||
|
|
||
| handleAuthentication(httpClient, protocol, options, objs, finalCallback): void { | ||
| super(username, password); | ||
| } | ||
| } | ||
| } |
This file contains hidden or 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 |
|---|---|---|
| @@ -1,27 +1,11 @@ | ||
| // Copyright (c) Microsoft. All rights reserved. | ||
| // Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
|
||
| import VsoBaseInterfaces = require('../interfaces/common/VsoBaseInterfaces'); | ||
|
|
||
| export class BearerCredentialHandler implements VsoBaseInterfaces.IRequestHandler { | ||
| token: string; | ||
| import ifm = require('../interfaces/common/VsoBaseInterfaces'); | ||
| import * as resthandlers from 'typed-rest-client/Handlers'; | ||
|
|
||
| export class BearerCredentialHandler extends resthandlers.BearerCredentialHandler implements ifm.IRequestHandler { | ||
| constructor(token: string) { | ||
| this.token = token; | ||
| } | ||
|
|
||
| // currently implements pre-authorization | ||
| // TODO: support preAuth = false where it hooks on 401 | ||
| prepareRequest(options:any): void { | ||
| options.headers['Authorization'] = 'Bearer ' + this.token; | ||
| options.headers['X-TFS-FedAuthRedirect'] = 'Suppress'; | ||
| } | ||
|
|
||
| // This handler cannot handle 401 | ||
| canHandleAuthentication(res: VsoBaseInterfaces.IHttpResponse): boolean { | ||
| return false; | ||
| } | ||
|
|
||
| handleAuthentication(httpClient, protocol, options, objs, finalCallback): void { | ||
| super(token); | ||
| } | ||
| } | ||
| } |
This file contains hidden or 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 |
|---|---|---|
| @@ -1,125 +1,11 @@ | ||
| // Copyright (c) Microsoft. All rights reserved. | ||
| // Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
|
||
| import VsoBaseInterfaces = require('../interfaces/common/VsoBaseInterfaces'); | ||
| import ifm = require('../interfaces/common/VsoBaseInterfaces'); | ||
| import * as resthandlers from 'typed-rest-client/Handlers'; | ||
|
|
||
| import http = require("http"); | ||
| import https = require("https"); | ||
| var _ = require("underscore"); | ||
| var ntlm = require("../opensource/node-http-ntlm/ntlm"); | ||
|
|
||
| export class NtlmCredentialHandler implements VsoBaseInterfaces.IRequestHandler { | ||
| username: string; | ||
| password: string; | ||
| workstation: string; | ||
| domain: string; | ||
|
|
||
| constructor(username: string, password: string, workstation?: string, domain?: string) { | ||
| this.username = username; | ||
| this.password = password; | ||
| if (workstation !== undefined) { | ||
| this.workstation = workstation; | ||
| } | ||
| if (domain !== undefined) { | ||
| this.domain = domain; | ||
| } | ||
| } | ||
|
|
||
| prepareRequest(options:any): void { | ||
| // No headers or options need to be set. We keep the credentials on the handler itself. | ||
| // If a (proxy) agent is set, remove it as we don't support proxy for NTLM at this time | ||
| if (options.agent) { | ||
| delete options.agent; | ||
| } | ||
| } | ||
|
|
||
| canHandleAuthentication(res: VsoBaseInterfaces.IHttpResponse): boolean { | ||
| if (res && res.statusCode === 401) { | ||
| // Ensure that we're talking NTLM here | ||
| // Once we have the www-authenticate header, split it so we can ensure we can talk NTLM | ||
| var wwwAuthenticate = res.headers['www-authenticate']; | ||
| if (wwwAuthenticate !== undefined) { | ||
| var mechanisms = wwwAuthenticate.split(', '); | ||
| var idx = mechanisms.indexOf("NTLM"); | ||
| if (idx >= 0) { | ||
| // Check specifically for 'NTLM' since www-authenticate header can also contain | ||
| // the Authorization value to use in the form of 'NTLM TlRMTVNT....AAAADw==' | ||
| if (mechanisms[idx].length == 4) { | ||
| return true; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| return false; | ||
| } | ||
|
|
||
| // The following method is an adaptation of code found at https://github.com/SamDecrock/node-http-ntlm/blob/master/httpntlm.js | ||
| handleAuthentication(httpClient, protocol, options, objs, finalCallback): void { | ||
| // Set up the headers for NTLM authentication | ||
| var ntlmOptions = _.extend(options, { | ||
| username: this.username, | ||
| password: this.password, | ||
| domain: this.domain || '', | ||
| workstation: this.workstation || '' | ||
| }); | ||
| var keepaliveAgent; | ||
| if (httpClient.isSsl === true) { | ||
| keepaliveAgent = new https.Agent({}); | ||
| } else { | ||
| keepaliveAgent = new http.Agent({ keepAlive: true }); | ||
| } | ||
| let self = this; | ||
| // The following pattern of sending the type1 message following immediately (in a setImmediate) is | ||
| // critical for the NTLM exchange to happen. If we removed setImmediate (or call in a different manner) | ||
| // the NTLM exchange will always fail with a 401. | ||
| this.sendType1Message(httpClient, protocol, ntlmOptions, objs, keepaliveAgent, function (err, res) { | ||
| if (err) { | ||
| return finalCallback(err, null, null); | ||
| } | ||
| setImmediate(function () { | ||
| self.sendType3Message(httpClient, protocol, ntlmOptions, objs, keepaliveAgent, res, finalCallback); | ||
| }); | ||
| }); | ||
| } | ||
|
|
||
| // The following method is an adaptation of code found at https://github.com/SamDecrock/node-http-ntlm/blob/master/httpntlm.js | ||
| private sendType1Message(httpClient, protocol, options, objs, keepaliveAgent, callback): void { | ||
| var type1msg = ntlm.createType1Message(options); | ||
| var type1options = { | ||
| headers: { | ||
| 'Connection': 'keep-alive', | ||
| 'Authorization': type1msg | ||
| }, | ||
| timeout: options.timeout || 0, | ||
| agent: keepaliveAgent, | ||
| // don't redirect because http could change to https which means we need to change the keepaliveAgent | ||
| allowRedirects: false | ||
| }; | ||
| type1options = _.extend(type1options, _.omit(options, 'headers')); | ||
| httpClient.requestInternal(protocol, type1options, objs, callback); | ||
| } | ||
|
|
||
| // The following method is an adaptation of code found at https://github.com/SamDecrock/node-http-ntlm/blob/master/httpntlm.js | ||
| private sendType3Message(httpClient, protocol, options, objs, keepaliveAgent, res, callback): void { | ||
| if (!res.headers['www-authenticate']) { | ||
| return callback(new Error('www-authenticate not found on response of second request')); | ||
| } | ||
| // parse type2 message from server: | ||
| var type2msg = ntlm.parseType2Message(res.headers['www-authenticate']); | ||
| // create type3 message: | ||
| var type3msg = ntlm.createType3Message(type2msg, options); | ||
| // build type3 request: | ||
| var type3options = { | ||
| headers: { | ||
| 'Authorization': type3msg | ||
| }, | ||
| allowRedirects: false, | ||
| agent: keepaliveAgent | ||
| }; | ||
| // pass along other options: | ||
| type3options.headers = _.extend(type3options.headers, options.headers); | ||
| type3options = _.extend(type3options, _.omit(options, 'headers')); | ||
| // send type3 message to server: | ||
| httpClient.requestInternal(protocol, type3options, objs, callback); | ||
| export class NtlmCredentialHandler extends resthandlers.NtlmCredentialHandler implements ifm.IRequestHandler { | ||
| constructor(username: string, password: string, workstation?: string, domain?: string) { | ||
| super(username, password, workstation, domain); | ||
| } | ||
| } | ||
| } |
This file contains hidden or 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 |
|---|---|---|
| @@ -1,27 +1,11 @@ | ||
| // Copyright (c) Microsoft. All rights reserved. | ||
| // Licensed under the MIT license. See LICENSE file in the project root for full license information. | ||
|
|
||
| import VsoBaseInterfaces = require('../interfaces/common/VsoBaseInterfaces'); | ||
|
|
||
| export class PersonalAccessTokenCredentialHandler implements VsoBaseInterfaces.IRequestHandler { | ||
| token: string; | ||
| import ifm = require('../interfaces/common/VsoBaseInterfaces'); | ||
| import * as resthandlers from 'typed-rest-client/Handlers'; | ||
|
|
||
| export class PersonalAccessTokenCredentialHandler extends resthandlers.PersonalAccessTokenCredentialHandler implements ifm.IRequestHandler { | ||
| constructor(token: string) { | ||
| this.token = token; | ||
| } | ||
|
|
||
| // currently implements pre-authorization | ||
| // TODO: support preAuth = false where it hooks on 401 | ||
| prepareRequest(options:any): void { | ||
| options.headers['Authorization'] = 'Basic ' + new Buffer('PAT:' + this.token).toString('base64'); | ||
| options.headers['X-TFS-FedAuthRedirect'] = 'Suppress'; | ||
| } | ||
|
|
||
| // This handler cannot handle 401 | ||
| canHandleAuthentication(res: VsoBaseInterfaces.IHttpResponse): boolean { | ||
| return false; | ||
| } | ||
|
|
||
| handleAuthentication(httpClient, protocol, options, objs, finalCallback): void { | ||
| super(token); | ||
| } | ||
| } | ||
| } |
This file contains hidden or 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 |
|---|---|---|
|
|
@@ -6,6 +6,8 @@ | |
| //---------------------------------------------------------------------------- | ||
|
|
||
| import Serialization = require('../../Serialization'); | ||
| import http = require("http"); | ||
| import url = require("url"); | ||
|
|
||
| /** | ||
| * Information about the location of a REST API resource | ||
|
|
@@ -52,15 +54,34 @@ export interface IBasicCredentials { | |
| password: string; | ||
| } | ||
|
|
||
| export interface IHttpClient { | ||
| options(requestUrl: string, additionalHeaders?: IHeaders): Promise<IHttpClientResponse>; | ||
| get(requestUrl: string, additionalHeaders?: IHeaders): Promise<IHttpClientResponse>; | ||
| del(requestUrl: string, additionalHeaders?: IHeaders): Promise<IHttpClientResponse>; | ||
| post(requestUrl: string, data: string, additionalHeaders?: IHeaders): Promise<IHttpClientResponse>; | ||
| patch(requestUrl: string, data: string, additionalHeaders?: IHeaders): Promise<IHttpClientResponse>; | ||
| put(requestUrl: string, data: string, additionalHeaders?: IHeaders): Promise<IHttpClientResponse>; | ||
| sendStream(verb: string, requestUrl: string, stream: NodeJS.ReadableStream, additionalHeaders?: IHeaders): Promise<IHttpClientResponse>; | ||
| request(verb: string, requestUrl: string, data: string | NodeJS.ReadableStream, headers: IHeaders): Promise<IHttpClientResponse>; | ||
| requestRaw(info: IRequestInfo, data: string | NodeJS.ReadableStream): Promise<IHttpClientResponse>; | ||
| requestRawWithCallback(info: IRequestInfo, data: string | NodeJS.ReadableStream, onResult: (err: any, res: IHttpClientResponse) => void): void; | ||
| } | ||
|
|
||
| export interface IRequestInfo { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same question. |
||
| options: http.RequestOptions; | ||
| parsedUrl: url.Url; | ||
| httpModule: any; | ||
| } | ||
|
|
||
| export interface IRequestHandler { | ||
| prepareRequest(options: any): void; | ||
| canHandleAuthentication(res: IHttpResponse): boolean; | ||
| handleAuthentication(httpClient, protocol, options, objs, finalCallback): void; | ||
| prepareRequest(options: http.RequestOptions): void; | ||
| canHandleAuthentication(response: IHttpClientResponse): boolean; | ||
| handleAuthentication(httpClient: IHttpClient, requestInfo: IRequestInfo, objs): Promise<IHttpClientResponse>; | ||
| } | ||
|
|
||
| export interface IHttpResponse { | ||
| statusCode?: number; | ||
| headers: any; | ||
| export interface IHttpClientResponse { | ||
| message: http.IncomingMessage; | ||
| readBody(): Promise<string>; | ||
| } | ||
|
|
||
| export interface IRequestOptions { | ||
|
|
||
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or 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
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Do we need to export this?
Uh oh!
There was an error while loading. Please reload this page.
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 we need to export both this and IRequestInfo because we're using them as parameters in other interfaces that are being exported. If I don't export them, an error is thrown Parameter 'httpClient' of method from exported interface has or is using private name 'IHttpClient'.