From 3db753e886955f7f534d0d0af7f18beb96c845c9 Mon Sep 17 00:00:00 2001 From: Laurin Wolf Date: Tue, 26 Apr 2022 09:51:11 +0200 Subject: [PATCH] =?UTF-8?q?feat(auth):=20=F0=9F=94=92=20add=20checking=20f?= =?UTF-8?q?or=20required=20group?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/builder/pages/api/auth/[...nextauth].ts | 35 +++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/apps/builder/pages/api/auth/[...nextauth].ts b/apps/builder/pages/api/auth/[...nextauth].ts index c15527c1a9..92841037e4 100644 --- a/apps/builder/pages/api/auth/[...nextauth].ts +++ b/apps/builder/pages/api/auth/[...nextauth].ts @@ -1,4 +1,4 @@ -import NextAuth from 'next-auth' +import NextAuth, { Account } from 'next-auth' import EmailProvider from 'next-auth/providers/email' import GitHubProvider from 'next-auth/providers/github' import GitlabProvider from 'next-auth/providers/gitlab' @@ -96,6 +96,14 @@ const handler = (req: NextApiRequest, res: NextApiResponse) => { user: userFromDb, } }, + signIn: async ({ account }) => { + const requiredGroups = getRequiredGroups(account.provider) + if (requiredGroups.length > 0) { + const userGroups = await getUserGroups(account) + return checkHasGroups(userGroups, requiredGroups) + } + return true + }, }, }) } @@ -113,4 +121,29 @@ const updateLastActivityDate = async (user: User) => { }) } +async function getUserGroups(account: Account): Promise { + switch (account.provider) { + case 'gitlab': { + const res = await fetch( + `${process.env.NEXT_PUBLIC_GITLAB_BASE_URL || 'gitlab.com'}/api/v4/groups`, + { headers: { 'Authorization': `Bearer ${account.access_token}` } }, + ) + const userGroups: string[] = (await res.json()) + return userGroups.map((group: any) => group.full_path) + } + default: return [] + } +} + +function getRequiredGroups(provider: string): string[] { + switch (provider) { + case 'gitlab': return process.env.GITLAB_REQUIRED_GROUPS?.split(',') || [] + default: return [] + } +} + +function checkHasGroups(userGroups: string[], requiredGroups: string[]) { + return userGroups?.some(userGroup => requiredGroups?.includes(userGroup)) +} + export default withSentry(handler)