Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into MCR-3777-single-rate
Browse files Browse the repository at this point in the history
  • Loading branch information
haworku committed Feb 6, 2024
2 parents fa8f498 + 23fd4ea commit a1b3769
Show file tree
Hide file tree
Showing 4 changed files with 77 additions and 3 deletions.
22 changes: 21 additions & 1 deletion services/app-api/src/resolvers/rate/fetchRate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,12 @@ import {
setSuccessAttributesOnActiveSpan,
} from '../attributeHelper'
import { NotFoundError } from '../../postgres'
import type { QueryResolvers } from '../../gen/gqlServer'
import type { QueryResolvers, State } from '../../gen/gqlServer'
import type { Store } from '../../postgres'
import { GraphQLError } from 'graphql'
import { isStateUser } from '../../domain-models'
import { logError } from '../../logger'
import { ForbiddenError } from 'apollo-server-core'

export function fetchRateResolver(store: Store): QueryResolvers['fetchRate'] {
return async (_parent, { input }, context) => {
Expand Down Expand Up @@ -35,6 +38,23 @@ export function fetchRateResolver(store: Store): QueryResolvers['fetchRate'] {
})
}

if (isStateUser(user)) {
const stateForCurrentUser: State['code'] = user.stateCode
if (rateWithHistory.stateCode !== stateForCurrentUser) {
logError(
'fetchRate',
'State users are not authorized to fetch rate data from a different state.'
)
setErrorAttributesOnActiveSpan(
'State users are not authorized to fetch rate data from a different state.',
span
)
throw new ForbiddenError(
'State users are not authorized to fetch rate data from a different state.'
)
}
}

setSuccessAttributesOnActiveSpan(span)
return { rate: rateWithHistory }
}
Expand Down
28 changes: 28 additions & 0 deletions services/app-web/src/pages/Errors/ErrorForbiddenPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react'
import styles from './Errors.module.scss'
import { GridContainer } from '@trussworks/react-uswds'
import { PageHeading } from '../../components'

interface ForbiddenErrorPageProps {
errorMsg?: string
}

export const ErrorForbiddenPage = ({
errorMsg,
}: ForbiddenErrorPageProps): React.ReactElement => {
return (
<section className={styles.errorsContainer}>
<GridContainer>
<PageHeading>Forbidden</PageHeading>
{errorMsg ? (
<p>{errorMsg}</p>
) : (
<p>
You do not have permission to view the requested file or
resource.
</p>
)}
</GridContainer>
</section>
)
}
17 changes: 16 additions & 1 deletion services/app-web/src/pages/RateEdit/RateEdit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import { RouteT, RoutesRecord } from '../../constants'
import { PageBannerAlerts } from '../StateSubmission/StateSubmissionForm'
import { useAuth } from '../../contexts/AuthContext'
import { FormContainer } from '../StateSubmission/FormContainer'
import { ErrorForbiddenPage } from '../Errors/ErrorForbiddenPage'
import { Error404 } from '../Errors/Error404Page'

export type SubmitOrUpdateRate = (
rateID: string,
Expand Down Expand Up @@ -84,7 +86,20 @@ export const RateEdit = (): React.ReactElement => {
</GridContainer>
)
} else if (fetchError || !rate) {
return <GenericErrorPage />
//error handling for a state user that tries to access rates for a different state
if (fetchError?.graphQLErrors[0]?.extensions?.code === 'FORBIDDEN') {
return (
<ErrorForbiddenPage
errorMsg={fetchError.graphQLErrors[0].message}
/>
)
} else if (
fetchError?.graphQLErrors[0]?.extensions?.code === 'NOT_FOUND'
) {
return <Error404 />
} else {
return <GenericErrorPage />
}
}

if (rate.status !== 'UNLOCKED') {
Expand Down
13 changes: 12 additions & 1 deletion services/app-web/src/pages/RateSummary/RateSummary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import { GenericErrorPage } from '../Errors/GenericErrorPage'
import { RoutesRecord } from '../../constants'
import { SingleRateSummarySection } from '../../components/SubmissionSummarySection/RateDetailsSummarySection/SingleRateSummarySection'
import { useAuth } from '../../contexts/AuthContext'
import { ErrorForbiddenPage } from '../Errors/ErrorForbiddenPage'
import { Error404 } from '../Errors/Error404Page'

type RouteParams = {
id: string
Expand Down Expand Up @@ -50,7 +52,16 @@ export const RateSummary = (): React.ReactElement => {
</GridContainer>
)
} else if (error || !rate || !currentRateRev?.formData) {
return <GenericErrorPage />
//error handling for a state user that tries to access rates for a different state
if (error?.graphQLErrors[0]?.extensions?.code === 'FORBIDDEN') {
return (
<ErrorForbiddenPage errorMsg={error.graphQLErrors[0].message} />
)
} else if (error?.graphQLErrors[0]?.extensions?.code === 'NOT_FOUND') {
return <Error404 />
} else {
return <GenericErrorPage />
}
}

// Redirecting a state user to the edit page if rate is unlocked
Expand Down

0 comments on commit a1b3769

Please sign in to comment.