mirror of
https://github.com/Jermolene/TiddlyWiki5
synced 2024-11-29 21:09:56 +00:00
parent
266b32bfee
commit
0cd2190ddf
@ -31,9 +31,14 @@ exports.useACL = true;
|
|||||||
exports.entityName = "recipe"
|
exports.entityName = "recipe"
|
||||||
|
|
||||||
exports.handler = function(request,response,state) {
|
exports.handler = function(request,response,state) {
|
||||||
|
var server = state.server,
|
||||||
|
sqlTiddlerDatabase = server.sqlTiddlerDatabase
|
||||||
if(state.data.recipe_name && state.data.bag_names) {
|
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);
|
const result = $tw.mws.store.createRecipe(state.data.recipe_name,$tw.utils.parseStringArray(state.data.bag_names),state.data.description);
|
||||||
if(!result) {
|
if(!result) {
|
||||||
|
if(state.authenticatedUser) {
|
||||||
|
sqlTiddlerDatabase.assignRecipeToUser(state.data.recipe_name,state.authenticatedUser.user_id);
|
||||||
|
}
|
||||||
state.sendResponse(302,{
|
state.sendResponse(302,{
|
||||||
"Content-Type": "text/plain",
|
"Content-Type": "text/plain",
|
||||||
"Location": "/"
|
"Location": "/"
|
||||||
|
@ -48,33 +48,44 @@ exports.middleware = function (request, response, state, entityType, permissionN
|
|||||||
var aclRecord = sqlTiddlerDatabase.getACLByName(entityType, decodedEntityName);
|
var aclRecord = sqlTiddlerDatabase.getACLByName(entityType, decodedEntityName);
|
||||||
var isGetRequest = request.method === "GET";
|
var isGetRequest = request.method === "GET";
|
||||||
var hasAnonymousAccess = isGetRequest ? state.allowAnonReads : state.allowAnonWrites;
|
var hasAnonymousAccess = isGetRequest ? state.allowAnonReads : state.allowAnonWrites;
|
||||||
// Get permission record
|
var entity = sqlTiddlerDatabase.getEntityByName(entityType, decodedEntityName);
|
||||||
const permission = sqlTiddlerDatabase.getPermissionByName(permissionName);
|
if(entity?.owner_id) {
|
||||||
// ACL Middleware will only apply if the entity has a middleware record
|
if(state.authenticatedUser?.user_id !== entity.owner_id) {
|
||||||
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) {
|
if(!response.headersSent) {
|
||||||
response.writeHead(403, "Forbidden");
|
response.writeHead(403, "Forbidden");
|
||||||
response.end();
|
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 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 (
|
CREATE TABLE IF NOT EXISTS recipes (
|
||||||
recipe_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
recipe_id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
recipe_name TEXT UNIQUE NOT NULL,
|
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
|
-- ...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;
|
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:}
|
Returns {tiddler_id:}
|
||||||
*/
|
*/
|
||||||
@ -486,6 +500,18 @@ SqlTiddlerDatabase.prototype.getRecipeTiddler = function(title,recipe_name) {
|
|||||||
Checks if a user has permission to access a recipe
|
Checks if a user has permission to access a recipe
|
||||||
*/
|
*/
|
||||||
SqlTiddlerDatabase.prototype.hasRecipePermission = function(userId, recipeName, permissionName) {
|
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)
|
return this.checkACLPermission(userId, "recipe", recipeName, permissionName)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -556,7 +582,7 @@ SqlTiddlerDatabase.prototype.checkACLPermission = function(userId, entityType, e
|
|||||||
$permission_id: aclRecord.permission_id
|
$permission_id: aclRecord.permission_id
|
||||||
});
|
});
|
||||||
|
|
||||||
const hasPermission = result !== undefined;
|
let hasPermission = result !== undefined;
|
||||||
|
|
||||||
return hasPermission;
|
return hasPermission;
|
||||||
};
|
};
|
||||||
@ -578,6 +604,19 @@ SqlTiddlerDatabase.prototype.getEntityAclRecords = function(entityName) {
|
|||||||
return aclRecords
|
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
|
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