mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-26 11:37:20 +00:00
parent
266b32bfee
commit
0cd2190ddf
@ -31,9 +31,14 @@ exports.useACL = true;
|
||||
exports.entityName = "recipe"
|
||||
|
||||
exports.handler = function(request,response,state) {
|
||||
var server = state.server,
|
||||
sqlTiddlerDatabase = server.sqlTiddlerDatabase
|
||||
if(state.data.recipe_name && state.data.bag_names) {
|
||||
const result = $tw.mws.store.createRecipe(state.data.recipe_name,$tw.utils.parseStringArray(state.data.bag_names),state.data.description);
|
||||
if(!result) {
|
||||
if(state.authenticatedUser) {
|
||||
sqlTiddlerDatabase.assignRecipeToUser(state.data.recipe_name,state.authenticatedUser.user_id);
|
||||
}
|
||||
state.sendResponse(302,{
|
||||
"Content-Type": "text/plain",
|
||||
"Location": "/"
|
||||
|
@ -48,33 +48,44 @@ exports.middleware = function (request, response, state, entityType, permissionN
|
||||
var aclRecord = sqlTiddlerDatabase.getACLByName(entityType, decodedEntityName);
|
||||
var isGetRequest = request.method === "GET";
|
||||
var hasAnonymousAccess = isGetRequest ? state.allowAnonReads : state.allowAnonWrites;
|
||||
// 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) {
|
||||
response.writeHead(401, "Unauthorized");
|
||||
response.end();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check ACL permission
|
||||
var hasPermission = request.method === "POST" || sqlTiddlerDatabase.checkACLPermission(state.authenticatedUser.user_id, entityType, decodedEntityName, permissionName)
|
||||
if(!hasPermission && !hasAnonymousAccess) {
|
||||
var entity = sqlTiddlerDatabase.getEntityByName(entityType, decodedEntityName);
|
||||
if(entity?.owner_id) {
|
||||
if(state.authenticatedUser?.user_id !== entity.owner_id) {
|
||||
if(!response.headersSent) {
|
||||
response.writeHead(403, "Forbidden");
|
||||
response.end();
|
||||
}
|
||||
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) {
|
||||
response.writeHead(401, "Unauthorized");
|
||||
response.end();
|
||||
return;
|
||||
}
|
||||
|
||||
// Check ACL permission
|
||||
var hasPermission = request.method === "POST" || sqlTiddlerDatabase.checkACLPermission(state.authenticatedUser.user_id, entityType, decodedEntityName, permissionName)
|
||||
if(!hasPermission && !hasAnonymousAccess) {
|
||||
if(!response.headersSent) {
|
||||
response.writeHead(403, "Forbidden");
|
||||
response.end();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -137,7 +137,9 @@ SqlTiddlerDatabase.prototype.createTables = function() {
|
||||
CREATE TABLE IF NOT EXISTS recipes (
|
||||
recipe_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
recipe_name TEXT UNIQUE NOT NULL,
|
||||
description TEXT NOT NULL
|
||||
description TEXT NOT NULL,
|
||||
owner_id INTEGER,
|
||||
FOREIGN KEY (owner_id) REFERENCES users(user_id)
|
||||
)
|
||||
`,`
|
||||
-- ...and recipes also have an ordered list of bags
|
||||
@ -291,6 +293,18 @@ SqlTiddlerDatabase.prototype.createRecipe = function(recipe_name,bag_names,descr
|
||||
return updateRecipes.lastInsertRowid;
|
||||
};
|
||||
|
||||
/*
|
||||
Assign a recipe to a user
|
||||
*/
|
||||
SqlTiddlerDatabase.prototype.assignRecipeToUser = function(recipe_name,user_id) {
|
||||
this.engine.runStatement(`
|
||||
UPDATE recipes SET owner_id = $user_id WHERE recipe_name = $recipe_name
|
||||
`,{
|
||||
$recipe_name: recipe_name,
|
||||
$user_id: user_id
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
Returns {tiddler_id:}
|
||||
*/
|
||||
@ -486,6 +500,18 @@ SqlTiddlerDatabase.prototype.getRecipeTiddler = function(title,recipe_name) {
|
||||
Checks if a user has permission to access a recipe
|
||||
*/
|
||||
SqlTiddlerDatabase.prototype.hasRecipePermission = function(userId, recipeName, permissionName) {
|
||||
// check if the user is the owner of the entity
|
||||
const recipe = this.engine.runStatementGet(`
|
||||
SELECT owner_id
|
||||
FROM recipes
|
||||
WHERE recipe_name = $recipe_name
|
||||
`, {
|
||||
$recipe_name: recipeName
|
||||
});
|
||||
|
||||
if(recipe?.owner_id) {
|
||||
return recipe.owner_id === userId;
|
||||
}
|
||||
return this.checkACLPermission(userId, "recipe", recipeName, permissionName)
|
||||
};
|
||||
|
||||
@ -556,7 +582,7 @@ SqlTiddlerDatabase.prototype.checkACLPermission = function(userId, entityType, e
|
||||
$permission_id: aclRecord.permission_id
|
||||
});
|
||||
|
||||
const hasPermission = result !== undefined;
|
||||
let hasPermission = result !== undefined;
|
||||
|
||||
return hasPermission;
|
||||
};
|
||||
@ -578,6 +604,19 @@ SqlTiddlerDatabase.prototype.getEntityAclRecords = function(entityName) {
|
||||
return aclRecords
|
||||
}
|
||||
|
||||
/*
|
||||
Get the entity by name
|
||||
*/
|
||||
SqlTiddlerDatabase.prototype.getEntityByName = function(entityType, entityName) {
|
||||
const entityInfo = this.entityTypeToTableMap[entityType];
|
||||
if (entityInfo) {
|
||||
return this.engine.runStatementGet(`SELECT * FROM ${entityInfo.table} WHERE ${entityInfo.column} = $entity_name`, {
|
||||
$entity_name: entityName
|
||||
});
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
Get the titles of the tiddlers in a bag. Returns an empty array for bags that do not exist
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user