Created
August 29, 2022 18:47
-
-
Save tsibley/a42514eca2a44a73e5bf7eb33cfe3235 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
| diff --git a/src/app.js b/src/app.js | |
| index 75b14b7..4a03fb4 100644 | |
| --- a/src/app.js | |
| +++ b/src/app.js | |
| @@ -20,6 +20,7 @@ const PRODUCTION = process.env.NODE_ENV === "production"; | |
| const CANARY_ORIGIN = process.env.CANARY_ORIGIN; | |
| const authn = require("./authn"); | |
| +const authz = require("./authz"); | |
| const endpoints = require("./endpoints"); | |
| const {AuthzDenied} = require("./exceptions"); | |
| const {replacer: jsonReplacer} = require("./json"); | |
| @@ -45,7 +46,6 @@ const { | |
| CoreStagingSource, | |
| CommunitySource, | |
| UrlDefinedSource, | |
| - GroupSource, | |
| } = sources; | |
| const esc = encodeURIComponent; | |
| @@ -279,13 +279,13 @@ app.routeAsync("/fetch/:authority/*") | |
| */ | |
| app.use("/groups/:groupName", | |
| - setSource(req => new GroupSource(req.params.groupName)), | |
| + endpoints.groups.setGroup(req => req.params.groupName), | |
| // Canonicalize the Group name. | |
| (req, res, next) => { | |
| const restOfUrl = req.url !== "/" ? req.url : ""; | |
| - const canonicalName = req.context.source.group.name; | |
| + const canonicalName = req.context.group.name; | |
| const canonicalUrl = `/groups/${esc(canonicalName)}${restOfUrl}`; | |
| return req.params.groupName !== canonicalName | |
| @@ -301,7 +301,7 @@ app.routeAsync("/groups/:groupName") | |
| ; | |
| app.use("/groups/:groupName/settings", | |
| - endpoints.groups.setGroup(req => req.params.groupName)); | |
| + authz.assertAuthorizedReq(req => [req.user, authz.actions.Read, req.context.group])); | |
| app.routeAsync("/groups/:groupName/settings/members") | |
| .getAsync(endpoints.groups.listMembers); | |
| @@ -326,14 +326,18 @@ app.routeAsync("/groups/:groupName/narratives") | |
| .getAsync((req, res) => res.redirect(`/groups/${esc(req.params.groupName)}`)); | |
| app.routeAsync("/groups/:groupName/narratives/*") | |
| - .all(setNarrative(req => req.params[0])) | |
| + .all( | |
| + setSource(req => req.context.group.source()), | |
| + setNarrative(req => req.params[0])) | |
| .getAsync(getNarrative) | |
| .putAsync(putNarrative) | |
| .deleteAsync(deleteNarrative) | |
| ; | |
| app.routeAsync("/groups/:groupName/*") | |
| - .all(setDataset(req => req.params[0])) | |
| + .all( | |
| + setSource(req => req.context.group.source()), | |
| + setDataset(req => req.params[0])) | |
| .getAsync(getDataset) | |
| .putAsync(putDataset) | |
| .deleteAsync(deleteDataset) | |
| diff --git a/src/authz/index.js b/src/authz/index.js | |
| index 8aeeab2..85dc8b9 100644 | |
| --- a/src/authz/index.js | |
| +++ b/src/authz/index.js | |
| @@ -122,9 +122,31 @@ const assertAuthorized = (user, action, object) => { | |
| }; | |
| +/** | |
| + * Express-style middleware that calls {@link assertAuthorized} with the (user, | |
| + * action, object) produced from the request by the given extractor function. | |
| + * | |
| + * @param {argsExtractor} argsExtractor - Function to extract (user, action, | |
| + * object) array from the request | |
| + * @returns {expressMiddleware} | |
| + * @throws {AuthzDenied} | |
| + */ | |
| +const assertAuthorizedReq = (argsExtractor) => (req, res, next) => { | |
| + assertAuthorized(...argsExtractor(req)); | |
| + return next(); | |
| +}; | |
| + | |
| +/** | |
| + * @callback argsExtractor | |
| + * @param {express.request} req | |
| + * @returns {Array} args - three element array of (user, action, object) | |
| + */ | |
| + | |
| + | |
| module.exports = { | |
| authorized, | |
| assertAuthorized, | |
| + assertAuthorizedReq, | |
| evaluatePolicy, | |
| actions, | |
| diff --git a/src/endpoints/groups.js b/src/endpoints/groups.js | |
| index 7a38e66..ad72d48 100644 | |
| --- a/src/endpoints/groups.js | |
| +++ b/src/endpoints/groups.js | |
| @@ -8,8 +8,6 @@ const {slurp} = require("../utils/iterators"); | |
| const setGroup = (nameExtractor) => (req, res, next) => { | |
| const group = new Group(nameExtractor(req)); | |
| - authz.assertAuthorized(req.user, authz.actions.Read, group); | |
| - | |
| req.context.group = group; | |
| return next(); | |
| }; | |
| diff --git a/src/groups.js b/src/groups.js | |
| index 552c588..1512133 100644 | |
| --- a/src/groups.js | |
| +++ b/src/groups.js | |
| @@ -88,6 +88,18 @@ class Group { | |
| } | |
| + /** | |
| + * Source for this Group. | |
| + */ | |
| + source() { | |
| + // XXX FIXME re-consider ordering that puts this require here or if we'd | |
| + // rather shift a require around elsewhere or otherwise change the module | |
| + // dep graph. | |
| + const {GroupSource} = require("./sources"); | |
| + return new GroupSource(this); | |
| + } | |
| + | |
| + | |
| /** | |
| * Policy for this Group itself. Separate from the policy for the group's | |
| * Source, which is the container for the group's datasets and narratives. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment