-
Notifications
You must be signed in to change notification settings - Fork 1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds a hasRole() and isAuthenticated() to determine the role membersh…
…ip or if the request is authenticated (#3006) * Move parseJWT * Adds isAuthenticated and hasRole to auth.js * Moves parseJWT from api into api/auth * Reformat auth.js template * Update role and auth check logic * Use roles instead of role * Use roles * Default auth ts uses roles * Update auth templates to use roles instead of role * Updates templates for other providers * Updates dbauth auth template * Simplify hasRole logic * Update packages/cli/src/commands/setup/auth/templates/auth.js.template Co-authored-by: Tobbe Lundberg <[email protected]> * Update packages/cli/src/commands/setup/auth/templates/auth.js.template Co-authored-by: Tobbe Lundberg <[email protected]> * Clarify hasRole return value if no roles provided Co-authored-by: Tobbe Lundberg <[email protected]>
- Loading branch information
1 parent
f61940a
commit ecf8aa9
Showing
10 changed files
with
198 additions
and
82 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103 changes: 62 additions & 41 deletions
103
packages/cli/src/commands/setup/auth/templates/azureActiveDirectory.auth.js.template
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,61 +1,82 @@ | ||
// Define what you want `currentUser` to return throughout your app. For example, | ||
// to return a real user from your database, you could do something like: | ||
// | ||
// export const getCurrentUser = async ({ email }) => { | ||
// return await db.user.findUnique({ where: { email } }) | ||
// } | ||
|
||
import { AuthenticationError, ForbiddenError, parseJWT } from '@redwoodjs/api' | ||
|
||
export const getCurrentUser = async (decoded, { token, type }) => { | ||
return { | ||
email: decoded.preferred_username ?? null, | ||
...decoded, | ||
roles: parseJWT({ decoded }).roles | ||
} | ||
/** | ||
* getCurrentUser returns the user information together with | ||
* an optional collection of roles used by requireAuth() to check | ||
* if the user is authenticated or has role-based access | ||
* | ||
* @param decoded - The decoded access token containing user info and JWT claims like `sub` | ||
* @param { token, SupportedAuthTypes type } - The access token itself as well as the auth provider type | ||
* @param { APIGatewayEvent event, Context context } - An object which contains information from the invoker | ||
* such as headers and cookies, and the context information about the invocation such as IP Address | ||
* | ||
* @see https://github.com/redwoodjs/redwood/tree/main/packages/auth for examples | ||
*/ | ||
export const getCurrentUser = async ( | ||
decoded, | ||
{ _token, _type }, | ||
{ _event, _context } | ||
) => { | ||
return { ...decoded, roles: parseJWT({ decoded }).roles } | ||
} | ||
|
||
// Use this function in your services to check that a user is logged in, and | ||
// optionally raise an error if they're not. | ||
/** | ||
* The user is authenticated if there is a currentUser in the context | ||
* | ||
* @returns {boolean} - If the currentUser is authenticated | ||
*/ | ||
export const isAuthenticated = () => { | ||
return !!context.currentUser | ||
} | ||
|
||
/** | ||
* Checks if the currentUser is authenticated (and assigned one of the given roles) | ||
* | ||
* @param {string= | string[]=} roles - A single role or list of roles to check if the user belongs to | ||
* | ||
* @returns {boolean} - Returns true if the currentUser is authenticated (and assigned one of the given roles) | ||
*/ | ||
export const hasRole = ({ roles }) => { | ||
if (!isAuthenticated()) { | ||
return false | ||
} | ||
|
||
if(!!roles) { | ||
if (Array.isArray(roles) { | ||
return context.currentUser.roles?.some((r) => roles.includes(r)) | ||
} | ||
|
||
if (typeof roles === 'string') { | ||
return context.currentUser.roles?.includes(roles) | ||
} | ||
|
||
// roles not found | ||
return false | ||
} | ||
|
||
return false | ||
} | ||
|
||
/** | ||
* Use requireAuth in your services to check that a user is logged in, | ||
* whether or not they are assigned a role, and optionally raise an | ||
* error if they're not. | ||
* | ||
* @param {string=} roles - An optional role or list of roles | ||
* @param {string[]=} roles - An optional list of roles | ||
|
||
* @example | ||
* @param {string= | string[]=} roles - A single role or list of roles to check if the user belongs to | ||
* | ||
* // checks if currentUser is authenticated | ||
* requireAuth() | ||
* @returns - If the currentUser is authenticated (and assigned one of the given roles) | ||
* | ||
* @example | ||
* @throws {AuthenticationError} - If the currentUser is not authenticated | ||
* @throws {ForbiddenError} If the currentUser is not allowed due to role permissions | ||
* | ||
* // checks if currentUser is authenticated and assigned one of the given roles | ||
* requireAuth({ role: 'admin' }) | ||
* requireAuth({ role: ['editor', 'author'] }) | ||
* requireAuth({ role: ['publisher'] }) | ||
* @see https://github.com/redwoodjs/redwood/tree/main/packages/auth for examples | ||
*/ | ||
export const requireAuth = ({ role } = {}) => { | ||
if (!context.currentUser) { | ||
export const requireAuth = ({ roles } = {}) => { | ||
if (!isAuthenticated) { | ||
throw new AuthenticationError("You don't have permission to do that.") | ||
} | ||
|
||
if ( | ||
typeof role !== 'undefined' && | ||
typeof role === 'string' && | ||
!context.currentUser.roles?.includes(role) | ||
) { | ||
throw new ForbiddenError("You don't have access to do that.") | ||
} | ||
|
||
if ( | ||
typeof role !== 'undefined' && | ||
Array.isArray(role) && | ||
!context.currentUser.roles?.some((r) => role.includes(r)) | ||
) { | ||
if (!hasRole({ roles })) { | ||
throw new ForbiddenError("You don't have access to do that.") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters