Skip to content

Commit

Permalink
Fix: show template variables (#287)
Browse files Browse the repository at this point in the history
* substitutes tokens in urls [anonymous experience]

* adds profile to state and reducers

* substitutes token for authenticated user

* autogenerates password in the postbody
  • Loading branch information
Charles Wahome committed Nov 13, 2019
1 parent 25e9a2b commit 65ba338
Show file tree
Hide file tree
Showing 16 changed files with 1,728 additions and 1,436 deletions.
19 changes: 10 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"file-loader": "2.0.0",
"fork-ts-checker-webpack-plugin-alt": "0.4.14",
"fs-extra": "7.0.1",
"guid-typescript": "^1.0.9",
"html-webpack-plugin": "4.0.0-alpha.2",
"identity-obj-proxy": "3.0.0",
"isomorphic-fetch": "2.2.1",
Expand Down
4 changes: 1 addition & 3 deletions src/app/services/actions/permissions-action-creator.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { IAction } from '../../../types/action';
import { IRequestOptions } from '../../../types/request';

import { FETCH_SCOPES_ERROR, FETCH_SCOPES_SUCCESS, GET_CONSENT_ERROR } from '../redux-constants';
import { authenticatedRequest, parseResponse, queryResponse } from './query-action-creator-util';
import { FETCH_SCOPES_ERROR, FETCH_SCOPES_SUCCESS } from '../redux-constants';

export function fetchScopesSuccess(response: object): IAction {
return {
Expand Down
29 changes: 21 additions & 8 deletions src/app/services/actions/profile-action-creators.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { IQuery } from '../../../types/query-runner';
import { PROFILE_REQUEST_ERROR, PROFILE_REQUEST_SUCCESS } from '../redux-constants';
import { authenticatedRequest, parseResponse } from './query-action-creator-util';
import { PROFILE_IMAGE_REQUEST_SUCCESS, PROFILE_REQUEST_ERROR, PROFILE_REQUEST_SUCCESS } from '../redux-constants';
import { authenticatedRequest, isImageResponse, parseResponse } from './query-action-creator-util';

export function profileRequestSuccess(response: object): any {
return {
Expand All @@ -9,6 +9,13 @@ export function profileRequestSuccess(response: object): any {
};
}

export function profileImageRequestSuccess(response: object): any {
return {
type: PROFILE_IMAGE_REQUEST_SUCCESS,
response,
};
}

export function profileRequestError(response: object): any {
return {
type: PROFILE_REQUEST_ERROR,
Expand All @@ -24,12 +31,18 @@ export function getProfileInfo(query: IQuery): Function {

if (response && response.ok) {
const json = await parseResponse(response, respHeaders);
return dispatch(
profileRequestSuccess({
body: json,
headers: respHeaders
}),
);
const contentType = respHeaders['content-type'];
const isImageResult = isImageResponse(contentType);

if (isImageResult) {
return dispatch(
profileImageRequestSuccess(json),
);
} else {
return dispatch(
profileRequestSuccess(json),
);
}
}
return dispatch(profileRequestError({ response }));
});
Expand Down
2 changes: 2 additions & 0 deletions src/app/services/reducers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { adaptiveCard } from './adaptive-cards-reducer';
import { authToken, consentedScopes } from './auth-reducers';
import { graphExplorerMode } from './graph-explorer-mode-reducer';
import { scopes } from './permissions-reducer';
import { profile } from './profile-reducer';
import { sampleQuery } from './query-input-reducers';
import { isLoadingData } from './query-loading-reducers';
import { graphResponse } from './query-runner-reducers';
Expand All @@ -24,6 +25,7 @@ export default combineReducers({
headersAdded,
history,
isLoadingData,
profile,
queryRunnerStatus,
sampleQuery,
samples,
Expand Down
13 changes: 13 additions & 0 deletions src/app/services/reducers/profile-reducer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { IAction } from '../../../types/action';
import { LOGOUT_SUCCESS, PROFILE_REQUEST_SUCCESS } from '../redux-constants';

export function profile(state = null, action: IAction): any {
switch (action.type) {
case LOGOUT_SUCCESS:
return null;
case PROFILE_REQUEST_SUCCESS:
return action.response;
default:
return state;
}
}
3 changes: 3 additions & 0 deletions src/app/services/reducers/query-loading-reducers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { IAction } from '../../../types/action';
import {
FETCH_SCOPES_ERROR,
GET_CONSENT_ERROR,
PROFILE_IMAGE_REQUEST_SUCCESS,
PROFILE_REQUEST_ERROR,
PROFILE_REQUEST_SUCCESS,
QUERY_GRAPH_RUNNING,
Expand All @@ -27,6 +28,8 @@ export function isLoadingData(state = {}, action: IAction): any {
return false;
case PROFILE_REQUEST_SUCCESS:
return false;
case PROFILE_IMAGE_REQUEST_SUCCESS:
return false;
default:
return state;
}
Expand Down
1 change: 1 addition & 0 deletions src/app/services/redux-constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const HEADER_REMOVE_SUCCESS = 'HEADER_REMOVE_SUCCESS';
export const SET_GRAPH_EXPLORER_MODE_SUCCESS = 'SET_GRAPH_EXPLORER_MODE_SUCCESS';
export const SET_SAMPLE_QUERY_SUCCESS = 'SET_SAMPLE_QUERY_SUCCESS';
export const PROFILE_REQUEST_SUCCESS = 'PROFILE_REQUEST_SUCCESS';
export const PROFILE_IMAGE_REQUEST_SUCCESS = 'PROFILE_IMAGE_REQUEST_SUCCESS';
export const PROFILE_REQUEST_ERROR = 'PROFILE_REQUEST_ERROR';
export const GET_SNIPPET_SUCCESS = 'GET_SNIPPET_SUCCESS';
export const REMOVE_HISTORY_ITEM_SUCCESS = 'REMOVE_HISTORY_ITEM_SUCCESS';
Expand Down
63 changes: 63 additions & 0 deletions src/app/utils/token-helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import { IQuery } from '../../types/query-runner';
import { IToken } from '../../types/sidebar';
import { getTokens } from '../views/sidebar/sample-queries/tokens';

/*
* Given a token, go through each of the possible replacement scenarios and find which value to
* replace the token with.
* Order: Authenticated user values, demo tenant replacament values, default replacement values.
*/
export function getTokenSubstituteValue(token: IToken, isAuthenticated: boolean) {
const priorityOrder = []; // Desc
if (isAuthenticated) {
priorityOrder.push(token.authenticatedUserValueFn);
priorityOrder.push(token.authenticatedUserValue);
} else {
priorityOrder.push(token.demoTenantValueFn);
priorityOrder.push(token.demoTenantValue);
}

priorityOrder.push(token.defaultValueFn);
priorityOrder.push(token.defaultValue);

for (const tokenVal of priorityOrder) {
if (!tokenVal) {
continue;
}
if (typeof tokenVal === 'string') {
return tokenVal;
} else if (typeof tokenVal === 'function') {
return tokenVal();
}
}

}

/**
* Given a query, replace all tokens in the request URL and the POST body with their
* values. When a token is found, use getTokenSubstituteValue() to find the right
* value to substitute based on the session.
*/

export function substituteTokens(query: IQuery, profile: object) {
type QueryFields = keyof IQuery;
const tokens = getTokens(profile);
const authenticated = !!profile;
for (const token of tokens) {
const queryFieldsToCheck: QueryFields[] = ['sampleBody', 'sampleUrl'];

for (const queryField of queryFieldsToCheck) {
if (!query[queryField]) {
continue;
}

if ((query[queryField] as string).indexOf(`{${token.placeholder}}`) !== -1) {
const substitutedValue = getTokenSubstituteValue(token, authenticated);
if (!substitutedValue) {
continue;
}
query[queryField] = (query[queryField] as string).replace(`{${token.placeholder}}`, substitutedValue);
}
}
}
}
24 changes: 12 additions & 12 deletions src/app/views/authentication/profile/Profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export class Profile extends Component<IProfileProps, IProfileState> {
})
: null;

const userInfo = jsonUserInfo.response.body;
const userInfo = jsonUserInfo.response;
if (userInfo) {
let imageUrl = '';

Expand All @@ -50,7 +50,7 @@ export class Profile extends Component<IProfileProps, IProfileState> {
: null;

if (userPicture) {
const buffer = await userPicture.response.body.arrayBuffer();
const buffer = await userPicture.response.arrayBuffer();
const blob = new Blob([buffer], { type: 'image/jpeg' });
imageUrl = URL.createObjectURL(blob);
}
Expand Down Expand Up @@ -153,17 +153,17 @@ export class Profile extends Component<IProfileProps, IProfileState> {
{!mobileScreen &&
<Card compact={true} tokens={profileCardTokens}>
<Card.Item fill={true}>
<Persona {...persona} coinSize={60} size={PersonaSize.size40} hidePersonaDetails={true} />
<Persona {...persona} coinSize={60} size={PersonaSize.size40} hidePersonaDetails={true} />
</Card.Item>
<Card.Section>
<span className={classes.personaText}>
{persona.text}
</span>
<span className={classes.personaSecondaryText}>{persona.secondaryText}</span>
<ActionButton ariaLabel='profile' role='button' menuProps={menuProperties}>
<FormattedMessage id='More actions' />
</ActionButton>
</Card.Section>
<Card.Section>
<span className={classes.personaText}>
{persona.text}
</span>
<span className={classes.personaSecondaryText}>{persona.secondaryText}</span>
<ActionButton ariaLabel='profile' role='button' menuProps={menuProperties}>
<FormattedMessage id='More actions' />
</ActionButton>
</Card.Section>
</Card>
}
</div>
Expand Down
14 changes: 9 additions & 5 deletions src/app/views/sidebar/sample-queries/SampleQueries.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import * as queryInputActionCreators from '../../../services/actions/query-input
import * as samplesActionCreators from '../../../services/actions/samples-action-creators';
import { GRAPH_URL } from '../../../services/graph-constants';
import { getStyleFor } from '../../../utils/badge-color';
import { substituteTokens } from '../../../utils/token-helpers';
import { classNames } from '../../classnames';
import { sidebarStyles } from '../Sidebar.styles';

Expand Down Expand Up @@ -97,7 +98,7 @@ export class SampleQueries extends Component<ISampleQueriesProps, any> {
});
}

public getToolTipContent (item: any, queryContent: any) {
public getToolTipContent(item: any, queryContent: any) {
let selectionDisabled = false;

if (!this.props.tokenPresent && item.method !== 'GET') {
Expand Down Expand Up @@ -129,7 +130,7 @@ export class SampleQueries extends Component<ISampleQueriesProps, any> {
/>;

case 'method':
return <TooltipHost
return <TooltipHost
tooltipProps={{ onRenderContent: () => <div style={{ paddingBottom: 3 }}>{toolTipContent}</div> }}
id={hostId}
calloutProps={{ gapSpace: 0 }}
Expand All @@ -143,7 +144,7 @@ export class SampleQueries extends Component<ISampleQueriesProps, any> {
default:
return <>
<TooltipHost
tooltipProps={{ onRenderContent: () => <div style={{ paddingBottom: 3 }}>{toolTipContent}</div>}}
tooltipProps={{ onRenderContent: () => <div style={{ paddingBottom: 3 }}>{toolTipContent}</div> }}
id={hostId}
calloutProps={{ gapSpace: 0 }}
styles={{ root: { display: 'inline-block' } }}
Expand Down Expand Up @@ -173,7 +174,7 @@ export class SampleQueries extends Component<ISampleQueriesProps, any> {
{...props}
className={classes.queryRow + ' ' + (selectionDisabled ? classes.rowDisabled : '')}
data-selection-disabled={selectionDisabled}
/>
/>
</div>
);
}
Expand Down Expand Up @@ -242,7 +243,7 @@ export class SampleQueries extends Component<ISampleQueriesProps, any> {

const selection = new Selection({
onSelectionChanged: () => {
const { actions } = this.props;
const { actions, profile } = this.props;
const selectedQuery = selection.getSelection()[0] as any;
if (!selectedQuery) { return; }

Expand All @@ -255,6 +256,8 @@ export class SampleQueries extends Component<ISampleQueriesProps, any> {
selectedVersion: queryVersion,
};

substituteTokens(sampleQuery, profile);

if (actions) {
if (sampleQuery.selectedVerb === 'GET') {
sampleQuery.sampleBody = JSON.parse('{}');
Expand Down Expand Up @@ -300,6 +303,7 @@ export class SampleQueries extends Component<ISampleQueriesProps, any> {
function mapStateToProps(state: any) {
return {
tokenPresent: !!state.authToken,
profile: state.profile,
samples: state.samples
};
}
Expand Down
Loading

0 comments on commit 65ba338

Please sign in to comment.