escape params in console data section routes (close #3164) (#3275)

This commit is contained in:
ap 2019-11-07 13:24:23 +01:00 committed by Rikin Kachhia
parent 37dd0966d0
commit 5832adae73
16 changed files with 151 additions and 129 deletions

View File

@ -1,17 +1,10 @@
// import globals from '../../../Globals';
import {
getTableSchema,
getTableName,
checkIfTable,
getFunctionSchema,
getFunctionName,
} from './pgUtils';
/*** DATA ROUTES ***/
export const getSchemaBaseRoute = schemaName => {
// return `${globals.urlPrefix}/data/schema/${schemaName}`;
return `/data/schema/${schemaName}`;
return `/data/schema/${encodeURIComponent(schemaName)}`;
};
export const getSchemaAddTableRoute = schemaName => {
@ -22,46 +15,46 @@ export const getSchemaPermissionsRoute = schemaName => {
return `${getSchemaBaseRoute(schemaName)}/permissions`;
};
export const getTableBaseRoute = table => {
return `${getSchemaBaseRoute(getTableSchema(table))}/${
checkIfTable(table) ? 'tables' : 'views'
}/${getTableName(table)}`;
const getTableBaseRoute = (schemaName, tableName, isTable) => {
return `${getSchemaBaseRoute(schemaName)}/${
isTable ? 'tables' : 'views'
}/${encodeURIComponent(tableName)}`;
};
export const getTableBrowseRoute = table => {
return `${getTableBaseRoute(table)}/browse`;
export const getTableBrowseRoute = (schemaName, tableName, isTable) => {
return `${getTableBaseRoute(schemaName, tableName, isTable)}/browse`;
};
export const getTableInsertRowRoute = table => {
return `${getTableBaseRoute(table)}/insert`;
export const getTableInsertRowRoute = (schemaName, tableName, isTable) => {
return `${getTableBaseRoute(schemaName, tableName, isTable)}/insert`;
};
export const getTableEditRowRoute = table => {
return `${getTableBaseRoute(table)}/edit`;
export const getTableEditRowRoute = (schemaName, tableName, isTable) => {
return `${getTableBaseRoute(schemaName, tableName, isTable)}/edit`;
};
export const getTableModifyRoute = table => {
return `${getTableBaseRoute(table)}/modify`;
export const getTableModifyRoute = (schemaName, tableName, isTable) => {
return `${getTableBaseRoute(schemaName, tableName, isTable)}/modify`;
};
export const getTableRelationshipsRoute = table => {
return `${getTableBaseRoute(table)}/relationships`;
export const getTableRelationshipsRoute = (schemaName, tableName, isTable) => {
return `${getTableBaseRoute(schemaName, tableName, isTable)}/relationships`;
};
export const getTablePermissionsRoute = table => {
return `${getTableBaseRoute(table)}/permissions`;
export const getTablePermissionsRoute = (schemaName, tableName, isTable) => {
return `${getTableBaseRoute(schemaName, tableName, isTable)}/permissions`;
};
export const getFunctionBaseRoute = pgFunction => {
return `${getSchemaBaseRoute(
getFunctionSchema(pgFunction)
)}/functions/${getFunctionName(pgFunction)}`;
export const getFunctionBaseRoute = (schemaName, functionName) => {
return `${getSchemaBaseRoute(schemaName)}/functions/${encodeURIComponent(
functionName
)}`;
};
export const getFunctionModifyRoute = pgFunction => {
return `${getFunctionBaseRoute(pgFunction)}/modify`;
export const getFunctionModifyRoute = (schemaName, functionName) => {
return `${getFunctionBaseRoute(schemaName, functionName)}/modify`;
};
export const getFunctionPermissionsRoute = pgFunction => {
return `${getFunctionBaseRoute(pgFunction)}/permissions`;
export const getFunctionPermissionsRoute = (schemaName, functionName) => {
return `${getFunctionBaseRoute(schemaName, functionName)}/permissions`;
};

View File

@ -31,6 +31,7 @@ import {
} from './loveConsentLocalStorage';
import { versionGT, FT_JWT_ANALYZER } from '../../helpers/versionUtils';
import { getSchemaBaseRoute } from '../Common/utils/routesUtils';
class Main extends React.Component {
constructor(props) {
@ -485,7 +486,7 @@ class Main extends React.Component {
'Data',
'fa-database',
tooltips.data,
'/data/schema/' + currentSchema
getSchemaBaseRoute(currentSchema)
)}
{getSidebarItem(
'Remote Schemas',

View File

@ -11,6 +11,7 @@ import { setTable } from '../DataActions.js';
import { isPostgresFunction } from '../utils';
import { sqlEscapeText } from '../../../Common/utils/sqlUtils';
import { getTableModifyRoute } from '../../../Common/utils/routesUtils';
const SET_DEFAULTS = 'AddTable/SET_DEFAULTS';
const SET_TABLENAME = 'AddTable/SET_TABLENAME';
@ -362,9 +363,7 @@ const createTableSql = () => {
dispatch({ type: SET_DEFAULTS });
dispatch(setTable(tableName));
dispatch(updateSchemaInfo()).then(() =>
dispatch(
_push('/schema/' + currentSchema + '/tables/' + tableName + '/modify')
)
dispatch(_push(getTableModifyRoute(currentSchema, tableName, true)))
);
return;
};

View File

@ -6,6 +6,13 @@ import {
makeMigrationCall,
} from '../DataActions';
import { showSuccessNotification } from '../../Common/Notification';
import {
getSchemaBaseRoute,
getTableBrowseRoute,
getTableModifyRoute,
getFunctionModifyRoute,
} from '../../../Common/utils/routesUtils';
import { checkIfTable } from '../../../Common/utils/pgUtils';
const SET_DEFAULTS = 'AddExistingTable/SET_DEFAULTS';
const SET_TABLENAME = 'AddExistingTable/SET_TABLENAME';
@ -22,11 +29,12 @@ const addExistingTableSql = () => {
dispatch(showSuccessNotification('Adding an existing table...'));
const state = getState().addTable.existingTableView;
const currentSchema = getState().tables.currentSchema;
const tableName = state.tableName.trim();
const requestBodyUp = {
type: 'add_existing_table_or_view',
args: {
name: state.tableName.trim(),
name: tableName,
schema: currentSchema,
},
};
@ -34,16 +42,13 @@ const addExistingTableSql = () => {
type: 'untrack_table',
args: {
table: {
name: state.tableName.trim(),
name: tableName,
schema: currentSchema,
},
},
};
const migrationName =
'add_existing_table_or_view_' +
currentSchema +
'_' +
state.tableName.trim();
'add_existing_table_or_view_' + currentSchema + '_' + tableName;
const upQuery = {
type: 'bulk',
args: [requestBodyUp],
@ -60,32 +65,13 @@ const addExistingTableSql = () => {
dispatch({ type: REQUEST_SUCCESS });
dispatch(updateSchemaInfo()).then(() => {
const newTable = getState().tables.allSchemas.find(
t =>
t.table_name === state.tableName.trim() &&
t.table_schema === currentSchema
t => t.table_name === tableName && t.table_schema === currentSchema
);
const isTable = newTable.table_type === 'BASE TABLE';
if (isTable) {
dispatch(
_push(
'/schema/' +
currentSchema +
'/tables/' +
state.tableName.trim() +
'/modify'
)
);
} else {
dispatch(
_push(
'/schema/' +
currentSchema +
'/views/' +
state.tableName.trim() +
'/browse'
)
);
}
const isTable = checkIfTable(newTable);
const nextRoute = isTable
? getTableModifyRoute(currentSchema, tableName, isTable)
: getTableBrowseRoute(currentSchema, tableName, isTable);
dispatch(_push(nextRoute));
});
return;
};
@ -145,9 +131,7 @@ const addExistingFunction = name => {
dispatch({ type: REQUEST_SUCCESS });
// Update the left side bar
dispatch(fetchTrackedFunctions(currentSchema));
dispatch(
_push('/schema/' + currentSchema + '/functions/' + name + '/modify')
);
dispatch(_push(getFunctionModifyRoute(currentSchema, name)));
return;
};
const customOnError = err => {
@ -214,7 +198,7 @@ const addAllUntrackedTablesSql = tableList => {
dispatch(showSuccessNotification('Existing table/view added!'));
dispatch({ type: REQUEST_SUCCESS });
dispatch(updateSchemaInfo()).then(() => {
dispatch(_push('/schema/' + currentSchema));
dispatch(_push(getSchemaBaseRoute(currentSchema)));
});
return;
};

View File

@ -1,6 +1,6 @@
import sanitize from 'sanitize-filename';
import { push } from 'react-router-redux';
import { getSchemaBaseRoute } from '../../Common/utils/routesUtils';
import Endpoints, { globalCookiePolicy } from '../../../Endpoints';
import requestAction from '../../../utils/requestAction';
import defaultState from './DataState';
@ -30,6 +30,8 @@ import {
mergeLoadSchemaData,
} from './utils';
import _push from './push';
import { fetchColumnTypesQuery, fetchColumnDefaultFunctions } from './utils';
import { fetchColumnCastsQuery, convertArrayToJson } from './TableModify/utils';
@ -410,7 +412,7 @@ const fetchFunctionInit = () => (dispatch, getState) => {
const updateCurrentSchema = (schemaName, redirect = true) => dispatch => {
if (redirect) {
dispatch(push(`${globals.urlPrefix}/data/schema/${schemaName}`));
dispatch(_push(getSchemaBaseRoute(schemaName)));
}
Promise.all([

View File

@ -9,8 +9,7 @@ import DataSubSidebar from './DataSubSidebar';
import { updateCurrentSchema } from './DataActions';
import { NotFoundError } from '../../Error/PageNotFound';
import { CLI_CONSOLE_MODE } from '../../../constants';
const sectionPrefix = '/data';
import { getSchemaBaseRoute } from '../../Common/utils/routesUtils';
const DataPageContainer = ({
currentSchema,
@ -39,7 +38,7 @@ const DataPageContainer = ({
currentLocation.includes('data/migrations') ? styles.active : ''
}
>
<Link className={styles.linkBorder} to={sectionPrefix + '/migrations'}>
<Link className={styles.linkBorder} to={'/data/migrations'}>
Migrations
</Link>
</li>
@ -66,7 +65,7 @@ const DataPageContainer = ({
>
<Link
className={styles.linkBorder}
to={sectionPrefix + '/schema/' + currentSchema}
to={getSchemaBaseRoute(currentSchema)}
>
<div className={styles.schemaWrapper}>
<div className={styles.schemaSidebarSection} data-test="schema">
@ -89,7 +88,7 @@ const DataPageContainer = ({
>
<Link
className={styles.linkBorder}
to={sectionPrefix + '/sql'}
to={'/data/sql'}
data-test="sql-link"
>
SQL

View File

@ -10,6 +10,8 @@ import {
getFunctionName,
getSchemaTables,
getTableName,
checkIfTable,
getFunctionSchema,
} from '../../Common/utils/pgUtils';
import {
getFunctionModifyRoute,
@ -119,7 +121,14 @@ class DataSubSidebar extends React.Component {
className={isActive ? styles.activeLink : ''}
key={'table ' + i}
>
<Link to={getTableBrowseRoute(table)} data-test={tableName}>
<Link
to={getTableBrowseRoute(
currentSchema,
tableName,
checkIfTable(table)
)}
data-test={tableName}
>
<i
className={styles.tableIcon + ' fa fa-table'}
aria-hidden="true"
@ -160,7 +169,10 @@ class DataSubSidebar extends React.Component {
return (
<li className={isActive ? styles.activeLink : ''} key={'fn ' + i}>
<Link to={getFunctionModifyRoute(func)} data-test={funcName}>
<Link
to={getFunctionModifyRoute(getFunctionSchema(func), funcName)}
data-test={funcName}
>
<img
src={isActive ? functionSymbolActive : functionSymbol}
className={styles.functionIcon}

View File

@ -25,6 +25,10 @@ import {
import { SET_SQL } from '../../RawSQL/Actions';
import { NotFoundError } from '../../../../Error/PageNotFound';
import { getConfirmation } from '../../../../Common/utils/jsUtils';
import {
getFunctionBaseRoute,
getSchemaBaseRoute,
} from '../../../../Common/utils/routesUtils';
class ModifyCustomFunction extends React.Component {
constructor() {
@ -83,7 +87,7 @@ class ModifyCustomFunction extends React.Component {
const { functionDefinition } = this.props.functions;
Promise.all([
this.props.dispatch({ type: SET_SQL, data: functionDefinition }),
this.props.dispatch(_push('/sql')),
this.props.dispatch(_push('/data/sql')),
]);
}
@ -140,7 +144,7 @@ class ModifyCustomFunction extends React.Component {
const { migrationMode } = this.props;
const baseUrl = `${appPrefix}/schema/${schema}/functions/${functionName}`;
const functionBaseUrl = getFunctionBaseRoute(schema, functionName);
const generateMigrateBtns = () => {
return (
@ -192,14 +196,14 @@ class ModifyCustomFunction extends React.Component {
},
{
title: schema,
url: appPrefix + '/schema/' + schema,
url: getSchemaBaseRoute(schema),
},
];
if (functionName) {
breadCrumbs.push({
title: functionName,
url: appPrefix + '/schema/' + schema + '/functions/' + functionName,
url: functionBaseUrl,
});
breadCrumbs.push({
title: 'Modify',
@ -218,7 +222,7 @@ class ModifyCustomFunction extends React.Component {
heading={functionName}
tabsInfo={tabInfo}
breadCrumbs={breadCrumbs}
baseUrl={baseUrl}
baseUrl={functionBaseUrl}
showLoader={isFetching}
testPrefix={'functions'}
/>

View File

@ -18,6 +18,11 @@ import {
setTable,
} from '../../DataActions';
import { NotFoundError } from '../../../../Error/PageNotFound';
import {
getSchemaBaseRoute,
getFunctionBaseRoute,
getTablePermissionsRoute,
} from '../../../../Common/utils/routesUtils';
const prefixUrl = globals.urlPrefix + appPrefix;
@ -61,8 +66,12 @@ class Permission extends React.Component {
const { dispatch } = this.props;
const baseUrl = `${appPrefix}/schema/${schema}/functions/${functionName}`;
const permissionTableUrl = `${appPrefix}/schema/${setOffTableSchema}/tables/${setOffTable}/permissions`;
const functionBaseUrl = getFunctionBaseRoute(schema, functionName);
const permissionTableUrl = getTablePermissionsRoute(
setOffTableSchema,
setOffTable,
true
);
const breadCrumbs = [
{
@ -75,7 +84,7 @@ class Permission extends React.Component {
},
{
title: schema,
url: appPrefix + '/schema/' + schema,
url: getSchemaBaseRoute(schema),
},
];
@ -96,7 +105,7 @@ class Permission extends React.Component {
if (functionName) {
breadCrumbs.push({
title: functionName,
url: appPrefix + '/schema/' + schema + '/functions/' + functionName,
url: functionBaseUrl,
});
breadCrumbs.push({
title: 'Permission',
@ -114,7 +123,7 @@ class Permission extends React.Component {
heading={functionName}
tabsInfo={tabInfo}
breadCrumbs={breadCrumbs}
baseUrl={baseUrl}
baseUrl={functionBaseUrl}
showLoader={false}
testPrefix={'functions'}
/>

View File

@ -21,6 +21,7 @@ import { fetchTrackedFunctions } from '../DataActions';
import { COMPUTED_FIELDS_SUPPORT } from '../../../../helpers/versionUtils';
import _push from '../push';
import { getSchemaBaseRoute } from '../../../Common/utils/routesUtils';
/* Constants */
@ -224,7 +225,7 @@ const deleteFunctionSql = () => {
const errorMsg = 'Deleting function failed';
const customOnSuccess = () => {
dispatch(_push(`/schema/${currentSchema}`));
dispatch(_push(getSchemaBaseRoute(currentSchema)));
};
const customOnError = () => {
dispatch({ type: DELETE_CUSTOM_FUNCTION_FAIL });
@ -289,7 +290,7 @@ const unTrackCustomFunction = () => {
const errorMsg = 'Delete custom function failed';
const customOnSuccess = () => {
dispatch(_push(`/schema/${currentSchema}`));
dispatch(_push(getSchemaBaseRoute(currentSchema)));
dispatch({ type: RESET });
dispatch(fetchTrackedFunctions());
};

View File

@ -17,6 +17,7 @@ import {
getTableDef,
getSchemaTables,
getTrackedTables,
checkIfTable,
} from '../../../Common/utils/pgUtils';
import { getConfirmation } from '../../../Common/utils/jsUtils';
@ -229,7 +230,15 @@ class PermissionsSummary extends Component {
const getCellOnClick = (table, role, action) => {
return () => {
dispatch(push(getTablePermissionsRoute(table)));
dispatch(
push(
getTablePermissionsRoute(
getTableSchema(table),
getTableName(table),
checkIfTable(table)
)
)
);
if (role && action) {
// TODO: fix this. above redirect clears state set by this

View File

@ -13,6 +13,7 @@ import { replace } from 'react-router-redux';
import globals from '../../../../Globals';
import { E_ONGOING_REQ, editItem } from './EditActions';
import { findTable, generateTableDef } from '../../../Common/utils/pgUtils';
import { getTableBrowseRoute } from '../../../Common/utils/routesUtils';
class EditItem extends Component {
constructor() {
@ -38,8 +39,7 @@ class EditItem extends Component {
if (!oldItem) {
dispatch(
replace(
`${globals.urlPrefix ||
''}/data/schema/${currentSchema}/tables/${tableName}/browse`
`${globals.urlPrefix || ''}${getTableBrowseRoute(currentSchema, tableName, true)}`
)
);
return null;

View File

@ -34,6 +34,10 @@ import Button from '../../../Common/Button/Button';
import { E_SET_EDITITEM } from './EditActions';
import { I_SET_CLONE } from '../TableInsertItem/InsertActions';
import {
getTableInsertRowRoute,
getTableEditRowRoute,
} from '../../../Common/utils/routesUtils';
const ViewRows = ({
curTableName,
@ -309,7 +313,7 @@ const ViewRows = ({
const handleEditClick = () => {
dispatch({ type: E_SET_EDITITEM, oldItem: row, pkClause });
dispatch(
_push(`/schema/${currentSchema}/tables/${curTableName}/edit`)
_push(getTableEditRowRoute(currentSchema, curTableName, true))
);
};
@ -348,7 +352,7 @@ const ViewRows = ({
const handleCloneClick = () => {
dispatch({ type: I_SET_CLONE, clone: row });
dispatch(
_push(`/schema/${currentSchema}/tables/${curTableName}/insert`)
_push(getTableInsertRowRoute(currentSchema, curTableName, true))
);
};

View File

@ -55,7 +55,7 @@ const TableHeader = ({ tabName, count, table, migrationMode, dispatch }) => {
},
{
title: tableName,
url: getTableBrowseRoute(table),
url: getTableBrowseRoute(tableSchema, tableName, isTable),
},
{
title: activeTab,
@ -93,31 +93,39 @@ const TableHeader = ({ tabName, count, table, migrationMode, dispatch }) => {
<ul className="nav nav-pills">
{getTab(
'browse',
getTableBrowseRoute(table),
getTableBrowseRoute(tableSchema, tableName, isTable),
`Browse Rows ${countDisplay}`,
'table-browse-rows'
)}
{isTable &&
getTab(
'insert',
getTableInsertRowRoute(table),
getTableInsertRowRoute(tableSchema, tableName, isTable),
'Insert Row',
'table-insert-rows'
)}
{migrationMode &&
getTab('modify', getTableModifyRoute(table), 'Modify')}
getTab(
'modify',
getTableModifyRoute(tableSchema, tableName, isTable),
'Modify'
)}
{getTab(
'relationships',
getTableRelationshipsRoute(table),
getTableRelationshipsRoute(tableSchema, tableName, isTable),
'Relationships'
)}
{getTab(
'permissions',
getTablePermissionsRoute(table),
getTablePermissionsRoute(tableSchema, tableName, isTable),
'Permissions'
)}
{tabName === 'edit' &&
getTab('edit', getTableEditRowRoute(table), 'Edit Row')}
getTab(
'edit',
getTableEditRowRoute(tableSchema, tableName, isTable),
'Edit Row'
)}
</ul>
</div>
<div className="clearfix" />

View File

@ -47,6 +47,12 @@ import {
getDropPkSql,
sanitiseRootFields,
} from './utils';
import {
getSchemaBaseRoute,
getTableModifyRoute,
} from '../../../Common/utils/routesUtils';
import {
checkFeatureSupport,
CUSTOM_GRAPHQL_FIELDS_SUPPORT,
@ -425,8 +431,8 @@ const saveForeignKeys = (index, tableSchema, columns) => {
// foreign key already exists, alter the foreign key
const migrationUpAlterFKeySql = `
alter table "${schemaName}"."${tableName}" drop constraint "${constraintName}",
add constraint "${generatedConstraintName}"
foreign key (${lcols.join(', ')})
add constraint "${generatedConstraintName}"
foreign key (${lcols.join(', ')})
references "${refSchemaName}"."${refTableName}"
(${rcols.join(', ')}) on update ${onUpdate} on delete ${onDelete};
`;
@ -441,8 +447,8 @@ const saveForeignKeys = (index, tableSchema, columns) => {
// foreign key not found, create a new one
const migrationUpCreateFKeySql = `
alter table "${schemaName}"."${tableName}"
add constraint "${generatedConstraintName}"
foreign key (${lcols.join(', ')})
add constraint "${generatedConstraintName}"
foreign key (${lcols.join(', ')})
references "${refSchemaName}"."${refTableName}"
(${rcols.join(', ')}) on update ${onUpdate} on delete ${onDelete};
`;
@ -462,16 +468,16 @@ const saveForeignKeys = (index, tableSchema, columns) => {
const oldConstraint = tableSchema.foreign_key_constraints[index];
const migrationDownAlterFKeySql = `
alter table "${schemaName}"."${tableName}" drop constraint "${generatedConstraintName}",
add constraint "${constraintName}"
add constraint "${constraintName}"
foreign key (${Object.keys(oldConstraint.column_mapping)
.map(lc => `"${lc}"`)
.join(', ')})
.join(', ')})
references "${oldConstraint.ref_table_table_schema}"."${
oldConstraint.ref_table
}"
(${Object.values(oldConstraint.column_mapping)
.map(rc => `"${rc}"`)
.join(', ')})
.join(', ')})
on update ${pgConfTypes[oldConstraint.on_update]}
on delete ${pgConfTypes[oldConstraint.on_delete]};
`;
@ -673,19 +679,9 @@ const changeTableName = (oldName, newName, isTable) => {
const errorMsg = `Renaming ${property} failed`;
const customOnSuccess = () => {
dispatch(_push('/schema/' + currentSchema)); // to avoid 404
dispatch(_push(getSchemaBaseRoute(currentSchema))); // to avoid 404
dispatch(updateSchemaInfo()).then(() => {
dispatch(
_push(
'/schema/' +
currentSchema +
'/' +
property +
's/' +
newName +
'/modify'
)
);
dispatch(_push(getTableModifyRoute(currentSchema, newName, isTable)));
});
};
const customOnError = err => {
@ -802,7 +798,7 @@ const deleteTableSql = tableName => {
const customOnSuccess = () => {
dispatch(updateSchemaInfo());
dispatch(_push('/'));
dispatch(_push('/data/'));
};
const customOnError = err => {
@ -886,7 +882,7 @@ const untrackTableSql = tableName => {
tables: tableData,
})
).then(() => {
dispatch(_push('/'));
dispatch(_push('/data/'));
});
};
const customOnError = err => {
@ -943,7 +939,7 @@ const fetchViewDefinition = (viewName, isRedirect) => {
const finalDef = data.result[1][0];
// set state and redirect to run_sql
if (isRedirect) {
dispatch(_push('/sql'));
dispatch(_push('/data/sql'));
}
const runSqlDef =
@ -995,7 +991,7 @@ const deleteViewSql = viewName => {
const errorMsg = 'Deleting view failed';
const customOnSuccess = () => {
dispatch(_push('/'));
dispatch(_push('/data/'));
};
const customOnError = () => {};

View File

@ -3,9 +3,10 @@ import { push } from 'react-router-redux';
import globals from '../../../Globals';
const urlPrefix = globals.urlPrefix;
const appPrefix = urlPrefix !== '/' ? urlPrefix + '/data' : '/data';
const rootPrefix = urlPrefix !== '/' ? urlPrefix : '';
const appPrefix = rootPrefix + '/data';
const _push = path => push(appPrefix + path);
const _push = path => push(rootPrefix + path);
export default _push;
export { appPrefix };