From 1f055a6c7d3762d44aafcda19d57195bdc161182 Mon Sep 17 00:00:00 2001 From: Robert Adams Date: Sun, 13 Jun 2021 13:19:00 -0700 Subject: [PATCH] Rework Places request data setup and permissions Don't lookup Place's domain when doing initial request parameter setup Fix permission lookup to use DOMAINACCESS Closes #92 --- src/route-tools/middleware.ts | 11 +--- src/routes/api/v1/places/placeId.ts | 51 +++++++++---------- .../api/v1/places/placeId/field/fieldname.ts | 4 +- 3 files changed, 28 insertions(+), 38 deletions(-) diff --git a/src/route-tools/middleware.ts b/src/route-tools/middleware.ts index 09842c61..cf6c3166 100755 --- a/src/route-tools/middleware.ts +++ b/src/route-tools/middleware.ts @@ -231,7 +231,7 @@ export const domainFromParams: RequestHandler = async (req: Request, resp: Respo next(); }; -// Look for :placeId label and lookup and set req.vPlace and req.vDomain. +// Look for :placeId label and lookup and set req.vPlace // The accepts either the 'placeId' or the name of the place export const placeFromParams: RequestHandler = async (req: Request, resp: Response, next: NextFunction) => { if (req.params && req.params.placeId) { @@ -240,15 +240,8 @@ export const placeFromParams: RequestHandler = async (req: Request, resp: Respon if (IsNullOrEmpty(aPlace)) { aPlace = await Places.getPlaceWithName(decodeURIComponent(req.params.placeId)); }; - if (aPlace) { - const aDomain = await Domains.getDomainWithId(aPlace.domainId); - if (aDomain) { + if (IsNotNullOrEmpty(aPlace)) { req.vPlace = aPlace; - req.vDomain = aDomain; - } - else { - Logger.error(`placeFromParams: lookup Place with bad domain. placeId=${req.params.placeId}, domainId=${aPlace.domainId}`); - }; }; }; }; diff --git a/src/routes/api/v1/places/placeId.ts b/src/routes/api/v1/places/placeId.ts index 8d5615e5..c8b82266 100755 --- a/src/routes/api/v1/places/placeId.ts +++ b/src/routes/api/v1/places/placeId.ts @@ -25,7 +25,9 @@ import { checkAccessToEntity } from '@Route-Tools/Permissions'; import { buildPlaceInfo } from '@Route-Tools/Util'; +import { Accounts } from '@Entities/Accounts'; import { Places } from '@Entities/Places'; +import { Domains } from '@Entities/Domains'; import { Maturity } from '@Entities/Sets/Maturity'; import { IsNotNullOrEmpty, IsNullOrEmpty } from '@Tools/Misc'; @@ -55,35 +57,30 @@ export const procGetPlacesPlaceId: RequestHandler = async (req: Request, resp: R export const procPutPlacesPlaceId: RequestHandler = async (req: Request, resp: Response, next: NextFunction) => { if (req.vAuthAccount) { if (req.vPlace) { - if (req.vDomain) { - if (await checkAccessToEntity(req.vAuthToken, req.vDomain, [ Perm.SPONSOR, Perm.ADMIN ], req.vAuthAccount)) { - if (req.body.place) { - const updates: VKeyedCollection = {}; - if (req.body.place.pointee_query) { - // The caller specified a domain. Either the same domain or changing - if (req.body.place.pointee_query !== req.vPlace.domainId) { - Logger.info(`procPutPlacesPlaceId: domain changing from ${req.vPlace.domainId} to ${req.body.place.pointee_query}`) - req.vPlace.domainId = req.body.place.pointee_query; - updates.domainId = req.vPlace.domainId; - }; + if (await checkAccessToEntity(req.vAuthToken, req.vPlace, [ Perm.DOMAINACCESS, Perm.ADMIN ], req.vAuthAccount)) { + if (req.body.place) { + const updates: VKeyedCollection = {}; + if (req.body.place.pointee_query) { + // The caller specified a domain. Either the same domain or changing + if (req.body.place.pointee_query !== req.vPlace.domainId) { + Logger.info(`procPutPlacesPlaceId: domain changing from ${req.vPlace.domainId} to ${req.body.place.pointee_query}`) + req.vPlace.domainId = req.body.place.pointee_query; + updates.domainId = req.vPlace.domainId; }; - for (const field of [ 'path', 'description', 'thumbnail' ]) { - if (req.body.place.hasOwnProperty(field)) { - await Places.setField(req.vAuthToken, req.vPlace, field, req.body.place[field], req.vAuthAccount, updates); - }; + }; + for (const field of [ 'path', 'description', 'thumbnail' ]) { + if (req.body.place.hasOwnProperty(field)) { + await Places.setField(req.vAuthToken, req.vPlace, field, req.body.place[field], req.vAuthAccount, updates); }; - Places.updateEntityFields(req.vPlace, updates); - } - else { - req.vRestResp.respondFailure('badly formed data'); }; + Places.updateEntityFields(req.vPlace, updates); } else { - req.vRestResp.respondFailure('unauthorized'); + req.vRestResp.respondFailure('badly formed data'); }; } else { - req.vRestResp.respondFailure('Target domain not found'); + req.vRestResp.respondFailure('unauthorized'); }; } else { @@ -99,9 +96,9 @@ export const procPutPlacesPlaceId: RequestHandler = async (req: Request, resp: R export const procDeletePlacesPlaceId: RequestHandler = async (req: Request, resp: Response, next: NextFunction) => { if (req.vAuthAccount) { if (req.vPlace) { - if (await checkAccessToEntity(req.vAuthToken, req.vDomain, [ Perm.SPONSOR, Perm.ADMIN ], req.vAuthAccount)) { - Logger.info(`procDeletePlacesPlaceId: deleting place "${req.vPlace.name}", id=${req.vPlace.id}`); - await Places.removePlace(req.vPlace); + if (await checkAccessToEntity(req.vAuthToken, req.vPlace, [ Perm.DOMAINACCESS, Perm.ADMIN ], req.vAuthAccount)) { + Logger.info(`procDeletePlacesPlaceId: deleting place "${req.vPlace.name}", id=${req.vPlace.id}`); + await Places.removePlace(req.vPlace); } else { req.vRestResp.respondFailure('unauthorized'); @@ -124,19 +121,19 @@ export const router = Router(); router.get( '/api/v1/places/:placeId', [ setupMetaverseAPI, // req.vRESTResp accountFromAuthToken, // req.vAuthAccount - placeFromParams, // req.vPlace, req.vDomain + placeFromParams, // req.vPlace procGetPlacesPlaceId, finishMetaverseAPI ] ); router.put( '/api/v1/places/:placeId', [ setupMetaverseAPI, // req.vRESTResp accountFromAuthToken, // req.vAuthAccount - placeFromParams, // req.vPlace, req.vDomain + placeFromParams, // req.vPlace procPutPlacesPlaceId, finishMetaverseAPI ] ); router.delete( '/api/v1/places/:placeId', [ setupMetaverseAPI, // req.vRESTResp accountFromAuthToken, // req.vAuthAccount - placeFromParams, // req.vPlace, req.vDomain + placeFromParams, // req.vPlace procDeletePlacesPlaceId, finishMetaverseAPI ] ); diff --git a/src/routes/api/v1/places/placeId/field/fieldname.ts b/src/routes/api/v1/places/placeId/field/fieldname.ts index d9413299..713fbe76 100755 --- a/src/routes/api/v1/places/placeId/field/fieldname.ts +++ b/src/routes/api/v1/places/placeId/field/fieldname.ts @@ -71,7 +71,7 @@ export const router = Router(); router.get( '/api/v1/places/:placeId/field/:param1', [ setupMetaverseAPI, // req.vRestResp - placeFromParams, // req.vPlace, req.vDomain + placeFromParams, // req.vPlace param1FromParams, // req.vParam1 (field name) procGetField, finishMetaverseAPI @@ -79,7 +79,7 @@ router.get( '/api/v1/places/:placeId/field/:param1', router.post('/api/v1/places/:placeId/field/:param1', [ setupMetaverseAPI, // req.vRestResp accountFromAuthToken, // req.vAuthAccount - placeFromParams, // req.vPlace, req.vDomain + placeFromParams, // req.vPlace param1FromParams, // req.vParam1 (field name) procPostField, finishMetaverseAPI