sesamefilter
This commit is contained in:
+12
-5
@@ -25,6 +25,7 @@ export class RPCServer<
|
||||
private errorHandler: T.ErrorHandler
|
||||
private connectionHandler: T.ConnectionHandler
|
||||
private sesame? : T.SesameFunction
|
||||
private accessFilter: T.AccessFilter<InterfaceT, SubResType>
|
||||
|
||||
/**
|
||||
* @throws On RPC with no name
|
||||
@@ -35,10 +36,12 @@ export class RPCServer<
|
||||
constructor(
|
||||
private port:number,
|
||||
private exporters: Exporters<InterfaceT, SubResType> = [],
|
||||
conf: T.ServerConf = {}
|
||||
conf: T.ServerConf<InterfaceT, SubResType> = {}
|
||||
){
|
||||
if(!conf.visibility) this.visibility = "127.0.0.1"
|
||||
|
||||
this.accessFilter = conf.accessFilter || (async () => true)
|
||||
|
||||
if(conf.sesame){
|
||||
this.sesame = U.makeSesameFunction(conf.sesame)
|
||||
}
|
||||
@@ -87,10 +90,14 @@ export class RPCServer<
|
||||
}
|
||||
|
||||
protected initRPCs(socket:I.Socket){
|
||||
socket.hook('info', () => rpcInfos)
|
||||
const rpcInfos:T.ExtendedRpcInfo[] = [
|
||||
...this.exporters.flatMap(exporter => U.rpcHooker(socket, exporter, this.errorHandler, this.sesame))
|
||||
]
|
||||
socket.hook('info', async (sesame? : string) => {
|
||||
const rpcs = await Promise.all(this.exporters.map(async exp => {
|
||||
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])
|
||||
})
|
||||
|
||||
const info:T.ExtendedRpcInfo[] = await this.info()
|
||||
const info:T.ExtendedRpcInfo[] = await this.info(sesame)
|
||||
info.forEach(i => {
|
||||
let f: any
|
||||
|
||||
@@ -159,9 +159,9 @@ export class RPCSocket implements I.Socket{
|
||||
/**
|
||||
* 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")
|
||||
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 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 ConnectionHandler = (socket:I.Socket) => void
|
||||
export type ErrorHandler = (socket:I.Socket, error:any, rpcName: string, args: any[]) => void
|
||||
@@ -17,7 +17,8 @@ export type FrontEndHandlerType = {
|
||||
'close' : () => void
|
||||
}
|
||||
|
||||
export type ServerConf = {
|
||||
export type ServerConf<InterfaceT extends RPCInterface, SubresT> = {
|
||||
accessFilter?: AccessFilter<InterfaceT, SubresT>
|
||||
connectionHandler?: ConnectionHandler
|
||||
errorHandler?: ErrorHandler
|
||||
closeHandler?: CloseHandler
|
||||
|
||||
+25
-4
@@ -542,8 +542,9 @@ type myExporterIfc = {
|
||||
describe("Class binding", ()=>{
|
||||
|
||||
let exporter1 : MyExporter
|
||||
let serv : RPCServer
|
||||
let serv : RPCServer<{}, myExporterIfc>
|
||||
let sock: RPCSocket & myExporterIfc
|
||||
let allowed = true
|
||||
|
||||
class MyExporter implements RPCExporter<myExporterIfc>{
|
||||
name = "MyExporter" as "MyExporter";
|
||||
@@ -563,20 +564,34 @@ describe("Class binding", ()=>{
|
||||
this.myRPC
|
||||
]
|
||||
|
||||
myRPC = async () => "Hello Borld"
|
||||
myRPC = async () => {
|
||||
return "Hello Borld"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
before(done => {
|
||||
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()
|
||||
})
|
||||
|
||||
beforeEach((done)=>{
|
||||
|
||||
const s = new RPCSocket(21004, 'localhost')
|
||||
s.connect<myExporterIfc>().then(conn => {
|
||||
s.connect<myExporterIfc>("xxx").then(conn => {
|
||||
sock = conn
|
||||
done()
|
||||
})
|
||||
@@ -596,6 +611,7 @@ describe("Class binding", ()=>{
|
||||
done(new Error(res))
|
||||
}).catch(e => {
|
||||
//job will time out because of setExporters
|
||||
allowed = true
|
||||
done()
|
||||
})
|
||||
})
|
||||
@@ -608,6 +624,11 @@ describe("Class binding", ()=>{
|
||||
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