fix(api): проверять достоверность WAN и не опрашивать выключенные серверы
This commit is contained in:
1 parent
4f084222ad
commit
d91cc77cda
13 files changed
+353
-12
No files matched your search
@@ -0,0 +1,27 @@
|
||||
import assert from 'node:assert/strict'
|
||||
import fs from 'node:fs'
|
||||
import {createServer} from 'node:http'
|
||||
import {randomBytes} from 'node:crypto'
|
||||
const database=process.env.MMAPP_OWN_SQL_DB,url=new URL(process.env.DATABASE_URL)
|
||||
assert(/^mm_accept_166_\d+$/.test(database??''));assert.equal(url.pathname,'/'+database);assert.equal(url.username,database)
|
||||
process.env.AUTH_REQUIRED='true';process.env.AUTH_JWT_SECRET=randomBytes(32).toString('hex');process.env.AUTH_ISSUER='https://own217.invalid';process.env.AUTH_PORTAL_URL='https://own217.invalid'
|
||||
const {pool,closePool}=await import('/app/backend/dist/db/index.js'),{initDatabase}=await import('/app/backend/dist/db/bootstrap.js'),{buildApp}=await import('/app/backend/dist/index.js')
|
||||
assert.equal((await pool.query('SELECT current_database() AS name')).rows[0].name,database);assert(Object.values((await pool.query('SELECT rolsuper,rolcreatedb,rolcreaterole,rolbypassrls FROM pg_roles WHERE rolname=current_user')).rows[0]).every(v=>v===false))
|
||||
const baseline=process.env.MMAPP_BASELINE==='true',cases=[];let phase='populated',nativeCalls=0,nativeWrites=0,app
|
||||
const collections={dhcp:[{interface:'ether1',address:'192.0.2.10/24',gateway:'192.0.2.254',status:'bound'}],addresses:[{address:'192.0.2.10/24',interface:'ether1'}],routes:[{'dst-address':'0.0.0.0/0',gateway:'192.0.2.254','immediate-gw':'192.0.2.254%ether1',active:'true',distance:'1'}]}
|
||||
const native=createServer((req,res)=>{nativeCalls++;if(req.method!=='GET')nativeWrites++;res.setHeader('content-type','application/json');const section=req.url==='/rest/ip/dhcp-client'?'dhcp':req.url==='/rest/ip/address'?'addresses':'routes';if(phase==='fail-'+section){res.statusCode=401;res.end(JSON.stringify({error:401,message:'own217 denied'}));return}res.end(JSON.stringify(phase==='malformed-'+section?[{unknown:'fixture'}]:phase==='empty'?[]:collections[section]))});await new Promise(r=>native.listen(0,'127.0.0.1',r))
|
||||
const report={date:'2026-10-14',block:'12.5.217',baseline,database,cases,scope:'Compiled WAN runtime route/auth, owned SQL/native HTTP fixture; real CHR untouched',passed:false}
|
||||
try{
|
||||
await initDatabase();const uplinks=[{id:'wan1',iface:'ether1',name:'WAN-test',isp:'Fixture',ip:'198.51.100.10',maxDl:100,maxUl:50}],id=Number((await pool.query("INSERT INTO servers(name,host,port,use_ssl,enabled,username,password,type,wan_uplinks) VALUES('own217-native','127.0.0.1',$1,false,true,'fixture','fixture','home-router',$2::jsonb) RETURNING id",[native.address().port,JSON.stringify(uplinks)])).rows[0].id)
|
||||
app=await buildApp({logger:false,startScheduler:false});await app.ready();const token=permissions=>app.jwt.sign({sub:'own217-reader',apps:['mm'],permissions,iss:process.env.AUTH_ISSUER},{expiresIn:'5m'}),headers={authorization:'Bearer '+token(['mm:servers:read'])},endpoint='/api/servers/'+id+'/wan-runtime'
|
||||
for(const [name,h,status] of [['anonymous',{},401],['wrong permission',{authorization:'Bearer '+token(['mm:network:read'])},403]]){const before=nativeCalls,r=await app.inject({method:'GET',url:endpoint,headers:h});assert.equal(r.statusCode,status);assert.equal(nativeCalls,before);cases.push({phase:name,status,nativeCalls:0})}
|
||||
for(phase of ['populated','empty','fail-dhcp','fail-addresses','fail-routes','malformed-dhcp','malformed-addresses','malformed-routes','recovery']){
|
||||
const before=nativeCalls,r=await app.inject({method:'GET',url:endpoint,headers}),body=r.json(),failed=phase.startsWith('fail-')||phase.startsWith('malformed-');assert.equal(r.statusCode,failed&&!baseline?502:200)
|
||||
if(failed&&!baseline)assert.match(body.error,/WAN:/)
|
||||
else{assert.deepEqual(Object.keys(body).sort(),['defaultGateway','defaultInterface','immediateGateway','uplinks']);assert.equal(body.uplinks.length,1);if(['populated','recovery'].includes(phase)){assert.equal(body.defaultGateway,'192.0.2.254');assert.equal(body.defaultInterface,'ether1');assert.equal(body.uplinks[0].leasedIp,'192.0.2.10');assert.equal(body.uplinks[0].isDefault,true)}if(phase==='empty'){assert.equal(body.defaultGateway,null);assert.equal(body.uplinks[0].leasedIp,null);assert.equal(body.uplinks[0].isDefault,false)}}
|
||||
cases.push({phase,status:r.statusCode,nativeCalls:nativeCalls-before})
|
||||
}
|
||||
phase='populated';for(const type of ['home-router','exit-node']){await pool.query('UPDATE servers SET enabled=false,type=$1 WHERE id=$2',[type,id]);const before=nativeCalls,r=await app.inject({method:'GET',url:endpoint,headers});assert.equal(r.statusCode,baseline?200:409);if(!baseline){assert.equal(nativeCalls,before);assert.match(r.json().error,/выключен/)}else assert(nativeCalls>before);cases.push({phase:'disabled',type,status:r.statusCode,nativeCalls:nativeCalls-before})}
|
||||
for(const [path,status] of [['/api/servers/9999999/wan-runtime',404],['/api/servers/1oops/wan-runtime',400]]){const before=nativeCalls,r=await app.inject({method:'GET',url:path,headers});assert.equal(r.statusCode,status);assert.equal(nativeCalls,before);cases.push({phase:'missing-invalid',status,nativeCalls:0})}
|
||||
assert.equal(nativeWrites,0);report.passed=true
|
||||
}catch(e){report.errorName=e.name;fs.writeFileSync('/app/backend/acceptance/wan217-private.log',String(e.stack??e),{mode:0o600})}finally{if(app)await app.close();native.closeAllConnections();await new Promise(r=>native.close(r));await closePool();report.nativeWrites=nativeWrites;fs.writeFileSync('/app/backend/acceptance/wan217-'+(baseline?'baseline':'fixed')+'.json',JSON.stringify(report,null,2));console.log(JSON.stringify(report))}if(!report.passed)process.exitCode=1
|
||||
Reference in new issue
Block a user