add content permission
This commit is contained in:
		
							parent
							
								
									0e2698569a
								
							
						
					
					
						commit
						6e3e2426c8
					
				
					 2 changed files with 70 additions and 10 deletions
				
			
		
							
								
								
									
										59
									
								
								src/permission/permission.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/permission/permission.ts
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,59 @@
 | 
				
			||||||
 | 
					import Koa from 'koa';
 | 
				
			||||||
 | 
					import { UserState } from '../login';
 | 
				
			||||||
 | 
					import { sendError } from '../route/error_handler';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export enum Permission{
 | 
				
			||||||
 | 
					    //========
 | 
				
			||||||
 | 
					    //not implemented
 | 
				
			||||||
 | 
					    //admin only
 | 
				
			||||||
 | 
					    /** remove document */
 | 
				
			||||||
 | 
					    //removeContent = 'removeContent',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** upload document */
 | 
				
			||||||
 | 
					    //uploadContent = 'uploadContent',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** modify document except base path, filename, content_hash. but admin can modify all. */
 | 
				
			||||||
 | 
					    //modifyContent = 'modifyContent',
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /** add tag into document */
 | 
				
			||||||
 | 
					    //addTagContent = 'addTagContent',
 | 
				
			||||||
 | 
					    /** remove tag from document */
 | 
				
			||||||
 | 
					    //removeTagContent = 'removeTagContent',
 | 
				
			||||||
 | 
					    /** ModifyTagInDoc */
 | 
				
			||||||
 | 
					    ModifyTag = 'ModifyTag',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /** find documents with query */
 | 
				
			||||||
 | 
					    //findAllContent = 'findAllContent',
 | 
				
			||||||
 | 
					    /** find one document. */
 | 
				
			||||||
 | 
					    //findOneContent = 'findOneContent',
 | 
				
			||||||
 | 
					    /** view content*/
 | 
				
			||||||
 | 
					    //viewContent = 'viewContent',
 | 
				
			||||||
 | 
					    QueryContent = 'QueryContent',
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /** modify description about the one tag. */
 | 
				
			||||||
 | 
					    modifyTagDesc = 'ModifyTagDesc',
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const createPermissionCheckMiddleware = (...permissions:string[]) => async (ctx: Koa.ParameterizedContext<UserState>,next:Koa.Next)=>{
 | 
				
			||||||
 | 
					    const user = ctx.state['user'];
 | 
				
			||||||
 | 
					    if(user === undefined){
 | 
				
			||||||
 | 
					        return sendError(401,"you are guest. login needed.");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if(user.username === "admin"){
 | 
				
			||||||
 | 
					        return await next();    
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const user_permission = user.permission;
 | 
				
			||||||
 | 
					    //if permissions is not subset of user permission
 | 
				
			||||||
 | 
					    if(!permissions.map(p=>user_permission.includes(p)).every(x=>x)){
 | 
				
			||||||
 | 
					        return sendError(403,"do not have permission");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    await next();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					export const AdminOnlyMiddleware = async (ctx: Koa.ParameterizedContext<UserState>,next:Koa.Next)=>{
 | 
				
			||||||
 | 
					    const user = ctx.state['user'];
 | 
				
			||||||
 | 
					    if(user === undefined || user.username !== "admin"){
 | 
				
			||||||
 | 
					        return sendError(403,"admin only");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    await next();    
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,7 @@ import {sendError} from './error_handler';
 | 
				
			||||||
import { createContentReferrer } from '../content/mod';
 | 
					import { createContentReferrer } from '../content/mod';
 | 
				
			||||||
import { join } from 'path';
 | 
					import { join } from 'path';
 | 
				
			||||||
import {AllContentRouter} from './all';
 | 
					import {AllContentRouter} from './all';
 | 
				
			||||||
 | 
					import {createPermissionCheckMiddleware as PerCheck, Permission as Per, AdminOnlyMiddleware as AdminOnly} from '../permission/permission';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const ContentIDHandler = (controller: ContentAccessor) => async (ctx: Context,next: Next)=>{
 | 
					const ContentIDHandler = (controller: ContentAccessor) => async (ctx: Context,next: Next)=>{
 | 
				
			||||||
    const num = Number.parseInt(ctx.params['num']);
 | 
					    const num = Number.parseInt(ctx.params['num']);
 | 
				
			||||||
| 
						 | 
					@ -128,17 +129,17 @@ const ContentHandler = (controller : ContentAccessor) => async (ctx:Context, nex
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const getContentRouter = (controller: ContentAccessor)=>{
 | 
					export const getContentRouter = (controller: ContentAccessor)=>{
 | 
				
			||||||
    const ret = new Router();
 | 
					    const ret = new Router();
 | 
				
			||||||
    ret.get("/search",ContentQueryHandler(controller));
 | 
					    ret.get("/search",PerCheck(Per.QueryContent),ContentQueryHandler(controller));
 | 
				
			||||||
    ret.get("/:num(\\d+)",ContentIDHandler(controller));
 | 
					    ret.get("/:num(\\d+)",PerCheck(Per.QueryContent),ContentIDHandler(controller));
 | 
				
			||||||
    ret.post("/:num(\\d+)",UpdateContentHandler(controller));
 | 
					    ret.post("/:num(\\d+)",AdminOnly,UpdateContentHandler(controller));
 | 
				
			||||||
    //ret.use("/:num(\\d+)/:content_type");
 | 
					    //ret.use("/:num(\\d+)/:content_type");
 | 
				
			||||||
    ret.post("/",CreateContentHandler(controller));
 | 
					    ret.post("/",AdminOnly,CreateContentHandler(controller));
 | 
				
			||||||
    ret.get("/:num(\\d+)/tags",ContentTagIDHandler(controller));
 | 
					    ret.get("/:num(\\d+)/tags",PerCheck(Per.QueryContent),ContentTagIDHandler(controller));
 | 
				
			||||||
    ret.post("/:num(\\d+)/tags/:tag",AddTagHandler(controller));
 | 
					    ret.post("/:num(\\d+)/tags/:tag",PerCheck(Per.ModifyTag),AddTagHandler(controller));
 | 
				
			||||||
    ret.del("/:num(\\d+)/tags/:tag",DelTagHandler(controller));
 | 
					    ret.del("/:num(\\d+)/tags/:tag",PerCheck(Per.ModifyTag),DelTagHandler(controller));
 | 
				
			||||||
    ret.del("/:num(\\d+)",DeleteContentHandler(controller));
 | 
					    ret.del("/:num(\\d+)",AdminOnly,DeleteContentHandler(controller));
 | 
				
			||||||
    ret.all("/:num(\\d+)/(.*)",ContentHandler(controller));
 | 
					    ret.all("/:num(\\d+)/(.*)",PerCheck(Per.QueryContent),ContentHandler(controller));
 | 
				
			||||||
    ret.use("/:num",(new AllContentRouter).routes());
 | 
					    ret.use("/:num",PerCheck(Per.QueryContent),(new AllContentRouter).routes());
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue