imageManagementRoutes.test.ts 2.0 KB

123456789101112131415161718192021222324
  1. // @vitest-environment node
  2. import {it,expect,vi} from 'vitest'
  3. import Koa from 'koa'
  4. import {bodyParser} from '@koa/bodyparser'
  5. import request from 'supertest'
  6. import {mkdtempSync,rmSync} from 'node:fs'
  7. import {tmpdir} from 'node:os'
  8. import {join} from 'node:path'
  9. import {randomUUID} from 'node:crypto'
  10. import {WorkspaceStore} from '../../src/server/workspaceStore'
  11. import {ImageManagementService} from '../../src/server/imageManagement'
  12. import {HttpError} from '../../src/server/errors'
  13. it('restricts image operations to admins and fences job grants to user version and Runner',async()=>{
  14. const home=mkdtempSync(join(tmpdir(),'yaoyao-image-route-')),store=new WorkspaceStore(home);let version=1,active=true
  15. const auth:any={requireAdmin:(ctx:any)=>{if(ctx.get('x-admin')!=='yes')throw new HttpError(403,'管理员权限','admin_required');return {id:'owner'}},isAdminActive:()=>active,pushAuthorizationVersion:()=>version}
  16. const images=vi.fn(async(owner:string,runnerId:string,p:any)=>({owner,runnerId,job:{id:p.id}})),service=new ImageManagementService(store,auth,{images} as any),app=new Koa();app.use(async(ctx,next)=>{try{await next()}catch(e){ctx.status=(e as any).status||500;ctx.body={error:String(e)}}});app.use(bodyParser());app.use(service.router().routes())
  17. try{const runner=randomUUID(),id=randomUUID(),base=`/api/app/admin/runners/${runner}/images`
  18. await request(app.callback()).post(base+'/jobs').send({requestId:id,operation:'prepare'}).expect(403);expect(images).not.toHaveBeenCalled()
  19. await request(app.callback()).post(base+'/jobs').set('x-admin','yes').send({requestId:id,operation:'prepare',path:'/etc/passwd'}).expect(400)
  20. await request(app.callback()).post(base+'/jobs').set('x-admin','yes').send({requestId:id,operation:'prepare'}).expect(202)
  21. expect(service.allowed(id,runner)).toBe(true);expect(service.allowed(id,randomUUID())).toBe(false)
  22. version++;expect(service.allowed(id,runner)).toBe(false);version--;active=false;expect(service.allowed(id,runner)).toBe(false)
  23. }finally{store.close();rmSync(home,{recursive:true,force:true})}
  24. })