Skip to content
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

Add netrc as auth type #384

Merged
merged 6 commits into from
Jul 31, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions app/__mocks__/node-libcurl.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,12 @@ Curl.auth = {
ANY: 'ANY'
};

Curl.netrc = {
IGNORED: 0,
OPTIONAL: 1,
REQUIRED: 2
};

Curl.option = {
ACCEPT_ENCODING: 'ACCEPT_ENCODING',
CAINFO: 'CAINFO',
Expand All @@ -93,6 +99,7 @@ Curl.option = {
HTTPPOST: 'HTTPPOST',
INFILESIZE: 'INFILESIZE',
KEYPASSWD: 'KEYPASSWD',
NETRC: 'NETRC',
NOBODY: 'NOBODY',
NOPROGRESS: 'NOPROGRESS',
NOPROXY: 'NOPROXY',
Expand Down
4 changes: 3 additions & 1 deletion app/common/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ export const AUTH_DIGEST = 'digest';
export const AUTH_BEARER = 'bearer';
export const AUTH_NTLM = 'ntlm';
export const AUTH_AWS_IAM = 'iam';
export const AUTH_NETRC = 'netrc';

const authTypesMap = {
[AUTH_BASIC]: ['Basic', 'Basic Auth'],
Expand All @@ -148,7 +149,8 @@ const authTypesMap = {
[AUTH_BEARER]: ['Bearer', 'Bearer Token'],
[AUTH_OAUTH_1]: ['OAuth 1', 'OAuth 1.0'],
[AUTH_OAUTH_2]: ['OAuth 2', 'OAuth 2.0'],
[AUTH_AWS_IAM]: ['AWS', 'AWS IAM v4']
[AUTH_AWS_IAM]: ['AWS', 'AWS IAM v4'],
[AUTH_NETRC]: ['Netrc', 'Netrc']
};

export function getPreviewModeName (previewMode, useLong = false) {
Expand Down
7 changes: 6 additions & 1 deletion app/models/request.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// @flow
import type {BaseModel} from './index';
import {AUTH_BASIC, AUTH_DIGEST, AUTH_NONE, AUTH_NTLM, AUTH_OAUTH_2, AUTH_AWS_IAM, CONTENT_TYPE_FILE, CONTENT_TYPE_FORM_DATA, CONTENT_TYPE_FORM_URLENCODED, CONTENT_TYPE_OTHER, getContentTypeFromHeaders, METHOD_GET, CONTENT_TYPE_GRAPHQL, CONTENT_TYPE_JSON} from '../common/constants';
import {AUTH_BASIC, AUTH_DIGEST, AUTH_NONE, AUTH_NTLM, AUTH_OAUTH_2, AUTH_AWS_IAM, AUTH_NETRC, CONTENT_TYPE_FILE, CONTENT_TYPE_FORM_DATA, CONTENT_TYPE_FORM_URLENCODED, CONTENT_TYPE_OTHER, getContentTypeFromHeaders, METHOD_GET, CONTENT_TYPE_GRAPHQL, CONTENT_TYPE_JSON} from '../common/constants';
import * as db from '../common/database';
import {getContentTypeHeader} from '../common/misc';
import {buildFromParams, deconstructToParams} from '../common/querystring';
Expand Down Expand Up @@ -101,6 +101,7 @@ export function newAuth (type: string, oldAuth: RequestAuthentication = {}): Req
case AUTH_OAUTH_2:
return {type, grantType: GRANT_TYPE_AUTHORIZATION_CODE};

// Aws IAM
case AUTH_AWS_IAM:
return {
type,
Expand All @@ -109,6 +110,10 @@ export function newAuth (type: string, oldAuth: RequestAuthentication = {}): Req
secretAccessKey: oldAuth.secretAccessKey || ''
};

// netrc
case AUTH_NETRC:
return {type};

// Types needing no defaults
default:
return {type};
Expand Down
36 changes: 35 additions & 1 deletion app/network/__tests__/network.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import * as networkUtils from '../network';
import {join as pathJoin, resolve as pathResolve} from 'path';
import {getRenderedRequest} from '../../common/render';
import * as models from '../../models';
import {AUTH_AWS_IAM, AUTH_BASIC, CONTENT_TYPE_FILE, CONTENT_TYPE_FORM_DATA, CONTENT_TYPE_FORM_URLENCODED, getAppVersion} from '../../common/constants';
import {AUTH_AWS_IAM, AUTH_BASIC, AUTH_NETRC, CONTENT_TYPE_FILE, CONTENT_TYPE_FORM_DATA, CONTENT_TYPE_FORM_URLENCODED, getAppVersion} from '../../common/constants';
import {filterHeaders} from '../../common/misc';
import {globalBeforeEach} from '../../__jest__/before-each';

Expand Down Expand Up @@ -425,6 +425,40 @@ describe('actuallySend()', () => {
}
});
});

it('uses netrc', async () => {
const workspace = await models.workspace.create();
const settings = await models.settings.create();

const request = Object.assign(models.request.init(), {
_id: 'req_123',
parentId: workspace._id,
authentication: {
type: AUTH_NETRC
}
});

const renderedRequest = await getRenderedRequest(request);
const {bodyBuffer} = await networkUtils._actuallySend(renderedRequest, workspace, settings);

const body = JSON.parse(bodyBuffer);
expect(body).toEqual({
options: {
CUSTOMREQUEST: 'GET',
ACCEPT_ENCODING: '',
COOKIEFILE: '',
FOLLOWLOCATION: true,
HTTPHEADER: ['content-type: '],
NOPROGRESS: false,
PROXY: '',
TIMEOUT_MS: 0,
NETRC: 2,
URL: '',
USERAGENT: `insomnia/${getAppVersion()}`,
VERBOSE: true
}
});
});
});

describe('_getAwsAuthHeaders', () => {
Expand Down
4 changes: 3 additions & 1 deletion app/network/network.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {join as pathJoin} from 'path';
import * as models from '../models';
import * as querystring from '../common/querystring';
import * as util from '../common/misc.js';
import {AUTH_AWS_IAM, AUTH_BASIC, AUTH_DIGEST, AUTH_NTLM, CONTENT_TYPE_FORM_DATA, CONTENT_TYPE_FORM_URLENCODED, getAppVersion, STATUS_CODE_PLUGIN_ERROR} from '../common/constants';
import {AUTH_AWS_IAM, AUTH_BASIC, AUTH_DIGEST, AUTH_NETRC, AUTH_NTLM, CONTENT_TYPE_FORM_DATA, CONTENT_TYPE_FORM_URLENCODED, getAppVersion, STATUS_CODE_PLUGIN_ERROR} from '../common/constants';
import {describeByteSize, hasAuthHeader, hasContentTypeHeader, hasUserAgentHeader, setDefaultProtocol} from '../common/misc';
import {getRenderedRequest} from '../common/render';
import fs from 'fs';
Expand Down Expand Up @@ -467,6 +467,8 @@ export function _actuallySend (
for (const header of extraHeaders) {
headers.push(header);
}
} else if (renderedRequest.authentication.type === AUTH_NETRC) {
setOpt(Curl.option.NETRC, Curl.netrc.REQUIRED);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does REQUIRED mean here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A user:password in the URL will be ignored. Unless one is set programmatically, the .netrc will be queried.
I thought this was a good way for it to behave, since falling back to the password in the URL might be werid behaviour. Could be set to Optional if you think that's better tho!

} else {
const authHeader = await getAuthHeader(
renderedRequest._id,
Expand Down
3 changes: 2 additions & 1 deletion app/ui/components/dropdowns/auth-dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {trackEvent} from '../../../analytics';
import {showModal} from '../modals';
import AlertModal from '../modals/alert-modal';
import * as models from '../../../models';
import {AUTH_BASIC, AUTH_DIGEST, AUTH_BEARER, AUTH_NONE, AUTH_NTLM, AUTH_OAUTH_1, AUTH_OAUTH_2, AUTH_AWS_IAM, getAuthTypeName} from '../../../common/constants';
import {AUTH_BASIC, AUTH_DIGEST, AUTH_BEARER, AUTH_NONE, AUTH_NTLM, AUTH_OAUTH_1, AUTH_OAUTH_2, AUTH_AWS_IAM, AUTH_NETRC, getAuthTypeName} from '../../../common/constants';

@autobind
class AuthDropdown extends PureComponent {
Expand Down Expand Up @@ -68,6 +68,7 @@ class AuthDropdown extends PureComponent {
{this.renderAuthType(AUTH_BEARER)}
{this.renderAuthType(AUTH_NTLM)}
{this.renderAuthType(AUTH_AWS_IAM)}
{this.renderAuthType(AUTH_NETRC)}
<DropdownDivider>Other</DropdownDivider>
{this.renderAuthType(AUTH_NONE, 'No Authentication')}
</Dropdown>
Expand Down
11 changes: 8 additions & 3 deletions app/ui/components/editors/auth/auth-wrapper.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import React, {PropTypes, PureComponent} from 'react';
import {AUTH_BASIC, AUTH_DIGEST, AUTH_BEARER, AUTH_NTLM, AUTH_OAUTH_1, AUTH_OAUTH_2, AUTH_AWS_IAM} from '../../../../common/constants';
import {AUTH_BASIC, AUTH_DIGEST, AUTH_BEARER, AUTH_NTLM, AUTH_OAUTH_1, AUTH_OAUTH_2, AUTH_AWS_IAM, AUTH_NETRC} from '../../../../common/constants';
import BasicAuth from './basic-auth';
import DigestAuth from './digest-auth';
import BearerAuth from './bearer-auth';
import NTLMAuth from './ntlm-auth';
import OAuth2 from './o-auth-2';
import OAuth2Auth from './o-auth-2-auth';
import AWSAuth from './aws-auth';
import NetrcAuth from './netrc-auth';
import autobind from 'autobind-decorator';
import Link from '../../base/link';

Expand Down Expand Up @@ -37,7 +38,7 @@ class AuthWrapper extends PureComponent {
);
} else if (authentication.type === AUTH_OAUTH_2) {
return (
<OAuth2
<OAuth2Auth
oAuth2Token={oAuth2Token}
request={request}
handleRender={handleRender}
Expand Down Expand Up @@ -104,6 +105,10 @@ class AuthWrapper extends PureComponent {
showPasswords={showPasswords}
/>
);
} else if (authentication.type === AUTH_NETRC) {
return (
<NetrcAuth />
);
} else {
return (
<div className="vertically-center text-center">
Expand Down
16 changes: 16 additions & 0 deletions app/ui/components/editors/auth/netrc-auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React, {PureComponent} from 'react';

class NetrcAuth extends PureComponent {
render () {
return (
<div className="vertically-center text-center">
<p className="pad super-faint text-sm text-center">
<br/>
Your netrc file will be used to authenticate this request
</p>
</div>
);
}
}

export default NetrcAuth;
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const getAuthorizationUrls = () => authorizationUrls;
const getAccessTokenUrls = () => accessTokenUrls;

@autobind
class OAuth2 extends React.PureComponent {
class OAuth2Auth extends React.PureComponent {
props: {
handleRender: Function,
handleGetRenderContext: Function,
Expand Down Expand Up @@ -433,4 +433,4 @@ class OAuth2 extends React.PureComponent {
}
}

export default OAuth2;
export default OAuth2Auth;
7 changes: 7 additions & 0 deletions flow-typed/node-libcurl.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ declare class Curl {
HTTPPOST: number,
INFILESIZE: number,
KEYPASSWD: number,
NETRC: number,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you also add these to __mocks__/node-libcurl and add a basic test to network.test.js?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure! The only test I could think of would be pulling creds out of a mocked .netrc file and making sure the creds are in the request. Is this what you were thinking? Or is there a simpler way to just make sure the curl options were set?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking of something even simpler. If you look at the other tests in there, they basically just make sure the correct options are passed to libcurl. It's safe to assume that libcurl will do the right thing if it gets the correct options.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a simple test!

NOBODY: number,
NOPROGRESS: number,
NOPROXY: number,
Expand Down Expand Up @@ -49,6 +50,12 @@ declare class Curl {
CURLE_ABORTED_BY_CALLBACK: string
};

static netrc: {
IGNORED: number,
OPTIONAL: number,
REQUIRED: number,
};

static info: {
EFFECTIVE_URL: string,
SIZE_DOWNLOAD: string,
Expand Down