First pass at permissions; Updated auth0 to work with access token instead of id token

This commit is contained in:
2023-01-11 16:31:39 -06:00
parent eff5a04c0f
commit e096e055a4
16 changed files with 273 additions and 96 deletions

View File

@ -88,7 +88,7 @@ function EntityForm(props: Props): JSX.Element
const [tableSections, setTableSections] = useState(null as QTableSection[]);
const [, forceUpdate] = useReducer((x) => x + 1, 0);
const [noCapabilityError, setNoCapabilityError] = useState(null as string);
const [notAllowedError, setNotAllowedError] = useState(null as string);
const {pageHeader, setPageHeader} = useContext(QContext);
@ -189,7 +189,11 @@ function EntityForm(props: Props): JSX.Element
if (!tableMetaData.capabilities.has(Capability.TABLE_UPDATE))
{
setNoCapabilityError("You may not edit records in this table");
setNotAllowedError("Records may not be edited in this table");
}
else if (!tableMetaData.editPermission)
{
setNotAllowedError(`You do not have permission to edit ${tableMetaData.label} records`);
}
}
else
@ -206,7 +210,11 @@ function EntityForm(props: Props): JSX.Element
if (!tableMetaData.capabilities.has(Capability.TABLE_INSERT))
{
setNoCapabilityError("You may not create records in this table");
setNotAllowedError("Records may not be created in this table");
}
else if (!tableMetaData.insertPermission)
{
setNotAllowedError(`You do not have permission to create ${tableMetaData.label} records`);
}
////////////////////////////////////////////////////////////////////////////////////////////////
@ -420,14 +428,19 @@ function EntityForm(props: Props): JSX.Element
const formId = props.id != null ? `edit-${tableMetaData?.name}-form` : `create-${tableMetaData?.name}-form`;
let body;
if (noCapabilityError)
if (notAllowedError)
{
body = (
<Box mb={3}>
<Grid container spacing={3}>
<Grid item xs={12}>
<Box mb={3}>
<Alert severity="error">{noCapabilityError}</Alert>
<Alert severity="error">{notAllowedError}</Alert>
{props.isModal &&
<Box mt={5}>
<QCancelButton onClickHandler={props.isModal ? props.closeModalHandler : handleCancelClicked} label="Close" disabled={false} />
</Box>
}
</Box>
</Grid>
</Grid>

View File

@ -39,8 +39,8 @@ interface Props
export function GoogleDriveFolderPicker({showDefaultFoldersView, showSharedDrivesView, qInstance}: Props): JSX.Element
{
const clientId = "649816208522-m6oa971vqicrc1hlam7333pt4qck0tm8.apps.googleusercontent.com";
const appApiKey = "AIzaSyBhXK34CF2fUfCgUS1VIHoKZbHxEBuHtDM";
const clientId = qInstance.environmentValues.get("GOOGLE_APP_CLIENT_ID") || process.env.REACT_APP_GOOGLE_APP_CLIENT_ID;
const appApiKey = qInstance.environmentValues.get("GOOGLE_APP_API_KEY") || process.env.REACT_APP_GOOGLE_APP_API_KEY;
if(!clientId)
{
console.error("Missing environmentValue GOOGLE_APP_CLIENT_ID")

View File

@ -24,6 +24,7 @@ import Card from "@mui/material/Card";
import Divider from "@mui/material/Divider";
import Icon from "@mui/material/Icon";
import {ReactNode} from "react";
import colors from "qqq/assets/theme/base/colors";
import MDTypography from "qqq/components/legacy/MDTypography";
interface Props
@ -37,33 +38,34 @@ interface Props
label: string;
};
icon: ReactNode;
isDisabled?: boolean;
[key: string]: any;
}
function ProcessLinkCard({
color, isReport, title, percentage, icon,
color, isReport, title, percentage, icon, isDisabled
}: Props): JSX.Element
{
return (
<Card>
<Box display="flex" justifyContent="space-between" pt={3} px={2}>
<Box display="flex" justifyContent="space-between" pt={3} px={2} title={isDisabled ? `You do not have permission to access this ${isReport ? "report" : "process"}` : ""}>
<Box
color={color === "light" ? "dark" : "white"}
color={color === "light" ? "#000000" : "#FFFFFF"}
borderRadius="xl"
display="flex"
justifyContent="center"
alignItems="center"
width="4rem"
height="4rem"
mt={-3}
sx={{backgroundColor: color}}
mt={-1.5}
sx={{borderRadius: "10px", backgroundColor: isDisabled ? colors.secondary.main : colors.info.main}}
>
<Icon fontSize="medium" color="inherit">
{icon}
</Icon>
</Box>
<Box textAlign="right" lineHeight={1.25}>
<Box textAlign="right" lineHeight={1.25} mt={1}>
<MDTypography variant="button" fontWeight="bold" color="text">
{title}
</MDTypography>
@ -81,9 +83,15 @@ function ProcessLinkCard({
{percentage.amount}
</MDTypography>
{
isReport
? `Click here to access the ${title} report.`
: `Click here to run the process called ${title}.`
isDisabled ? (
isReport
? `You do not have permission to access the ${title} report.`
: `You do not have permission to run the process called ${title}.`
) : (
isReport
? `Click here to access the ${title} report.`
: `Click here to run the process called ${title}.`
)
}
{percentage.label}
</MDTypography>
@ -100,6 +108,7 @@ ProcessLinkCard.defaultProps = {
text: "",
label: "",
},
isDisabled: false,
};
export default ProcessLinkCard;

View File

@ -61,7 +61,10 @@ function RecordGridWidget({title, data}: Props): JSX.Element
const tableMetaData = new QTableMetaData(data.childTableMetaData);
const {rows, columnsToRender} = DataGridUtils.makeRows(records, tableMetaData);
const childTablePath = data.tablePath + (data.tablePath.endsWith("/") ? "" : "/")
/////////////////////////////////////////////////////////////////////////////////
// note - tablePath may be null, if the user doesn't have access to the table. //
/////////////////////////////////////////////////////////////////////////////////
const childTablePath = data.tablePath ? data.tablePath + (data.tablePath.endsWith("/") ? "" : "/") : data.tablePath;
const columns = DataGridUtils.setupGridColumns(tableMetaData, columnsToRender, childTablePath);
////////////////////////////////////////////////////////////////

View File

@ -46,6 +46,7 @@ interface Props {
component: ReactNode;
};
direction?: "right" | "left";
isDisabled?: boolean;
[key: string]: any;
}
@ -56,6 +57,7 @@ function MiniStatisticsCard({
percentage,
icon,
direction,
isDisabled,
}: Props): JSX.Element
{
const [controller] = useMaterialUIController();
@ -108,7 +110,7 @@ function MiniStatisticsCard({
justifyContent="center"
alignItems="center"
color="#FFFFFF"
sx={{borderRadius: "10px", backgroundColor: colors.info.main}}
sx={{borderRadius: "10px", backgroundColor: isDisabled ? colors.secondary.main : colors.info.main}}
>
<Icon fontSize="medium" color="inherit">
{icon.component}
@ -134,6 +136,7 @@ MiniStatisticsCard.defaultProps = {
text: "",
},
direction: "right",
isDisabled: false,
};
export default MiniStatisticsCard;