From ae5bd9d4cd500d52a084d6d0de93c973fa884c1a Mon Sep 17 00:00:00 2001 From: webplusai Date: Wed, 11 Dec 2024 13:08:09 +0100 Subject: [PATCH] #8812 resolve issue with anonymous access (#8814) --- .../multiwikiserver/modules/mws-server.js | 4 +-- .../modules/routes/handlers/get-index.js | 4 +-- .../modules/routes/helpers/acl-middleware.js | 35 ++++++++++--------- 3 files changed, 23 insertions(+), 20 deletions(-) diff --git a/plugins/tiddlywiki/multiwikiserver/modules/mws-server.js b/plugins/tiddlywiki/multiwikiserver/modules/mws-server.js index fd033b3d7..be46a53d2 100644 --- a/plugins/tiddlywiki/multiwikiserver/modules/mws-server.js +++ b/plugins/tiddlywiki/multiwikiserver/modules/mws-server.js @@ -453,10 +453,10 @@ Server.prototype.requestHandler = function(request,response,options) { // Check whether anonymous access is granted state.allowAnon = false; //this.isAuthorized(state.authorizationType,null); var {allowReads, allowWrites, isEnabled} = this.getAnonymousAccessConfig(); - state.allowAnon = isEnabled; + state.allowAnon = isEnabled && (request.method === 'GET' ? allowReads : allowWrites); state.allowAnonReads = allowReads; state.allowAnonWrites = allowWrites; - state.showAnonConfig = !!state.authenticatedUser?.isAdmin && !state.allowAnon; + state.showAnonConfig = !!state.authenticatedUser?.isAdmin && !isEnabled; state.firstGuestUser = this.sqlTiddlerDatabase.listUsers().length === 0 && !state.authenticatedUser; // Authorize with the authenticated username diff --git a/plugins/tiddlywiki/multiwikiserver/modules/routes/handlers/get-index.js b/plugins/tiddlywiki/multiwikiserver/modules/routes/handlers/get-index.js index 88e51ac1c..7b2f39719 100644 --- a/plugins/tiddlywiki/multiwikiserver/modules/routes/handlers/get-index.js +++ b/plugins/tiddlywiki/multiwikiserver/modules/routes/handlers/get-index.js @@ -31,8 +31,8 @@ exports.handler = function(request,response,state) { "Content-Type": "text/html" }); // filter bags and recipies by user's read access from ACL - var allowedRecipes = recipeList.filter(recipe => sqlTiddlerDatabase.hasRecipePermission(state.authenticatedUser?.user_id, recipe.recipe_name, 'READ') || state.allowAnonReads); - var allowedBags = bagList.filter(bag => sqlTiddlerDatabase.hasBagPermission(state.authenticatedUser?.user_id, bag.bag_name, 'READ') || state.allowAnonReads); + var allowedRecipes = recipeList.filter(recipe => recipe.recipe_name.startsWith("$:/") || sqlTiddlerDatabase.hasRecipePermission(state.authenticatedUser?.user_id, recipe.recipe_name, 'READ') || state.allowAnon && state.allowAnonReads); + var allowedBags = bagList.filter(bag => bag.bag_name.startsWith("$:/") || sqlTiddlerDatabase.hasBagPermission(state.authenticatedUser?.user_id, bag.bag_name, 'READ') || state.allowAnon && state.allowAnonReads); // Render the html var html = $tw.mws.store.adminWiki.renderTiddler("text/plain","$:/plugins/tiddlywiki/multiwikiserver/templates/page",{ diff --git a/plugins/tiddlywiki/multiwikiserver/modules/routes/helpers/acl-middleware.js b/plugins/tiddlywiki/multiwikiserver/modules/routes/helpers/acl-middleware.js index 2bd044965..2f66060ea 100644 --- a/plugins/tiddlywiki/multiwikiserver/modules/routes/helpers/acl-middleware.js +++ b/plugins/tiddlywiki/multiwikiserver/modules/routes/helpers/acl-middleware.js @@ -47,10 +47,10 @@ exports.middleware = function (request, response, state, entityType, permissionN var decodedEntityName = decodeURIComponent(partiallyDecoded); var aclRecord = sqlTiddlerDatabase.getACLByName(entityType, decodedEntityName); var isGetRequest = request.method === "GET"; - var hasAnonymousAccess = isGetRequest ? state.allowAnonReads : state.allowAnonWrites; + var hasAnonymousAccess = state.allowAnon && (isGetRequest ? state.allowAnonReads : state.allowAnonWrites); var entity = sqlTiddlerDatabase.getEntityByName(entityType, decodedEntityName); if(entity?.owner_id) { - if(state.authenticatedUser?.user_id !== entity.owner_id) { + if(state.authenticatedUser?.user_id && (state.authenticatedUser?.user_id !== entity.owner_id) || !state.authenticatedUser?.user_id && !hasAnonymousAccess) { if(!response.headersSent) { response.writeHead(403, "Forbidden"); response.end(); @@ -58,22 +58,25 @@ exports.middleware = function (request, response, state, entityType, permissionN return; } } else { - // Get permission record - const permission = sqlTiddlerDatabase.getPermissionByName(permissionName); - // ACL Middleware will only apply if the entity has a middleware record - if(aclRecord && aclRecord?.permission_id === permission?.permission_id) { - // If not authenticated and anonymous access is not allowed, request authentication - if(!state.authenticatedUsername && !state.allowAnon) { - if(state.urlInfo.pathname !== '/login') { - redirectToLogin(response, request.url); - return; - } - } - // Check if user is authenticated - if(!state.authenticatedUser && !hasAnonymousAccess && !response.headersSent) { + // First, we need to check if anonymous access is allowed + if(!state.authenticatedUser?.user_id && !hasAnonymousAccess && (isGetRequest && entity?.owner_id)) { + if(!response.headersSent) { response.writeHead(401, "Unauthorized"); response.end(); - return; + } + return; + } else { + // Get permission record + const permission = sqlTiddlerDatabase.getPermissionByName(permissionName); + // ACL Middleware will only apply if the entity has a middleware record + if(aclRecord && aclRecord?.permission_id === permission?.permission_id) { + // If not authenticated and anonymous access is not allowed, request authentication + if(!state.authenticatedUsername && !state.allowAnon) { + if(state.urlInfo.pathname !== '/login') { + redirectToLogin(response, request.url); + return; + } + } } // Check ACL permission