sesamefilter
This commit is contained in:
+12
-5
@@ -25,6 +25,7 @@ export class RPCServer<
|
|||||||
private errorHandler: T.ErrorHandler
|
private errorHandler: T.ErrorHandler
|
||||||
private connectionHandler: T.ConnectionHandler
|
private connectionHandler: T.ConnectionHandler
|
||||||
private sesame? : T.SesameFunction
|
private sesame? : T.SesameFunction
|
||||||
|
private accessFilter: T.AccessFilter<InterfaceT, SubResType>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @throws On RPC with no name
|
* @throws On RPC with no name
|
||||||
@@ -35,10 +36,12 @@ export class RPCServer<
|
|||||||
constructor(
|
constructor(
|
||||||
private port:number,
|
private port:number,
|
||||||
private exporters: Exporters<InterfaceT, SubResType> = [],
|
private exporters: Exporters<InterfaceT, SubResType> = [],
|
||||||
conf: T.ServerConf = {}
|
conf: T.ServerConf<InterfaceT, SubResType> = {}
|
||||||
){
|
){
|
||||||
if(!conf.visibility) this.visibility = "127.0.0.1"
|
if(!conf.visibility) this.visibility = "127.0.0.1"
|
||||||
|
|
||||||
|
this.accessFilter = conf.accessFilter || (async () => true)
|
||||||
|
|
||||||
if(conf.sesame){
|
if(conf.sesame){
|
||||||
this.sesame = U.makeSesameFunction(conf.sesame)
|
this.sesame = U.makeSesameFunction(conf.sesame)
|
||||||
}
|
}
|
||||||
@@ -87,10 +90,14 @@ export class RPCServer<
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected initRPCs(socket:I.Socket){
|
protected initRPCs(socket:I.Socket){
|
||||||
socket.hook('info', () => rpcInfos)
|
socket.hook('info', async (sesame? : string) => {
|
||||||
const rpcInfos:T.ExtendedRpcInfo[] = [
|
const rpcs = await Promise.all(this.exporters.map(async exp => {
|
||||||
...this.exporters.flatMap(exporter => U.rpcHooker(socket, exporter, this.errorHandler, this.sesame))
|
const allowed = await this.accessFilter(sesame, exp)
|
||||||
]
|
if(!allowed) return []
|
||||||
|
return U.rpcHooker(socket, exp, this.errorHandler, this.sesame)
|
||||||
|
}))
|
||||||
|
return rpcs.flat()
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+3
-3
@@ -136,7 +136,7 @@ export class RPCSocket implements I.Socket{
|
|||||||
this.socket.hook(kv[0], kv[1])
|
this.socket.hook(kv[0], kv[1])
|
||||||
})
|
})
|
||||||
|
|
||||||
const info:T.ExtendedRpcInfo[] = await this.info()
|
const info:T.ExtendedRpcInfo[] = await this.info(sesame)
|
||||||
info.forEach(i => {
|
info.forEach(i => {
|
||||||
let f: any
|
let f: any
|
||||||
|
|
||||||
@@ -159,9 +159,9 @@ export class RPCSocket implements I.Socket{
|
|||||||
/**
|
/**
|
||||||
* Get a list of available RPCs from the server
|
* Get a list of available RPCs from the server
|
||||||
*/
|
*/
|
||||||
public async info(){
|
public async info(sesame?:string){
|
||||||
if(!this.socket) throw new Error("The socket is not connected! Use socket.connect() first")
|
if(!this.socket) throw new Error("The socket is not connected! Use socket.connect() first")
|
||||||
return await this.socket.call('info')
|
return await this.socket.call('info', sesame)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
+3
-2
@@ -2,7 +2,7 @@ import * as I from "./Interfaces";
|
|||||||
|
|
||||||
export type AnyFunction = (...args:any) => any
|
export type AnyFunction = (...args:any) => any
|
||||||
export type HookFunction<F extends AnyFunction = AnyFunction, SubresT = {}> = (...args: Parameters<F>) => Promise<SubscriptionResponse<SubresT> | ErrorResponse>
|
export type HookFunction<F extends AnyFunction = AnyFunction, SubresT = {}> = (...args: Parameters<F>) => Promise<SubscriptionResponse<SubresT> | ErrorResponse>
|
||||||
|
export type AccessFilter<InterfaceT extends RPCInterface, SubresT> = (sesame:string|undefined, exporter: I.RPCExporter<RPCInterface<InterfaceT>, keyof InterfaceT, SubresT>) => Promise<boolean>
|
||||||
export type Visibility = "127.0.0.1" | "0.0.0.0"
|
export type Visibility = "127.0.0.1" | "0.0.0.0"
|
||||||
export type ConnectionHandler = (socket:I.Socket) => void
|
export type ConnectionHandler = (socket:I.Socket) => void
|
||||||
export type ErrorHandler = (socket:I.Socket, error:any, rpcName: string, args: any[]) => void
|
export type ErrorHandler = (socket:I.Socket, error:any, rpcName: string, args: any[]) => void
|
||||||
@@ -17,7 +17,8 @@ export type FrontEndHandlerType = {
|
|||||||
'close' : () => void
|
'close' : () => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ServerConf = {
|
export type ServerConf<InterfaceT extends RPCInterface, SubresT> = {
|
||||||
|
accessFilter?: AccessFilter<InterfaceT, SubresT>
|
||||||
connectionHandler?: ConnectionHandler
|
connectionHandler?: ConnectionHandler
|
||||||
errorHandler?: ErrorHandler
|
errorHandler?: ErrorHandler
|
||||||
closeHandler?: CloseHandler
|
closeHandler?: CloseHandler
|
||||||
|
|||||||
+25
-4
@@ -542,8 +542,9 @@ type myExporterIfc = {
|
|||||||
describe("Class binding", ()=>{
|
describe("Class binding", ()=>{
|
||||||
|
|
||||||
let exporter1 : MyExporter
|
let exporter1 : MyExporter
|
||||||
let serv : RPCServer
|
let serv : RPCServer<{}, myExporterIfc>
|
||||||
let sock: RPCSocket & myExporterIfc
|
let sock: RPCSocket & myExporterIfc
|
||||||
|
let allowed = true
|
||||||
|
|
||||||
class MyExporter implements RPCExporter<myExporterIfc>{
|
class MyExporter implements RPCExporter<myExporterIfc>{
|
||||||
name = "MyExporter" as "MyExporter";
|
name = "MyExporter" as "MyExporter";
|
||||||
@@ -563,20 +564,34 @@ describe("Class binding", ()=>{
|
|||||||
this.myRPC
|
this.myRPC
|
||||||
]
|
]
|
||||||
|
|
||||||
myRPC = async () => "Hello Borld"
|
myRPC = async () => {
|
||||||
|
return "Hello Borld"
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
before(done => {
|
before(done => {
|
||||||
exporter1 = new MyExporter()
|
exporter1 = new MyExporter()
|
||||||
serv = new RPCServer(21004, [exporter1])
|
serv = new RPCServer<{}, myExporterIfc>(21004, [exporter1], {
|
||||||
|
accessFilter: async (sesame,exporter) => {
|
||||||
|
switch(exporter.name){
|
||||||
|
case "MyExporter":
|
||||||
|
if(!allowed) return false
|
||||||
|
allowed = false
|
||||||
|
return sesame==='xxx';
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
sesame: "xxx"
|
||||||
|
})
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
|
|
||||||
beforeEach((done)=>{
|
beforeEach((done)=>{
|
||||||
|
|
||||||
const s = new RPCSocket(21004, 'localhost')
|
const s = new RPCSocket(21004, 'localhost')
|
||||||
s.connect<myExporterIfc>().then(conn => {
|
s.connect<myExporterIfc>("xxx").then(conn => {
|
||||||
sock = conn
|
sock = conn
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
@@ -596,6 +611,7 @@ describe("Class binding", ()=>{
|
|||||||
done(new Error(res))
|
done(new Error(res))
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
//job will time out because of setExporters
|
//job will time out because of setExporters
|
||||||
|
allowed = true
|
||||||
done()
|
done()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -608,6 +624,11 @@ describe("Class binding", ()=>{
|
|||||||
done(new Error(res))
|
done(new Error(res))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("use sesameFilter", (done) => {
|
||||||
|
if(!sock['MyExporter']) done()
|
||||||
|
else done(new Error("RPC supposed to be gone"))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user