Skip to content

Commit

Permalink
Merge branch 'main' into feat-cd-deploy-impaas
Browse files Browse the repository at this point in the history
  • Loading branch information
Gum-Joe committed Aug 21, 2024
2 parents 9aad48b + b8bf427 commit 3ab5ee1
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 13 deletions.
22 changes: 13 additions & 9 deletions components/navbar/DesktopNavbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import ProfileDropdown from "@/components/navbar/ProfileDropdown"
import { NavbarProps, isSignedIn } from "./Navbar"
import styles from "./desktopNavbar.module.scss"

import RestrictedAreaClient from "../rbac/RestrictedAreaClient"
import { Role } from "@prisma/client"
import { Flex } from "@radix-ui/themes"
import { useSession } from "next-auth/react"
import Image from "next/image"
Expand All @@ -27,15 +29,17 @@ const DesktopNavbar = (props: NavbarProps) => {

{isSignedIn(data, props) && (
<Flex className={styles.linksContainer}>
<Link href="/companies" className={styles.link}>
<span>Companies</span>
</Link>
<Link href="/events" className={styles.link}>
<span>Events</span>
</Link>
<Link href="/opportunities" className={styles.link}>
<span>Opportunities</span>
</Link>
<RestrictedAreaClient allowedRoles={[Role.STUDENT]} showMessage={false}>
<Link href="/companies" className={styles.link}>
<span>Companies</span>
</Link>
<Link href="/events" className={styles.link}>
<span>Events</span>
</Link>
<Link href="/opportunities" className={styles.link}>
<span>Opportunities</span>
</Link>
</RestrictedAreaClient>
<Link href="/students" className={styles.link}>
<span>Students</span>
</Link>
Expand Down
11 changes: 7 additions & 4 deletions components/navbar/MobileNavbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import styles from "./mobileNavbar.module.scss"

import Link from "../Link"
import UserAvatar from "../UserAvatar"
import RestrictedAreaClient from "../rbac/RestrictedAreaClient"
import { CONTENT_ID, FOOTER_ID } from "../util/constants"
import { Role } from "@prisma/client"
import * as DropdownMenu from "@radix-ui/react-dropdown-menu"
import { Button, Flex, Heading, IconButton, Link as RadixLink, Separator, Text } from "@radix-ui/themes"
import { signOut, useSession } from "next-auth/react"
Expand Down Expand Up @@ -57,10 +59,11 @@ const AuthenticatedContent = (props: RoleNavbarProps) => {
)}

<Separator orientation="horizontal" className={styles.Separator} />

<SidebarLink href="/companies" Icon={BsBuilding} displayText="Companies" />
<SidebarLink href="/events" Icon={BsCalendar2Date} displayText="Events" />
<SidebarLink href="/opportunities" Icon={BsBriefcase} displayText="Opportunities" />
<RestrictedAreaClient allowedRoles={[Role.STUDENT]} showMessage={false}>
<SidebarLink href="/companies" Icon={BsBuilding} displayText="Companies" />
<SidebarLink href="/events" Icon={BsCalendar2Date} displayText="Events" />
<SidebarLink href="/opportunities" Icon={BsBriefcase} displayText="Opportunities" />
</RestrictedAreaClient>
<SidebarLink href="/students" Icon={BsMortarboard} displayText="Students" />

<Separator orientation="horizontal" className={styles.Separator} />
Expand Down
39 changes: 39 additions & 0 deletions components/rbac/RestrictedAreaClient.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { Role } from "@prisma/client"
import { Session } from "next-auth"
import { useSession } from "next-auth/react"
import React from "react"

/**
* Make children only be available to certain roles - designed for client-side use where a server-side check is not possible.
* @param children The children to display if the user is authenticated and has the correct role.
* @param allowedRoles (default []) The roles that are allowed to access the children. Note: ADMIN is always allowed and should not be passed explicitly.
* @param showMessage (default true) Whether to show a message if the user is not authenticated or does not have the correct role.
* @param additionalCheck (default async() => true) An additional check is not performed for ADMIN.
*/
const RestrictedAreaClient = ({
children,
allowedRoles = [],
showMessage = true,
additionalCheck = () => true,
}: {
children: React.ReactNode
allowedRoles?: Role[]
showMessage?: boolean
additionalCheck?: (session: Session) => boolean
}) => {
const { data: session } = useSession()

if (!session) {
return showMessage ? <p>Not authenticated.</p> : <></>
}

// Allow ADMIN to access all restricted areas
// Additional check function is not performed for ADMIN
if (session.user.role === "ADMIN" || (allowedRoles.includes(session.user.role) && additionalCheck(session))) {
return <>{children}</>
}

return showMessage ? <p>Not authorised.</p> : <></>
}

export default RestrictedAreaClient

0 comments on commit 3ab5ee1

Please sign in to comment.